diff --git a/packages/mobile-aelf/app.json b/packages/mobile-aelf/app.json index 450db7b60..e4a3342c2 100644 --- a/packages/mobile-aelf/app.json +++ b/packages/mobile-aelf/app.json @@ -8,6 +8,11 @@ "ios": { "googleServicesFile": "./GoogleService-Info.plist" }, - "plugins": ["@react-native-firebase/app", "@react-native-firebase/perf", "@react-native-firebase/crashlytics"] + "plugins": [ + "@react-native-firebase/app", + "@react-native-firebase/perf", + "@react-native-firebase/crashlytics", + "react-native-cloud-storage" + ] } } diff --git a/packages/mobile-aelf/js/assets/image/svgs.js b/packages/mobile-aelf/js/assets/image/svgs.js index b1ede2b79..2f23a2713 100644 --- a/packages/mobile-aelf/js/assets/image/svgs.js +++ b/packages/mobile-aelf/js/assets/image/svgs.js @@ -1,2 +1,2 @@ /* eslint-disable prettier/prettier */ -export default {'Contract':'\n\n\n\n\n','ELF':'\n\n\n','ETransfer':'\n\n\n','ETransferLogo':'\n\n\n\n\n\n\n\n\n\n\n','accessory':'\n\n\n','activity-fail':'\n\n\n\n\n\n\n','activity-mined':'\n\n\n\n\n\n\n','activity-pending':'\n\n\n\n\n\n\n\n\n\n','activity':'\n\n\n\n','add-contact':'\n\n\n\n\n\n\n','add-contact1':'\n \n','add-tab':'\n\n\n','add':'\n\n\n','add1':'\n\n\n\n\n\n\n','add2':'\n\n ymquiytxjt\n \n \n \n \n \n \n \n \n \n \n \n \n \n','add3':'\n\n wivmphxoms\n \n \n \n \n \n \n \n \n','add4':'\n\n\n','album':'\n\n epepouhbdw\n \n \n \n \n \n \n \n \n','allowance-delete':'\n \n','app-blue-logo':'\n\n\n\n','app-logo-new':'\n\n\n\n','apple-icon':'\n\n\n\n\n\n','apple-white':'\n\n\n','apple':'\n\n\n\n','arrow-down-thin':'\n\n\n\n\n','arrow-left':'\n\n\n','arrow-right-thin':'\n\n\n\n\n','arrow-right':'\n\n\n','awaken-swap-round':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','awaken-swap':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','awakenLogo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','bingoGame':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','block-back':'\n\n\n','book-mark-fill':'\n\n\n','book-mark':'\n\n\n','bookmark':'\n\n\n\n','bookmarked':'\n\n\n\n','buy':'\n\n\n\n\n','buy1':'\n\n\n\n','buy2':'\n\n\n\n','camera':'\n\n\n\n\n','chain_Logos':'\n\n\n\n\n\n\n','chain_side':'\n\n\n\n\n\n\n\n\n','change':'\n\n\n','chat-add-contact':'\n\n\n','chat-add-member':'\n\n\n','chat-add':'\n\n\n','chat-added':'\n\n\n','chat-album':'\n\n\n\n\n','chat-block':'cg\n\n\n','chat-bookmark':'\n\n\n','chat-camera':'\n\n\n\n','chat-chat':'\n\n\n','chat-create-group':'\n\n\n\n\n\n','chat-delete-emoji':'\n\n\n\n\n','chat-delete':'\n\n\n','chat-emoji':'\n\n\n\n\n\n','chat-file':'\n\n\n\n\n\n\n\n\n\n\n\n','chat-find-more':'\n\n\n\n','chat-group-avatar-header':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-avatar-small-logo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-avatar':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-info':'\n\n\n\n\n\n','chat-keyboard':'\n\n\n\n\n\n\n\n\n\n\n\n','chat-leave-group':'\n\n\n\n\n','chat-mute':'\n\n\n','chat-new-chat':'\n\n\n','chat-pin':'\n\n\n','chat-profile':'\n\n\n\n\n','chat-qr-code':'\n\n\n','chat-remove-member':'\n\n\n','chat-reply':'\n\n\n','chat-report':'\n\n\n','chat-reshutter':'\n\n\n\n\n','chat-robot':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-scroll-to-bottom':'\n\n\n\n','chat-send':'\n\n\n','chat-shutter':'\n\n\n\n','chat-tab':'\n\n\n','chat-transfer':'\n\n\n\n\n','chat-unmute':'\n\n\n\n\n','chat-unpin':'\n\n\n\n\n','chat-unsupported-channel':'\n\n\n\n\n\n\n\n\n\n\n\n','check-circle':'\n\n\n\n\n','check-false':'\n\n fzoykpdoyh\n \n \n \n \n \n \n \n','check-true':'\n\n mbcnnswjqh\n \n \n \n \n \n \n \n \n \n \n','check':'\n\n\n','checkUpdate':'\n\n\n\n\n\n\n','checkbox-Checked':'\n\n\n\n\n\n\n\n\n\n\n','checkbox-new':'\n\n\n','checkbox':'\n\n\n\n\n\n\n','checked':'\n\n\n','checked_circle':'\n\n\n\n\n','chevron-right':'\n \n','chevron_down':'\n\n\n\n\n','chevron_right':'\n\n\n','chevron_right2':'\n\n\n','clear':'\n\n qzqvrhcbqn\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','clear1':'\n\n pgqcjmcbit\n \n \n \n \n \n \n \n \n','clear2':'\n\n oinrqzcjps\n \n \n \n \n \n \n \n \n \n \n \n \n','clear3':'\n\n\n','clear4':'\n\n\n\n','clock':'\n\n\n','close-red-packet':'\n\n\n\n\n','close':'\n\n tqsruqxgrb\n \n \n \n \n \n \n \n \n','close1':'\n\n ozresgjsts\n \n \n \n \n \n \n \n \n \n \n','close2':'\n\n yyybesklsg\n \n \n \n \n \n \n \n \n \n \n','close3':'\n\n\n','close4':'\n\n\n\n\n','close_thick':'\n\n\n\n\n','collect':'\n\n\n','collected':'\n\n\n','contact':'\n\n ymwllfkfjj\n \n \n \n \n \n \n \n \n \n \n \n \n \n','contact2':'\n\n mkokwgrdlj\n \n \n \n \n \n \n \n \n \n \n','copy-checked':'\n\n\n\n','copy-pre':'\n\n\n\n','copy-thin':'\n\n\n\n\n','copy':'\n\n\n\n\n','copy1':'\n\n\n\n','copy3':'\n\n\n','copy_v2':'\n\n\n\n\n','crypto-box-with-border':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','crypto-gift':'\n\n\n\n\n','default_record':'\n\n\n\n\n','delete-image2':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','delete-img':'\n\n\n\n\n\n\n\n\n\n\n\n\n','delete-mint':'\n\n\n\n\n','delete':'\n\n\n','deposit-receive':'\n\n\n\n','deposit':'\n\n\n\n','deposit1':'\n\n\n\n','depositMain':'\n\n\n\n','deposit_status_failed':'\n\n\n','deposit_status_processing':'\n\n\n','deposit_status_success':'\n\n\n','desk-mac':'\n\n desk_mac\n \n \n \n \n \n \n \n \n \n \n','desk-win':'\n\n wnusftfmuc\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','direction-arrow-right':'\n\n\n\n\n\n\n','direction-right':'\n\n\n','direction-up':'\n\n\n','direction_down':'\n\n\n\n\n','disabled_visible':'\n\n\n','discord':'\n\n\n','discover':'\n\n\n\n','discover_close':'\n\n\n\n\n','down-arrow':'\n\n\n','drag':'\n\n\n\n','eBridge':'\n\n\n\n\n\n\n\n\n\n\n\n','eBridgeFavIcon':'\n\n\n\n\n\n','eBridgeLogo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','edit':'\n\n\n','edit1':'\n \n','edit_thin':'\n\n\n\n\n','edit_token':'\n\n\n\n\n\n\n','elf-icon':'\n\n\n\n\n','email-login':'\n\n\n','email-white':'\n\n\n\n\n\n\n\n\n\n','email':'\n\n\n\n\n\n\n\n\n\n','error':'\n\n\n\n\n','explore':'\n\n\n','external':'\n \n','eye':'\n\n\n\n\n','eyeClosed':'\n\n\n\n\n','face-id':'\n\n\n','facebook-icon':'\n\n\n\n\n\n\n\n\n\n\n\n','facebook-white':'\n\n\n','facebook':'\n\n\n','fail':'\n\n gjgrrybzwe\n \n \n \n \n \n \n','faucet':'\n\n\n\n\n\n\n\n\n\n','favorite-disable':'\n\n\n','favorite-unselected':'\n\n\n','favorite':'\n\n\n','filter-top':'\n\n\n','filter':'\n\n\n','finish':'\n\n sytkvvhtjm\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','forest':'\n\n\n\n','free-mint-entry':'\n\n\n\n\n','gear':'\n\n\n\n\n','gift-box-close':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','gift-box-open':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','gift-thin':'\n\n\n\n\n','gift':'\n\n\n\n\n','gift_thin':'\n\n\n\n\n','google-drive':'\n\n\n\n\n\n\n\n','google-icon':'\n\n\n\n\n\n\n\n','google':'\n\n\n\n\n\n','grid':'\n\n\n\n\n','guardian-apple':'\n\n\n\n\n','guardian-email':'\n\n\n\n\n\n\n\n\n\n\n','guardian-facebook':'\n\n\n\n\n','guardian-google':'\n\n\n\n\n\n\n','guardian-phone':'\n\n\n\n\n\n\n\n\n\n\n','guardian':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','guardians-telegram':'\n\n\n\n\n\n\n\n\n\n\n\n','guardians-x':'\n\n\n\n\n','help-gray':'\n\n\n\n\n','help-white':'\n\n\n\n\n','help':'\n\n\n\n\n','history':'\n\n\n','home':'\n\n\n','homepage':'\n\n\n','httpWarn':'\n\n\n\n\n','httpsLock':'\n\n\n\n\n\n\n','iCloud':'\n\n\n\n\n\n\n\n\n','image-loading':'\n\n\n\n\n\n\n','import':'\n\n cfqdrgpdnt\n \n \n \n \n \n \n \n \n','info-white':'\n\n\n\n\n','info':'\n\n\n\n\n','inport':'\n\n\n','inviteFriend':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','keyboard_arrow_down':'\n\n\n','left-arrow-v2':'\n\n\n','left-arrow':'\n\n\n','lock-gift':'\n\n\n\n\n','lock':'\n\n\n','lock_security':'\n\n\n\n\n','logo-icon-text':'\n\n\n\n\n\n\n\n\n\n','logo-icon':'\n\n\n','logo-text':'\n\n zjqebghwfq\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','logout':'\n\n\n\n\n','luckiest':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','mainnet':'\n\n\n\n','master1':'\n\n master1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master2':'\n\n master2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master3':'\n\n master3\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master4':'\n\n master4\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master5':'\n\n master5\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master6':'\n\n master6\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','mintFail':'\n\n\n\n','minted':'\n\n\n\n','more-circle':'\n\n\n','more-info':'\n\n\n\n\n','more-vertical':'\n\n\n','more':'\n\n\n','more_normal':'\n\n\n\n','more_selected':'\n\n\n\n','more_verti':'\n\n\n\n\n','my-avatar':'\n\n\n','my-pin':'\n\n\n\n\n','my':'\n\n\n','my_about':'\n\n\n\n\n','my_auto_lock':'\n\n\n\n\n','my_biometric':'\n\n\n\n\n','my_change':'\n\n\n\n\n','my_connect':'\n\n\n\n\n','my_contact':'\n\n\n','my_device':'\n\n\n','my_guardians':'\n\n\n','my_help':'\n\n\n','my_mail_thin':'\n\n\n','my_pin':'\n\n\n\n\n','my_referral':'\n\n\n','my_token allowance':'\n\n\n','my_transaction_limit':'\n\n\n','my_update':'\n\n\n','no-bookmarks':'\n\n\n\n\n\n','no-data-detail':'\n\n\n\n\n\n\n\n\n','no-data-nft':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','no-data':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','no-message':'\n\n\n\n\n\n\n\n','no-records':'\n\n\n\n\n\n','no-result':'\n\n nsgwxrxohh\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','officialGroup':'\n\n\n\n\n\n\n\n\n\n\n','paste':'\n\n\n','phone-Android':'\n\n phone_Android\n \n \n \n \n \n \n \n \n \n \n','phone-iOS':'\n\n phone_iOS\n \n \n \n \n \n \n \n \n \n \n','phone':'\n\n\n','photo':'\n\n\n\n\n','pin-list-icon':'\n\n\n','pin-message':'\n\n\n','privacy-policy':'\n\n\n\n\n\n','private key':'\n\n\n','profile':'\n\n\n\n\n','qrCode-white':'\n\n\n','question-mark':'\n\n uhxdjnzjyz\n \n \n \n \n \n \n \n \n','question-mark2':'\n\n\n','question':'\n\n\n','receive':'\n\n\n\n\n\n\n\n\n\n','receive1':'\n\n\n\n','recovery phrase':'\n\n\n','red-delete':'\n\n\n','red-packet-opened':'\n\n\n\n\n\n\n\n','red-packet':'\n\n\n\n\n\n','referral':'\n\n\n\n\n\n','refresh':'\n\n wxwmniiwhr\n \n \n \n \n \n \n \n \n \n \n','refresh1':'\n\n\n\n\n','reload':'\n\n glmbgniwte\n \n \n \n \n \n \n \n \n \n \n \n','remove':'\n \n','right-arrow':'\n\n\n','right-arrow2':'\n\n right02\n \n \n \n \n \n \n \n \n','rows':'\n\n\n\n\n','scan-frame':'\n\n vzbmmmilfr\n \n \n \n \n \n \n \n \n \n \n','scan-square':'\n\n\n\n\n\n\n\n','scan':'\n\n\n\n\n','search':'\n\n\n','selected':'\n\n\n','selected2':'\n\n sdcfxhevmq\n \n \n \n \n \n \n \n \n \n \n','selected3':'\n\n a a a\n \n \n \n \n \n \n \n \n \n \n \n \n','selected4':'\n\n\n','selected5':'\n\n\n','sell':'\n\n\n\n\n\n\n\n\n\n\n','send-red-packet-button':'\n\n\n\n\n','send-small':'\n\n\n\n\n','send-thin':'\n\n\n\n\n','send':'\n\n\n\n\n','send1':'\n\n\n\n','setting':'\n\n rokdjfskko\n \n \n \n \n \n \n \n \n \n','setting2':'\n\n jjtrxyphxg\n \n \n \n \n \n \n \n \n \n \n \n \n','settings':'\n\n\n','settingsAboutUs':'\n\n zqlgqdoeve\n \n \n \n \n \n \n \n \n \n \n \n \n','settingsAddressBook':'\n\n qgmvghoedy\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsHelp':'\n\n zqoxrydqmd\n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsNetworks':'\n\n otxgxofwcv\n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsSecurity':'\n\n hqqhptctxw\n \n \n \n \n \n \n \n \n \n \n','settingsSetting':'\n\n vuuzuuyxty\n \n \n \n \n \n \n \n \n \n \n \n \n','share-gift':'\n\n\n\n\n','share-thin':'\n\n\n','share':'\n\n\n\n\n\n','share2':'\n\n\n\n\n\n\n','sideChain':'\n\n\n\n\n\n\n\n\n','side_chain':'\n\n\n\n\n\n\n','social-recovery':'\n\n cjrewsnkts\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','solid-down-arrow':'\n\n\n','sort-asc':'\n\n\n','sort-desc':'\n\n\n','star':'\n\n\n','success':'\n\n gxszmwdsui\n \n \n \n \n \n \n','suggest-add':'\n\n\n','suggest-circle':'\n\n\n\n\n\n\n','suggest-close':'\n\n\n','swap-arrow':'\n\n\n\n\n','swap-thin':'\n\n\n\n\n','swap':'\n\n\n\n\n','switch':'\n\n\n','telegram-blue':'\n\n\n','telegram-mono':'\n\n\n\n\n\n\n\n\n\n','telegram-white':'\n\n\n\n\n\n\n\n\n\n','telegram':'\n\n\n\n\n\n\n\n\n\n\n','terms':'\n\n\n\n\n\n','testnet':'\n\n\n\n\n','third-party-gate-io':'\n\n\n\n\n\n\n\n\n\n\n','time':'\n\n\n\n','token_list_item_right':'\n\n\n\n\n\n\n','touch-id':'\n\n\n\n','trade-small':'\n\n\n','trade':'\n\n\n\n\n\n\n\n\n\n','transfer-preview':'\n\n\n\n\n','transfer-receive':'\n\n iyvgjvxgxm\n \n \n \n \n \n \n \n \n \n \n \n \n','transfer-send':'\n\n uonrsgnbug\n \n \n \n \n \n \n \n \n \n \n \n','transfer':'\n\n xpkknuehvy\n \n \n \n \n \n \n \n \n \n \n \n \n \n','trend':'\n\n\n','tune':'\n\n\n','twitter-icon':'\n\n\n\n\n','twitter-white':'\n\n\n','twitter':'\n\n\n','unselected':'\n\n\n','up-arrow':'\n\n up\n \n \n \n \n \n \n \n \n','upload-avatar-button':'\n\n\n\n\n\n\n\n\n\n\n','upload':'\n\n\n\n\n','usdt-icon':'\n\n\n\n\n\n','vector-right':'\n\n\n','visa':'\n\n\n','visibility_lock':'\n\n\n','wallet-gray':'\n\n\n','wallet-security':'\n\n\n\n\n\n','wallet':'\n\n bfzjdifnru\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','wallet_fill':'\n\n\n','warning-fill':'\n\n\n\n\n','warning':'\n\n\n','warning1':'\n\n\n','warning2':'\n\n\n','warning3':'\n\n\n','warning_v2':'\n\n\n\n\n','withdraw':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','zklogin_watermark':'\n\n\n\n\n'}; +export default {'Chain=AELF Main':'\n\n\n\n','Chain=AELF Side':'\n\n\n\n\n\n\n\n\n','Chain=Arbitrum':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Avalanche':'\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Base':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Binance':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Ethereum':'\n\n\n\n\n\n\n\n\n','Chain=Flow':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Moonbeam':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Optimism':'\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Polkadot':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Polygon':'\n\n\n\n\n\n\n\n\n','Chain=Solana':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=TON':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','Chain=Testnet':'\n\n\n\n\n','Chain=Tron':'\n\n\n\n','Contract':'\n\n\n\n\n','ELF':'\n\n\n','ETransfer':'\n\n\n','ETransferLogo':'\n\n\n\n\n\n\n\n\n\n\n','accessory':'\n\n\n','activity-fail':'\n\n\n\n\n\n\n','activity-mined':'\n\n\n\n\n\n\n','activity-pending':'\n\n\n\n\n\n\n\n\n\n','activity':'\n\n\n\n','add-contact':'\n\n\n\n\n\n\n','add-contact1':'\n \n','add-tab':'\n\n\n','add':'\n\n\n','add1':'\n\n\n\n\n\n\n','add2':'\n\n ymquiytxjt\n \n \n \n \n \n \n \n \n \n \n \n \n \n','add3':'\n\n wivmphxoms\n \n \n \n \n \n \n \n \n','add4':'\n\n\n','album':'\n\n epepouhbdw\n \n \n \n \n \n \n \n \n','allowance-delete':'\n \n','app-blue-logo':'\n\n\n\n','app-logo-new':'\n\n\n\n','apple-icon':'\n\n\n\n\n\n','apple-white':'\n\n\n','apple':'\n\n\n\n','arrow-down-thin':'\n\n\n\n\n','arrow-left':'\n\n\n','arrow-right-thin':'\n\n\n\n\n','arrow-right':'\n\n\n','awaken-swap-round':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','awaken-swap':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','awakenLogo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','bingoGame':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','block-back':'\n\n\n','book-mark-fill':'\n\n\n','book-mark':'\n\n\n','bookmark':'\n\n\n\n','bookmarked':'\n\n\n\n','buy':'\n\n\n\n\n','buy1':'\n\n\n\n','buy2':'\n\n\n\n','camera':'\n\n\n\n\n','chain_Logos':'\n\n\n\n\n\n\n','chain_side':'\n\n\n\n\n\n\n\n\n','change':'\n\n\n','chat-add-contact':'\n\n\n','chat-add-member':'\n\n\n','chat-add':'\n\n\n','chat-added':'\n\n\n','chat-album':'\n\n\n\n\n','chat-block':'cg\n\n\n','chat-bookmark':'\n\n\n','chat-camera':'\n\n\n\n','chat-chat':'\n\n\n','chat-create-group':'\n\n\n\n\n\n','chat-delete-emoji':'\n\n\n\n\n','chat-delete':'\n\n\n','chat-emoji':'\n\n\n\n\n\n','chat-file':'\n\n\n\n\n\n\n\n\n\n\n\n','chat-find-more':'\n\n\n\n','chat-group-avatar-header':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-avatar-small-logo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-avatar':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-group-info':'\n\n\n\n\n\n','chat-keyboard':'\n\n\n\n\n\n\n\n\n\n\n\n','chat-leave-group':'\n\n\n\n\n','chat-mute':'\n\n\n','chat-new-chat':'\n\n\n','chat-pin':'\n\n\n','chat-profile':'\n\n\n\n\n','chat-qr-code':'\n\n\n','chat-remove-member':'\n\n\n','chat-reply':'\n\n\n','chat-report':'\n\n\n','chat-reshutter':'\n\n\n\n\n','chat-robot':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','chat-scroll-to-bottom':'\n\n\n\n','chat-send':'\n\n\n','chat-shutter':'\n\n\n\n','chat-tab':'\n\n\n','chat-transfer':'\n\n\n\n\n','chat-unmute':'\n\n\n\n\n','chat-unpin':'\n\n\n\n\n','chat-unsupported-channel':'\n\n\n\n\n\n\n\n\n\n\n\n','check-circle':'\n\n\n\n\n','check-false':'\n\n fzoykpdoyh\n \n \n \n \n \n \n \n','check-true':'\n\n mbcnnswjqh\n \n \n \n \n \n \n \n \n \n \n','check':'\n\n\n','checkUpdate':'\n\n\n\n\n\n\n','checkbox-Checked':'\n\n\n\n\n\n\n\n\n\n\n','checkbox-new':'\n\n\n','checkbox':'\n\n\n\n\n\n\n','checked':'\n\n\n','checked_circle':'\n\n\n\n\n','chevron-right':'\n \n','chevron_down':'\n\n\n\n\n','chevron_right':'\n\n\n','chevron_right2':'\n\n\n','clear':'\n\n qzqvrhcbqn\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','clear1':'\n\n pgqcjmcbit\n \n \n \n \n \n \n \n \n','clear2':'\n\n oinrqzcjps\n \n \n \n \n \n \n \n \n \n \n \n \n','clear3':'\n\n\n','clear4':'\n\n\n\n','clock':'\n\n\n','close-red-packet':'\n\n\n\n\n','close':'\n\n tqsruqxgrb\n \n \n \n \n \n \n \n \n','close1':'\n\n ozresgjsts\n \n \n \n \n \n \n \n \n \n \n','close2':'\n\n yyybesklsg\n \n \n \n \n \n \n \n \n \n \n','close3':'\n\n\n','close4':'\n\n\n\n\n','close_thick':'\n\n\n\n\n','collect':'\n\n\n','collected':'\n\n\n','contact':'\n\n ymwllfkfjj\n \n \n \n \n \n \n \n \n \n \n \n \n \n','contact2':'\n\n mkokwgrdlj\n \n \n \n \n \n \n \n \n \n \n','copy-checked':'\n\n\n\n','copy-pre':'\n\n\n\n','copy-thin':'\n\n\n\n\n','copy':'\n\n\n\n\n','copy1':'\n\n\n\n','copy3':'\n\n\n','copy_v2':'\n\n\n\n\n','crypto-box-with-border':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','crypto-gift':'\n\n\n\n\n','default_record':'\n\n\n\n\n','delete-image2':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','delete-img':'\n\n\n\n\n\n\n\n\n\n\n\n\n','delete-mint':'\n\n\n\n\n','delete':'\n\n\n','deposit-receive':'\n\n\n\n','deposit':'\n\n\n\n','deposit1':'\n\n\n\n','depositMain':'\n\n\n\n','deposit_status_failed':'\n\n\n','deposit_status_processing':'\n\n\n','deposit_status_success':'\n\n\n','desk-mac':'\n\n desk_mac\n \n \n \n \n \n \n \n \n \n \n','desk-win':'\n\n wnusftfmuc\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','direction-arrow-right':'\n\n\n\n\n\n\n','direction-right':'\n\n\n','direction-up':'\n\n\n','direction_down':'\n\n\n\n\n','disabled_visible':'\n\n\n','discord':'\n\n\n','discover':'\n\n\n\n','discover_close':'\n\n\n\n\n','down-arrow':'\n\n\n','drag':'\n\n\n\n','eBridge':'\n\n\n\n\n\n\n\n\n\n\n\n','eBridgeFavIcon':'\n\n\n\n\n\n','eBridgeLogo':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','edit':'\n\n\n','edit1':'\n \n','edit_thin':'\n\n\n\n\n','edit_token':'\n\n\n\n\n\n\n','elf-icon':'\n\n\n\n\n','email-login':'\n\n\n','email-white':'\n\n\n\n\n\n\n\n\n\n','email':'\n\n\n\n\n\n\n\n\n\n','error':'\n\n\n\n\n','explore':'\n\n\n','external':'\n \n','eye':'\n\n\n\n\n','eyeClosed':'\n\n\n\n\n','face-id':'\n\n\n','facebook-icon':'\n\n\n\n\n\n\n\n\n\n\n\n','facebook-white':'\n\n\n','facebook':'\n\n\n','fail':'\n\n gjgrrybzwe\n \n \n \n \n \n \n','faucet':'\n\n\n\n\n\n\n\n\n\n','favorite-disable':'\n\n\n','favorite-unselected':'\n\n\n','favorite':'\n\n\n','filter-top':'\n\n\n','filter':'\n\n\n','finish':'\n\n sytkvvhtjm\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','forest':'\n\n\n\n','free-mint-entry':'\n\n\n\n\n','gear':'\n\n\n\n\n','gift-box-close':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','gift-box-open':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','gift-thin':'\n\n\n\n\n','gift':'\n\n\n\n\n','gift_thin':'\n\n\n\n\n','google-drive':'\n\n\n\n\n\n\n\n','google-icon':'\n\n\n\n\n\n\n\n','google':'\n\n\n\n\n\n','grid':'\n\n\n\n\n','guardian-apple':'\n\n\n\n\n','guardian-email':'\n\n\n\n\n\n\n\n\n\n\n','guardian-facebook':'\n\n\n\n\n','guardian-google':'\n\n\n\n\n\n\n','guardian-phone':'\n\n\n\n\n\n\n\n\n\n\n','guardian':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','guardians-telegram':'\n\n\n\n\n\n\n\n\n\n\n\n','guardians-x':'\n\n\n\n\n','help-gray':'\n\n\n\n\n','help-white':'\n\n\n\n\n','help':'\n\n\n\n\n','history':'\n\n\n','home':'\n\n\n','homepage':'\n\n\n','httpWarn':'\n\n\n\n\n','httpsLock':'\n\n\n\n\n\n\n','iCloud':'\n\n\n\n\n\n\n\n\n','image-loading':'\n\n\n\n\n\n\n','import':'\n\n cfqdrgpdnt\n \n \n \n \n \n \n \n \n','info-white':'\n\n\n\n\n','info':'\n\n\n\n\n','inport':'\n\n\n','inviteFriend':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','keyboard_arrow_down':'\n\n\n','left-arrow-v2':'\n\n\n','left-arrow':'\n\n\n','lock-gift':'\n\n\n\n\n','lock':'\n\n\n','lock_security':'\n\n\n\n\n','logo-icon-text':'\n\n\n\n\n\n\n\n\n\n','logo-icon':'\n\n\n','logo-text':'\n\n zjqebghwfq\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','logout':'\n\n\n\n\n','luckiest':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n','mainnet':'\n\n\n\n','master1':'\n\n master1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master2':'\n\n master2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master3':'\n\n master3\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master4':'\n\n master4\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master5':'\n\n master5\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','master6':'\n\n master6\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','mintFail':'\n\n\n\n','minted':'\n\n\n\n','more-circle':'\n\n\n','more-info':'\n\n\n\n\n','more-vertical':'\n\n\n','more':'\n\n\n','more_normal':'\n\n\n\n','more_selected':'\n\n\n\n','more_verti':'\n\n\n\n\n','my-avatar':'\n\n\n','my-pin':'\n\n\n\n\n','my':'\n\n\n','my_about':'\n\n\n\n\n','my_auto_lock':'\n\n\n\n\n','my_biometric':'\n\n\n\n\n','my_change':'\n\n\n\n\n','my_connect':'\n\n\n\n\n','my_contact':'\n\n\n','my_device':'\n\n\n','my_guardians':'\n\n\n','my_help':'\n\n\n','my_mail_thin':'\n\n\n','my_pin':'\n\n\n\n\n','my_referral':'\n\n\n','my_token allowance':'\n\n\n','my_transaction_limit':'\n\n\n','my_update':'\n\n\n','no-bookmarks':'\n\n\n\n\n\n','no-data-detail':'\n\n\n\n\n\n\n\n\n','no-data-nft':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','no-data':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','no-message':'\n\n\n\n\n\n\n\n','no-records':'\n\n\n\n\n\n','no-result':'\n\n nsgwxrxohh\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','officialGroup':'\n\n\n\n\n\n\n\n\n\n\n','paste':'\n\n\n','phone-Android':'\n\n phone_Android\n \n \n \n \n \n \n \n \n \n \n','phone-iOS':'\n\n phone_iOS\n \n \n \n \n \n \n \n \n \n \n','phone':'\n\n\n','photo':'\n\n\n\n\n','pin-list-icon':'\n\n\n','pin-message':'\n\n\n','privacy-policy':'\n\n\n\n\n\n','private key':'\n\n\n','profile':'\n\n\n\n\n','qrCode-white':'\n\n\n','question-mark':'\n\n uhxdjnzjyz\n \n \n \n \n \n \n \n \n','question-mark2':'\n\n\n','question':'\n\n\n','receive':'\n\n\n\n\n\n\n\n\n\n','receive1':'\n\n\n\n','recovery phrase':'\n\n\n','red-delete':'\n\n\n','red-packet-opened':'\n\n\n\n\n\n\n\n','red-packet':'\n\n\n\n\n\n','referral':'\n\n\n\n\n\n','refresh':'\n\n wxwmniiwhr\n \n \n \n \n \n \n \n \n \n \n','refresh1':'\n\n\n\n\n','reload':'\n\n glmbgniwte\n \n \n \n \n \n \n \n \n \n \n \n','remove':'\n \n','right-arrow':'\n\n\n','right-arrow2':'\n\n right02\n \n \n \n \n \n \n \n \n','rows':'\n\n\n\n\n','scan-frame':'\n\n vzbmmmilfr\n \n \n \n \n \n \n \n \n \n \n','scan-square':'\n\n\n\n\n\n\n\n','scan':'\n\n\n\n\n','search':'\n\n\n','selected':'\n\n\n','selected2':'\n\n sdcfxhevmq\n \n \n \n \n \n \n \n \n \n \n','selected3':'\n\n a a a\n \n \n \n \n \n \n \n \n \n \n \n \n','selected4':'\n\n\n','selected5':'\n\n\n','sell':'\n\n\n\n\n\n\n\n\n\n\n','send-red-packet-button':'\n\n\n\n\n','send-small':'\n\n\n\n\n','send-thin':'\n\n\n\n\n','send':'\n\n\n\n\n','send1':'\n\n\n\n','setting':'\n\n rokdjfskko\n \n \n \n \n \n \n \n \n \n','setting2':'\n\n jjtrxyphxg\n \n \n \n \n \n \n \n \n \n \n \n \n','settings':'\n\n\n','settingsAboutUs':'\n\n zqlgqdoeve\n \n \n \n \n \n \n \n \n \n \n \n \n','settingsAddressBook':'\n\n qgmvghoedy\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsHelp':'\n\n zqoxrydqmd\n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsNetworks':'\n\n otxgxofwcv\n \n \n \n \n \n \n \n \n \n \n \n \n \n','settingsSecurity':'\n\n hqqhptctxw\n \n \n \n \n \n \n \n \n \n \n','settingsSetting':'\n\n vuuzuuyxty\n \n \n \n \n \n \n \n \n \n \n \n \n','share-gift':'\n\n\n\n\n','share-thin':'\n\n\n','share':'\n\n\n\n\n\n','share2':'\n\n\n\n\n\n\n','sideChain':'\n\n\n\n\n\n\n\n\n','side_chain':'\n\n\n\n\n\n\n','social-recovery':'\n\n cjrewsnkts\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','solid-down-arrow':'\n\n\n','sort-asc':'\n\n\n','sort-desc':'\n\n\n','star':'\n\n\n','success':'\n\n gxszmwdsui\n \n \n \n \n \n \n','suggest-add':'\n\n\n','suggest-circle':'\n\n\n\n\n\n\n','suggest-close':'\n\n\n','swap-arrow':'\n\n\n\n\n','swap-thin':'\n\n\n\n\n','swap':'\n\n\n\n\n','switch':'\n\n\n','telegram-blue':'\n\n\n','telegram-mono':'\n\n\n\n\n\n\n\n\n\n','telegram-white':'\n\n\n\n\n\n\n\n\n\n','telegram':'\n\n\n\n\n\n\n\n\n\n\n','terms':'\n\n\n\n\n\n','testnet':'\n\n\n\n\n','third-party-gate-io':'\n\n\n\n\n\n\n\n\n\n\n','time':'\n\n\n\n','token_list_item_right':'\n\n\n\n\n\n\n','touch-id':'\n\n\n\n','trade-small':'\n\n\n','trade':'\n\n\n\n\n\n\n\n\n\n','transfer-preview':'\n\n\n\n\n','transfer-receive':'\n\n iyvgjvxgxm\n \n \n \n \n \n \n \n \n \n \n \n \n','transfer-send':'\n\n uonrsgnbug\n \n \n \n \n \n \n \n \n \n \n \n','transfer':'\n\n xpkknuehvy\n \n \n \n \n \n \n \n \n \n \n \n \n \n','trend':'\n\n\n','tune':'\n\n\n','twitter-icon':'\n\n\n\n\n','twitter-white':'\n\n\n','twitter':'\n\n\n','unselected':'\n\n\n','up-arrow':'\n\n up\n \n \n \n \n \n \n \n \n','upload-avatar-button':'\n\n\n\n\n\n\n\n\n\n\n','upload':'\n\n\n\n\n','usdt-icon':'\n\n\n\n\n\n','vector-right':'\n\n\n','visa':'\n\n\n','visibility':'\n\n\n','visibility_lock':'\n\n\n','visibility_off':'\n\n\n','wallet-gray':'\n\n\n','wallet-security':'\n\n\n\n\n\n','wallet':'\n\n bfzjdifnru\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n','wallet_fill':'\n\n\n','warning-fill':'\n\n\n\n\n','warning':'\n\n\n','warning1':'\n\n\n','warning2':'\n\n\n','warning3':'\n\n\n','warning_v2':'\n\n\n\n\n','withdraw':'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n','zklogin_watermark':'\n\n\n\n\n'}; diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Main.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Main.svg new file mode 100644 index 000000000..144f39b26 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Main.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Side.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Side.svg new file mode 100644 index 000000000..3a8f3ae0e --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=AELF Side.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Arbitrum.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Arbitrum.svg new file mode 100644 index 000000000..93298f9cd --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Arbitrum.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Avalanche.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Avalanche.svg new file mode 100644 index 000000000..6c987a09d --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Avalanche.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Base.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Base.svg new file mode 100644 index 000000000..45f96343c --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Base.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Binance.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Binance.svg new file mode 100644 index 000000000..6a050aea1 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Binance.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Ethereum.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Ethereum.svg new file mode 100644 index 000000000..972eff085 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Ethereum.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Flow.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Flow.svg new file mode 100644 index 000000000..42820dcd7 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Flow.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Moonbeam.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Moonbeam.svg new file mode 100644 index 000000000..48c04d11f --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Moonbeam.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Optimism.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Optimism.svg new file mode 100644 index 000000000..7760b489e --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Optimism.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Polkadot.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Polkadot.svg new file mode 100644 index 000000000..7e9be784c --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Polkadot.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Polygon.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Polygon.svg new file mode 100644 index 000000000..3b223586f --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Polygon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Solana.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Solana.svg new file mode 100644 index 000000000..f243f2d8b --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Solana.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=TON.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=TON.svg new file mode 100644 index 000000000..b256265d4 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=TON.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Testnet.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Testnet.svg new file mode 100644 index 000000000..3fe6ae948 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Testnet.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/Chain=Tron.svg b/packages/mobile-aelf/js/assets/image/svgs/Chain=Tron.svg new file mode 100644 index 000000000..1d58a77d4 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/Chain=Tron.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/visibility.svg b/packages/mobile-aelf/js/assets/image/svgs/visibility.svg new file mode 100644 index 000000000..17786bc32 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/visibility.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/mobile-aelf/js/assets/image/svgs/visibility_off.svg b/packages/mobile-aelf/js/assets/image/svgs/visibility_off.svg new file mode 100644 index 000000000..02399c112 --- /dev/null +++ b/packages/mobile-aelf/js/assets/image/svgs/visibility_off.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx b/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx index da131720a..ca9079bba 100644 --- a/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx +++ b/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx @@ -190,6 +190,12 @@ const HomeTab: React.FC = ({ _ }) => { style={{ marginTop: 40 }}> Manual Backup + navigationService.push('CloudBackup')} style={{ marginTop: 40 }}> + CloudBackup + + navigationService.push('CloudBackupDev')} style={{ marginTop: 10 }}> + CloudBackupDev + navigationService.push('Referral')} style={{ marginTop: 20 }}> Referral diff --git a/packages/mobile-aelf/js/pages/Login/CloudBackup/cases.tsx b/packages/mobile-aelf/js/pages/Login/CloudBackup/cases.tsx new file mode 100644 index 000000000..68d08dc2e --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/CloudBackup/cases.tsx @@ -0,0 +1,308 @@ +// https://github.com/kuatsu/react-native-cloud-storage/blob/master/example/src/views/Home.tsx +import React, { useCallback, useEffect, useState } from 'react'; +import { Text, View } from 'react-native'; +import PageContainer from 'components/PageContainer'; +import { isIOS } from '@portkey-wallet/utils/mobile/device'; +import aes from '@portkey-wallet/utils/aes'; +import { makeStyles } from '@rneui/themed'; +import { pTd } from 'utils/unit'; +import fonts from 'assets/theme/fonts'; +import Svg from 'components/Svg'; +import Touchable from 'components/Touchable'; +import CommonButton from 'components/CommonButton'; +import GStyles from 'mobile-did/js/assets/theme/GStyles'; +import CommonInput from 'mobile-did/js/components/CommonInput'; +import CheckBox from 'components/CheckBox'; +import { OfficialWebsite } from '@portkey-wallet/constants/constants-ca/network'; +import navigationService from 'utils/navigationService'; +import { useCurrentWallet } from '@portkey-wallet/hooks/hooks-eoa/wallet'; +import { useCredentials } from 'hooks/store'; +import { useCloudStorage } from './useCloudStorage'; +import CommonToast from 'components/CommonToast'; +import { getPasswords, passwordShowFormat } from './index'; + +export default function CloudBackupCases() { + const styles = getStyles(); + // const { theme } = useTheme(); + // const [copied, setCopied] = useState(false); + // + // // const currentAccount = useCurrentAccount(); + const currentWallet = useCurrentWallet(); + const credentials = useCredentials(); + const [password, setPassword] = useState(''); + const [passwordShow, setPasswordShow] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [confirmPasswordShow, setConfirmPasswordShow] = useState(''); + const [secureTextEntry, setSecureTextEntry] = useState(true); + const [confirmSecureTextEntry, setConfirmSecureTextEntry] = useState(true); + const [errorMessage, setErrorMessage] = useState(''); + + const [isChecked, setIsChecked] = useState(false); + const onClickCheckBox = useCallback(() => { + setIsChecked(!isChecked); + }, [isChecked]); + + useEffect(() => { + console.log('cloud backup - currentWallet: ', currentWallet, credentials); + }, [credentials, currentWallet]); + + const { + // cloudStorage, + readFile, + handleCreateDirectory, + handleDeleteDirectory, + handleListContents, + handleCreateFile, + loading, + } = useCloudStorage(); + + return ( + + + + handleCreateDirectory + + { + if (!currentWallet) { + CommonToast.fail('Can not found wallet'); + return; + } + readFile(currentWallet.key); + }} + style={{ marginTop: 10 }}> + readFile + + handleDeleteDirectory(true)} + style={{ marginTop: 10 }}> + handleDeleteDirectory + + + handleListContents/Wallet List in Cloud + + { + if (!currentWallet) { + CommonToast.fail('Can not found wallet'); + return; + } + handleCreateFile({ + filename: currentWallet.key, + // TODO, encrypt before create + input: JSON.stringify(currentWallet), + }); + }} + style={{ marginTop: 10 }}> + handleCreateFile + + + Create password + + This password will secure your seed phrase in the cloud. We cannot reset it if you lose it, so please keep it + safe. + + + { + const { newPassword, passwordShow: _passwordShow } = getPasswords(value, password, secureTextEntry); + setPassword(newPassword); + setPasswordShow(_passwordShow); + if (confirmPassword !== newPassword) { + setErrorMessage('Not match, please try again.'); + } else { + setErrorMessage(''); + } + }} + rightIcon={ + + { + setPassword(''); + setPasswordShow(''); + }}> + + + { + const newSecureTextEntry = !secureTextEntry; + setSecureTextEntry(newSecureTextEntry); + setPasswordShow(passwordShowFormat(newSecureTextEntry, password)); + }}> + + + + } + /> + { + const { newPassword, passwordShow: _passwordShow } = getPasswords( + value, + confirmPassword, + confirmSecureTextEntry, + ); + setConfirmPassword(newPassword); + setConfirmPasswordShow(_passwordShow); + if (password !== newPassword) { + setErrorMessage('Not match, please try again.'); + } else { + setErrorMessage(''); + } + }} + rightIcon={ + + { + setConfirmPassword(''); + setConfirmPasswordShow(''); + }}> + + + { + const newSecureTextEntry = !confirmSecureTextEntry; + setConfirmSecureTextEntry(newSecureTextEntry); + setConfirmPasswordShow(passwordShowFormat(newSecureTextEntry, confirmPassword)); + }}> + + + + } + /> + + + + + + + onClickCheckBox()} boxStyle={styles.checkBox} /> + + + I understand that if I lose my password, I will not be able to access my backup, which could result in the + loss of all my assets. I agree to{' '} + { + navigationService.navigate('ViewOnWebView', { + title: 'Terms of Service', + url: `${OfficialWebsite}/terms-of-service`, + }); + }}> + terms + {' '} + and{' '} + { + navigationService.navigate('ViewOnWebView', { + title: 'Privacy Policy', + url: `${OfficialWebsite}/privacy-policy`, + }); + }}> + privacy policy + {' '} + for using aelf wallet. + + + { + // TODO: + // if directory exists, will not create again. + await handleCreateDirectory(); + if (!currentWallet) { + CommonToast.fail('Can not found wallet'); + return; + } + await handleCreateFile({ + filename: currentWallet.key, + // TODO, encrypt before create + input: aes.encrypt(JSON.stringify(currentWallet), password), + }); + }}> + Continue + + + + ); +} + +const getStyles = makeStyles(theme => ({ + containerStyles: { + backgroundColor: theme.colors.bgBase1, + justifyContent: 'space-between', + }, + title: { + marginTop: pTd(24), + fontSize: pTd(32), + ...fonts.BGMediumFont, + }, + desc: { + color: theme.colors.textBase2, + marginTop: pTd(16), + fontSize: pTd(14), + }, + inputContainer: { + marginTop: pTd(24), + flexDirection: 'row', + flexWrap: 'wrap', + }, + inputLabel: { + paddingLeft: 0, + }, + understandContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + checkBox: { + backgroundColor: theme.colors.bgBase1, + marginRight: pTd(12), + }, + understandText: { + flex: 1, + fontSize: pTd(14), + lineHeight: pTd(14) * 1.4, + }, + link: { + fontSize: pTd(14), + color: theme.colors.textBrand3, + }, + continueButton: { + marginTop: pTd(24), + marginBottom: pTd(16), + }, +})); diff --git a/packages/mobile-aelf/js/pages/Login/CloudBackup/index.tsx b/packages/mobile-aelf/js/pages/Login/CloudBackup/index.tsx new file mode 100644 index 000000000..35b962b40 --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/CloudBackup/index.tsx @@ -0,0 +1,309 @@ +// https://github.com/kuatsu/react-native-cloud-storage/blob/master/example/src/views/Home.tsx +import React, { useCallback, useState } from 'react'; +import { Text, View } from 'react-native'; +import PageContainer from 'components/PageContainer'; +import { isIOS } from '@portkey-wallet/utils/mobile/device'; +import aes from '@portkey-wallet/utils/aes'; +import { makeStyles } from '@rneui/themed'; +import { pTd } from 'utils/unit'; +import fonts from 'assets/theme/fonts'; +import Svg from 'components/Svg'; +import Touchable from 'components/Touchable'; +import CommonButton from 'components/CommonButton'; +import GStyles from 'mobile-did/js/assets/theme/GStyles'; +import CommonInput from 'mobile-did/js/components/CommonInput'; +import CheckBox from 'components/CheckBox'; +import { OfficialWebsite } from '@portkey-wallet/constants/constants-ca/network'; +import navigationService from 'utils/navigationService'; +import { useCurrentWallet } from '@portkey-wallet/hooks/hooks-eoa/wallet'; +// import { useCredentials } from 'hooks/store'; +import { useCloudStorage } from './useCloudStorage'; +import CommonToast from 'components/CommonToast'; +import { useCredentials } from 'hooks/store'; +import { TWalletInfo } from '@portkey-wallet/types/types-eoa/wallet'; + +function generateDots(length: number) { + if (length < 0) { + throw new Error('Length must be a non-negative number'); + } + return '•'.repeat(length); +} + +export function passwordShowFormat(isSecure: boolean, password: string) { + return isSecure ? generateDots(password.length) : password; +} + +export function getPasswords(newValue: string, prePassword: string, isSecure: boolean) { + const _password = newValue.trim(); + const _passwordLength = _password.length; + const prePasswordLength = prePassword.length; + // let newPassword = _password ? prePassword.slice(0, _passwordLength - 1) + _password[_passwordLength - 1] : ''; + let newPassword = prePassword.slice(0, prePasswordLength - 1); + if (!_password) { + newPassword = ''; + } else if (prePasswordLength < _passwordLength) { + newPassword = prePassword.slice(0, _passwordLength - 1) + _password[_passwordLength - 1]; + } + return { + newPassword, + passwordShow: passwordShowFormat(isSecure, newPassword), + }; +} + +export default function CloudBackup() { + const styles = getStyles(); + // const { theme } = useTheme(); + // const [copied, setCopied] = useState(false); + // + // // const currentAccount = useCurrentAccount(); + const currentWallet = useCurrentWallet(); + const credentials = useCredentials(); + const [password, setPassword] = useState(''); + const [passwordShow, setPasswordShow] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [confirmPasswordShow, setConfirmPasswordShow] = useState(''); + const [secureTextEntry, setSecureTextEntry] = useState(true); + const [confirmSecureTextEntry, setConfirmSecureTextEntry] = useState(true); + const [errorMessage, setErrorMessage] = useState(''); + + const [isChecked, setIsChecked] = useState(false); + const onClickCheckBox = useCallback(() => { + setIsChecked(!isChecked); + }, [isChecked]); + + const { handleCreateDirectory, handleCreateFile, loading } = useCloudStorage(); + + return ( + + + Create password + + This password will secure your seed phrase in the cloud. We cannot reset it if you lose it, so please keep it + safe. + + + { + const { newPassword, passwordShow: _passwordShow } = getPasswords(value, password, secureTextEntry); + setPassword(newPassword); + setPasswordShow(_passwordShow); + if (confirmPassword !== newPassword) { + setErrorMessage('Not match, please try again.'); + } else { + setErrorMessage(''); + } + }} + rightIcon={ + + { + setPassword(''); + setPasswordShow(''); + }}> + + + { + const newSecureTextEntry = !secureTextEntry; + setSecureTextEntry(newSecureTextEntry); + setPasswordShow(passwordShowFormat(newSecureTextEntry, password)); + }}> + + + + } + /> + { + const { newPassword, passwordShow: _passwordShow } = getPasswords( + value, + confirmPassword, + confirmSecureTextEntry, + ); + setConfirmPassword(newPassword); + setConfirmPasswordShow(_passwordShow); + if (password !== newPassword) { + setErrorMessage('Not match, please try again.'); + } else { + setErrorMessage(''); + } + }} + rightIcon={ + + { + setConfirmPassword(''); + setConfirmPasswordShow(''); + }}> + + + { + const newSecureTextEntry = !confirmSecureTextEntry; + setConfirmSecureTextEntry(newSecureTextEntry); + setConfirmPasswordShow(passwordShowFormat(newSecureTextEntry, confirmPassword)); + }}> + + + + } + /> + + + + + + + onClickCheckBox()} boxStyle={styles.checkBox} /> + + + I understand that if I lose my password, I will not be able to access my backup, which could result in the + loss of all my assets. I agree to{' '} + { + navigationService.navigate('ViewOnWebView', { + title: 'Terms of Service', + url: `${OfficialWebsite}/terms-of-service`, + }); + }}> + terms + {' '} + and{' '} + { + navigationService.navigate('ViewOnWebView', { + title: 'Privacy Policy', + url: `${OfficialWebsite}/privacy-policy`, + }); + }}> + privacy policy + {' '} + for using aelf wallet. + + + { + console.log('currentWallet: ', currentWallet); + if (!currentWallet) { + CommonToast.fail('Can not found wallet'); + return; + } + const _currentWallet: TWalletInfo = JSON.parse(JSON.stringify(currentWallet)); + if (!credentials?.pin) { + // almost impossible + CommonToast.fail('Wallet is locked'); + return; + } + const { pin } = credentials; + if (_currentWallet.AESEncryptMnemonic) { + const result = aes.decrypt(_currentWallet.AESEncryptMnemonic, pin); + if (!result) { + CommonToast.fail('Decrypt failed'); + } + _currentWallet.AESEncryptMnemonic = aes.encrypt(result as string, password); + } + _currentWallet.accountList.map(account => { + const result = aes.decrypt(account.AESEncryptPrivateKey, pin); + if (!result) { + CommonToast.fail('Decrypt failed'); + } + account.AESEncryptPrivateKey = aes.encrypt(result as string, password); + }); + console.log('_currentWallet: ', _currentWallet, currentWallet); + // if directory exists, will not create again. + await handleCreateDirectory(); + + await handleCreateFile({ + filename: _currentWallet.key, + input: JSON.stringify({ + updateTime: Date.now(), + wallet: aes.encrypt(JSON.stringify(_currentWallet), password), + }), + }); + navigationService.navigate('Home'); + CommonToast.success('Backup completed'); + }}> + Continue + + + + ); +} + +const getStyles = makeStyles(theme => ({ + containerStyles: { + backgroundColor: theme.colors.bgBase1, + justifyContent: 'space-between', + }, + title: { + marginTop: pTd(24), + fontSize: pTd(32), + ...fonts.BGMediumFont, + }, + desc: { + color: theme.colors.textBase2, + marginTop: pTd(16), + fontSize: pTd(14), + }, + inputContainer: { + marginTop: pTd(24), + flexDirection: 'row', + flexWrap: 'wrap', + }, + inputLabel: { + paddingLeft: 0, + }, + understandContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + checkBox: { + backgroundColor: theme.colors.bgBase1, + marginRight: pTd(12), + }, + understandText: { + flex: 1, + fontSize: pTd(14), + lineHeight: pTd(14) * 1.4, + }, + link: { + fontSize: pTd(14), + color: theme.colors.textBrand3, + }, + continueButton: { + marginTop: pTd(24), + marginBottom: pTd(16), + }, +})); diff --git a/packages/mobile-aelf/js/pages/Login/CloudBackup/useCloudStorage.tsx b/packages/mobile-aelf/js/pages/Login/CloudBackup/useCloudStorage.tsx new file mode 100644 index 000000000..ff743388e --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/CloudBackup/useCloudStorage.tsx @@ -0,0 +1,191 @@ +import { useState, useEffect, useMemo, useCallback } from 'react'; +import { + CloudStorage, + CloudStorageError, + CloudStorageErrorCode, + // type CloudStorageFileStat, + CloudStorageProvider, + // CloudStorageScope, + useIsCloudAvailable, +} from 'react-native-cloud-storage'; +import CommonToast from '../../../components/CommonToast'; + +function commonCloudStorageError(e: any) { + console.warn('commonCloudStorageError', e); + if (e instanceof CloudStorageError) { + if (e.code === CloudStorageErrorCode.READ_ERROR) { + CommonToast.fail('No backup found'); + } else { + CommonToast.fail(e.code); + } + } else { + CommonToast.fail('Something went wrong. Please try backing up later.'); + } +} + +export const useCloudStorage = () => { + // const [provider, setProvider] = useState(CloudStorage.getDefaultProvider()); + const [provider] = useState(CloudStorage.getDefaultProvider()); + // const [scope, setScope] = useState(CloudStorageScope.AppData); + // const [parentDirectory, setParentDirectory] = useState('/portkey-eoa/wallet'); + const [parentDirectory] = useState('/portkey-eoa/wallet'); + const [isParentDirectoryExist, setIsParentDirectoryExist] = useState(); + // const [filename, setFilename] = useState('test.txt'); + // const [stats, setStats] = useState(null); + // const [input, setInput] = useState(''); + // const [appendInput, setAppendInput] = useState(''); + // const [accessToken, setAccessToken] = useState(''); + const [loading, setLoading] = useState(false); + + const cloudStorage = useMemo(() => { + return new CloudStorage( + provider, + provider === CloudStorageProvider.GoogleDrive ? { strictFilenames: true } : undefined, + ); + }, [provider]); + const cloudAvailable = useIsCloudAvailable(cloudStorage); + + const isDirectoryExists = useCallback(async () => { + setLoading(true); + try { + const exists = await cloudStorage.exists(parentDirectory); + console.log('useCloudStorage - isDirectoryExists: ', exists); + setIsParentDirectoryExist(exists); + } catch (e) { + // console.warn(e); + setIsParentDirectoryExist(false); + commonCloudStorageError(e); + } finally { + setLoading(false); + } + }, [cloudStorage, parentDirectory]); + + const readFile = useCallback( + // eslint-disable-next-line @typescript-eslint/no-shadow + async (filename: string) => { + setLoading(true); + try { + const newStats = await cloudStorage.stat(parentDirectory + '/' + filename); + // setStats(newStats); + console.log('File stats', newStats); + if (newStats.isDirectory()) { + return; + } + const fileContent = await cloudStorage.readFile(parentDirectory + '/' + filename); + console.log('File content', fileContent); + return fileContent; + } catch (e) { + // console.log('readFile: ', e); + commonCloudStorageError(e); + return false; + // if (e instanceof CloudStorageError) { + // // TODO: return to page use, show Toast. + // if (e.code === CloudStorageErrorCode.FILE_NOT_FOUND) { + // // setStats(null); + // // setInput(''); + // CommonToast.fail(e.code); + // } else { + // console.warn('Native storage error', e.code, e.message); + // } + // } else { + // console.warn('Unknown error', e); + // } + } finally { + setLoading(false); + } + }, + [cloudStorage, parentDirectory], + ); + + const handleCreateFile = useCallback( + // eslint-disable-next-line @typescript-eslint/no-shadow + async ({ filename, input }: { filename: string; input: string }) => { + setLoading(true); + try { + await cloudStorage.writeFile(parentDirectory + '/' + filename, input); + readFile(filename); + } catch (e) { + // console.warn(e); + commonCloudStorageError(e); + } finally { + setLoading(false); + } + }, + [cloudStorage, parentDirectory, readFile], + ); + + const handleCreateDirectory = useCallback(async () => { + console.log('useCloudStorage - handleCreateDirectory: ', 'isParentDirectoryExist: ', isParentDirectoryExist); + if (isParentDirectoryExist) { + console.log('useCloudStorage - handleCreateDirectory: ', 'skip'); + return; + } + console.log('useCloudStorage - handleCreateDirectory: ', 'create'); + setLoading(true); + try { + await cloudStorage.mkdir(parentDirectory); + await isDirectoryExists(); + // readFile(filename); + } catch (e) { + // console.warn(e); + commonCloudStorageError(e); + } finally { + setLoading(false); + } + }, [cloudStorage, isDirectoryExists, isParentDirectoryExist, parentDirectory]); + + // List parent wallet/ privateKey Wallet addresses. + const handleListContents = useCallback(async () => { + setLoading(true); + try { + const contents = await cloudStorage.readdir(parentDirectory); + console.log('useCloudStorage - Directory contents', contents.length, contents.map(c => `• ${c}`).join('\n')); + return contents; + } catch (e) { + // console.warn(e); + commonCloudStorageError(e); + return false; + } finally { + setLoading(false); + } + }, [cloudStorage, parentDirectory]); + + const handleDeleteDirectory = async (recursive?: boolean) => { + if (recursive === undefined) { + handleDeleteDirectory(false); + // Alert.alert('Delete directory', 'Do you want to delete the directory and all its contents (recursively)?', [ + // { text: 'Cancel', style: 'cancel' }, + // { text: 'Directory only', onPress: () => handleDeleteDirectory(false) }, + // { text: 'Recursively', onPress: () => handleDeleteDirectory(true) }, + // ]); + } else { + setLoading(true); + try { + await cloudStorage.rmdir(parentDirectory, { recursive }); + await isDirectoryExists(); + // setStats(null); + // setInput(''); + } catch (e) { + // console.warn(e); + commonCloudStorageError(e); + } finally { + setLoading(false); + } + } + }; + + useEffect(() => { + isDirectoryExists(); + }, [isDirectoryExists]); + + return { + loading, + cloudStorage, + cloudAvailable, + handleCreateDirectory, + handleDeleteDirectory, + handleListContents, + handleCreateFile, + readFile, + }; +}; diff --git a/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/Decrypt/index.tsx b/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/Decrypt/index.tsx new file mode 100644 index 000000000..1e0dff0b3 --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/Decrypt/index.tsx @@ -0,0 +1,149 @@ +// https://github.com/kuatsu/react-native-cloud-storage/blob/master/example/src/views/Home.tsx +import React, { useState } from 'react'; +import { Text, View } from 'react-native'; +import PageContainer from 'components/PageContainer'; +import { isIOS } from '@portkey-wallet/utils/mobile/device'; +import aes from '@portkey-wallet/utils/aes'; +import { makeStyles } from '@rneui/themed'; +import { pTd } from 'utils/unit'; +import fonts from 'assets/theme/fonts'; +import Svg from 'components/Svg'; +import Touchable from 'components/Touchable'; +import CommonButton from 'components/CommonButton'; +import GStyles from 'mobile-did/js/assets/theme/GStyles'; +import CommonInput from 'mobile-did/js/components/CommonInput'; +import CommonToast from 'components/CommonToast'; +import { getPasswords, passwordShowFormat } from '../../../CloudBackup'; +import useRouterParams from '@portkey-wallet/hooks/useRouterParams'; +import { TWalletInfo } from '@portkey-wallet/types/types-eoa/wallet'; +import { useImportWallet } from '../../../hooks/useImportWallet'; + +export default function DecryptByPassword() { + const styles = getStyles(); + + const { walletInCloud } = useRouterParams<{ + walletInCloud: string; + }>(); + + console.log('walletInCloud: ', walletInCloud); + const [password, setPassword] = useState(''); + const [passwordShow, setPasswordShow] = useState(''); + const [secureTextEntry, setSecureTextEntry] = useState(true); + const { importWalletByPrivateKey, importWalletByMnemonic } = useImportWallet(); + + return ( + + + Password + Enter the password that protects your seed phrase in the cloud. + + { + const { newPassword, passwordShow: _passwordShow } = getPasswords(value, password, secureTextEntry); + setPassword(newPassword); + setPasswordShow(_passwordShow); + }} + rightIcon={ + + { + setPassword(''); + setPasswordShow(''); + }}> + + + { + const newSecureTextEntry = !secureTextEntry; + setSecureTextEntry(newSecureTextEntry); + setPasswordShow(passwordShowFormat(newSecureTextEntry, password)); + }}> + + + + } + /> + + + + + { + const result = aes.decrypt(walletInCloud, password); + if (!result) { + CommonToast.fail('Password error'); + return; + } + console.log('decrypt result: ', result, JSON.parse(result)); + const wallet: TWalletInfo = JSON.parse(result); + if (wallet.AESEncryptMnemonic) { + const mnemonic = aes.decrypt(wallet.AESEncryptMnemonic, password); + if (!mnemonic) { + CommonToast.fail('Password error'); + return; + } + console.log('mnemonic: ', mnemonic); + importWalletByMnemonic(mnemonic); + } else { + const privateKey = aes.decrypt(wallet.accountList[0].AESEncryptPrivateKey, password); + if (!privateKey) { + CommonToast.fail('Password error'); + return; + } + console.log('privateKey: ', privateKey); + importWalletByPrivateKey(privateKey); + } + }}> + Continue + + + + ); +} + +const getStyles = makeStyles(theme => ({ + containerStyles: { + backgroundColor: theme.colors.bgBase1, + justifyContent: 'space-between', + }, + title: { + marginTop: pTd(24), + fontSize: pTd(32), + ...fonts.BGMediumFont, + }, + desc: { + color: theme.colors.textBase2, + marginTop: pTd(16), + fontSize: pTd(14), + }, + inputContainer: { + marginTop: pTd(24), + flexDirection: 'row', + flexWrap: 'wrap', + }, + inputLabel: { + paddingLeft: 0, + }, + continueButton: { + marginTop: pTd(24), + marginBottom: pTd(16), + }, +})); diff --git a/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/index.tsx b/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/index.tsx new file mode 100644 index 000000000..56a94517e --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/ImportWallet/ImportByCloud/index.tsx @@ -0,0 +1,323 @@ +import React, { useEffect, useState } from 'react'; +import { Text, View } from 'react-native'; +import PageContainer from 'components/PageContainer'; +import { isIOS } from '@portkey-wallet/utils/mobile/device'; +import { makeStyles } from '@rneui/themed'; +import { pTd } from 'utils/unit'; +import { useCardStyles, useWalletCommonStyles } from '../../styles'; +import CommonAvatar from 'components/CommonAvatar'; +import navigationService from 'utils/navigationService'; +import Touchable from 'components/Touchable'; +import fonts from 'assets/theme/fonts'; +import { useCloudStorage } from '../../CloudBackup/useCloudStorage'; +// import LottieLoading from 'components/LottieLoading'; +import { addressFormat, formatStr2EllipsisStr } from '@portkey-wallet/utils'; +import dayjs from 'dayjs'; +import ActionSheet from 'components/ActionSheet'; +import * as Clipboard from 'expo-clipboard'; +import CommonToast from 'components/CommonToast'; +import { ChainId } from '@portkey-wallet/types'; +import { IconName } from 'components/Svg'; + +interface IAddressInfo { + address: string; + addressShow: string; + info?: { + updateTime: string; + wallet: string; + }; +} + +const modalAddressInfo: { + chain: ChainId; + name: string; + icon: IconName; + addressFormatted: string; + addressShow: string; +}[] = [ + { + chain: 'tDVV', + icon: 'Chain=AELF Side', + name: 'aelf dAppChain', + addressFormatted: '', + addressShow: '', + }, + { + chain: 'AELF', + icon: 'Chain=AELF Main', + name: 'aelf MainChain', + addressFormatted: '', + addressShow: '', + }, +]; + +export default function ImportByCloud() { + const styles = getStyles(); + const addressCardStyles = getAddressCardStyles(); + const commonStyles = useWalletCommonStyles(); + const cardStyles = useCardStyles(); + + const { handleListContents, readFile } = useCloudStorage(); + + const [addressesInfo, setAddressesInfo] = useState([]); + const [addresses, setAddresses] = useState([]); + + useEffect(() => { + const getAddressList = async () => { + const addressList = await handleListContents(); + console.log('address list', addressList); + if (addressList) { + const _addressesInfo = addressList.map(item => { + return { + address: item, + addressShow: formatStr2EllipsisStr(addressFormat(item), 8), + // addressShow: addressFormat(item), + info: { + updateTime: '', + wallet: '', + }, + }; + }); + setAddressesInfo(_addressesInfo); + setAddresses(addressList); + // getAddressInfo(addressList, _addressesInfo); + } + }; + getAddressList(); + }, [handleListContents, readFile]); + + useEffect(() => { + if (addresses.length === 0) { + return; + } + const getAddressInfo = async (addressList: string[]) => { + const promiseList = []; + for (const address of addressList) { + promiseList.push(readFile(address)); + } + const _addressesInfo = JSON.parse(JSON.stringify(addressesInfo)) as IAddressInfo[]; + await Promise.all(promiseList).then(results => { + results.forEach((result, index) => { + const address = addressList[index]; + const _index = _addressesInfo.findIndex(item => item.address === address); + if (result && _index >= 0) { + console.log('addressInfo result ', result, _index); + _addressesInfo[_index].info = JSON.parse(result); + } + }); + }); + setAddressesInfo(_addressesInfo); + }; + getAddressInfo(addresses); + }, [addresses, readFile]); + + return ( + + Choose backup + Select the backup you wish to import. + + {/*{loading ? : null}*/} + {addressesInfo.map((item, index) => { + return ( + { + if (!item.info?.wallet) { + return; + } + navigationService.push('ImportByCloudDecrypt', { + walletInCloud: item.info?.wallet, + }); + }}> + + + { + const addressesShowInfo = modalAddressInfo.map(_addressInfo => { + const addressFormatted = addressFormat(item.address, _addressInfo.chain); + return { + ..._addressInfo, + addressFormatted, + addressShow: formatStr2EllipsisStr(addressFormatted, 8), + }; + }); + ActionSheet.alert({ + isCloseShow: false, + title: ( + + Multichain addresses + + {addressesShowInfo.map((addressShowInfo, addressesShowInfoIndex) => { + return ( + + + + + {addressShowInfo.name} + {addressShowInfo.addressShow} + + + { + const isCopy = await Clipboard.setStringAsync(addressShowInfo.addressFormatted); + if (isCopy) { + CommonToast.success('Copied'); + } + }}> + + + + ); + })} + + + ), + buttonGroupDirection: 'column', + buttons: [], + }); + }}> + Multichain + + + {item.addressShow} + + {item.info?.updateTime ? 'Added on ' + dayjs(item.info.updateTime).format('MMM DD, YYYY') : ' '} + + + + + + + + ); + })} + + ); +} + +const getStyles = makeStyles(theme => ({ + rightContainer: { + justifyContent: 'center', + }, + icon: { + // marginRight: pTd(12), + backgroundColor: 'transparent', + }, + marginBottom40: { + marginBottom: pTd(40), + }, + marginVertical16: { + marginVertical: pTd(8), + }, + tagContainer: { + flexDirection: 'row', + borderColor: theme.colors.borderBase1, + borderRadius: pTd(4), + borderWidth: pTd(1), + // paddingHorizontal: pTd(4), + // paddingVertical: pTd(6), + width: pTd(90), + height: pTd(24), + backgroundColor: theme.colors.bgBase1, + alignItems: 'center', + // justifyContent: 'center', + }, + tagText: { + ...fonts.SGMediumFont, + color: theme.colors.textBase1, + fontSize: pTd(12), + lineHeight: pTd(12) * 1.4, + marginLeft: pTd(6), + marginRight: pTd(4), + }, + tagIcon: { + marginRight: pTd(16), + backgroundColor: 'transparent', + }, + title: { + ...fonts.SGMediumFont, + color: theme.colors.textBase1, + fontSize: pTd(16), + fontWeight: 'bold', + lineHeight: pTd(16) * 1.4, + marginTop: pTd(8), + }, + subtitle: { + color: theme.colors.textBase1Opacity07, + fontSize: pTd(14), + lineHeight: pTd(14) * 1.4, + marginTop: pTd(12), + }, +})); +const getAddressCardStyles = makeStyles(theme => ({ + header: { + ...fonts.BGMediumFont, + color: theme.colors.textBase1, + fontSize: pTd(20), + lineHeight: pTd(16) * 1.2, + }, + cardContainer: { + flexDirection: 'column', + }, + card: { + flexDirection: 'row', + paddingVertical: pTd(16), + // paddingHorizontal: pTd(12), + justifyContent: 'space-between', + width: '100%', + marginTop: pTd(12), + }, + info: { + flexDirection: 'row', + }, + chainIcon: { + marginRight: pTd(12), + }, + title: { + color: theme.colors.textBase1, + fontSize: pTd(16), + lineHeight: pTd(16) * 1.4, + // marginTop: pTd(8), + }, + subtitle: { + color: theme.colors.textBase1Opacity07, + fontSize: pTd(14), + lineHeight: pTd(14) * 1.4, + marginTop: pTd(5), + width: pTd(250), + }, +})); diff --git a/packages/mobile-aelf/js/pages/Login/ImportWallet/PrivateKey/index.tsx b/packages/mobile-aelf/js/pages/Login/ImportWallet/PrivateKey/index.tsx index 9d20cedbc..065aa32b4 100644 --- a/packages/mobile-aelf/js/pages/Login/ImportWallet/PrivateKey/index.tsx +++ b/packages/mobile-aelf/js/pages/Login/ImportWallet/PrivateKey/index.tsx @@ -6,9 +6,7 @@ import Touchable from 'components/Touchable'; import CommonButton from 'components/CommonButton'; import Svg from 'components/Svg'; import * as Clipboard from 'expo-clipboard'; -import navigationService from 'utils/navigationService'; -import { SetBiometricsTypeEnum } from 'pages/Pin/SetBiometrics'; -import { authenticationReady } from '@portkey-wallet/utils/mobile/authentication'; +import { useImportWallet } from '../../hooks/useImportWallet'; export default function RecoveryPhrase() { const styles = getStyles(); @@ -64,20 +62,7 @@ export default function RecoveryPhrase() { ); }, [onClear, styles.button, styles.buttonText, theme.colors.iconBase2]); - const importWalletByPrivateKey = useCallback(async () => { - const isReady = await authenticationReady(); - if (isReady) { - navigationService.push('SetBiometrics', { - type: SetBiometricsTypeEnum.create, - privateKey: inputText.trim(), - }); - return; - } - - navigationService.navigate('SetPin', { - privateKey: inputText.trim(), - }); - }, [inputText]); + const { importWalletByPrivateKey } = useImportWallet(); return ( @@ -96,7 +81,7 @@ export default function RecoveryPhrase() { style={styles.importButton} disabledStyle={styles.importButtonDisable} disabled={!isPrivateKeyValid} - onPress={importWalletByPrivateKey}> + onPress={() => importWalletByPrivateKey(inputText)}> Import diff --git a/packages/mobile-aelf/js/pages/Login/ImportWallet/RecoveryPhrase/index.tsx b/packages/mobile-aelf/js/pages/Login/ImportWallet/RecoveryPhrase/index.tsx index 5b386d68d..06fdccc4c 100644 --- a/packages/mobile-aelf/js/pages/Login/ImportWallet/RecoveryPhrase/index.tsx +++ b/packages/mobile-aelf/js/pages/Login/ImportWallet/RecoveryPhrase/index.tsx @@ -9,9 +9,7 @@ import CommonButton from 'components/CommonButton'; import CommonToast from 'components/CommonToast'; import * as bip39 from 'bip39'; import * as Clipboard from 'expo-clipboard'; -import { authenticationReady } from '@portkey-wallet/utils/mobile/authentication'; -import navigationService from 'utils/navigationService'; -import { SetBiometricsTypeEnum } from 'pages/Pin/SetBiometrics'; +import { useImportWallet } from '../../hooks/useImportWallet'; const MnemonicsWordCount = 12; let invalidMnemonicsToastTimer: NodeJS.Timeout; @@ -84,20 +82,7 @@ export default function RecoveryPhrase() { ); }, [onClear, styles.button, styles.buttonText, theme.colors.iconBase2]); - const importWalletByMnemonic = useCallback(async () => { - const isReady = await authenticationReady(); - if (isReady) { - navigationService.push('SetBiometrics', { - type: SetBiometricsTypeEnum.create, - mnemonics: mnemonics.join(' '), - }); - return; - } - - navigationService.navigate('SetPin', { - mnemonics: mnemonics.join(' '), - }); - }, [mnemonics]); + const { importWalletByMnemonic } = useImportWallet(); return ( @@ -130,7 +115,7 @@ export default function RecoveryPhrase() { style={styles.importButton} disabledStyle={styles.importButtonDisable} disabled={!isMnemonicsValid} - onPress={importWalletByMnemonic}> + onPress={() => importWalletByMnemonic(mnemonics)}> Import diff --git a/packages/mobile-aelf/js/pages/Login/WalletImportTypeSelect/index.tsx b/packages/mobile-aelf/js/pages/Login/WalletImportTypeSelect/index.tsx index 89b6afb53..82502bba6 100644 --- a/packages/mobile-aelf/js/pages/Login/WalletImportTypeSelect/index.tsx +++ b/packages/mobile-aelf/js/pages/Login/WalletImportTypeSelect/index.tsx @@ -24,12 +24,14 @@ const ListItem: { isAndroid: true, svgName: 'google-drive', title: 'Google Drive', + importType: 'google', subTitle: 'Import your seed phrase from Google Drive.', }, { isIOS: true, localImage: iCloudImage, title: 'iCloud', + importType: 'iCloud', subTitle: 'Import your seed phrase from iCloud.', }, { @@ -75,9 +77,15 @@ export default function WalletImportTypeSelect() { if (!item.importType) { return; } - navigationService.push('ImportWallet', { - importType: item.importType, - }); + if (item.isAndroid || item.isIOS) { + navigationService.push('ImportByCloud', { + importType: item.importType, + }); + } else { + navigationService.push('ImportWallet', { + importType: item.importType, + }); + } }}> {/* TODO: iCloud, google drive loading */} diff --git a/packages/mobile-aelf/js/pages/Login/hooks/useImportWallet.tsx b/packages/mobile-aelf/js/pages/Login/hooks/useImportWallet.tsx new file mode 100644 index 000000000..f257f3ec9 --- /dev/null +++ b/packages/mobile-aelf/js/pages/Login/hooks/useImportWallet.tsx @@ -0,0 +1,44 @@ +import { useCallback } from 'react'; +import navigationService from 'utils/navigationService'; +import { SetBiometricsTypeEnum } from 'pages/Pin/SetBiometrics'; +import { authenticationReady } from '@portkey-wallet/utils/mobile/authentication'; + +function formatMnemonics(mnemonics: string[] | string) { + return typeof mnemonics === 'string' ? mnemonics.trim() : mnemonics.join(' '); +} +export const useImportWallet = () => { + const importWalletByMnemonic = useCallback(async (mnemonics: string[] | string) => { + const isReady = await authenticationReady(); + if (isReady) { + navigationService.push('SetBiometrics', { + type: SetBiometricsTypeEnum.create, + mnemonics: formatMnemonics(mnemonics), + }); + return; + } + + navigationService.navigate('SetPin', { + mnemonics: formatMnemonics(mnemonics), + }); + }, []); + + const importWalletByPrivateKey = useCallback(async (privateKey: string) => { + const isReady = await authenticationReady(); + if (isReady) { + navigationService.push('SetBiometrics', { + type: SetBiometricsTypeEnum.create, + privateKey: privateKey.trim(), + }); + return; + } + + navigationService.navigate('SetPin', { + privateKey: privateKey.trim(), + }); + }, []); + + return { + importWalletByMnemonic, + importWalletByPrivateKey, + }; +}; diff --git a/packages/mobile-aelf/js/pages/Login/index.ts b/packages/mobile-aelf/js/pages/Login/index.ts index 8701f93d2..b01d0929a 100644 --- a/packages/mobile-aelf/js/pages/Login/index.ts +++ b/packages/mobile-aelf/js/pages/Login/index.ts @@ -10,6 +10,10 @@ import ConfirmBackup from './ConfirmBackup'; import ManualBackup from './ManualBackup'; import ManualBackupSuccess from './ManualBackup/Success'; import WalletImportTypeSelect from './WalletImportTypeSelect'; +import ImportByCloud from './ImportWallet/ImportByCloud'; +import ImportByCloudDecrypt from './ImportWallet/ImportByCloud/Decrypt'; +import CloudBackup from './CloudBackup'; +import CloudBackupDev from './CloudBackup/cases'; const stackNav = [ { name: 'LoginEmail', component: LoginEmail }, @@ -21,8 +25,12 @@ const stackNav = [ { name: 'PrepareWallet', component: PrepareWallet, options: { gestureEnabled: false } }, { name: 'ImportWallet', component: ImportWallet }, { name: 'WalletImportTypeSelect', component: WalletImportTypeSelect }, + { name: 'ImportByCloud', component: ImportByCloud }, + { name: 'ImportByCloudDecrypt', component: ImportByCloudDecrypt }, { name: 'ConfirmBackup', component: ConfirmBackup }, { name: 'ManualBackup', component: ManualBackup }, + { name: 'CloudBackup', component: CloudBackup }, + { name: 'CloudBackupDev', component: CloudBackupDev }, { name: 'ManualBackupSuccess', component: ManualBackupSuccess }, ] as const; diff --git a/packages/mobile-aelf/package.json b/packages/mobile-aelf/package.json index 316920c80..39414a20b 100644 --- a/packages/mobile-aelf/package.json +++ b/packages/mobile-aelf/package.json @@ -129,7 +129,7 @@ "react": "^18.3.1", "react-native": "^0.75.0", "react-native-background-timer": "^2.4.1", - "react-native-cloud-storage": "^2.2.1", + "react-native-cloud-storage": "^2.2.2", "react-native-config": "^1.4.6", "react-native-crypto": "^2.2.0", "react-native-device-info": "^10.11.0",