diff --git a/packages/api/api-eoa/activity/index.ts b/packages/api/api-eoa/activity/index.ts new file mode 100644 index 0000000000..c922095056 --- /dev/null +++ b/packages/api/api-eoa/activity/index.ts @@ -0,0 +1,6 @@ +export default { + activityList: '/api/app/user/activities/activities', + activity: '/api/app/user/activities/activity', + activityListWithAddress: '/api/app/user/activities/transactions', + reportTransaction: '/api/app/report/transaction', +} as const; diff --git a/packages/api/api-eoa/assets/index.ts b/packages/api/api-eoa/assets/index.ts new file mode 100644 index 0000000000..b854d7431d --- /dev/null +++ b/packages/api/api-eoa/assets/index.ts @@ -0,0 +1,39 @@ +export default { + fetchAccountTokenList: '/api/app/user/assets/token', + fetchAccountTokenListV2: '/api/app/v2/user/assets/token', + fetchAccountNftCollectionList: '/api/app/user/assets/nftCollections', + fetchAccountNftCollectionItemList: '/api/app/user/assets/nftItems', + fetchAccountNftCollectionItem: { + target: '/api/app/user/assets/nftItem', + config: { + method: 'POST', + timeout: 20 * 1000, + }, + }, + // nft and tokens + fetchAccountAssetsByKeywords: '/api/app/user/assets/searchUserAssets', + fetchAccountAssetsByKeywordsV2: '/api/app/v2/user/assets/searchUserAssets', + // nft and token in crypto box + fetchCryptoBoxAccountAssetsByKeywords: '/api/app/v2/user/assets/searchUserPackageAssets', + fetchTokenPrice: { + target: '/api/app/tokens/prices', + config: { method: 'GET' }, + }, + fetchTokenAllowanceList: '/api/app/tokens/allowances', + getSymbolImages: { + target: '/api/app/user/assets/symbolImages', + config: { method: 'GET' }, + }, + getTokenBalance: { + target: '/api/app/user/assets/tokenBalance', + config: { method: 'GET' }, + }, + getAssetsEstimation: { + target: '/api/app/user/assets/asset-estimation', + config: { method: 'GET' }, + }, + getAwakenTokenList: { + target: '/api/app/user/assets/awaken/token', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/assets/util.ts b/packages/api/api-eoa/assets/util.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/api/api-eoa/awaken/index.ts b/packages/api/api-eoa/awaken/index.ts new file mode 100644 index 0000000000..6053b9a0c4 --- /dev/null +++ b/packages/api/api-eoa/awaken/index.ts @@ -0,0 +1,14 @@ +export default { + getSwapRoutes: { + target: '/api/app/route/best-swap-routes', + config: { method: 'GET' }, + }, + getAwakenGasFee: { + target: '/api/app/transaction-fee', + config: { method: 'GET' }, + }, + getAwakenTokenPrice: { + target: '/api/app/token/price', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/chain/index.ts b/packages/api/api-eoa/chain/index.ts new file mode 100644 index 0000000000..c2f109ab37 --- /dev/null +++ b/packages/api/api-eoa/chain/index.ts @@ -0,0 +1,3 @@ +export default { + getChains: '/api/app/getChains', +} as const; diff --git a/packages/api/api-eoa/contact/index.ts b/packages/api/api-eoa/contact/index.ts new file mode 100644 index 0000000000..ca43c8e451 --- /dev/null +++ b/packages/api/api-eoa/contact/index.ts @@ -0,0 +1,82 @@ +import { BaseConfig } from '../../types'; + +const BASE_URL = `/api/app/contacts`; +const BASE_URL_V2 = `/api/app/address-book`; + +const KeyList = [ + 'addContact', + 'editContact', + 'deleteContact', + 'checkContactName', + 'readImputation', + 'contactPrivacyList', + 'updateContactPrivacy', +] as const; + +const KeyListV2 = [ + 'createSaved', + 'updateSaved', + 'deleteSaved', + 'checkSavedName', + 'getSavedList', + 'getSupportNetworkList', +] as const; + +const ApiObject: Record<(typeof KeyList)[number], BaseConfig> = { + addContact: { + target: `${BASE_URL}`, + config: { method: 'POST' }, + }, + editContact: { + target: `${BASE_URL}`, + config: { method: 'PUT' }, + }, + deleteContact: { + target: `${BASE_URL}`, + config: { method: 'DELETE' }, + }, + checkContactName: { + target: `${BASE_URL}/exist`, + config: { method: 'GET' }, + }, + readImputation: { + target: `${BASE_URL}/read`, + config: { method: 'POST' }, + }, + contactPrivacyList: { + target: `/api/app/privacyPermission`, + config: { method: 'GET' }, + }, + updateContactPrivacy: { + target: `/api/app/privacyPermission`, + config: { method: 'POST' }, + }, +}; +const ApiObjectV2: Record<(typeof KeyListV2)[number], BaseConfig> = { + createSaved: { + target: `${BASE_URL_V2}/create`, + config: { method: 'POST' }, + }, + updateSaved: { + target: `${BASE_URL_V2}/update`, + config: { method: 'POST' }, + }, + deleteSaved: { + target: `${BASE_URL_V2}/delete`, + config: { method: 'POST' }, + }, + checkSavedName: { + target: `${BASE_URL_V2}/exist`, + config: { method: 'GET' }, + }, + getSavedList: { + target: `${BASE_URL_V2}/read`, + config: { method: 'GET' }, + }, + getSupportNetworkList: { + target: `${BASE_URL_V2}/network`, + config: { method: 'GET' }, + }, +}; + +export default Object.assign(ApiObject, ApiObjectV2); diff --git a/packages/api/api-eoa/contact/type.ts b/packages/api/api-eoa/contact/type.ts new file mode 100644 index 0000000000..a1a6e02565 --- /dev/null +++ b/packages/api/api-eoa/contact/type.ts @@ -0,0 +1,3 @@ +export interface CheckContactNameResponseType { + existed: boolean; +} diff --git a/packages/api/api-eoa/deposit/index.ts b/packages/api/api-eoa/deposit/index.ts new file mode 100644 index 0000000000..0e36d9a312 --- /dev/null +++ b/packages/api/api-eoa/deposit/index.ts @@ -0,0 +1,35 @@ +export default { + getTokenList: { + target: '/api/app/transfer/token/list', + config: { method: 'GET' }, + }, + getTokenListByNetwork: { + target: '/api/app/transfer/network/tokens', + config: { method: 'GET' }, + }, + getDepositTokenList: { + target: '/api/app/transfer/token/option', + config: { method: 'GET' }, + }, + getNetworkList: { + target: '/api/app/transfer/network/list', + config: { method: 'GET' }, + }, + getDepositInfo: { + target: '/api/app/transfer/deposit/info', + config: { method: 'GET' }, + }, + depositCalculator: { + target: '/api/app/transfer/deposit/calculator', + config: { method: 'GET' }, + }, + recordList: { + target: '/api/app/transfer/record/list', + config: { method: 'GET' }, + }, + getTransferToken: { + target: '/api/app/transfer/connect/token', + config: { method: 'POST' }, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + }, +} as const; diff --git a/packages/api/api-eoa/device/index.ts b/packages/api/api-eoa/device/index.ts new file mode 100644 index 0000000000..9121feda0e --- /dev/null +++ b/packages/api/api-eoa/device/index.ts @@ -0,0 +1,4 @@ +export default { + fetchEncrypt: '/api/app/account/device/encrypt', + fetchDecrypt: '/api/app/account/device/decrypt', +} as const; diff --git a/packages/api/api-eoa/discover/index.ts b/packages/api/api-eoa/discover/index.ts new file mode 100644 index 0000000000..ddcf6b1375 --- /dev/null +++ b/packages/api/api-eoa/discover/index.ts @@ -0,0 +1,22 @@ +export default { + addBookmark: '/api/app/bookmarks', + deleteAllBookmark: { + target: '/api/app/bookmarks', + config: { method: 'DELETE' }, + }, + deleteBookmark: '/api/app/bookmarks/modify', + getBookmarks: { + target: '/api/app/bookmarks', + config: { method: 'GET' }, + }, + getCryptoCurrencyList: { + target: '/api/app/cryptocurrency/list', + config: { method: 'GET' }, + }, + markFavorite: { + target: '/api/app/cryptocurrency/mark', + }, + unMarkFavorite: { + target: '/api/app/cryptocurrency/unmark', + }, +} as const; diff --git a/packages/api/api-eoa/es/index.ts b/packages/api/api-eoa/es/index.ts new file mode 100644 index 0000000000..17b2f42fe8 --- /dev/null +++ b/packages/api/api-eoa/es/index.ts @@ -0,0 +1,47 @@ +import { ESBaseConfig } from './type'; + +const Method = 'GET'; +const BaseESUrl = `/api/app/`; + +const KeyList = [ + 'getUserTokenList', + 'getChainsInfo', + 'getRegisterResult', + 'getRecoverResult', + 'getContactList', + 'getContactListNew', + 'getCaHolder', +] as const; + +const ApiObject: Record<(typeof KeyList)[number], ESBaseConfig> = { + getUserTokenList: { + target: `${BaseESUrl}search/usertokenindex`, + config: { method: Method }, + }, + getChainsInfo: { + target: `${BaseESUrl}search/chainsinfoindex`, + config: { method: Method, params: { sort: 'chainId' } }, + }, + getRegisterResult: { + target: `${BaseESUrl}search/accountregisterindex`, + config: { method: Method }, + }, + getRecoverResult: { + target: `${BaseESUrl}search/accountrecoverindex`, + config: { method: Method }, + }, + getContactList: { + target: `${BaseESUrl}contacts/list`, + config: { method: Method }, + }, + getContactListNew: { + target: `${BaseESUrl}address-book/list`, + config: { method: Method }, + }, + getCaHolder: { + target: `${BaseESUrl}search/caholderindex`, + config: { method: Method }, + }, +}; + +export default ApiObject; diff --git a/packages/api/api-eoa/es/type.ts b/packages/api/api-eoa/es/type.ts new file mode 100644 index 0000000000..70ea8f1e0a --- /dev/null +++ b/packages/api/api-eoa/es/type.ts @@ -0,0 +1,25 @@ +import { CustomFetchConfig } from '@portkey-wallet/utils/fetch'; +import { BaseConfig, RequestConfig } from '../../types'; + +export interface ESConfig extends CustomFetchConfig { + params?: { + filter?: string; + sort?: string; + sortType?: 0 | 1; + skipCount?: number; + maxResultCount?: number; + }; +} + +export type ESBaseConfig = BaseConfig & { + config: ESConfig; +}; + +export type ES_API_REQ_FUNCTION = (config?: RequestConfig & ESConfig) => Promise<{ type: 'timeout' } | any>; + +export interface IGetContactListParams { + page: number; + size: number; + modificationTime: string; + keyword?: string; +} diff --git a/packages/api/api-eoa/es/utils/index.ts b/packages/api/api-eoa/es/utils/index.ts new file mode 100644 index 0000000000..d388292b30 --- /dev/null +++ b/packages/api/api-eoa/es/utils/index.ts @@ -0,0 +1,94 @@ +import { request } from '@portkey-wallet/api/api-did'; +import { GetContractListApiType } from '@portkey-wallet/types/types-ca/contact'; +import { TGetContactListApiType } from '@portkey-wallet/types/types-ca/contactNew'; + +import { IGetContactListParams } from '../type'; + +export const getContactList = ( + baseURL: string, + { page, size, modificationTime, keyword }: IGetContactListParams, +): Promise => { + return request.es.getContactList({ + baseURL, + params: { + filter: `modificationTime: [* TO ${modificationTime}] AND isDeleted: false`, + sort: 'modificationTime', + sortType: 0, + skipCount: (page - 1) * size, + maxResultCount: size, + keyword, + }, + }); +}; + +export const getContactEventList = ( + baseURL: string, + { page, size, modificationTime, fetchTime, keyword }: IGetContactListParams & { fetchTime: string }, +): Promise => { + return request.es.getContactList({ + baseURL, + params: { + filter: `modificationTime: [${modificationTime} TO ${fetchTime}]`, + sort: 'modificationTime', + sortType: 0, + skipCount: (page - 1) * size, + maxResultCount: size, + keyword, + }, + }); +}; + +export const getContactListV2 = ( + baseURL: string, + { page, size, modificationTime, keyword }: IGetContactListParams, +): Promise => { + return request.es.getContactListNew({ + baseURL, + params: { + filter: `modificationTime: [* TO ${modificationTime}] AND isDeleted: false`, + sort: 'modificationTime', + sortType: 0, + skipCount: (page - 1) * size, + maxResultCount: size, + keyword, + }, + }); +}; + +export const getContactEventListV2 = ( + baseURL: string, + { page, size, modificationTime, fetchTime, keyword }: IGetContactListParams & { fetchTime: string }, +): Promise => { + return request.es.getContactListNew({ + baseURL, + params: { + filter: `modificationTime: [${modificationTime} TO ${fetchTime}]`, + sort: 'modificationTime', + sortType: 0, + skipCount: (page - 1) * size, + maxResultCount: size, + keyword, + }, + }); +}; + +export const getCaHolder = ( + baseURL: string, + { caHash }: { caHash: string }, +): Promise<{ + items: Array<{ + userId: string; + caAddress: string; + caHash: string; + id: string; + nickName: string; + avatar: string; + }>; +}> => { + return request.es.getCaHolder({ + baseURL, + params: { + filter: `caHash: ${caHash}`, + }, + }); +}; diff --git a/packages/api/api-eoa/freeMint/index.ts b/packages/api/api-eoa/freeMint/index.ts new file mode 100644 index 0000000000..9fee9fe1c4 --- /dev/null +++ b/packages/api/api-eoa/freeMint/index.ts @@ -0,0 +1,24 @@ +export default { + getRecentStatus: { + target: '/api/app/mint/recentStatus', + config: { method: 'GET' }, + }, + getMintInfo: { + target: '/api/app/mint/Info', + config: { method: 'GET' }, + }, + confirmMint: '/api/app/mint/confirm', + confirmAgain: '/api/app/mint/mintAgain', + getMintStatus: { + target: '/api/app/mint/status', + config: { method: 'GET' }, + }, + getMintDetail: { + target: '/api/app/mint/detail', + config: { method: 'GET' }, + }, + getMintItemInfo: { + target: '/api/app/mint/itemInfo', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/guide/index.ts b/packages/api/api-eoa/guide/index.ts new file mode 100644 index 0000000000..121d8a12bc --- /dev/null +++ b/packages/api/api-eoa/guide/index.ts @@ -0,0 +1,11 @@ +export default { + getGuideList: { + target: '/api/app/user/guide/list', + config: { method: 'GET' }, + }, + getGuideItem: { + target: '/api/app/user/guide/query', + config: { method: 'GET' }, + }, + finishGuideItem: '/api/app/user/guide/finish', +} as const; diff --git a/packages/api/api-eoa/im/index.ts b/packages/api/api-eoa/im/index.ts new file mode 100644 index 0000000000..b87f3eeaf9 --- /dev/null +++ b/packages/api/api-eoa/im/index.ts @@ -0,0 +1,6 @@ +export default { + getImageThumb: { + target: '/api/app/image/getThumbnail', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/index.ts b/packages/api/api-eoa/index.ts new file mode 100644 index 0000000000..961c03b31c --- /dev/null +++ b/packages/api/api-eoa/index.ts @@ -0,0 +1,105 @@ +import walletApi from './wallet'; +import verificationApi from './verification'; +import contactApi from './contact'; +import chainApi from './chain'; +import assetsApi from './assets'; +import recentApi from './recent'; +import tokenApi from './token'; +import deviceApi from './device'; +import messageApi from './message'; +import switchApi from './switch'; +import discoverApi from './discover'; +import txFeeApi from './txFee'; +import imApi from './im'; +import privacyApi from './privacy'; +import sendApi from './send'; + +import esApi from './es'; +import myServer, { DidService } from './server'; +import { API_REQ_FUNCTION } from '../types'; +import { ES_API_REQ_FUNCTION } from './es/type'; +import activityApi from './activity'; +import securityApi from './security'; +import guideApi from './guide'; +import managerApi from './manager'; +import referralApi from './referral'; +import depositApi from './deposit'; +import redPackageApi from './red-package'; +import freeMintApi from './freeMint'; +import receiveApi from './receive'; +import awakenApi from './awaken'; + +export const DEFAULT_METHOD = 'POST'; + +/** + * api request configuration directory + * @example + * upload: { + * target: '/api/file-management/file-descriptor/upload', + * baseConfig: { method: 'POST', }, + * }, + * or: + * upload:'/api/file-management/file-descriptor/upload' + * + * @description api configuration default method is from DEFAULT_METHOD + * @type {UrlObj} // The type of this object from UrlObj. + */ + +export const BASE_APIS = {}; + +export const EXPAND_APIS = { + wallet: walletApi, + verify: verificationApi, + contact: contactApi, + chain: chainApi, + // token: tokenApi, + activity: activityApi, + assets: assetsApi, + recent: recentApi, + token: tokenApi, + device: deviceApi, + message: messageApi, + switch: switchApi, + discover: discoverApi, + txFee: txFeeApi, + im: imApi, + security: securityApi, + privacy: privacyApi, + guide: guideApi, + manager: managerApi, + referral: referralApi, + deposit: depositApi, + redPackage: redPackageApi, + freeMintApi: freeMintApi, + receive: receiveApi, + sendApi: sendApi, + awakenApi: awakenApi, +}; + +export type BASE_REQ_TYPES = { + [x in keyof typeof BASE_APIS]: API_REQ_FUNCTION; +}; + +export type EXPAND_REQ_TYPES = { + [X in keyof typeof EXPAND_APIS]: { + [K in keyof (typeof EXPAND_APIS)[X]]: API_REQ_FUNCTION; + }; +}; + +export type ES_REQ_TYPES = Record; + +myServer.parseRouter('es', esApi as any); + +myServer.parseRouter('base', BASE_APIS); + +Object.entries(EXPAND_APIS).forEach(([key, value]) => { + myServer.parseRouter(key, value as any); +}); + +export interface IRequest extends BASE_REQ_TYPES, EXPAND_REQ_TYPES { + es: ES_REQ_TYPES; +} + +const request = myServer as unknown as IRequest & DidService; + +export { request }; diff --git a/packages/api/api-eoa/manager/index.ts b/packages/api/api-eoa/manager/index.ts new file mode 100644 index 0000000000..1fca7568cb --- /dev/null +++ b/packages/api/api-eoa/manager/index.ts @@ -0,0 +1,6 @@ +export default { + checkManagerCount: { + target: '/api/app/account/checkManagerCount', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/message/index.ts b/packages/api/api-eoa/message/index.ts new file mode 100644 index 0000000000..cb01d4a85a --- /dev/null +++ b/packages/api/api-eoa/message/index.ts @@ -0,0 +1,5 @@ +export default { + sendScanLoginSuccess: '/api/app/message/scanLoginSuccess', + sendScanLogin: '/api/app/message/scanLogin', + checkQRCodeExist: '/api/app/qrcode', +}; diff --git a/packages/api/api-eoa/message/utils.ts b/packages/api/api-eoa/message/utils.ts new file mode 100644 index 0000000000..e7837cac55 --- /dev/null +++ b/packages/api/api-eoa/message/utils.ts @@ -0,0 +1,12 @@ +import { request } from '../index'; +type sendScanLoginSuccessParams = { + targetClientId: string; +}; + +export async function sendScanLoginSuccess({ targetClientId }: sendScanLoginSuccessParams) { + return request.message.sendScanLoginSuccess({ params: { targetClientId } }); +} + +export const checkQRCodeExist = (id: string): Promise => { + return request.message.checkQRCodeExist({ params: { id } }); +}; diff --git a/packages/api/api-eoa/privacy/index.ts b/packages/api/api-eoa/privacy/index.ts new file mode 100644 index 0000000000..9e9bbffb51 --- /dev/null +++ b/packages/api/api-eoa/privacy/index.ts @@ -0,0 +1,3 @@ +export default { + privacyPolicy: '/api/app/privacypolicy/sign', +} as const; diff --git a/packages/api/api-eoa/receive/index.ts b/packages/api/api-eoa/receive/index.ts new file mode 100644 index 0000000000..5ef3fe686c --- /dev/null +++ b/packages/api/api-eoa/receive/index.ts @@ -0,0 +1,6 @@ +export default { + fetchReceiveNetworkList: { + target: '/api/app/transfer/getReceiveNetworkList', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/recent/index.ts b/packages/api/api-eoa/recent/index.ts new file mode 100644 index 0000000000..110a98d58d --- /dev/null +++ b/packages/api/api-eoa/recent/index.ts @@ -0,0 +1,3 @@ +export default { + fetchRecentTransactionUsers: '/api/app/user/assets/recentTransactionUsers', +} as const; diff --git a/packages/api/api-eoa/red-package/index.ts b/packages/api/api-eoa/red-package/index.ts new file mode 100644 index 0000000000..2e5d5bbeab --- /dev/null +++ b/packages/api/api-eoa/red-package/index.ts @@ -0,0 +1,30 @@ +export default { + getFirstCryptoGift: { + target: '/api/app/cryptogift/history/first', + config: { method: 'GET' }, + }, + getCryptoGiftHistories: { + target: '/api/app/cryptogift/histories', + config: { method: 'GET' }, + }, + getCryptoGiftDetail: { + target: '/api/app/redpackage/detail', + config: { method: 'GET' }, + }, + sendCryptoGift: { + target: '/api/app/redpackage/send', + config: { method: 'POST' }, + }, + generateCryptoGift: { + target: '/api/app/redpackage/generate', + config: { method: 'POST' }, + }, + getCreationStatus: { + target: '/api/app/redPackage/getCreationResult', + config: { method: 'GET' }, + }, + getRedPackageConfig: { + target: '/api/app/redpackage/config', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/referral/index.ts b/packages/api/api-eoa/referral/index.ts new file mode 100644 index 0000000000..19775d1227 --- /dev/null +++ b/packages/api/api-eoa/referral/index.ts @@ -0,0 +1,11 @@ +export default { + getReferralRedDotsStatus: { + target: '/api/app/growth/redDot', + config: { method: 'GET' }, + }, + setReferralRedDotsStatus: '/api/app/growth/redDot', + getReferralShortLink: { + target: '/api/app/growth/shortLink', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/security/index.ts b/packages/api/api-eoa/security/index.ts new file mode 100644 index 0000000000..f7d345cfed --- /dev/null +++ b/packages/api/api-eoa/security/index.ts @@ -0,0 +1,27 @@ +export default { + securityList: { + target: '/api/app/user/security/transferLimit', + config: { method: 'GET' }, + }, + balanceCheck: { + target: '/api/app/user/security/balanceCheck', + config: { method: 'GET' }, + }, + // secondary email api + secondaryMail: { + target: '/api/app/account/secondary/email', + config: { method: 'GET' }, + }, + sendSecondaryEmailCode: { + target: '/api/app/account/secondary/email/verify', + config: { method: 'POST' }, + }, + secondaryEmailCodeCheck: { + target: '/api/app/account/verifyCode/secondary/email', + config: { method: 'POST' }, + }, + setSecondaryEmail: { + target: '/api/app/account/set/secondary/email', + config: { method: 'POST' }, + }, +} as const; diff --git a/packages/api/api-eoa/send/index.ts b/packages/api/api-eoa/send/index.ts new file mode 100644 index 0000000000..9f653aad29 --- /dev/null +++ b/packages/api/api-eoa/send/index.ts @@ -0,0 +1,10 @@ +export default { + getSendNetworkList: { + target: '/api/app/transfer/getSendNetworkList', + config: { method: 'GET' }, + }, + getTransferSupportNetworkMap: { + target: '/api/app/transfer/support', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/server.ts b/packages/api/api-eoa/server.ts new file mode 100644 index 0000000000..c28ef2f028 --- /dev/null +++ b/packages/api/api-eoa/server.ts @@ -0,0 +1,65 @@ +import { ServiceInit } from '../server/config'; +import { customFetch } from '@portkey-wallet/utils/fetch'; +import { IExceptionManager, Severity } from '@portkey-wallet/utils/ExceptionManager'; +import { BaseConfig, RequestConfig } from '../types'; +import { getRequestConfig, spliceUrl } from '../utils'; + +export class DidService extends ServiceInit { + protected onLockApp?: (expired?: boolean) => void; + locked?: boolean; + exceptionManager?: IExceptionManager; + constructor() { + super(); + } + + send = async (base: BaseConfig, config?: RequestConfig): Promise => { + try { + return await this.sendOrigin(base, config); + } catch (errResult: any) { + const { URL, fetchConfig } = this.getConfig(base, config); + this.errorReport(URL, fetchConfig, errResult); + throw errResult; + } + }; + + getConfig = (base: BaseConfig, config?: RequestConfig) => { + const { method = 'POST', url, baseURL, ...fetchConfig } = getRequestConfig(base, config, this.defaultConfig) || {}; + const _url = url || (typeof base === 'string' ? base : base.target); + const URL = spliceUrl(baseURL || '', _url); + return { + URL, + method, + fetchConfig, + }; + }; + + sendOrigin = async (base: BaseConfig, config?: RequestConfig): Promise => { + const { URL, fetchConfig, method } = this.getConfig(base, config); + const fetchResult = await customFetch(URL, { + ...fetchConfig, + method, + }); + + return fetchResult; + }; + setLockCallBack = (callBack: (expired?: boolean) => void) => { + this.onLockApp = callBack; + }; + + setExceptionManager = (exceptionManager: IExceptionManager) => { + this.exceptionManager = exceptionManager; + }; + errorReport = (url: string, fetchConfig: any, fetchResult: any) => { + this.exceptionManager?.reportErrorMessage?.(`${URL} request error`, Severity.Fatal, { + req: { + url, + config: fetchConfig, + }, + rep: fetchResult, + }); + }; +} + +const didServer = new DidService(); + +export default didServer; diff --git a/packages/api/api-eoa/switch/index.ts b/packages/api/api-eoa/switch/index.ts new file mode 100644 index 0000000000..aecad5c1b8 --- /dev/null +++ b/packages/api/api-eoa/switch/index.ts @@ -0,0 +1,6 @@ +export default { + checkButtonBuy: { + target: '/api/app/switch', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/token/index.ts b/packages/api/api-eoa/token/index.ts new file mode 100644 index 0000000000..3a6204bb5f --- /dev/null +++ b/packages/api/api-eoa/token/index.ts @@ -0,0 +1,50 @@ +export default { + fetchTokenPrice: { + target: '/api/app/tokens/prices', + config: { method: 'GET' }, + }, + fetchPopularToken: { + target: '/api/app/userTokens', + config: { method: 'GET' }, + }, + fetchPopularTokenV2: { + target: '/api/app/v2/userTokens', + config: { method: 'GET' }, + }, + displayUserToken: { + target: '/api/app/userTokens', + config: { method: 'PUT' }, + }, + displayUserTokenV2: { + target: '/api/app/v2/userTokens', + config: { method: 'PUT' }, + }, + fetchTokenListBySearch: { + target: '/api/app/tokens/list', + config: { method: 'GET' }, + }, + fetchTokenListBySearchV2: { + target: '/api/app/v2/tokens/list', + config: { method: 'GET' }, + }, + fetchTokenItemBySearch: { + target: 'api/app/tokens/token', + config: { method: 'GET' }, + }, + closeZeroHoldingsToken: { + target: '/api/app/assets/zeroHoldings/close', + config: { method: 'POST' }, + }, + openZeroHoldingsToken: { + target: '/api/app/assets/zeroHoldings/open', + config: { method: 'POST' }, + }, + zeroHoldingsTokenStatus: { + target: '/api/app/assets/zeroHoldings/status', + config: { method: 'GET' }, + }, + userTokensDisplaySwitch: { + target: '/api/app/v2/userTokens/display', + config: { method: 'POST' }, + }, +} as const; diff --git a/packages/api/api-eoa/txFee/index.ts b/packages/api/api-eoa/txFee/index.ts new file mode 100644 index 0000000000..06f5e68a58 --- /dev/null +++ b/packages/api/api-eoa/txFee/index.ts @@ -0,0 +1,6 @@ +export default { + fetchTxFee: { + target: '/api/app/account/transactionFee', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/api/api-eoa/types.ts b/packages/api/api-eoa/types.ts new file mode 100644 index 0000000000..23445884dc --- /dev/null +++ b/packages/api/api-eoa/types.ts @@ -0,0 +1,14 @@ +export interface BaseContext { + clientId: string; + requestId: string; +} + +export interface IContext { + context: BaseContext; +} + +export enum PlatFormInHeader { + ANDROID = 'android', + IOS = 'ios', + EXTENSION = 'extension', +} diff --git a/packages/api/api-eoa/utils/index.ts b/packages/api/api-eoa/utils/index.ts new file mode 100644 index 0000000000..4595aba3cc --- /dev/null +++ b/packages/api/api-eoa/utils/index.ts @@ -0,0 +1,70 @@ +import { AElfWallet } from '@portkey-wallet/types/aelf'; +import { customFetch } from '@portkey-wallet/utils/fetch'; +import { stringify } from 'query-string'; +import AElf from 'aelf-sdk'; +import { request } from '../index'; +import { ChainId } from '@portkey-wallet/types'; +export type RefreshTokenConfig = { + grant_type: 'signature'; + client_id: 'CAServer_App'; + scope: 'CAServer'; + signature: string; + pubkey: string; + timestamp: number; + ca_hash: string; + connectUrl: string; + chainId: ChainId; +}; + +const BEARER = 'Bearer'; + +export const queryAuthorization = async (config: RefreshTokenConfig) => { + const { connectUrl, ..._config } = config; + const { access_token } = await customFetch(config.connectUrl + '/connect/token', { + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + method: 'POST', + body: stringify({ ..._config, chain_id: config.chainId }), + }); + return `${BEARER} ${access_token}`; +}; + +export const formatTokenWithOutBear = (token: string) => { + if (token.startsWith(BEARER)) return token.replace(`${BEARER} `, ''); + return token; +}; + +const DAY = 24 * 60 * 60 * 1000; + +export const isValidRefreshTokenConfig = (config: RefreshTokenConfig) => { + const expireTime = config.timestamp + 1 * DAY; + return expireTime >= Date.now(); +}; + +export function setRefreshTokenConfig({ + account, + caHash, + connectUrl, + chainId, +}: { + account: AElfWallet; + caHash: string; + connectUrl: string; + chainId: ChainId; +}) { + const timestamp = Date.now(); + const message = Buffer.from(`${account.address}-${timestamp}`).toString('hex'); + const signature = AElf.wallet.sign(message, account.keyPair).toString('hex'); + const pubkey = (account.keyPair as any).getPublic('hex'); + const ca_hash = caHash; + return request.setRefreshTokenConfig({ + grant_type: 'signature', + client_id: 'CAServer_App', + scope: 'CAServer', + signature: signature, + pubkey, + timestamp, + ca_hash, + connectUrl, + chainId, + }); +} diff --git a/packages/api/api-eoa/utils/wallet.ts b/packages/api/api-eoa/utils/wallet.ts new file mode 100644 index 0000000000..a25bfae179 --- /dev/null +++ b/packages/api/api-eoa/utils/wallet.ts @@ -0,0 +1,124 @@ +import type { GuardiansApproved } from '@portkey/services'; +import { LoginKeyType } from '@portkey-wallet/types/types-ca/wallet'; +import { VerificationType, ZKLoginInfo } from '@portkey-wallet/types/verifier'; +import { request } from '..'; +import { IContext } from '../types'; +import { RequestSourceEnum } from '@portkey-wallet/constants/constants-ca/device'; + +interface RegisterDIDWalletParams extends IContext { + baseUrl?: string; + type: LoginKeyType; + loginGuardianIdentifier: string; //account + manager: string; + extraData: string; + verifierId: string; + verificationDoc?: string; + signature?: string; + chainId: string; + source?: RequestSourceEnum; +} + +export const registerDIDWallet = async ( + params: RegisterDIDWalletParams, +): Promise<{ + sessionId: string; +}> => { + const baseUrl = params.baseUrl; + delete params.baseUrl; + return request.wallet.requestRegister({ + baseURL: baseUrl, + params, + }); +}; + +// TODO Update services +export type GuardiansApprovedWithZK = GuardiansApproved & { zkLoginInfo?: ZKLoginInfo }; + +interface RecoveryDIDWalletParams extends IContext { + baseURL?: string; + loginGuardianIdentifier: string; + manager: string; + extraData: string; + chainId: string; + guardiansApproved: GuardiansApprovedWithZK[]; + source?: RequestSourceEnum; +} + +export const recoveryDIDWallet = async ( + params: RecoveryDIDWalletParams, +): Promise<{ + sessionId: string; +}> => { + const baseURL = params.baseURL; + delete params.baseURL; + return request.wallet.recoveryWallet({ + baseURL, + params, + }); +}; + +interface RequestCreateWalletParams { + baseURL?: string; + verificationType: VerificationType; + managerUniqueId: string; +} + +export const requestCreateWallet = async ({ + baseURL, + verificationType, + managerUniqueId, +}: RequestCreateWalletParams) => { + let fetch = request.es.getRegisterResult; + if (verificationType !== VerificationType.register) fetch = request.es.getRecoverResult; + const req = await fetch({ + baseURL, + params: { filter: `_id:${managerUniqueId}` }, + }); + const result = req.items[0]; + return result; +}; + +// TODO +export const setWalletName = ({ nickname, baseURL = '' }: { baseURL?: string; nickname: string }) => { + return request.wallet.setWalletName({ + baseURL, + params: { + nickname, + }, + }); +}; +interface FetchCreateWalletParams { + verificationType?: VerificationType; + type: LoginKeyType; + loginGuardianType: string; + managerUniqueId: string; + baseUrl?: string; +} + +export const fetchCreateWalletResult = async ({ + baseUrl, + type, + managerUniqueId, + loginGuardianType, + verificationType, +}: FetchCreateWalletParams) => { + let tmpFetch; + switch (verificationType) { + case VerificationType.register: + tmpFetch = request.wallet.queryRegister; + break; + case VerificationType.communityRecovery: + tmpFetch = request.wallet.queryRecovery; + break; + default: + throw Error('Unable to find the corresponding api'); + } + return await tmpFetch({ + baseURL: baseUrl, + params: { + type, + managerUniqueId, + loginGuardianType, + }, + }); +}; diff --git a/packages/api/api-eoa/verification/index.ts b/packages/api/api-eoa/verification/index.ts new file mode 100644 index 0000000000..40395cc1c8 --- /dev/null +++ b/packages/api/api-eoa/verification/index.ts @@ -0,0 +1,23 @@ +export default { + sendVerificationRequest: '/api/app/account/sendVerificationRequest', + checkVerificationCode: '/api/app/account/verifyCode', + getCountry: '/api/app/ipInfo/ipInfo', + verifyGoogleToken: '/api/app/account/verifyGoogleToken', + verifyAppleToken: '/api/app/account/verifyAppleToken', + verifyTelegramToken: '/api/app/account/verifyTelegramToken', + verifyTwitterToken: '/api/app/account/verifyTwitterToken', + verifyFacebookToken: '/api/app/account/verifyFacebookToken', + verifyZKLogin: { + target: '/api/app/account/verifiedzk', + config: { method: 'POST' }, + }, + sendAppleUserExtraInfo: '/api/app/userExtraInfo/appleUserExtraInfo', + getAppleUserExtraInfo: { + target: `/api/app/userExtraInfo`, + config: { method: 'GET' }, + }, + checkGoogleRecaptcha: '/api/app/account/isGoogleRecaptchaOpen', + getVerifierServer: '/api/app/account/getVerifierServer', + getTelegramBot: { target: '/api/app/telegramAuth/getTelegramBot', config: { method: 'GET' } }, + reportUnsetLoginGuardian: { target: '/api/app/account/guardianIdentifiers/unset', config: { method: 'POST' } }, +} as const; diff --git a/packages/api/api-eoa/verification/utils.ts b/packages/api/api-eoa/verification/utils.ts new file mode 100644 index 0000000000..e619c9ba42 --- /dev/null +++ b/packages/api/api-eoa/verification/utils.ts @@ -0,0 +1,98 @@ +import { IStorage, StorageBaseLoader } from '@portkey-wallet/types/storage'; +import { request } from '@portkey-wallet/api/api-did'; +import { RequestConfig } from '../../types'; +import { LoginKeyType } from '@portkey-wallet/types/types-ca/wallet'; +import { OperationTypeEnum } from '@portkey-wallet/types/verifier'; +import { ChainId } from '@portkey-wallet/types'; + +type VerifierInfo = { + verifierSessionId: string; + time: number; +}; + +export interface SendVerificationConfig extends RequestConfig { + params: { + type: LoginKeyType; + guardianIdentifier?: string; + verifierId?: string; + chainId: string | number; + operationType: OperationTypeEnum; + targetChainId?: ChainId; + operationDetails?: string; + }; +} + +export interface SendSecondVerificationConfig extends RequestConfig { + params: { + secondaryEmail: string; + platformType: number; + }; +} + +export const IntervalErrorMessage = 'The interval between sending two verification codes is less than 60s'; +export class Verification extends StorageBaseLoader { + private readonly _defaultKeyName = 'portkey_did_wallet'; + private readonly _expirationTime = 58 * 1000; + public verifierMap: { + [key: string]: VerifierInfo; + }; + constructor(store: IStorage) { + super(store); + this.verifierMap = {}; + this.load(); + } + public async load() { + try { + const storageVerifierMap = await this._store.getItem(this._defaultKeyName); + if (storageVerifierMap) this.verifierMap = JSON.parse(storageVerifierMap); + if (typeof this.verifierMap !== 'object') this.verifierMap = {}; + } catch (error) { + console.log(error, '====load-verification'); + } + } + public async save() { + this._store.setItem(this._defaultKeyName, JSON.stringify(this.verifierMap)); + } + public get(key: string): void | VerifierInfo { + const info = this.verifierMap[key]; + if (!info) return; + const endTime = info.time + this._expirationTime; + if (endTime > Date.now()) { + return info; + } else { + this.delete(key); + } + } + public delete(key: string) { + delete this.verifierMap[key]; + this.save(); + } + public async set(key: string, value: VerifierInfo) { + this.verifierMap[key] = value; + await this.save(); + } + + public async sendVerificationCode(config: SendVerificationConfig) { + const { guardianIdentifier, verifierId } = config.params; + const key = (guardianIdentifier || '') + (verifierId || ''); + try { + const req = await request.verify.sendVerificationRequest(config); + if (req?.verifierSessionId) { + await this.set(key, { ...req, time: Date.now() }); + } + return req; + } catch (error: any) { + const { message } = error?.error || error || {}; + const item = this.get(key); + if (message === IntervalErrorMessage && item) return item; + throw error; + } + } + public async checkVerificationCode(config: RequestConfig) { + const { guardianIdentifier, verifierId } = config.params || {}; + const key = (guardianIdentifier || '') + (verifierId || ''); + const req = await request.verify.checkVerificationCode(config); + this.delete(key); + return req; + } +} diff --git a/packages/api/api-eoa/wallet/index.ts b/packages/api/api-eoa/wallet/index.ts new file mode 100644 index 0000000000..19034e7efe --- /dev/null +++ b/packages/api/api-eoa/wallet/index.ts @@ -0,0 +1,67 @@ +export default { + requestRegister: '/api/app/account/register/request', + recoveryWallet: '/api/app/account/recovery/request', + guardianIdentifiers: { + target: '/api/app/account/guardianIdentifiers', + config: { method: 'GET' }, + }, + getRegisterInfo: { + target: '/api/app/account/registerInfo', + config: { method: 'GET' }, + }, + // TODO Test api + hubPing: '/api/app/account/hub/ping', + getCreateResponse: 'api/app/account/hub/response', + queryRecovery: '/api/app/account/recovery/query', + queryRegister: '/api/app/account/register/query', + setWalletName: '/api/app/account/setNickname', + getChainList: '/api/app/getChains', + editWalletName: { + target: '/api/app/account/nickname', + config: { method: 'PUT' }, + }, + editHolderInfo: '/api/app/account/holderInfo', + pullNotify: 'api/app/notify/pullNotify', + getPhoneCountryCode: { + target: '/api/app/phone/info', + config: { method: 'GET' }, + }, + getShowDeletionEntrance: { + target: '/api/app/account/revoke/entrance', + config: { method: 'GET' }, + }, + deletionCheck: { + target: '/api/app/account/revoke/check', + config: { method: 'GET' }, + }, + deletionCheckV2: { + target: '/api/app/account/revoke/validate', + config: { method: 'GET' }, + }, + deletionAccount: '/api/app/account/revoke/request', + deletionAccountV2: '/api/app/account/revoke/account', + getTwitterUserInfo: { + target: '/api/app/twitterAuth/userInfo', + config: { method: 'GET' }, + }, + reportExitWallet: { + target: '/api/app/report/exitWallet', + config: { method: 'POST' }, + }, + shouldShowSetNewWalletNameModal: { + target: '/api/app/account/poppedUp', + config: { method: 'GET' }, + }, + shouldShowSetNewWalletNameIcon: { + target: '/api/app/account/bubbling', + config: { method: 'GET' }, + }, + setNewWalletName: { + target: '/api/app/account/replace', + config: { method: 'POST' }, + }, + getIconList: { + target: '/api/app/account/defaultAvatars', + config: { method: 'GET' }, + }, +} as const; diff --git a/packages/constants/constants-eoa/network/backend-network.ts b/packages/constants/constants-eoa/network/backend-network.ts new file mode 100644 index 0000000000..05248eae36 --- /dev/null +++ b/packages/constants/constants-eoa/network/backend-network.ts @@ -0,0 +1,62 @@ +import { NetworkItem } from '@portkey-wallet/types/types-eoa/network'; + +type BackEndNetworkType = 'back-end-testnet' | 'back-end-mainnet'; + +// TODO: eoa update networkConfig +export const BackEndNetWorkMap: { + [key in BackEndNetworkType]: NetworkItem; +} = { + 'back-end-testnet': { + name: 'aelf Testnet', + walletType: 'aelf', + networkType: 'TESTNET', + isActive: true, + // apiUrl: 'https://eoa-portkey-test.portkey.finance', + apiUrl: 'https://aa-portkey-test.portkey.finance', + graphqlUrl: 'https://dapp-aa-portkey-test.portkey.finance/aefinder-v2/api/app/graphql/portkey', + tokenClaimContractAddress: '233wFn5JbyD4i8R5Me4cW4z6edfFGRn5bpWnGuY8fjR7b2kRsD', + cmsUrl: 'https://cms-test-aa.portkey.finance/graphql', + s3Url: 'https://portkey-cms-testnet.s3.ap-northeast-1.amazonaws.com', + referralUrl: 'https://test-referral.portkey.finance', + cryptoGiftUrl: 'https://test-cryptogift.portkey.finance', + eBridgeUrl: 'https://test.ebridge.exchange', + eTransferCA: { + AELF: '4xWFvoLvi5anZERDuJvzfMoZsb6WZLATEzqzCVe8sQnCp2XGS', + tDVW: '2AgU8BfyKyrxUrmskVCUukw63Wk96MVfVoJzDDbwKszafioCN1', + }, + eTransferUrl: 'https://test-app.etransfer.exchange', + awakenUrl: 'https://test-app.awaken.finance', + schrodingerUrl: 'https://schrodingerai.com', + eForestUrl: 'https://test.eforest.finance', + sgrSchrodingerUrl: 'https://cat.schrodingerai.com', + tomorrowDAOUrl: 'https://test.tmrwdao.com', + hamsterUrl: 'https://test-hamster.beangotown.com', + cryptoGiftTgUrl: 'https://t.me/PortkeyTestnet_Bot/crypto_gift', + }, + + 'back-end-mainnet': { + name: 'aelf Mainnet', + walletType: 'aelf', + networkType: 'MAINNET', + isActive: true, + apiUrl: 'https://aa-portkey.portkey.finance', + graphqlUrl: 'https://dapp-aa-portkey.portkey.finance/aefinder-v2/api/app/graphql/portkey', + cmsUrl: 'https://cms-aa.portkey.finance/graphql', + s3Url: 'https://portkey-cms-mainnet.s3.ap-northeast-1.amazonaws.com', + referralUrl: 'https://referral.portkey.finance', + cryptoGiftUrl: 'https://cryptogift.portkey.finance', + eBridgeUrl: 'https://ebridge.exchange', + eTransferUrl: 'https://app.etransfer.exchange', + eTransferCA: { + AELF: '2w13DqbuuiadvaSY2ZyKi2UoXg354zfHLM3kwRKKy85cViw4ZF', + tDVV: 'x4CTSuM8typUbpdfxRZDTqYVa42RdxrwwPkXX7WUJHeRmzE6k', + }, + awakenUrl: 'https://app.awaken.finance', + schrodingerUrl: 'https://schrodingernft.ai', + eForestUrl: 'https://www.eforest.finance', + sgrSchrodingerUrl: 'https://cat.schrodingernft.ai', + tomorrowDAOUrl: 'https://tmrwdao.com', + hamsterUrl: 'https://hamster.beangotown.com', + cryptoGiftTgUrl: 'https://t.me/PortkeyMainnet_Bot/crypto_gift', + }, +}; diff --git a/packages/constants/constants-eoa/network/index.ts b/packages/constants/constants-eoa/network/index.ts new file mode 100644 index 0000000000..c72c1daf84 --- /dev/null +++ b/packages/constants/constants-eoa/network/index.ts @@ -0,0 +1,42 @@ +import { NetworkItem } from '@portkey-wallet/types/types-eoa/network'; +import { BackEndNetWorkMap } from './backend-network'; +import { T_ENV_NAME } from '@portkey-wallet/types'; + +export const NetworkList: NetworkItem[] = [ + BackEndNetWorkMap['back-end-mainnet'], + BackEndNetWorkMap['back-end-testnet'], +]; + +export const DefaultChainId = 'AELF'; + +export const OfficialWebsite = 'https://portkey.finance'; + +export const ThirdParty = `https://thirdparty.portkey.finance`; + +export const OpenLogin = `https://openlogin.portkey.finance`; + +const EBridgeList = NetworkList.map(i => i.eBridgeUrl).filter(i => !!i) as string[]; +const ETransferList = NetworkList.map(i => i.eTransferUrl).filter(i => !!i) as string[]; +const AwakenUrlList = NetworkList.map(i => i.awakenUrl).filter(i => !!i) as string[]; +const SchrodingerList = NetworkList.map(i => i.schrodingerUrl).filter(i => !!i) as string[]; +const SGRSchrodingerList = NetworkList.map(i => i.sgrSchrodingerUrl).filter(i => !!i) as string[]; +const ReferralList = NetworkList.map(i => i.referralUrl).filter(i => !!i) as string[]; +const ForestUrlList = NetworkList.map(i => i.eForestUrl).filter(i => !!i) as string[]; +const TomorrowDAOUrlList = NetworkList.map(i => i.tomorrowDAOUrl).filter(i => !!i) as string[]; +const HamsterUrlList = NetworkList.map(i => i.hamsterUrl).filter(i => !!i) as string[]; + +export const DAPP_WHITELIST: string[] = [ + ...EBridgeList, + ...ETransferList, + ...AwakenUrlList, + ...SchrodingerList, + ...SGRSchrodingerList, + ...ReferralList, + ...ForestUrlList, + ...TomorrowDAOUrlList, + ...HamsterUrlList, +]; + +export const LinkPortkeyWebsite = OfficialWebsite; + +export const ENV_NAME: T_ENV_NAME = 'online'; diff --git a/packages/constants/network.ts b/packages/constants/network.ts index 44728460d3..295647c416 100644 --- a/packages/constants/network.ts +++ b/packages/constants/network.ts @@ -1,4 +1,4 @@ -import { ChainType } from '@portkey-wallet/types'; +import { ChainId, ChainType } from '@portkey-wallet/types'; import { ChainItemType } from '@portkey-wallet/types/chain'; export const DefaultChain: ChainItemType = { @@ -22,3 +22,5 @@ export const DefaultChain: ChainItemType = { }; export const NetworkSeries: { label: string; chainType: ChainType }[] = [{ label: 'AELF series', chainType: 'aelf' }]; + +export const MAIN_CHAIN_ID: ChainId = 'AELF'; diff --git a/packages/hooks/hooks-eoa/network/chain.ts b/packages/hooks/hooks-eoa/network/chain.ts new file mode 100644 index 0000000000..dc21f457fc --- /dev/null +++ b/packages/hooks/hooks-eoa/network/chain.ts @@ -0,0 +1,75 @@ +import { useCallback, useEffect, useMemo } from 'react'; +import { useChainListMapState, useCurrentNetwork } from './index'; +import { ChainId } from '@portkey-wallet/types'; +import { request } from '@portkey-wallet/api/api-did'; +import { NetworkList } from '@portkey-wallet/constants/constants-eoa/network'; +import { useAppCommonDispatch } from '../../index'; +import { setChainList } from '@portkey-wallet/store/store-eoa/network/actions'; +import { handleLoopFetch } from '@portkey-wallet/utils'; +import { MAIN_CHAIN_ID } from '@portkey-wallet/constants/network'; + +export const useChainList = () => { + const chainListMapState = useChainListMapState(); + const currentNetwork = useCurrentNetwork(); + + return useMemo(() => chainListMapState[currentNetwork], [chainListMapState, currentNetwork]); +}; + +export const useGetChainInfo = () => { + const chainList = useChainList(); + + return useCallback((chainId: ChainId) => chainList?.find(item => item.chainId === chainId), [chainList]); +}; + +export const useChainInfo = (chainId: ChainId) => { + const getChainInfo = useGetChainInfo(); + return useMemo(() => getChainInfo(chainId), [chainId, getChainInfo]); +}; + +export const useInitChainList = () => { + const currentNetwork = useCurrentNetwork(); + const dispatch = useAppCommonDispatch(); + + const init = useCallback(async () => { + try { + const baseUrl = NetworkList.find(item => item.networkType === currentNetwork)?.apiUrl; + + const result = await handleLoopFetch({ + fetch: () => { + return request.es.getChainsInfo({ baseURL: baseUrl }); + }, + times: 5, + interval: 2000, + }); + if (!result?.items) throw Error('No data'); + + dispatch( + setChainList({ + network: currentNetwork, + chainList: result.items, + }), + ); + } catch (error: any) { + console.log('useInitChainList error', error); + } + }, [currentNetwork, dispatch]); + + useEffect(() => { + init(); + }, [init]); +}; + +export const useMainChain = () => { + const chainList = useChainList(); + return useMemo(() => chainList?.find(item => item.chainId === MAIN_CHAIN_ID), [chainList]); +}; + +export const useDAppChain = () => { + const chainList = useChainList(); + return useMemo(() => chainList?.find(item => item.chainId !== MAIN_CHAIN_ID), [chainList]); +}; + +export const useDAppChainId = () => { + const dAppChain = useDAppChain(); + return useMemo(() => dAppChain?.chainId || 'tDVV', [dAppChain?.chainId]); +}; diff --git a/packages/hooks/hooks-eoa/network/index.ts b/packages/hooks/hooks-eoa/network/index.ts new file mode 100644 index 0000000000..2728221ff0 --- /dev/null +++ b/packages/hooks/hooks-eoa/network/index.ts @@ -0,0 +1,54 @@ +import { useCallback, useMemo } from 'react'; +import { useAppEOASelector } from '../index'; +import { NetworkList } from '@portkey-wallet/constants/constants-eoa/network'; +import { useAppCommonDispatch } from '../../index'; +import { setCurrentNetwork } from '@portkey-wallet/store/store-eoa/network/actions'; +import { NetworkType } from '@portkey-wallet/types'; + +export const useNetworkState = () => useAppEOASelector(state => state.network); + +export const useChainListMapState = () => useAppEOASelector(state => state.network.chainListMap); + +export const useCurrentNetwork = () => useAppEOASelector(state => state.network.currentNetwork); + +export const useIsMainnet = () => { + const currentNetwork = useCurrentNetwork(); + return useMemo(() => currentNetwork === 'MAINNET', [currentNetwork]); +}; + +export const useNetworkList = () => { + return NetworkList; +}; + +export const useCurrentNetworkInfo = () => { + const currentNetwork = useCurrentNetwork(); + const networkList = useNetworkList(); + + return useMemo( + () => networkList.find(item => item.networkType === currentNetwork) || networkList[0], + [currentNetwork, networkList], + ); +}; + +export const useSetCurrentNetwork = () => { + const dispatch = useAppCommonDispatch(); + return useCallback( + (network: NetworkType) => { + dispatch( + setCurrentNetwork({ + currentNetwork: network, + }), + ); + }, + [dispatch], + ); +}; + +export const useSwitchNetwork = () => { + const isMainnet = useIsMainnet(); + const setCurrentNetwork = useSetCurrentNetwork(); + + return useCallback(() => { + setCurrentNetwork(isMainnet ? 'TESTNET' : 'MAINNET'); + }, [isMainnet, setCurrentNetwork]); +}; diff --git a/packages/mobile-aelf/ios/Podfile.lock b/packages/mobile-aelf/ios/Podfile.lock index 0f63300b49..1ed35c4f69 100644 --- a/packages/mobile-aelf/ios/Podfile.lock +++ b/packages/mobile-aelf/ios/Podfile.lock @@ -2715,40 +2715,40 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - amplitude-react-native: 2e7c6439b56cd96217cc1e42174baa53ef5c7453 + amplitude-react-native: 3fc003fed8453ac8131703869cc52ea626196a83 AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 AppCheckCore: 9feb4300caa596a36416cde10674dc5bec1e022e Base64: cecfb41a004124895a7bcee567a89bae5a89d49b boost: 4cb898d0bf20404aab1850c656dcea009429d6c1 - BVLinearGradient: cb006ba232a1f3e4f341bb62c42d1098c284da70 - CodePush: 8119f47df607085a6185bfc5ef5c4137709e1068 + BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3 + CodePush: ea174f879b85dff65380bee54243bbe523ea16b2 DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5 - EXApplication: ec862905fdab3a15bf6bd8ca1a99df7fc02d7762 - EXBarCodeScanner: 6415603150dd5989a139570bb5af19b7f169fe49 - EXConstants: 89d35611505a8ce02550e64e43cd05565da35f9a - EXImageLoader: 1fe96c70cdc78bedc985ec4b1fab5dd8e67dc38b - EXNotifications: ac3c2f16e766e5f22fb0f4c5693c590be4454009 - Expo: 723b25eaad8c356d626c579e3d78d5b969e1d3ea - ExpoAdapterFBSDKNext: 304f7faf6f019b6df77a3573a264db85f2a3ebc0 - ExpoAdapterGoogleSignIn: a36e0fd0ab572c6e32c91494ae00ec9752f213de - ExpoAsset: 286fee7ba711ce66bf20b315e68106b13b8629fc - ExpoBattery: 9575fe12e063206275013cf0dfc1583e8e7fd00c - ExpoCamera: cf49d2d121a9f883be0f98dde15a2185a1dd42be - ExpoClipboard: 243e22ff4161bbffcd3d2db469ae860ddc1156be - ExpoCrypto: c5c052d5f9f668c21975cb4caf072cec23c823fa - ExpoDevice: 84b3ed79df1234c17edfbf335f6ecf3c636f74de - ExpoFileSystem: 2988caaf68b7cb706e36d382829d99811d9d76a5 - ExpoFont: 38dddf823e32740c2a9f37c926a33aeca736b5c4 - ExpoImagePicker: 517a47896adf5d55d0a1c159e5d1e312af12e57c - ExpoKeepAwake: dd02e65d49f1cfd9194640028ae2857e536eb1c9 - ExpoLocalAuthentication: b94db59f55df95350223200c746b4ddf0cb7cfc0 - ExpoModulesCore: d300c94764c3d7ea27d8e894fbfff6d334b84d80 - ExpoNetwork: 3406d873b73ca189fd41c51dff9a1c8625771260 - ExpoScreenCapture: 41d39c845d85f740595e411d1c251ba893c69200 - ExpoScreenOrientation: 4d2a15bc161d0316685a53c1c77ea5cf4a13e43b - ExpoSecureStore: 6506992a9f53c94ea716c54d4a63144965945c2c - ExpoWebBrowser: cf10afe886891ab495877dada977fe6c269614a4 - EXSplashScreen: e67c7d6545cbe7229fea8db77890701b70f7ab37 + EXApplication: c08200c34daca7af7fd76ac4b9d606077410e8ad + EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1 + EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59 + EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334 + EXNotifications: dd289340c26bc5388e440fc90d0b2c661cbd0285 + Expo: 9b6666ef2fedcfc89c5b9be2aa1ce12b81f9e7f5 + ExpoAdapterFBSDKNext: 1df7347324200bf7efb288fdb902c68224054f43 + ExpoAdapterGoogleSignIn: b7792934ab1b5d559a3eee31334d752a73f0366e + ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875 + ExpoBattery: 4b21f628f2b70af3af66e83c566949ba9cc65eb1 + ExpoCamera: 929be541d1c1319fcf32f9f5d9df8b97804346b5 + ExpoClipboard: 23d203f5d4843699fbc45be1cc4fe1fbd811a6fa + ExpoCrypto: 156078f266bf28f80ecf5e2a9c3a0d6ffce07a1c + ExpoDevice: fc94f0e42ecdfd897e7590f2874fc64dfa7e9b1c + ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51 + ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238 + ExpoImagePicker: 12a420923383ae38dccb069847218f27a3b87816 + ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08 + ExpoLocalAuthentication: 9e02a56a4cf9868f0052656a93d4c94101a42ed7 + ExpoModulesCore: 3c510215eb78bb9c757cc0a6c1b1f52d9dbb63c8 + ExpoNetwork: 0d2c2504d56096fe8be3930d5c70cb3390dac5bf + ExpoScreenCapture: ece7593264d1384aff2481eea29f9a238b484090 + ExpoScreenOrientation: 9a13e7438f4b62f313ca3c22d1abeeef847c9599 + ExpoSecureStore: 060cebcb956b80ddae09821610ac1aa9e1ac74cd + ExpoWebBrowser: 7595ccac6938eb65b076385fd23d035db9ecdc8e + EXSplashScreen: ba896e2d289a08d56d00c6140d23b896c49ae5df FBAEMKit: 6c7b5eb77c96861bb59e040842c6e55bf39512ce FBLazyVector: 430e10366de01d1e3d57374500b1b150fe482e6d FBSDKCoreKit: 5e4dd478947ab1bcc887e8cfadeae0727af1a942 @@ -2784,104 +2784,104 @@ SPEC CHECKSUMS: JWT: ef71dfb03e1f842081e64dc42eef0e164f35d251 libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 lottie-ios: 8f97d3271e155c2d688875c29cd3c74908aef5f8 - lottie-react-native: 5d89c05930d4180a1e39b1757d46e6c0eec90255 + lottie-react-native: 8f9d4be452e23f6e5ca0fdc11669dc99ab52be81 nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 - RCT-Folly: 34124ae2e667a0e5f0ea378db071d27548124321 + RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740 RCTDeprecation: 726d24248aeab6d7180dac71a936bbca6a994ed1 RCTRequired: a94e7febda6db0345d207e854323c37e3a31d93b RCTTypeSafety: 28e24a6e44f5cbf912c66dde6ab7e07d1059a205 React: c2830fa483b0334bda284e46a8579ebbe0c5447e React-callinvoker: 4aecde929540c26b841a4493f70ebf6016691eb8 - React-Core: 32a581847d74ce9b5f51d9d11a4e4d132ad61553 - React-CoreModules: f53e0674e1747fa41c83bc970e82add97b14ad87 - React-cxxreact: 86f3b1692081fd954a0cb27cc90d14674645b64b + React-Core: 9c059899f00d46b5cec3ed79251f77d9c469553d + React-CoreModules: 9fac2d31803c0ed03e4ddaa17f1481714f8633a5 + React-cxxreact: a979810a3ca4045ceb09407a17563046a7f71494 React-debug: 3d21f69d8def0656f8b8ec25c0f05954f4d862c5 - React-defaultsnativemodule: 2ed121c5a1edeab09cff382b8d9b538260f07848 - React-domnativemodule: 4393dd5dd7e13dbe42e69ebc791064a616990f91 - React-Fabric: cbf38ceefb1ac6236897abdb538130228e126695 - React-FabricComponents: dd4b01c4a60920d8dc15f3b5594c6fe9e7648a38 - React-FabricImage: 8b13aedfbd20f349b9b3314baf993c71c02995d9 + React-defaultsnativemodule: 2fa2bdb7bd03ff9764facc04aa8520ebf14febae + React-domnativemodule: 986e6fe7569e1383dce452a7b013b6c843a752df + React-Fabric: 3bc7be9e3a6b7581fc828dc2aa041e107fc8ffb8 + React-FabricComponents: 668e0cb02344c2942e4c8921a643648faa6dc364 + React-FabricImage: 3f44dd25a2b020ed5215d4438a1bb1f3461cd4f1 React-featureflags: ee1abd6f71555604a36cda6476e3c502ca9a48e5 - React-featureflagsnativemodule: 87b58caf3cd8eca1e53179453789def019af2a65 - React-graphics: f5c4cf3abc5aa083e28fe7a866bd95fb3bbbc1e0 - React-hermes: cad69ee9a53870cc38e5386889aa7ea81c75b6a1 - React-idlecallbacksnativemodule: 445390be0f533797ace18c419eb57110dbfe90d6 - React-ImageManager: cb78d7a24f45f8f9a5a1640b52fce4c9f637f98d - React-jserrorhandler: dfe9b96e99a93d4f4858bad66d5bc4813a87a21a - React-jsi: bc1f6073e203fb540edd6d26f926ad041809b443 - React-jsiexecutor: 1e8fc70dd9614c3e9d5c3c876b2ea3cd1d931ee4 - React-jsinspector: 7544a20e9beac390f1b65d9f0040d97cd55dc198 - React-jsitracing: cac972ccc097db399df8044e49add8e5b25cb34a - React-logger: 80d87daf2f98bf95ab668b79062c1e0c3f0c2f8a - React-Mapbuffer: acffb35a53a5f474ede09f082ac609b41aafab2e - React-microtasksnativemodule: 71ca9282bce93b319218d75362c0d646b376eb43 - react-native-background-timer: 4638ae3bee00320753647900b21260b10587b6f7 - react-native-cloud-storage: 73ccd8b961a80909777e31f0533547a011305ac2 - react-native-compat: ed1f3c4184069e6d2e021e567bb5bde08d013df8 - react-native-config: ea75335a7cca1d3326de1da384227e580a7c082e - react-native-fbsdk-next: ddf303a27fa0a9598639a6f421036f6b9f0483c3 - react-native-get-random-values: 0fd2b6a3129988d701d10e30f0622d5f039531bc - react-native-minimizer: 0e8167e99bb05e63e12521f12f41dca6db027ebe - react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-pager-view: 8bd7d72d1c260ef565952ac617ab6e492c457894 - react-native-randombytes: 3c8f3e89d12487fd03a2f966c288d495415fc116 - react-native-safe-area-context: 17a482f540310e2209f884fd49472d9e1c0e73d6 - react-native-spinkit: 96a74c3519fab0eded2ab8c285f774aa3f4b7944 - react-native-view-shot: d1a701eb0719c6dccbd20b4bb43b1069f304cb70 - react-native-webview: 1d14b6d22fe11c300bac255eafe1ef5202c8c525 + React-featureflagsnativemodule: 7ccc0cd666c2a6257401dceb7920818ac2b42803 + React-graphics: d7dd9c8d75cad5af19e19911fa370f78f2febd96 + React-hermes: 2069b08e965e48b7f8aa2c0ca0a2f383349ed55d + React-idlecallbacksnativemodule: e211b2099b6dced97959cb58257bab2b2de4d7ef + React-ImageManager: ab7a7d17dd0ff1ef1d4e1e88197d1119da9957ce + React-jserrorhandler: d9e867bb83b868472f3f7601883f0403b3e3942d + React-jsi: d68f1d516e5120a510afe356647a6a1e1f98f2db + React-jsiexecutor: 6366a08a0fc01c9b65736f8deacd47c4a397912a + React-jsinspector: 0ac947411f0c73b34908800cc7a6a31d8f93e1a8 + React-jsitracing: 0e8c0aadb1fcec6b1e4f2a66ee3b0da80f0f8615 + React-logger: d79b704bf215af194f5213a6b7deec50ba8e6a9b + React-Mapbuffer: b982d5bba94a8bc073bda48f0d27c9b28417fae3 + React-microtasksnativemodule: 2b73e68f0462f3175f98782db08896f8501afd20 + react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe + react-native-cloud-storage: 7e7398f3271a50ba6380d0100aa102ba705d3163 + react-native-compat: 6f315a20c4a80382bd315d01c1672b4536104bcc + react-native-config: 8f7283449bbb048902f4e764affbbf24504454af + react-native-fbsdk-next: fcecfa33c37ce63bcda9cd24766ee9d345463230 + react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a + react-native-minimizer: 48a715600fd432ef1d182cfd1858f92f0afa022f + react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac + react-native-pager-view: c476f76d54f946df5147645e902d3d7173688187 + react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846 + react-native-safe-area-context: 5141f11858b033636f1788b14f32eaba92cee810 + react-native-spinkit: da294fd828216ad211fe36a5c14c1e09f09e62db + react-native-view-shot: 6b7ed61d77d88580fed10954d45fad0eb2d47688 + react-native-webview: 926d2665cf3196e39c4449a72d136d0a53b9df8a React-nativeconfig: 8c83d992b9cc7d75b5abe262069eaeea4349f794 - React-NativeModulesApple: 97f606f09fd9840b3868333984d6a0e7bcc425b5 + React-NativeModulesApple: 9f7920224a3b0c7d04d77990067ded14cee3c614 React-perflogger: 59e1a3182dca2cee7b9f1f7aab204018d46d1914 - React-performancetimeline: 3e3f5c5576fe1cc2dd5fcfb1ae2046d5dceda3d7 + React-performancetimeline: a9d05533ff834c6aa1f532e05e571f3fd2e3c1ed React-RCTActionSheet: d80e68d3baa163e4012a47c1f42ddd8bcd9672cc - React-RCTAnimation: 051f0781709c5ed80ba8aa2b421dfb1d72a03162 - React-RCTAppDelegate: 106d225d076988b06aa4834e68d1ab754f40cacf - React-RCTBlob: 895eaf8bca2e76ee1c95b479235c6ccebe586fc6 - React-RCTFabric: 8d01df202ee9e933f9b5dd44b72ec89a7ac6ee01 - React-RCTImage: b73149c0cd54b641dba2d6250aaf168fee784d9f - React-RCTLinking: 23e519712285427e50372fbc6e0265d422abf462 - React-RCTNetwork: a5d06d122588031989115f293654b13353753630 - React-RCTSettings: 87d03b5d94e6eadd1e8c1d16a62f790751aafb55 - React-RCTText: 75e9dd39684f4bcd1836134ac2348efaca7437b3 - React-RCTVibration: 033c161fe875e6fa096d0d9733c2e2501682e3d4 + React-RCTAnimation: bde981f6bd7f8493696564da9b3bd05721d3b3cc + React-RCTAppDelegate: 0176615c51476c88212bf3edbafb840d39ea7631 + React-RCTBlob: 520a0382bf8e89b9153d60e3c6293e51615834e9 + React-RCTFabric: c9da097b19b30017a99498b8c66a69c72f3ce689 + React-RCTImage: 90448d2882464af6015ed57c98f463f8748be465 + React-RCTLinking: 1bd95d0a704c271d21d758e0f0388cced768d77d + React-RCTNetwork: 218af6e63eb9b47935cc5a775b7a1396cf10ff91 + React-RCTSettings: e10b8e42b0fce8a70fbf169de32a2ae03243ef6b + React-RCTText: e7bf9f4997a1a0b45c052d4ad9a0fe653061cf29 + React-RCTVibration: 5b70b7f11e48d1c57e0d4832c2097478adbabe93 React-rendererconsistency: f620c6e003e3c4593e6349d8242b8aeb3d4633f0 - React-rendererdebug: 5be7b834677b2a7a263f4d2545f0d4966cafad82 + React-rendererdebug: e697680f4dd117becc5daf9ea9800067abcee91c React-rncore: c22bd84cc2f38947f0414fab6646db22ff4f80cd - React-RuntimeApple: 71160e6c02efa07d198b84ef5c3a52a7d9d0399d - React-RuntimeCore: f88f79ec995c12af56a265d7505c7630733d9d82 + React-RuntimeApple: de0976836b90b484305638616898cbc665c67c13 + React-RuntimeCore: 3c4a5aa63d9e7a3c17b7fb23f32a72a8bcfccf57 React-runtimeexecutor: ea90d8e3a9e0f4326939858dafc6ab17c031a5d3 - React-RuntimeHermes: 49f86328914021f50fd5a5b9756685f5f6d8b4da - React-runtimescheduler: fed70991b942c6df752a59a22081e45fc811b11c - React-utils: 02526ea15628a768b8db9517b6017a1785c734d2 - ReactCodegen: 8b5341ecb61898b8bd40a73ebc443c6bf2d14423 - ReactCommon: 36d48f542b4010786d6b2bcee615fe5f906b7105 - RNAppleAuthentication: 8d313d93fe2238d6b7ff0a39c67ebcf298d96653 - RNCAsyncStorage: 40367e8d25522dca9c3513c7b9815a184669bd97 - RNDeviceInfo: 98bb51ba1519cd3f19f14e7236b5bb1c312c780f - RNFastImage: 462a183c4b0b6b26fdfd639e1ed6ba37536c3b87 - RNFBAnalytics: b0c3726ee8297f50302c45675f67c120b02bd773 - RNFBApp: 20bfba7e2a61a959518c1d57e5d48817c62ed3f6 - RNFBAppCheck: c5e77f500b36ad540eb323769448d2d0a954095b - RNFBCrashlytics: 35e45b650ea8caa14f341eba943a58d47073f23e - RNFBMessaging: 48579eec1f6ffaed4038b67426d7076963ab9401 - RNFBPerf: 244a4d455fe2fb34aedec78ea7d7b0bb4dae7177 - RNFlashList: be712ce93b2ddcbff2d6bb01de4b9c4b0b84a185 - RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 - RNGestureHandler: d21c9c1cc8b1bb19336d2e1bc48e56882bd13bc6 - RNGoogleSignin: f19de8e6c64812ad0acef412bb70d6ceb99400bb - RNLocalize: 8bf466de4c92d4721b254aabe1ff0a1456e7b9f4 - RNNestedScrollView: 45783b74adaada13024d33e4200e83f5e972df7d - RNNotifee: be8434a9e622f05808aaf7e2f02f30ed7dd0c67a - RNPermissions: bd0d9ca7969ff7b999aa605ee2e5919c12522bfe - RNPullToRefresh: 1200b244de188ce3c2b3f870b5e8f5487afc39cc - RNReanimated: 6398ee150e1ebeda517fdd1e1b5525833a0c0ddc - RNScreens: 28fbd73104cc9719371da9d9aaa3c70d876a8c6b - RNSentry: e99002ced0a78ba64f6c8bac9bc76036e2d95fe6 - RNSpringScrollView: b7a0cd86c5f939458ab60e9592b474d4a7c2ea7c - RNSVG: 8542aa11770b27563714bbd8494a8436385fc85f - RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28 + React-RuntimeHermes: c6b0afdf1f493621214eeb6517fb859ce7b21b81 + React-runtimescheduler: 84f0d876d254bce6917a277b3930eb9bc29df6c7 + React-utils: cbe8b8b3d7b2ac282e018e46f0e7b25cdc87c5a0 + ReactCodegen: 4bcb34e6b5ebf6eef5cee34f55aa39991ea1c1f1 + ReactCommon: 6a952e50c2a4b694731d7682aaa6c79bc156e4ad + RNAppleAuthentication: e00c76acb03351f5544373c78fa7f359bef6d5d3 + RNCAsyncStorage: d35c79ffba52c1013013e16b1fc295aec2feabb6 + RNDeviceInfo: 59344c19152c4b2b32283005f9737c5c64b42fba + RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8 + RNFBAnalytics: c79cf8da7d0bbbad0e0cc233402d2cadc4a694b9 + RNFBApp: a3e139715386fe79a09c387f2dbeb6890eb05b39 + RNFBAppCheck: 3cbdc88c15c3d1173c43c0582350fee9420ce2e9 + RNFBCrashlytics: e6d595ed2619e5e8ee3cdfd12c6a62e470280a03 + RNFBMessaging: a65862d8eba03cb6c838241bd328166504996894 + RNFBPerf: 9cd7430cb90e4b8aebcd86312f1eb3aae28bd0e7 + RNFlashList: 115dd44377580761bff386a0caebf165424cf16f + RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 + RNGestureHandler: 6dfe7692a191ee224748964127114edf057a1475 + RNGoogleSignin: 81521697b2c8f97f9a586ac7257b1a1d9b51b115 + RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 + RNNestedScrollView: b9a2ac8588c89dd671d571b1184a0af007e1bea3 + RNNotifee: 5155e0a5e0a97d0c839030d8192783cd63053999 + RNPermissions: 4e3714e18afe7141d000beae3755e5b5fb2f5e05 + RNPullToRefresh: cc6d153a0b4dac79e4bbaa5c81d177aee92c9fdf + RNReanimated: f6a10979b3701f8029c71dbfe35d0ff4328dce4c + RNScreens: 19719a9c326e925498ac3b2d35c4e50fe87afc06 + RNSentry: a7660b72556d6574867d488e60c4b4b0be7422d8 + RNSpringScrollView: e354167d96f2c3d2f20b186990b2c3946987cb3c + RNSVG: 8b1a777d54096b8c2a0fd38fc9d5a454332bbb4d + RNVectorIcons: 6382277afab3c54658e9d555ee0faa7a37827136 SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d Sentry: ee060c09b2f7ec1240e95c766ab44c04c7bdb052 diff --git a/packages/mobile-aelf/js/components/Updater/index.tsx b/packages/mobile-aelf/js/components/Updater/index.tsx index 85252ddec8..f78667e1c1 100644 --- a/packages/mobile-aelf/js/components/Updater/index.tsx +++ b/packages/mobile-aelf/js/components/Updater/index.tsx @@ -1,56 +1,35 @@ -import { request } from '@portkey-wallet/api/api-did'; -import { useChainListFetch } from '@portkey-wallet/hooks/hooks-ca/chainList'; -import { service } from 'api/utils'; -import { usePin } from 'hooks/store'; +import { request } from '@portkey-wallet/api/api-eoa'; +import { useCurrentNetworkInfo } from '@portkey-wallet/hooks/hooks-eoa/network'; +import { useInitChainList } from '@portkey-wallet/hooks/hooks-eoa/network/chain'; + import useEffectOnce from 'hooks/useEffectOnce'; import { useLanguage } from 'i18n/hooks'; -import { useEffect, useMemo } from 'react'; -import { useRefreshTokenConfig } from '@portkey-wallet/hooks/hooks-ca/api'; -import { useCurrentNetworkInfo, useIsMainnet } from '@portkey-wallet/hooks/hooks-ca/network'; -import useLocking from 'hooks/useLocking'; -import { useCaInfoOnChain } from 'hooks/useCaInfoOnChain'; -import { useFetchSymbolImages } from '@portkey-wallet/hooks/hooks-ca/useToken'; -import { useCheckManager } from '@portkey-wallet/hooks/hooks-ca/graphql'; -import { useCheckManagerOnLogout } from 'hooks/useLogOut'; -import { usePhoneCountryCode } from '@portkey-wallet/hooks/hooks-ca/misc'; -import { - useDiscoverGroupList, - useSocialMediaList, - useRememberMeBlackList, - useTabMenuList, -} from '@portkey-wallet/hooks/hooks-ca/cms'; +import { useMemo } from 'react'; import { exceptionManager } from 'utils/errorHandler/ExceptionHandler'; -import EntryScriptWeb3 from 'utils/EntryScriptWeb3'; -import { useFetchTxFee } from '@portkey-wallet/hooks/hooks-ca/useTxFee'; -import { useCheckAndInitNetworkDiscoverMap } from 'hooks/discover'; -import im from '@portkey-wallet/im'; -import s3Instance from '@portkey-wallet/utils/s3'; -import Config from 'react-native-config'; -import { useCheckContactMap } from '@portkey-wallet/hooks/hooks-ca/contact'; -import { useAppEntrance } from 'hooks/cms'; -import { codePushOperator } from 'utils/update'; -import { useCheckCodePushUpdate } from 'store/user/hooks'; -import useInterval from '@portkey-wallet/hooks/useInterval'; -import { useLatestRef } from '@portkey-wallet/hooks'; -import MatchValueMap from 'utils/matchValueMap'; -import { useInitCmsBanner } from '@portkey-wallet/hooks/hooks-ca/cms/banner'; -import { useInitCMSDiscoverNewData, useInitDappWhiteListData } from '@portkey-wallet/hooks/hooks-ca/cms/discover'; -import { useInitAwaken } from '@portkey-wallet/hooks/hooks-ca/awaken'; +import { service } from 'api/utils'; request.setExceptionManager(exceptionManager); -const CHECK_CODE_PUSH_TIME = 5 * 60 * 1000; - export default function Updater() { - const isMainnet = useIsMainnet(); + // const isMainnet = useIsMainnet(); // FIXME: delete language const { changeLanguage } = useLanguage(); useEffectOnce(() => { changeLanguage('en'); }); + + const { apiUrl } = useCurrentNetworkInfo(); + useMemo(() => { + request.set('baseURL', apiUrl); + if (service.defaults.baseURL !== apiUrl) { + service.defaults.baseURL = apiUrl; + } + }, [apiUrl]); + + useInitChainList(); // useChainListFetch(); - // const { apiUrl, imApiUrl, imWsUrl, imS3Bucket } = useCurrentNetworkInfo(); + // const pin = usePin(); // const onLocking = useLocking(); // const checkManagerOnLogout = useCheckManagerOnLogout(); @@ -68,12 +47,7 @@ export default function Updater() { // useCheckAndInitNetworkDiscoverMap(); // useFetchSymbolImages(); // useFetchTxFee(); - // useMemo(() => { - // request.set('baseURL', apiUrl); - // if (service.defaults.baseURL !== apiUrl) { - // service.defaults.baseURL = apiUrl; - // } - // }, [apiUrl]); + // useMemo(() => { // im.setUrl({ // apiUrl: imApiUrl || '', diff --git a/packages/mobile-aelf/js/contexts/useInterface/actions.ts b/packages/mobile-aelf/js/contexts/useInterface/actions.ts index 805a47b0ed..2cfd294d3a 100644 --- a/packages/mobile-aelf/js/contexts/useInterface/actions.ts +++ b/packages/mobile-aelf/js/contexts/useInterface/actions.ts @@ -9,7 +9,6 @@ export enum InterfaceActions { setViewContracts = 'setViewContracts', setViewContract = 'setViewContract', setCAContract = 'setCAContract', - setTokenContract = 'setTokenContract', destroy = 'DESTROY', } @@ -22,16 +21,8 @@ export const basicInterfaceActions = { basicActions(InterfaceActions.setViewContract, { viewContract }), setCAContract: (caContract: { [key: string]: ContractBasic }, chainId: ChainId) => basicActions(InterfaceActions.setCAContract, { caContract, chainId }), - setTokenContract: (tokenContract: { [key: string]: ContractBasic }, chainId: ChainId) => - basicActions(InterfaceActions.setTokenContract, { tokenContract, chainId }), interfaceDestroy: () => basicActions(InterfaceActions.destroy), }; -export const { - interfaceDestroy, - setCurrentInterface, - setViewContracts, - setViewContract, - setCAContract, - setTokenContract, -} = basicInterfaceActions; +export const { interfaceDestroy, setCurrentInterface, setViewContracts, setViewContract, setCAContract } = + basicInterfaceActions; diff --git a/packages/mobile-aelf/js/contexts/useInterface/index.tsx b/packages/mobile-aelf/js/contexts/useInterface/index.tsx index cbd931fcbb..7fd09a6d85 100644 --- a/packages/mobile-aelf/js/contexts/useInterface/index.tsx +++ b/packages/mobile-aelf/js/contexts/useInterface/index.tsx @@ -33,18 +33,11 @@ function reducer(state: State, { type, payload }: any) { }), }); } - case InterfaceActions.setTokenContract: { - const { tokenContracts } = state; - const { tokenContract, chainId } = payload; - return Object.assign({}, state, { - tokenContracts: Object.assign({}, tokenContracts, { - [chainId]: { ...tokenContracts?.[chainId as ChainId], ...tokenContract }, - }), - }); - } default: { const { destroy } = payload; - if (destroy) return Object.assign({}, payload); + if (destroy) { + return Object.assign({}, payload); + } return Object.assign({}, state, payload); } } @@ -66,7 +59,9 @@ export default function Provider({ children }: { children: React.ReactNode }) { useEffect(() => { if (currentNetwork.chainType === 'aelf') { - if (prevRpcUrl !== currentNetwork.rpcUrl) dispatch(setCurrentInterface(getAelfInstance(currentNetwork.rpcUrl))); + if (prevRpcUrl !== currentNetwork.rpcUrl) { + dispatch(setCurrentInterface(getAelfInstance(currentNetwork.rpcUrl))); + } } else { // TODO: ethereum } diff --git a/packages/mobile-aelf/js/hooks/contract.ts b/packages/mobile-aelf/js/hooks/contract.ts index 4400030212..7e3106193f 100644 --- a/packages/mobile-aelf/js/hooks/contract.ts +++ b/packages/mobile-aelf/js/hooks/contract.ts @@ -1,9 +1,8 @@ -import { useCurrentChain, useGetChain } from '@portkey-wallet/hooks/hooks-ca/chainList'; import { useCurrentWalletInfo, useOriginChainId } from '@portkey-wallet/hooks/hooks-ca/wallet'; import { ChainId } from '@portkey-wallet/types'; import aes from '@portkey-wallet/utils/aes'; import { useInterface } from 'contexts/useInterface'; -import { setCAContract, setViewContract, setTokenContract } from 'contexts/useInterface/actions'; +import { setCAContract, setViewContract } from 'contexts/useInterface/actions'; import { getContractBasic } from '@portkey-wallet/contracts/utils'; import { useCallback, useMemo } from 'react'; import { getDefaultWallet } from '@portkey-wallet/utils/aelfUtils'; @@ -11,21 +10,33 @@ import AElf from 'aelf-sdk'; import { usePin } from './store'; import { ContractBasic } from '@portkey-wallet/contracts/utils/ContractBasic'; import { IChainItemType } from '@portkey-wallet/types/types-ca/chain'; +import { useChainInfo, useGetChainInfo } from '@portkey-wallet/hooks/hooks-eoa/network/chain'; +import { useCurrentAccount } from '@portkey-wallet/hooks/hooks-eoa/wallet'; +// TODO: eoa delete deprecated + +/** + * @deprecated This method is deprecated and will be removed in future versions. + * Please use the `useGetViewContract` instead. + */ export function useGetCurrentCAViewContract(_chainId?: ChainId) { const originChainId = useOriginChainId(); const chainId = useMemo(() => _chainId || originChainId, [_chainId, originChainId]); - const chainInfo = useCurrentChain(chainId); + const chainInfo = useChainInfo(chainId); const [{ viewContracts }, dispatch] = useInterface(); return useCallback( async (paramChainInfo?: IChainItemType) => { const _chainInfo = paramChainInfo || chainInfo; - if (!_chainInfo) throw Error('Could not find chain information'); + if (!_chainInfo) { + throw Error('Could not find chain information'); + } const key = _chainInfo.caContractAddress + _chainInfo.endPoint; const caContract = viewContracts?.[key]; - if (caContract) return caContract; + if (caContract) { + return caContract; + } const contract = await getContractBasic({ contractAddress: _chainInfo.caContractAddress, @@ -40,10 +51,14 @@ export function useGetCurrentCAViewContract(_chainId?: ChainId) { ); } +/** + * @deprecated This method is deprecated and will be removed in future versions. + * Please use the `useGetContract` instead. + */ export function useGetCurrentCAContract(_chainId?: ChainId) { const originChainId = useOriginChainId(); const chainId = useMemo(() => _chainId || originChainId, [_chainId, originChainId]); - const chainInfo = useCurrentChain(chainId); + const chainInfo = useChainInfo(chainId); const pin = usePin(); const { AESEncryptPrivateKey, address } = useCurrentWalletInfo(); const [{ caContracts }, dispatch] = useInterface(); @@ -56,10 +71,16 @@ export function useGetCurrentCAContract(_chainId?: ChainId) { }, [caContracts, chainId, key]); return useCallback(async () => { - if (caContract) return caContract; + if (caContract) { + return caContract; + } - if (!chainInfo) throw Error('Could not find chain information'); - if (!pin || !AESEncryptPrivateKey) throw Error('Could not find wallet information'); + if (!chainInfo) { + throw Error('Could not find chain information'); + } + if (!pin || !AESEncryptPrivateKey) { + throw Error('Could not find wallet information'); + } const privateKey = aes.decrypt(AESEncryptPrivateKey, pin); const wallet = AElf.wallet.getWalletByPrivateKey(privateKey); @@ -74,22 +95,32 @@ export function useGetCurrentCAContract(_chainId?: ChainId) { }, [AESEncryptPrivateKey, caContract, chainId, chainInfo, dispatch, key, pin]); } +/** + * @deprecated This method is deprecated and will be removed in future versions. + * Please use the `useGetContract` instead. + */ export function useGetCAContract() { const pin = usePin(); const { AESEncryptPrivateKey, address } = useCurrentWalletInfo(); const [{ caContracts }, dispatch] = useInterface(); - const getChain = useGetChain(); + const getChainInfo = useGetChainInfo(); return useCallback( async (chainId: ChainId) => { - const chainInfo = getChain(chainId); - if (!chainInfo) throw Error('Could not find chain information'); + const chainInfo = getChainInfo(chainId); + if (!chainInfo) { + throw Error('Could not find chain information'); + } const key = `${address}_${chainInfo.caContractAddress}_${chainInfo.chainId}`; const caContract = caContracts?.[chainId]?.[key]; - if (caContract) return caContract; + if (caContract) { + return caContract; + } - if (!pin || !AESEncryptPrivateKey) throw Error('Could not find wallet information'); + if (!pin || !AESEncryptPrivateKey) { + throw Error('Could not find wallet information'); + } const privateKey = aes.decrypt(AESEncryptPrivateKey, pin); const wallet = AElf.wallet.getWalletByPrivateKey(privateKey); @@ -102,27 +133,27 @@ export function useGetCAContract() { dispatch(setCAContract({ [key]: contract as ContractBasic }, chainId)); return contract as ContractBasic; }, - [AESEncryptPrivateKey, address, caContracts, dispatch, getChain, pin], + [AESEncryptPrivateKey, address, caContracts, dispatch, getChainInfo, pin], ); } export function useGetTokenContract() { const pin = usePin(); - const { AESEncryptPrivateKey, address } = useCurrentWalletInfo(); - const [{ tokenContracts }, dispatch] = useInterface(); + const currentAccount = useCurrentAccount(); - const getChain = useGetChain(); + const getChainInfo = useGetChainInfo(); return useCallback( async (chainId: ChainId) => { - const chainInfo = getChain(chainId); - if (!chainInfo) throw Error('Could not find chain information'); - const key = `${address}_${chainInfo.defaultToken.address}_${chainInfo.chainId}`; - - const tokenContract = tokenContracts?.[chainId]?.[key]; - if (tokenContract) return tokenContract; + const chainInfo = getChainInfo(chainId); + if (!chainInfo) { + throw Error('Could not find chain information'); + } - if (!pin || !AESEncryptPrivateKey) throw Error('Could not find wallet information'); + const { AESEncryptPrivateKey } = currentAccount || {}; + if (!pin || !AESEncryptPrivateKey) { + throw Error('Could not find wallet information'); + } const privateKey = aes.decrypt(AESEncryptPrivateKey, pin); const wallet = AElf.wallet.getWalletByPrivateKey(privateKey); @@ -132,20 +163,22 @@ export function useGetTokenContract() { rpcUrl: chainInfo.endPoint, account: wallet, }); - dispatch(setTokenContract({ [key]: contract as ContractBasic }, chainId)); + return contract as ContractBasic; }, - [AESEncryptPrivateKey, address, dispatch, getChain, pin, tokenContracts], + [currentAccount, getChainInfo, pin], ); } export function useGetTokenViewContract() { - const getChain = useGetChain(); + const getChainInfo = useGetChainInfo(); return useCallback( async (chainId: ChainId) => { - const chainInfo = getChain(chainId); - if (!chainInfo) throw Error('Could not find chain information'); + const chainInfo = getChainInfo(chainId); + if (!chainInfo) { + throw Error('Could not find chain information'); + } const contract = await getContractBasic({ contractAddress: chainInfo.defaultToken.address, @@ -154,7 +187,7 @@ export function useGetTokenViewContract() { }); return contract as ContractBasic; }, - [getChain], + [getChainInfo], ); } @@ -163,12 +196,14 @@ export type TGetViewContractParams = { contractAddress: string; }; export const useGetViewContract = () => { - const getChain = useGetChain(); + const getChainInfo = useGetChainInfo(); return useCallback( async ({ chainId, contractAddress }: TGetViewContractParams) => { - const chainInfo = getChain(chainId); - if (!chainInfo) throw Error('Could not find chain information'); + const chainInfo = getChainInfo(chainId); + if (!chainInfo) { + throw Error('Could not find chain information'); + } const contract = await getContractBasic({ contractAddress, @@ -177,6 +212,39 @@ export const useGetViewContract = () => { }); return contract as ContractBasic; }, - [getChain], + [getChainInfo], ); }; + +export function useGetContract() { + const pin = usePin(); + const currentAccount = useCurrentAccount(); + + const getChainInfo = useGetChainInfo(); + + return useCallback( + async (chainId: ChainId, contractAddress: string) => { + const chainInfo = getChainInfo(chainId); + if (!chainInfo) { + throw Error('Could not find chain information'); + } + + const { AESEncryptPrivateKey } = currentAccount || {}; + if (!pin || !AESEncryptPrivateKey) { + throw Error('Could not find wallet information'); + } + + const privateKey = aes.decrypt(AESEncryptPrivateKey, pin); + const wallet = AElf.wallet.getWalletByPrivateKey(privateKey); + + const contract = await getContractBasic({ + contractAddress, + rpcUrl: chainInfo.endPoint, + account: wallet, + }); + + return contract as ContractBasic; + }, + [currentAccount, getChainInfo, pin], + ); +} diff --git a/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx b/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx index fdc8f312ae..5e96bfa97b 100644 --- a/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx +++ b/packages/mobile-aelf/js/pages/Home/HomeTab/index.tsx @@ -8,11 +8,17 @@ import CommonButton from 'components/CommonButton'; import navigationService from 'utils/navigationService'; import { useCheckSecurityLock } from 'hooks/securityLock'; import { useBackupWalletModal } from '../../Login/hooks/useBackupWalletModal'; +import * as Clipboard from 'expo-clipboard'; +import { useGetContract, useGetViewContract } from 'hooks/contract'; +import { useCurrentNetwork, useSwitchNetwork } from '@portkey-wallet/hooks/hooks-eoa/network'; +import { useDAppChain, useDAppChainId, useGetChainInfo } from '@portkey-wallet/hooks/hooks-eoa/network/chain'; const HomeTab: React.FC = ({ _ }) => { const { theme } = useTheme(); const currentAccount = useCurrentAccount(); const walletList = useWalletListState(); + const currentNetwork = useCurrentNetwork(); + useEffect(() => { console.log('currentAccount', currentAccount); console.log('walletList', walletList); @@ -32,39 +38,98 @@ const HomeTab: React.FC = ({ _ }) => { const { showBackupWalletModal } = useBackupWalletModal(); + const dAppChain = useDAppChain(); + const getContract = useGetContract(); + // const getTokenContract = useGetTokenContract(); + const sendElf = useCallback(async () => { + if (!dAppChain) { + return; + } + try { + console.log('send ELF'); + // const contract = await getTokenContract(dAppChain.chainId); + const contract = await getContract(dAppChain.chainId, dAppChain.defaultToken.address); + const result = await contract.callSendMethod('Transfer', currentAccount?.address || '', { + to: 'ELF_bPVEs5WFMMwiqPnaXiJpTmoR9xYVqBK2QDLZdA3HChqNebFQz_tDVW', + symbol: 'ELF', + amount: '10000000', + memo: '', + }); + console.log('result', result); + } catch (error) { + console.log('sendElf error', error); + } + }, [currentAccount?.address, dAppChain, getContract]); + + // const getTokenViewContract = useGetTokenViewContract(); + const getViewContract = useGetViewContract(); + + const dAppChainId = useDAppChainId(); + const getChainInfo = useGetChainInfo(); + const getBalance = useCallback(async () => { + try { + // const viewContract = await getTokenViewContract('tDVW'); + + const chainInfo = getChainInfo(dAppChainId); + const viewContract = await getViewContract({ + chainId: 'tDVW', + contractAddress: chainInfo?.defaultToken.address || '', + }); + const result = await viewContract.callViewMethod('GetBalance', { + symbol: 'ELF', + owner: currentAccount?.address || '', + }); + console.log('result', result); + } catch (error) { + console.log('getBalance error', error); + } + }, [currentAccount?.address, dAppChainId, getChainInfo, getViewContract]); + + const switchNetwork = useSwitchNetwork(); + return ( Home Tab {`Address: ${currentAccount?.address}`} - navigationService.push('Home')}> + {`Network: ${currentNetwork}`} + + Clipboard.setStringAsync(currentAccount?.address || '')}> + Copy Address + + + + Switch Network + + + navigationService.push('Home')} style={{ marginTop: 20 }}> Home - navigationService.push('ImportWallet')} style={{ marginTop: 40 }}> + navigationService.push('ImportWallet')} style={{ marginTop: 20 }}> Import Wallets navigationService.push('WalletImportTypeSelect')} - style={{ marginTop: 40 }}> + style={{ marginTop: 20 }}> WalletImportTypeSelect - navigationService.push('ConfirmBackup')} style={{ marginTop: 40 }}> + navigationService.push('ConfirmBackup')} style={{ marginTop: 20 }}> Confirm Backup navigationService.push('ManualBackupSuccess')} - style={{ marginTop: 40 }}> + style={{ marginTop: 20 }}> Confirm Backup Success - navigationService.push('ManualBackup')} style={{ marginTop: 40 }}> + navigationService.push('ManualBackup')} style={{ marginTop: 20 }}> Manual Backup - navigationService.push('Referral')} style={{ marginTop: 40 }}> + navigationService.push('Referral')} style={{ marginTop: 20 }}> Referral - + Check Pin = ({ _ }) => { onPress={() => { showBackupWalletModal(); }} - style={{ marginTop: 40 }}> + style={{ marginTop: 20 }}> Backup Modal + + + ELF Balance tDVW + + + Send ELF + ); diff --git a/packages/mobile-aelf/js/store/config.ts b/packages/mobile-aelf/js/store/config.ts index 6686970abd..74a9e0c458 100644 --- a/packages/mobile-aelf/js/store/config.ts +++ b/packages/mobile-aelf/js/store/config.ts @@ -5,6 +5,7 @@ import { } from '@reduxjs/toolkit'; import { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE } from 'redux-persist'; import { walletSlice } from '@portkey-wallet/store/store-eoa/wallet/slice'; +import { networkSlice } from '@portkey-wallet/store/store-eoa/network/slice'; interface ThunkOptions { extraArgument: E; @@ -24,7 +25,7 @@ const reduxPersistConfig = { // Optionally, just specify the keys you DO want stored to persistence. // An empty array means 'don't store any reducers' -> infinite-red/ignite#409 - whitelist: [walletSlice.name], + whitelist: [walletSlice.name, networkSlice.name], // More info here: https://shift.infinite.red/shipping-persistant-reducers-7341691232b1 // transforms: [immutablePersistenceTransform], diff --git a/packages/mobile-aelf/js/store/rootReducer.ts b/packages/mobile-aelf/js/store/rootReducer.ts index a6f4889cf3..032b1dd0d0 100644 --- a/packages/mobile-aelf/js/store/rootReducer.ts +++ b/packages/mobile-aelf/js/store/rootReducer.ts @@ -6,6 +6,7 @@ import userSlice from './user/slice'; import { walletSlice } from '@portkey-wallet/store/store-eoa/wallet/slice'; import { settingsSlice } from '@portkey-wallet/store/settings/slice'; import chainSlice from '@portkey-wallet/store/network/slice'; +import { networkSlice } from '@portkey-wallet/store/store-eoa/network/slice'; const userPersistConfig = { key: userSlice.name, @@ -40,6 +41,7 @@ const rootReducer = combineReducers({ [walletSlice.name]: walletSlice.reducer, [settingsSlice.name]: settingsSlice.reducer, [chainSlice.name]: chainSlice.reducer, + [networkSlice.name]: networkSlice.reducer, // [contactSlice.name]: contactSlice.reducer, // [miscSlice.name]: miscSlice.reducer, // [guardiansSlice.name]: guardiansSlice.reducer, diff --git a/packages/store/store-eoa/network/actions.ts b/packages/store/store-eoa/network/actions.ts new file mode 100644 index 0000000000..0c9e16e689 --- /dev/null +++ b/packages/store/store-eoa/network/actions.ts @@ -0,0 +1,12 @@ +import { NetworkType } from '@portkey-wallet/types'; +import { IChainItemType } from '@portkey-wallet/types/types-eoa/chain'; +import { createAction } from '@reduxjs/toolkit'; + +export const setCurrentNetwork = createAction<{ + currentNetwork: NetworkType; +}>('network/setCurrentNetwork'); + +export const setChainList = createAction<{ + network: NetworkType; + chainList: IChainItemType[]; +}>('network/setChainList'); diff --git a/packages/store/store-eoa/network/slice.ts b/packages/store/store-eoa/network/slice.ts new file mode 100644 index 0000000000..e2c128ca2f --- /dev/null +++ b/packages/store/store-eoa/network/slice.ts @@ -0,0 +1,33 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { TNetworkState } from './type'; +import { setChainList, setCurrentNetwork } from './actions'; + +const initialState: TNetworkState = { + currentNetwork: 'MAINNET', + chainListMap: {}, +}; +export const networkSlice = createSlice({ + name: 'network', + initialState, + reducers: {}, + extraReducers: builder => { + builder + .addCase(setCurrentNetwork, (state, action) => { + const { currentNetwork } = action.payload; + return { + ...state, + currentNetwork, + }; + }) + .addCase(setChainList, (state, action) => { + const { network, chainList } = action.payload; + return { + ...state, + chainListMap: { + ...state.chainListMap, + [network]: chainList, + }, + }; + }); + }, +}); diff --git a/packages/store/store-eoa/network/type.ts b/packages/store/store-eoa/network/type.ts new file mode 100644 index 0000000000..2b9dce7a73 --- /dev/null +++ b/packages/store/store-eoa/network/type.ts @@ -0,0 +1,7 @@ +import { NetworkType } from '@portkey-wallet/types'; +import { IChainItemType } from '@portkey-wallet/types/types-eoa/chain'; + +export type TNetworkState = { + currentNetwork: NetworkType; + chainListMap: { [key in NetworkType]?: IChainItemType[] }; +}; diff --git a/packages/types/types-eoa/chain.ts b/packages/types/types-eoa/chain.ts new file mode 100644 index 0000000000..205cdc221c --- /dev/null +++ b/packages/types/types-eoa/chain.ts @@ -0,0 +1,17 @@ +import { ChainId } from '../index'; + +export type DefaultToken = { + address: string; + decimals: string; + imageUrl: string; + name: string; + symbol: string; +}; +export interface IChainItemType { + chainId: ChainId; + chainName: string; + endPoint: string; + explorerUrl: string; + defaultToken: DefaultToken; + chainImageUrl?: string; +} diff --git a/packages/types/types-eoa/network.ts b/packages/types/types-eoa/network.ts new file mode 100644 index 0000000000..2087e4a6e3 --- /dev/null +++ b/packages/types/types-eoa/network.ts @@ -0,0 +1,28 @@ +import { ChainId, ChainType, NetworkType } from '@portkey-wallet/types'; +export type NetworkItem = { + name: string; + walletType: ChainType; + networkType: NetworkType; + isActive?: boolean; + apiUrl: string; + domain?: string; + graphqlUrl: string; + networkIconUrl?: string; + tokenClaimContractAddress?: string; + cmsUrl?: string; + s3Url?: string; + referralUrl?: string; + cryptoGiftUrl?: string; + eBridgeUrl?: string; + eTransferUrl?: string; + eForestUrl?: string; + awakenUrl?: string; + schrodingerUrl?: string; + sgrSchrodingerUrl?: string; + tomorrowDAOUrl?: string; + eTransferCA?: { + [x in ChainId]?: string; + }; + hamsterUrl?: string; + cryptoGiftTgUrl?: string; +}; diff --git a/packages/types/types-eoa/store.ts b/packages/types/types-eoa/store.ts index eb175ce4fd..5ab75db3b7 100644 --- a/packages/types/types-eoa/store.ts +++ b/packages/types/types-eoa/store.ts @@ -4,9 +4,12 @@ import settingsSlice from '@portkey-wallet/store/settings/slice'; import { SettingsState } from '@portkey-wallet/store/settings/types'; import { walletSlice } from '@portkey-wallet/store/store-eoa/wallet/slice'; import { TWalletState } from '@portkey-wallet/store/store-eoa/wallet/type'; +import { networkSlice } from '@portkey-wallet/store/store-eoa/network/slice'; +import { TNetworkState } from '@portkey-wallet/store/store-eoa/network/type'; export type EOACommonState = { [settingsSlice.name]: SettingsState; [walletSlice.name]: TWalletState; [chainSlice.name]: ChainState; + [networkSlice.name]: TNetworkState; };