@sabaaa1/common 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -0
- package/.eslintrc.json +18 -0
- package/README.md +164 -0
- package/copyPackageJson.js +81 -0
- package/handleCDNWorkers.js +92 -0
- package/jest.config.ts +10 -0
- package/package.json +101 -0
- package/polyfillWorker.ts +15 -0
- package/project.json +32 -0
- package/src/API/API.ts +203 -0
- package/src/API/admin-calls.ts +8 -0
- package/src/API/ai-calls.ts +48 -0
- package/src/API/brotherhoodCalls.ts +184 -0
- package/src/API/callLifiAPI.ts +41 -0
- package/src/API/callMonitor.ts +9 -0
- package/src/API/callOdosAPI.ts +89 -0
- package/src/API/callOneInchAPI.ts +47 -0
- package/src/API/callRelayer.ts +23 -0
- package/src/API/checkRisk.ts +7 -0
- package/src/API/duneAPI.ts +26 -0
- package/src/API/enclaveCalls.ts +23 -0
- package/src/API/fetchCommitmentsCache.ts +63 -0
- package/src/API/generate-trading-points.ts +77 -0
- package/src/API/get-token-data.ts +12 -0
- package/src/API/getBridgeProtocols.ts +16 -0
- package/src/API/getCoingeckoPrice.ts +59 -0
- package/src/API/getGasEstimates.ts +30 -0
- package/src/API/getLifiStatus.ts +35 -0
- package/src/API/getRelayerURL.ts +27 -0
- package/src/API/getServerURL.ts +116 -0
- package/src/API/getTokenPrice.ts +39 -0
- package/src/API/getWebsiteURL.ts +58 -0
- package/src/API/index.ts +19 -0
- package/src/API/is-tx-stateless.ts +32 -0
- package/src/API/kycCalls.ts +81 -0
- package/src/API/leaderboardCalls.ts +32 -0
- package/src/API/mysteryBoxesCalls.ts +141 -0
- package/src/API/passwordCalls.ts +34 -0
- package/src/API/proxyAccountsCalls.ts +40 -0
- package/src/API/referralsCalls.ts +52 -0
- package/src/API/relayCalls.ts +14 -0
- package/src/API/restoreSnapshots.ts +7 -0
- package/src/API/rewardsUserCalls.ts +124 -0
- package/src/API/send-telegram-callback.ts +17 -0
- package/src/API/simulate-batch-tx.ts +19 -0
- package/src/API/tenderly.api.ts +96 -0
- package/src/API/token-calls.ts +19 -0
- package/src/API/weeklyAnalyticCalls.ts +43 -0
- package/src/constants/activity.constants.ts +10 -0
- package/src/constants/addresses.constants.ts +74 -0
- package/src/constants/assets.constants.ts +15 -0
- package/src/constants/backend.constants.ts +16 -0
- package/src/constants/balance.constants.ts +1 -0
- package/src/constants/bridging.constants.ts +5 -0
- package/src/constants/chains.constants.ts +194 -0
- package/src/constants/coingecko.constants.ts +67 -0
- package/src/constants/contracts.constants.ts +106 -0
- package/src/constants/conversion.constants.ts +1 -0
- package/src/constants/deploy-data/deploy-data-arbMainnet.json +5685 -0
- package/src/constants/deploy-data/deploy-data-arcTestnet.json +6157 -0
- package/src/constants/deploy-data/deploy-data-avalanche.json +5921 -0
- package/src/constants/deploy-data/deploy-data-base.json +5695 -0
- package/src/constants/deploy-data/deploy-data-bnbMainnet.json +5921 -0
- package/src/constants/deploy-data/deploy-data-ethMainnet.json +5922 -0
- package/src/constants/deploy-data/deploy-data-localhost.json +5921 -0
- package/src/constants/deploy-data/deploy-data-optimism.json +5687 -0
- package/src/constants/deploy-data/deploy-data-polygon.json +5695 -0
- package/src/constants/deploy-data/index.ts +21 -0
- package/src/constants/events.constants.ts +10 -0
- package/src/constants/fees.constants.ts +4 -0
- package/src/constants/function-signatures.constants.ts +6 -0
- package/src/constants/index.ts +30 -0
- package/src/constants/kyc.constants.ts +202 -0
- package/src/constants/lifi.constants.ts +1 -0
- package/src/constants/mediaUrls.constants.ts +25 -0
- package/src/constants/mystery-boxes.constants.ts +402 -0
- package/src/constants/oauthUrls.constants.ts +7 -0
- package/src/constants/permit2.constants.ts +28 -0
- package/src/constants/presale.constants.ts +503 -0
- package/src/constants/protocol.constants.ts +65 -0
- package/src/constants/reorg-depths.constants.ts +13 -0
- package/src/constants/rewards.constants.ts +27 -0
- package/src/constants/save-depths.ts +13 -0
- package/src/constants/server.constants.ts +233 -0
- package/src/constants/tasks.constants.ts +205 -0
- package/src/constants/token-data/ERC20Registry.ts +90 -0
- package/src/constants/token-data/arbMainnetRegistry.json +1841 -0
- package/src/constants/token-data/arbMainnetRegistryFixed.json +1841 -0
- package/src/constants/token-data/arcTestnetRegistry.json +436 -0
- package/src/constants/token-data/avalancheRegistry.json +729 -0
- package/src/constants/token-data/avalancheRegistryFixed.json +729 -0
- package/src/constants/token-data/baseRegistry.json +1134 -0
- package/src/constants/token-data/baseRegistryFixed.json +1134 -0
- package/src/constants/token-data/bnbMainnetRegistry.json +900 -0
- package/src/constants/token-data/bnbMainnetRegistryFixed.json +900 -0
- package/src/constants/token-data/ethMainnetRegistry.json +4298 -0
- package/src/constants/token-data/ethMainnetRegistryFixed.json +4298 -0
- package/src/constants/token-data/index.ts +60 -0
- package/src/constants/token-data/localhostRegistry.json +2784 -0
- package/src/constants/token-data/optimismRegistry.json +701 -0
- package/src/constants/token-data/optimismRegistryFixed.json +701 -0
- package/src/constants/token-data/polygonRegistry.json +2309 -0
- package/src/constants/token-data/polygonRegistryFixed.json +2309 -0
- package/src/constants/token-data/popularTokens.constants.ts +11 -0
- package/src/constants/token-data/tokenPricing.consts.ts +2 -0
- package/src/constants/token.limits.constants.ts +31 -0
- package/src/constants/vite.constants.ts +74 -0
- package/src/constants/wallet.constants.ts +9 -0
- package/src/crypto/babyJub.ts +31 -0
- package/src/crypto/index.ts +3 -0
- package/src/crypto/poseidon.ts +36 -0
- package/src/crypto/preProcessing.ts +20 -0
- package/src/data-structures/ApprovalDBs/EventsPublicApprovalsDB.ts +288 -0
- package/src/data-structures/ApprovalDBs/index.ts +1 -0
- package/src/data-structures/Hinkal/Hinkal.ts +746 -0
- package/src/data-structures/Hinkal/IHinkal.ts +315 -0
- package/src/data-structures/Hinkal/handleAutoDepositBack.ts +138 -0
- package/src/data-structures/Hinkal/hinkalActionFundApproveAndTransact.ts +64 -0
- package/src/data-structures/Hinkal/hinkalActionReceive.ts +65 -0
- package/src/data-structures/Hinkal/hinkalActionStake.ts +152 -0
- package/src/data-structures/Hinkal/hinkalApprove.ts +170 -0
- package/src/data-structures/Hinkal/hinkalCheckTokenRegistry.ts +26 -0
- package/src/data-structures/Hinkal/hinkalDeposit.ts +199 -0
- package/src/data-structures/Hinkal/hinkalGetRecipientInfo.ts +12 -0
- package/src/data-structures/Hinkal/hinkalGetZkMeProvider.ts +31 -0
- package/src/data-structures/Hinkal/hinkalInsideTransact.ts +190 -0
- package/src/data-structures/Hinkal/hinkalMultiSend.ts +26 -0
- package/src/data-structures/Hinkal/hinkalPrivateWallet.ts +198 -0
- package/src/data-structures/Hinkal/hinkalProoflessDeposit.ts +91 -0
- package/src/data-structures/Hinkal/hinkalProxySwap.ts +91 -0
- package/src/data-structures/Hinkal/hinkalSignSubAccount.ts +28 -0
- package/src/data-structures/Hinkal/hinkalSwap.ts +157 -0
- package/src/data-structures/Hinkal/hinkalTransfer.ts +171 -0
- package/src/data-structures/Hinkal/hinkalWithdraw.ts +161 -0
- package/src/data-structures/Hinkal/index.ts +9 -0
- package/src/data-structures/Hinkal/resetMerkleTrees.ts +64 -0
- package/src/data-structures/IndexedDB/activity-db.ts +204 -0
- package/src/data-structures/IndexedDB/balances-db.ts +97 -0
- package/src/data-structures/IndexedDB/contact-db.ts +81 -0
- package/src/data-structures/IndexedDB/index.ts +6 -0
- package/src/data-structures/IndexedDB/prices-db.ts +89 -0
- package/src/data-structures/IndexedDB/private-balances-db.ts +31 -0
- package/src/data-structures/IndexedDB/signatures-db.ts +62 -0
- package/src/data-structures/MultiThreadedUtxoUtils/MultiThreadedUtxoUtils.ts +152 -0
- package/src/data-structures/TokenDBs/AlchemyPublicTokensDB.ts +224 -0
- package/src/data-structures/TokenDBs/ArcPublicTokensDB.ts +198 -0
- package/src/data-structures/TokenDBs/EventsPublicTokensDB.ts +216 -0
- package/src/data-structures/TokenDBs/IPublicTokensDB.ts +7 -0
- package/src/data-structures/TokenDBs/PrivateTokensDB.ts +96 -0
- package/src/data-structures/TokenDBs/PublicTokensDB.ts +49 -0
- package/src/data-structures/TokenDBs/index.ts +4 -0
- package/src/data-structures/TokenDBs/token-visibility-db.ts +154 -0
- package/src/data-structures/ValueCache/ValueCache.ts +29 -0
- package/src/data-structures/ValueCache/index.ts +1 -0
- package/src/data-structures/cacheDevices/AttachableMemoryCacheDevice.ts +33 -0
- package/src/data-structures/cacheDevices/BaseCacheDevice.ts +30 -0
- package/src/data-structures/cacheDevices/FileCacheDevice.ts +59 -0
- package/src/data-structures/cacheDevices/LocalStorageCacheDevice.ts +36 -0
- package/src/data-structures/cacheDevices/index.ts +2 -0
- package/src/data-structures/crypto-keys/decodeUTXO.ts +60 -0
- package/src/data-structures/crypto-keys/encryptDecryptUtxo.ts +74 -0
- package/src/data-structures/crypto-keys/index.ts +4 -0
- package/src/data-structures/crypto-keys/keyUtils.ts +8 -0
- package/src/data-structures/crypto-keys/keys.ts +203 -0
- package/src/data-structures/custom-token-registry/CustomTokenRegistry.ts +49 -0
- package/src/data-structures/event-service/AbstractAccessTokenSnapshotService.ts +142 -0
- package/src/data-structures/event-service/AbstractApprovalsSnapshotService.ts +152 -0
- package/src/data-structures/event-service/AbstractCommitmentsSnapshotService.ts +116 -0
- package/src/data-structures/event-service/AbstractEventService.ts +44 -0
- package/src/data-structures/event-service/AbstractNullifierSnapshotService.ts +76 -0
- package/src/data-structures/event-service/AbstractSnapshotService.ts +63 -0
- package/src/data-structures/event-service/BlockchainEventEmitter.ts +132 -0
- package/src/data-structures/event-service/index.ts +7 -0
- package/src/data-structures/index.ts +18 -0
- package/src/data-structures/merkle-tree/MerkleTree.test.ts +77 -0
- package/src/data-structures/merkle-tree/MerkleTree.ts +253 -0
- package/src/data-structures/merkle-tree/MerkleTreeIncompleteError.ts +6 -0
- package/src/data-structures/merkle-tree/getPatchedAccessTokenMerkleTree.ts +24 -0
- package/src/data-structures/merkle-tree/index.ts +3 -0
- package/src/data-structures/presale/PresaleContractWrapper.ts +80 -0
- package/src/data-structures/presale/index.ts +1 -0
- package/src/data-structures/provider-adapter/IProviderAdapter.ts +43 -0
- package/src/data-structures/snapshot/ClientAccessTokenSnapshotService.ts +41 -0
- package/src/data-structures/snapshot/ClientApprovalsSnapshotService.ts +36 -0
- package/src/data-structures/snapshot/ClientCommitmentsSnapshotService.ts +30 -0
- package/src/data-structures/snapshot/ClientNullifierSnapshotService.ts +28 -0
- package/src/data-structures/snapshot/SnapshotFetcherService.ts +68 -0
- package/src/data-structures/snapshot/index.ts +1 -0
- package/src/data-structures/token-price-fetcher/TokenChecker.ts +45 -0
- package/src/data-structures/token-price-fetcher/index.ts +1 -0
- package/src/data-structures/tor/HttpClient.ts +118 -0
- package/src/data-structures/tor/TorAdapter.ts +94 -0
- package/src/data-structures/tor/TorClient.ts +283 -0
- package/src/data-structures/tor/WebSocketDuplex.ts +32 -0
- package/src/data-structures/tor/index.ts +3 -0
- package/src/data-structures/transactions-manager/history/history.types.ts +14 -0
- package/src/data-structures/transactions-manager/index.ts +1 -0
- package/src/data-structures/utxo/Utxo.ts +189 -0
- package/src/error-handling/customErrors/ErrorWithAmount.ts +8 -0
- package/src/error-handling/customErrors/ErrorWithTx.ts +10 -0
- package/src/error-handling/customErrors/FeeOverTransactionValueError.ts +16 -0
- package/src/error-handling/customErrors/SimulationFailureError.ts +9 -0
- package/src/error-handling/customErrors/customErrors.helpers.ts +39 -0
- package/src/error-handling/customErrors/index.ts +5 -0
- package/src/error-handling/error-codes.constants.ts +214 -0
- package/src/error-handling/get-error.message.ts +149 -0
- package/src/error-handling/handleErrorRestore.ts +25 -0
- package/src/error-handling/index.ts +7 -0
- package/src/error-handling/logError.ts +8 -0
- package/src/error-handling/logger.ts +21 -0
- package/src/error-handling/types.ts +10 -0
- package/src/externalABIs/BUSD.ts +516 -0
- package/src/externalABIs/BabPassport.json +24 -0
- package/src/externalABIs/DAI.ts +331 -0
- package/src/externalABIs/ERC1155.json +316 -0
- package/src/externalABIs/ERC20.json +297 -0
- package/src/externalABIs/ERC20.ts +1 -0
- package/src/externalABIs/ERC721.json +205 -0
- package/src/externalABIs/GalxePassport.json +23 -0
- package/src/externalABIs/IQuoterV2.json +211 -0
- package/src/externalABIs/ISwapRouter.json +568 -0
- package/src/externalABIs/IUniswapV3Factory.json +207 -0
- package/src/externalABIs/IUniswapV3Pool.json +999 -0
- package/src/externalABIs/NodeInterfaceABI.json +1 -0
- package/src/externalABIs/OptimismGasPriceOracle.json +1 -0
- package/src/externalABIs/PoLidoNftAbi.json +307 -0
- package/src/externalABIs/SanctionsList.ts +86 -0
- package/src/externalABIs/USDC.ts +718 -0
- package/src/externalABIs/USDR.ts +343 -0
- package/src/externalABIs/USDR3CRV.ts +539 -0
- package/src/externalABIs/USDT.ts +390 -0
- package/src/externalABIs/UniswapV2PoolAbi.json +66 -0
- package/src/externalABIs/WETH.ts +153 -0
- package/src/externalABIs/amToken.ts +347 -0
- package/src/externalABIs/index.ts +53 -0
- package/src/externalABIs/swapAbi.ts +442 -0
- package/src/externalABIs/transactionsProver.json +45 -0
- package/src/functions/index.ts +16 -0
- package/src/functions/kyc/aiPriseHelper.ts +0 -0
- package/src/functions/kyc/authentoHelper.ts +44 -0
- package/src/functions/kyc/index.ts +3 -0
- package/src/functions/kyc/openDefaultPassportWindow.ts +9 -0
- package/src/functions/kyc/passportHelper.ts +13 -0
- package/src/functions/kyc/zkMeHelper.ts +69 -0
- package/src/functions/pre-transaction/constructAdminData.ts +21 -0
- package/src/functions/pre-transaction/getExternalSwapAddress.ts +30 -0
- package/src/functions/pre-transaction/getFeeStructure.ts +44 -0
- package/src/functions/pre-transaction/getFlatFees.ts +88 -0
- package/src/functions/pre-transaction/getSignatureDataForTransact.ts +16 -0
- package/src/functions/pre-transaction/getVolatileTransferAmount.ts +56 -0
- package/src/functions/pre-transaction/index.ts +7 -0
- package/src/functions/pre-transaction/interaction-to-action.ts +17 -0
- package/src/functions/pre-transaction/merge-with-fee-structure-emporium.ts +50 -0
- package/src/functions/pre-transaction/merge-with-fee-structure.ts +35 -0
- package/src/functions/pre-transaction/outputApprovalDataProcessing.ts +95 -0
- package/src/functions/pre-transaction/outputUtxoProcessing.ts +52 -0
- package/src/functions/pre-transaction/process-gas-estimates.ts +36 -0
- package/src/functions/pre-transaction/shouldPatchAccessTokenMerkleTree.ts +15 -0
- package/src/functions/private-wallet/emporium.helpers.ts +296 -0
- package/src/functions/private-wallet/emporium.swap.helpers.ts +284 -0
- package/src/functions/private-wallet/index.ts +3 -0
- package/src/functions/private-wallet/opProducer.ts +33 -0
- package/src/functions/snarkjs/common.snarkjs.ts +377 -0
- package/src/functions/snarkjs/constant.ts +490 -0
- package/src/functions/snarkjs/constructEmporiumProof.ts +301 -0
- package/src/functions/snarkjs/constructGeneralZkProof.ts +281 -0
- package/src/functions/snarkjs/generateCircomData.ts +81 -0
- package/src/functions/snarkjs/generateZkProof.ts +21 -0
- package/src/functions/snarkjs/generateZkProofEnclave.ts +45 -0
- package/src/functions/snarkjs/generateZkProofSelf.ts +29 -0
- package/src/functions/snarkjs/getOriginalSender.ts +4 -0
- package/src/functions/snarkjs/getZKFiles.ts +29 -0
- package/src/functions/snarkjs/index.ts +4 -0
- package/src/functions/staking/index.ts +78 -0
- package/src/functions/utils/addresses.ts +37 -0
- package/src/functions/utils/amounts.utils.test.ts +91 -0
- package/src/functions/utils/amounts.utils.ts +119 -0
- package/src/functions/utils/arraysMatch.ts +4 -0
- package/src/functions/utils/cacheDevice.utils.ts +21 -0
- package/src/functions/utils/cacheFunctions.ts +154 -0
- package/src/functions/utils/caseInsensitive.utils.ts +10 -0
- package/src/functions/utils/convertEmporiumOpToCallInfo.ts +19 -0
- package/src/functions/utils/convertIntegrationProviderToExternalActionId.ts +14 -0
- package/src/functions/utils/create-provider.ts +11 -0
- package/src/functions/utils/encodeTokenWithId.ts +4 -0
- package/src/functions/utils/encryptInputForEnclave.ts +119 -0
- package/src/functions/utils/enum.utils.ts +30 -0
- package/src/functions/utils/erc20tokenFunctions.ts +110 -0
- package/src/functions/utils/ethers-formatter.utils.ts +32 -0
- package/src/functions/utils/evmNetworkFunctions.ts +9 -0
- package/src/functions/utils/external-action.utils.ts +15 -0
- package/src/functions/utils/fees.utils.ts +26 -0
- package/src/functions/utils/get-hinkal-approvals.ts +36 -0
- package/src/functions/utils/get-signature-header.ts +5 -0
- package/src/functions/utils/getBlockExplorerUrl.ts +14 -0
- package/src/functions/utils/getDataFromTransaction.ts +79 -0
- package/src/functions/utils/getRecipientInfoFromUserKeys.ts +28 -0
- package/src/functions/utils/inLogicMetadata.ts +9 -0
- package/src/functions/utils/index.ts +43 -0
- package/src/functions/utils/involves-permit2-op.ts +17 -0
- package/src/functions/utils/ipfs.ts +74 -0
- package/src/functions/utils/is-valid-url.ts +5 -0
- package/src/functions/utils/lifi.utils.ts +3 -0
- package/src/functions/utils/memoize.utils.ts +23 -0
- package/src/functions/utils/merkleTree.utils.ts +27 -0
- package/src/functions/utils/mutexes.utils.ts +3 -0
- package/src/functions/utils/mystery-box-auction.utils.ts +61 -0
- package/src/functions/utils/networks.utils.ts +6 -0
- package/src/functions/utils/nftTokenFunctions.ts +25 -0
- package/src/functions/utils/nickname.utils.ts +4 -0
- package/src/functions/utils/postToOffscreen.ts +6 -0
- package/src/functions/utils/prepareHinkal.ts +78 -0
- package/src/functions/utils/process.utils.ts +23 -0
- package/src/functions/utils/processUseApprovalUtxoData.ts +26 -0
- package/src/functions/utils/publicBalance.utils.ts +131 -0
- package/src/functions/utils/reloadPage.ts +1 -0
- package/src/functions/utils/replaceAddressInCalldata.ts +6 -0
- package/src/functions/utils/requireEnv.ts +10 -0
- package/src/functions/utils/resolve-sync.utils.ts +40 -0
- package/src/functions/utils/rpc-int-encode.ts +7 -0
- package/src/functions/utils/serialize.utils.ts +12 -0
- package/src/functions/utils/string.utils.ts +92 -0
- package/src/functions/utils/time.utils.ts +80 -0
- package/src/functions/utils/token-check.utils.ts +12 -0
- package/src/functions/utils/trimFieldValues.ts +24 -0
- package/src/functions/utils/upToDateState.ts +12 -0
- package/src/functions/utils/userAgent.ts +26 -0
- package/src/functions/utils/walletBalances.utils.ts +117 -0
- package/src/functions/web3/EIP-712.test.ts +302 -0
- package/src/functions/web3/EIP-712.ts +243 -0
- package/src/functions/web3/etherFunctions.test.ts +129 -0
- package/src/functions/web3/etherFunctions.ts +84 -0
- package/src/functions/web3/events/balanceChangedCustomHandler.ts +13 -0
- package/src/functions/web3/events/balanceChangedHandler.ts +10 -0
- package/src/functions/web3/events/getApprovedBalance.ts +154 -0
- package/src/functions/web3/events/getInputUtxoAndBalance.ts +305 -0
- package/src/functions/web3/events/getInputUtxosEnclave.ts +40 -0
- package/src/functions/web3/events/getShieldedBalance.ts +163 -0
- package/src/functions/web3/events/getTransactionLogEvents.ts +55 -0
- package/src/functions/web3/events/index.ts +7 -0
- package/src/functions/web3/events/web3RetrieveEvents.ts +33 -0
- package/src/functions/web3/functionCalls/accessTokenCalls.ts +27 -0
- package/src/functions/web3/functionCalls/approveToken.ts +180 -0
- package/src/functions/web3/functionCalls/approveTokensToHinkal.ts +21 -0
- package/src/functions/web3/functionCalls/estimateGasRelayer.ts +40 -0
- package/src/functions/web3/functionCalls/getRootHash.ts +7 -0
- package/src/functions/web3/functionCalls/inHinkalApprovalCalls.ts +60 -0
- package/src/functions/web3/functionCalls/relayFunctions.ts +12 -0
- package/src/functions/web3/functionCalls/transactCallDirect.ts +71 -0
- package/src/functions/web3/functionCalls/transactCallRelayer.ts +57 -0
- package/src/functions/web3/getContractMetadata.ts +43 -0
- package/src/functions/web3/getPublicAddressBalance.ts +17 -0
- package/src/functions/web3/getTokenHolder.ts +53 -0
- package/src/functions/web3/index.ts +9 -0
- package/src/functions/web3/lifiAPI.ts +41 -0
- package/src/functions/web3/odosAPI.ts +50 -0
- package/src/functions/web3/oneInchAPI.ts +47 -0
- package/src/functions/web3/runContractFunction.ts +116 -0
- package/src/functions/web3/uniswapAPI.ts +156 -0
- package/src/index.ts +9 -0
- package/src/mutexes/index.ts +1 -0
- package/src/mutexes/mutex.ts +3 -0
- package/src/providers/EthersProviderAdapter.ts +230 -0
- package/src/providers/TorExternalProvider.ts +36 -0
- package/src/providers/WagmiProviderAdapter.ts +311 -0
- package/src/providers/exportProviers.ts +11 -0
- package/src/providers/prepareEthersHinkal.ts +18 -0
- package/src/providers/prepareWagmiHinkal.ts +16 -0
- package/src/types/API.types.ts +23 -0
- package/src/types/ICacheDevice.ts +5 -0
- package/src/types/IMultiThreadedUtxoUtils.ts +16 -0
- package/src/types/RewardUserEnums.ts +12 -0
- package/src/types/TransactionSimulator.types.ts +30 -0
- package/src/types/WeeklyAnalytics.types.ts +44 -0
- package/src/types/activities.types.ts +90 -0
- package/src/types/admin.types.ts +30 -0
- package/src/types/all-points.types.ts +8 -0
- package/src/types/approvals.types.ts +45 -0
- package/src/types/balances.types.ts +20 -0
- package/src/types/big-intable.types.ts +3 -0
- package/src/types/bridging.types.ts +30 -0
- package/src/types/brotherhood-user.types.ts +13 -0
- package/src/types/cache.types.ts +42 -0
- package/src/types/circom-data.types.ts +120 -0
- package/src/types/coingecko.types.ts +216 -0
- package/src/types/commitments.types.ts +39 -0
- package/src/types/confirmation-request.types.ts +10 -0
- package/src/types/contacts.types.ts +6 -0
- package/src/types/crypto.types.ts +8 -0
- package/src/types/duneAPI.types.ts +9 -0
- package/src/types/eip5792.types.ts +31 -0
- package/src/types/ethereum-network.types.ts +70 -0
- package/src/types/external-action.types.ts +19 -0
- package/src/types/fee.types.ts +11 -0
- package/src/types/generatePoints.ts +14 -0
- package/src/types/hinkal.stake.types.ts +12 -0
- package/src/types/hinkal.types.ts +150 -0
- package/src/types/index.ts +50 -0
- package/src/types/kyc.types.ts +49 -0
- package/src/types/merch-order.types.ts +18 -0
- package/src/types/message.types.ts +6 -0
- package/src/types/mystery-boxes.types.ts +50 -0
- package/src/types/new-rewards.type.ts +181 -0
- package/src/types/offscreen.types.ts +8 -0
- package/src/types/presaleReferral.types.ts +4 -0
- package/src/types/proxy.types.ts +11 -0
- package/src/types/referral.types.ts +13 -0
- package/src/types/relayer.types.ts +16 -0
- package/src/types/remote-proof.types.ts +18 -0
- package/src/types/rewards.types.ts +53 -0
- package/src/types/routing.types.ts +7 -0
- package/src/types/sandbox.types.ts +246 -0
- package/src/types/session.types.ts +12 -0
- package/src/types/signature.types.ts +11 -0
- package/src/types/slippage.types.ts +3 -0
- package/src/types/snark.types.ts +43 -0
- package/src/types/tenderly.api.types.ts +200 -0
- package/src/types/token-prices.types.ts +8 -0
- package/src/types/token-with-id.types.ts +4 -0
- package/src/types/token.types.ts +86 -0
- package/src/types/transactions.types.ts +120 -0
- package/src/types/wc.types.ts +83 -0
- package/src/types/with-id.types.ts +1 -0
- package/src/webworker/performTaskWithWorker.ts +50 -0
- package/src/webworker/snarkjsWorker/snarkjs.d.ts +2 -0
- package/src/webworker/snarkjsWorker/snarkjsWorker.types.ts +18 -0
- package/src/webworker/snarkjsWorker/snarkjsWorkerLauncher.ts +19 -0
- package/src/webworker/snarkjsWorker/snarkjsWorkerLogic.ts +90 -0
- package/src/webworker/utxoWorker/utxoWorker.types.ts +41 -0
- package/src/webworker/utxoWorker/utxoWorkerLauncher.ts +19 -0
- package/src/webworker/utxoWorker/utxoWorkerLogic.ts +107 -0
- package/src/webworker/viteWorkerURL.constant.ts +25 -0
- package/src/webworker/worker.registry.ts +11 -0
- package/src/webworker/worker.types.ts +35 -0
- package/src/webworker/workerErrorHandler.ts +10 -0
- package/src/webworker/workerFactory.ts +47 -0
- package/src/webworker/workerProxy.ts +88 -0
- package/src/webworker/zkProofWorker/zkProofWorker.types.ts +52 -0
- package/src/webworker/zkProofWorker/zkProofWorkerLauncher.ts +19 -0
- package/src/webworker/zkProofWorker/zkProofWorkerLogic.ts +84 -0
- package/tsconfig.json +23 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +15 -0
- package/vite.config.ts +97 -0
- package/vite.config.workers.ts +51 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { EncryptedOutputWithSign, OutputsWithSignAndLast } from '../../types/commitments.types';
|
|
2
|
+
import { IMultiThreadedUtxoUtils } from '../../types/IMultiThreadedUtxoUtils';
|
|
3
|
+
|
|
4
|
+
import { stealthAddressCacheDevice, stealthPairCacheDevice, UserKeys } from '../crypto-keys/keys';
|
|
5
|
+
import { IUtxoConstructor, Utxo } from '../utxo/Utxo';
|
|
6
|
+
import {
|
|
7
|
+
DecipherProcessPayload,
|
|
8
|
+
UtxoWorkerActionType,
|
|
9
|
+
UtxoWorkerPayload,
|
|
10
|
+
} from '../../webworker/utxoWorker/utxoWorker.types';
|
|
11
|
+
import { performTaskWithWorker } from '../../webworker/performTaskWithWorker';
|
|
12
|
+
import { WorkerVariant } from '../../webworker/worker.registry';
|
|
13
|
+
import { isNode } from '../../constants/vite.constants';
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface Navigator {
|
|
17
|
+
deviceMemory: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class MultiThreadedUtxoUtils implements IMultiThreadedUtxoUtils {
|
|
22
|
+
public readonly NUM_WORKERS: number;
|
|
23
|
+
|
|
24
|
+
public readonly NUM_WORKERS_BATCH_PROCESS: number;
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
if (isNode) {
|
|
28
|
+
this.NUM_WORKERS = 1;
|
|
29
|
+
this.NUM_WORKERS_BATCH_PROCESS = 1;
|
|
30
|
+
} else {
|
|
31
|
+
this.NUM_WORKERS = 3; // 3 seems to offer the best performance, on my machine at least
|
|
32
|
+
|
|
33
|
+
// in general the more workers we use with batchProcess the better the performance even if there are
|
|
34
|
+
// less cores / threads on device, however the problem is that
|
|
35
|
+
// if the number is too large we'll run out of memory and fail to fetch balance
|
|
36
|
+
// to not encounter any problems we limit the amount of workers to amount of GiB RAM the user has
|
|
37
|
+
// this will never be more than 8, navigator.deviceMemory will only report the following values:
|
|
38
|
+
// 0.25, 0.5, 1, 2, 4, 8
|
|
39
|
+
// in website is running in http mode navigator.deviceMemory might not be available, we assume it to be 4 if it's not
|
|
40
|
+
this.NUM_WORKERS_BATCH_PROCESS = Math.ceil(navigator.deviceMemory ?? 4);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async createUtxoPromise<T>(message: UtxoWorkerPayload) {
|
|
45
|
+
const data = await performTaskWithWorker<UtxoWorkerPayload, T>({
|
|
46
|
+
type: WorkerVariant.UTXO,
|
|
47
|
+
payload: message,
|
|
48
|
+
});
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async batchFilterUtxosWithNullifier(allUtxos: Utxo[], nullifiers: Set<string>): Promise<Utxo[]> {
|
|
53
|
+
const slices = this.sliceArrayIntoParts(allUtxos, this.NUM_WORKERS);
|
|
54
|
+
|
|
55
|
+
const workerResponsePromises = slices.map((utxoListSlice) =>
|
|
56
|
+
this.createUtxoPromise<{
|
|
57
|
+
utxoConstructors: IUtxoConstructor[];
|
|
58
|
+
stealthPairCache: Record<string, string>;
|
|
59
|
+
stealthAddressCache: Record<string, string>;
|
|
60
|
+
}>({
|
|
61
|
+
type: UtxoWorkerActionType.BATCH_FILTER_UTXOS_WITH_NULLIFIER,
|
|
62
|
+
data: {
|
|
63
|
+
utxos: utxoListSlice.map((utxo) => utxo.getConstructableParams()),
|
|
64
|
+
nullifiers,
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
const workerResults = await Promise.all(workerResponsePromises);
|
|
69
|
+
workerResults.forEach((item) => {
|
|
70
|
+
stealthPairCacheDevice.mergeWithSerialized(item.stealthPairCache);
|
|
71
|
+
stealthAddressCacheDevice.mergeWithSerialized(item.stealthAddressCache);
|
|
72
|
+
});
|
|
73
|
+
return workerResults.flatMap((item) => item.utxoConstructors).map((serializedUtxo) => new Utxo(serializedUtxo));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async buildBatchProcess(encryptedOutputs: EncryptedOutputWithSign[], userKeys: UserKeys) {
|
|
77
|
+
const slices = this.sliceArrayIntoParts(encryptedOutputs, this.NUM_WORKERS);
|
|
78
|
+
|
|
79
|
+
const messageResponsePromises = slices.map((encryptedOutputsSlice) =>
|
|
80
|
+
this.createUtxoPromise<IUtxoConstructor[]>({
|
|
81
|
+
type: UtxoWorkerActionType.BUILD_UTXOS,
|
|
82
|
+
data: { signature: userKeys.getSignature(), encryptedOutputs: encryptedOutputsSlice },
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
const messageResponses = await Promise.all(messageResponsePromises);
|
|
86
|
+
const outputs = messageResponses.flat();
|
|
87
|
+
const result = outputs.map((item) => new Utxo(item));
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
sliceArrayIntoParts<T>(arr: T[], numberOfParts: number) {
|
|
92
|
+
const lengthOfSubarray = Math.ceil(arr.length / numberOfParts);
|
|
93
|
+
const subarrays = Array.from({ length: numberOfParts }, (_value, index) =>
|
|
94
|
+
arr.slice(lengthOfSubarray * index, lengthOfSubarray * (index + 1)),
|
|
95
|
+
);
|
|
96
|
+
return subarrays;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
findLastOutput(lastOutputsArray: string[], lastOutput: string) {
|
|
100
|
+
let newLastOutput = lastOutput;
|
|
101
|
+
|
|
102
|
+
lastOutputsArray.forEach((value) => {
|
|
103
|
+
if (value !== lastOutput) newLastOutput = value;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return newLastOutput;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async batchProcess(encryptedOutputs: EncryptedOutputWithSign[], lastOutput: string, userKeys: UserKeys) {
|
|
110
|
+
const slices = this.sliceArrayIntoParts(encryptedOutputs, this.NUM_WORKERS_BATCH_PROCESS);
|
|
111
|
+
|
|
112
|
+
const signature = userKeys.getSignature();
|
|
113
|
+
|
|
114
|
+
const messageResponsePromises = slices.map((encryptedOutputsSlice) => {
|
|
115
|
+
const message: DecipherProcessPayload = {
|
|
116
|
+
type: UtxoWorkerActionType.DECIPHER_OUTPUTS,
|
|
117
|
+
data: {
|
|
118
|
+
encryptedOutputs: encryptedOutputsSlice,
|
|
119
|
+
lastOutput, // doesn't matter what we pass here, it will not be used regardless
|
|
120
|
+
signature,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return this.createUtxoPromise<OutputsWithSignAndLast>(message);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const workersResponses = await Promise.all(messageResponsePromises);
|
|
128
|
+
|
|
129
|
+
const resolvedEncryptedOutputs = workersResponses
|
|
130
|
+
.map(({ additionalEncryptedOutputs }) => additionalEncryptedOutputs)
|
|
131
|
+
.flat();
|
|
132
|
+
|
|
133
|
+
const uniqueValues = new Set<string>();
|
|
134
|
+
const uniqueEncryptedOutputs = resolvedEncryptedOutputs.reduce<EncryptedOutputWithSign[]>((prev, cur) => {
|
|
135
|
+
if (uniqueValues.has(cur.value)) return prev;
|
|
136
|
+
uniqueValues.add(cur.value);
|
|
137
|
+
return [...prev, cur];
|
|
138
|
+
}, []);
|
|
139
|
+
|
|
140
|
+
const newLastOutput = this.findLastOutput(
|
|
141
|
+
workersResponses.map((response) => response.lastOutput),
|
|
142
|
+
lastOutput,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const outputsWithSignAndLast: OutputsWithSignAndLast = {
|
|
146
|
+
additionalEncryptedOutputs: uniqueEncryptedOutputs,
|
|
147
|
+
lastOutput: newLastOutput ?? lastOutput, // keep the last output the same if no new output is present
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return outputsWithSignAndLast;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { get, update } from 'idb-keyval';
|
|
2
|
+
import { API } from '../../API/API';
|
|
3
|
+
import { ALCHEMY_API_KEY, chainIds } from '../../constants/chains.constants';
|
|
4
|
+
import { TokenType, zeroAddress } from '../../constants/protocol.constants';
|
|
5
|
+
import { caseInsensitiveEqual, lowerCaseIncludes } from '../../functions/utils/caseInsensitive.utils';
|
|
6
|
+
import { getPublicBalanceByTokenAddress } from '../../functions/utils/publicBalance.utils';
|
|
7
|
+
import { getStateKey } from '../../functions/utils/string.utils';
|
|
8
|
+
import { StorageKeys } from '../../types/cache.types';
|
|
9
|
+
import { ERC20Token } from '../../types/token.types';
|
|
10
|
+
import { IPublicTokensDB } from './IPublicTokensDB';
|
|
11
|
+
import { tokenVisibilityStorage } from './token-visibility-db';
|
|
12
|
+
import { httpClient } from '../tor';
|
|
13
|
+
|
|
14
|
+
interface AlchemyResponse {
|
|
15
|
+
result: {
|
|
16
|
+
tokenBalances: { contractAddress: string; tokenBalance: string }[];
|
|
17
|
+
address: string;
|
|
18
|
+
pageKey?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface AlchemyNFTResponse {
|
|
23
|
+
ownedNfts: { contractAddress: string; tokenId: string }[];
|
|
24
|
+
pageKey: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class AlchemyPublicTokensDB implements IPublicTokensDB {
|
|
28
|
+
private fetchedTokens: Record<string, ERC20Token[]> = {};
|
|
29
|
+
|
|
30
|
+
private readonly ALCHEMY_URLS = {
|
|
31
|
+
[chainIds.ethMainnet]: `eth-mainnet`,
|
|
32
|
+
[chainIds.polygon]: `polygon-mainnet`,
|
|
33
|
+
[chainIds.arbMainnet]: `arb-mainnet`,
|
|
34
|
+
[chainIds.optimism]: `opt-mainnet`,
|
|
35
|
+
[chainIds.base]: `base-mainnet`,
|
|
36
|
+
[chainIds.avalanche]: `avax-mainnet`,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Known legitimate NFT collections that should be included in fallback
|
|
40
|
+
private readonly KNOWN_GOOD_NFTS: Record<number, string[]> = {
|
|
41
|
+
[chainIds.base]: [
|
|
42
|
+
'0x20bc8d248fe9c18a947406cea50d716828ab821f', // Hinkal Mason NFT
|
|
43
|
+
],
|
|
44
|
+
[chainIds.optimism]: [
|
|
45
|
+
'0x3c3e0e73b53a19bcaf4178b8f9c9428fd2a2775e', // Uniswap v4 Positions
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
private isWhitelistedNFT(address: string, chainId: number): boolean {
|
|
50
|
+
// Only allow known good NFT collections in the fallback to avoid spam
|
|
51
|
+
if (this.KNOWN_GOOD_NFTS[chainId]) {
|
|
52
|
+
return this.KNOWN_GOOD_NFTS[chainId].some((goodAddress) => caseInsensitiveEqual(address, goodAddress));
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public async getPublicTokens(chainId: number, walletAddress: string): Promise<ERC20Token[]> {
|
|
58
|
+
const key = getStateKey(walletAddress, chainId);
|
|
59
|
+
const publicTokens = await get<Record<string, ERC20Token[]>>(StorageKeys.ALCHEMY_PUBLIC_TOKENS);
|
|
60
|
+
return publicTokens?.[key] || [];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public getFetchedTokens(chainId: number, walletAddress: string): ERC20Token[] {
|
|
64
|
+
const key = getStateKey(walletAddress, chainId);
|
|
65
|
+
return this.fetchedTokens[key] || [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public async fetchAndUpdatePublicTokens(walletAddress: string, chainId: number) {
|
|
69
|
+
const stateKey = getStateKey(walletAddress, chainId);
|
|
70
|
+
|
|
71
|
+
const erc20TokenAddresses = await this.getERC20TokenAddresses(chainId, walletAddress);
|
|
72
|
+
|
|
73
|
+
const nftTokensInfo = await this.getNFTTokens(chainId, walletAddress);
|
|
74
|
+
const nftTokenAddresses = nftTokensInfo.map((nft) => nft.contractAddress);
|
|
75
|
+
|
|
76
|
+
const tokenAddresses = [...erc20TokenAddresses, ...nftTokenAddresses];
|
|
77
|
+
|
|
78
|
+
if (!tokenAddresses.length) return;
|
|
79
|
+
|
|
80
|
+
const tokensFromBackend = await API.tokensInfoCall(chainId, tokenAddresses);
|
|
81
|
+
|
|
82
|
+
// Fallback: Get minimal NFT metadata when backend returns null but Alchemy confirms it's indeed an NFT
|
|
83
|
+
// ONLY for NFTs with valid tokenIds (user actually owns them)
|
|
84
|
+
const erc20Tokens = tokensFromBackend
|
|
85
|
+
.map((token, index) => {
|
|
86
|
+
if (token) return token;
|
|
87
|
+
|
|
88
|
+
// Check if this address is an NFT that Alchemy found
|
|
89
|
+
const tokenAddress = tokenAddresses[index];
|
|
90
|
+
const nftInfo = nftTokensInfo.find((nft) => caseInsensitiveEqual(nft.contractAddress, tokenAddress));
|
|
91
|
+
|
|
92
|
+
if (nftInfo && nftInfo.tokenIds && nftInfo.tokenIds.length > 0) {
|
|
93
|
+
if (!this.isWhitelistedNFT(tokenAddress, chainId)) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
chainId,
|
|
98
|
+
name: 'Unknown NFT',
|
|
99
|
+
symbol: 'NFT',
|
|
100
|
+
erc20TokenAddress: tokenAddress,
|
|
101
|
+
decimals: 0,
|
|
102
|
+
nftTokenType: TokenType.ERC721,
|
|
103
|
+
tokenIds: nftInfo.tokenIds,
|
|
104
|
+
} as ERC20Token;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return null;
|
|
108
|
+
})
|
|
109
|
+
.filter((token): token is ERC20Token => !!token);
|
|
110
|
+
|
|
111
|
+
const hiddenTokenAddresses = await tokenVisibilityStorage.hideSpamsAndFetchHiddenTokensAddresses(
|
|
112
|
+
chainId,
|
|
113
|
+
erc20Tokens,
|
|
114
|
+
);
|
|
115
|
+
const nonHiddenErc20Tokens = erc20Tokens.filter(
|
|
116
|
+
(token) => !lowerCaseIncludes(hiddenTokenAddresses, token.erc20TokenAddress), // filter out hidden tokens
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const erc20TokensWithIds = nonHiddenErc20Tokens.map((token) => ({
|
|
120
|
+
...token,
|
|
121
|
+
tokenIds: nftTokensInfo.find((nft) => caseInsensitiveEqual(nft.contractAddress, token.erc20TokenAddress))
|
|
122
|
+
?.tokenIds,
|
|
123
|
+
}));
|
|
124
|
+
|
|
125
|
+
await update(StorageKeys.ALCHEMY_PUBLIC_TOKENS, (pubTokens: Record<string, ERC20Token[]> = {}) => {
|
|
126
|
+
const newPublicTokens = {
|
|
127
|
+
...pubTokens,
|
|
128
|
+
[stateKey]: erc20TokensWithIds,
|
|
129
|
+
};
|
|
130
|
+
this.fetchedTokens = newPublicTokens;
|
|
131
|
+
return newPublicTokens;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private async getERC20TokenAddresses(chainId: number, walletAddress: string): Promise<string[]> {
|
|
136
|
+
const nativeTokenBalance = await getPublicBalanceByTokenAddress(chainId, walletAddress, zeroAddress);
|
|
137
|
+
|
|
138
|
+
const alchemyUrl = `https://${this.ALCHEMY_URLS[chainId]}.g.alchemy.com/v2/${ALCHEMY_API_KEY}`;
|
|
139
|
+
const allBalances: { contractAddress: string; tokenBalance: string }[] = [];
|
|
140
|
+
let pageKey: string | undefined;
|
|
141
|
+
|
|
142
|
+
do {
|
|
143
|
+
const params: (string | { pageKey: string })[] = [walletAddress, 'erc20'];
|
|
144
|
+
if (pageKey) params.push({ pageKey });
|
|
145
|
+
|
|
146
|
+
// eslint-disable-next-line no-await-in-loop
|
|
147
|
+
const response = await httpClient.post<AlchemyResponse>(alchemyUrl, {
|
|
148
|
+
jsonrpc: '2.0',
|
|
149
|
+
id: 1,
|
|
150
|
+
method: 'alchemy_getTokenBalances',
|
|
151
|
+
params,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const { result } = response;
|
|
155
|
+
allBalances.push(...(result?.tokenBalances ?? []));
|
|
156
|
+
pageKey = result?.pageKey;
|
|
157
|
+
} while (pageKey);
|
|
158
|
+
|
|
159
|
+
if (nativeTokenBalance && nativeTokenBalance > 0n) {
|
|
160
|
+
allBalances.push({
|
|
161
|
+
contractAddress: zeroAddress,
|
|
162
|
+
tokenBalance: nativeTokenBalance.toString(),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const uniqueBalances: Record<string, { contractAddress: string; tokenBalance: string }> = {};
|
|
167
|
+
allBalances.forEach((token) => {
|
|
168
|
+
if (!uniqueBalances[token.contractAddress] || BigInt(token.tokenBalance) > 0n) {
|
|
169
|
+
uniqueBalances[token.contractAddress] = token;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return Object.keys(uniqueBalances);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private async getNFTTokens(
|
|
177
|
+
chainId: number,
|
|
178
|
+
walletAddress: string,
|
|
179
|
+
): Promise<{ contractAddress: string; tokenIds: string[] }[]> {
|
|
180
|
+
const baseUrl = `https://${this.ALCHEMY_URLS[chainId]}.g.alchemy.com/nft/v3/${ALCHEMY_API_KEY}/getNFTsForOwner`;
|
|
181
|
+
|
|
182
|
+
const allNfts: AlchemyNFTResponse['ownedNfts'] = [];
|
|
183
|
+
let pageKey: string | undefined;
|
|
184
|
+
|
|
185
|
+
// Handle pagination to get all NFTs
|
|
186
|
+
do {
|
|
187
|
+
const params = new URLSearchParams({
|
|
188
|
+
owner: walletAddress,
|
|
189
|
+
withMetadata: 'false',
|
|
190
|
+
pageSize: '100', // max is 100
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (pageKey) {
|
|
194
|
+
params.append('pageKey', pageKey);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// eslint-disable-next-line no-await-in-loop
|
|
198
|
+
const response = await httpClient.get<AlchemyNFTResponse>(`${baseUrl}?${params.toString()}`);
|
|
199
|
+
|
|
200
|
+
const { ownedNfts = [], pageKey: newPageKey } = response;
|
|
201
|
+
|
|
202
|
+
allNfts.push(...ownedNfts);
|
|
203
|
+
pageKey = newPageKey;
|
|
204
|
+
} while (pageKey);
|
|
205
|
+
|
|
206
|
+
const validNfts = allNfts.filter(({ contractAddress, tokenId }) => contractAddress && tokenId);
|
|
207
|
+
|
|
208
|
+
const groupedByContract = validNfts.reduce((acc: Map<string, string[]>, { contractAddress, tokenId }) => {
|
|
209
|
+
const contract = contractAddress.toLowerCase();
|
|
210
|
+
if (!acc.has(contract)) {
|
|
211
|
+
acc.set(contract, []);
|
|
212
|
+
}
|
|
213
|
+
acc.get(contract)?.push(tokenId);
|
|
214
|
+
return acc;
|
|
215
|
+
}, new Map<string, string[]>());
|
|
216
|
+
|
|
217
|
+
return Array.from(groupedByContract.entries()).map(([contractAddress, tokenIds]) => ({
|
|
218
|
+
contractAddress,
|
|
219
|
+
tokenIds,
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export const alchemyPublicTokensDB = new AlchemyPublicTokensDB();
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { getContractWithFetcherByChainId } from '../../functions/web3/getContractMetadata';
|
|
3
|
+
import { ContractType } from '../../types/ethereum-network.types';
|
|
4
|
+
import { Logger } from '../../error-handling/logger';
|
|
5
|
+
import { StorageKeys } from '../../types/cache.types';
|
|
6
|
+
import { ERC20Token } from '../../types/token.types';
|
|
7
|
+
import { getStateKey } from '../../functions/utils/string.utils';
|
|
8
|
+
import { get, update } from 'idb-keyval';
|
|
9
|
+
import { API } from '../../API/API';
|
|
10
|
+
import { caseInsensitiveEqual, lowerCaseIncludes } from '../../functions/utils/caseInsensitive.utils';
|
|
11
|
+
import { TokenType } from '../../constants/protocol.constants';
|
|
12
|
+
import { tokenVisibilityStorage } from './token-visibility-db';
|
|
13
|
+
import { chainIds } from '../../constants/chains.constants';
|
|
14
|
+
|
|
15
|
+
interface ApiResponse {
|
|
16
|
+
message: string;
|
|
17
|
+
result: { contractAddress: string }[];
|
|
18
|
+
status: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface NFTResponse {
|
|
22
|
+
items: NFTItem[];
|
|
23
|
+
next_page_params: NextPageParams | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface NFTItem {
|
|
27
|
+
id: string;
|
|
28
|
+
token: { address_hash: string };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface NextPageParams {
|
|
32
|
+
token_contract_address_hash: string;
|
|
33
|
+
token_id: string;
|
|
34
|
+
token_type: string;
|
|
35
|
+
[key: string]: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class ArcPublicTokensDB {
|
|
39
|
+
private readonly API_BASE = 'https://testnet.arcscan.app/api';
|
|
40
|
+
|
|
41
|
+
private fetchedTokens: Record<string, ERC20Token[]> = {};
|
|
42
|
+
|
|
43
|
+
public async getPublicTokens(walletAddress: string): Promise<ERC20Token[]> {
|
|
44
|
+
const key = getStateKey(walletAddress, chainIds.arcTestnet);
|
|
45
|
+
const publicTokens = await get<Record<string, ERC20Token[]>>(StorageKeys.ARC_PUBLIC_TOKENS);
|
|
46
|
+
return publicTokens?.[key] || [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public getFetchedTokens(walletAddress: string): ERC20Token[] {
|
|
50
|
+
const key = getStateKey(walletAddress, chainIds.arcTestnet);
|
|
51
|
+
return this.fetchedTokens[key] || [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public async fetchAndUpdatePublicTokens(walletAddress: string) {
|
|
55
|
+
const stateKey = getStateKey(walletAddress, chainIds.arcTestnet);
|
|
56
|
+
|
|
57
|
+
const erc20TokenAddresses = await this.getERC20TokenAddresses(walletAddress);
|
|
58
|
+
|
|
59
|
+
const nftTokensInfo = await this.getNFTTokens(walletAddress);
|
|
60
|
+
const nftTokenAddresses = nftTokensInfo.map((nft) => nft.contractAddress);
|
|
61
|
+
|
|
62
|
+
const tokenAddresses = [...erc20TokenAddresses, ...nftTokenAddresses];
|
|
63
|
+
|
|
64
|
+
if (!tokenAddresses.length) return;
|
|
65
|
+
|
|
66
|
+
const tokensFromBackend = await API.tokensInfoCall(chainIds.arcTestnet, tokenAddresses);
|
|
67
|
+
|
|
68
|
+
// Fallback: Get minimal NFT metadata when backend returns null but arcscan confirms it's indeed an NFT
|
|
69
|
+
// ONLY for NFTs with valid tokenIds (user actually owns them)
|
|
70
|
+
const erc20Tokens = tokensFromBackend
|
|
71
|
+
.map((token, index) => {
|
|
72
|
+
if (token) return token;
|
|
73
|
+
|
|
74
|
+
// Check if this address is an NFT that arcscan found
|
|
75
|
+
const tokenAddress = tokenAddresses[index];
|
|
76
|
+
const nftInfo = nftTokensInfo.find((nft) => caseInsensitiveEqual(nft.contractAddress, tokenAddress));
|
|
77
|
+
|
|
78
|
+
if (nftInfo && nftInfo.tokenIds && nftInfo.tokenIds.length > 0) {
|
|
79
|
+
return {
|
|
80
|
+
chainId: chainIds.arcTestnet,
|
|
81
|
+
name: 'Unknown NFT',
|
|
82
|
+
symbol: 'NFT',
|
|
83
|
+
erc20TokenAddress: tokenAddress,
|
|
84
|
+
decimals: 0,
|
|
85
|
+
nftTokenType: TokenType.ERC721,
|
|
86
|
+
tokenIds: nftInfo.tokenIds,
|
|
87
|
+
} as ERC20Token;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return null;
|
|
91
|
+
})
|
|
92
|
+
.filter((token): token is ERC20Token => !!token);
|
|
93
|
+
|
|
94
|
+
const hiddenTokenAddresses = await tokenVisibilityStorage.hideSpamsAndFetchHiddenTokensAddresses(
|
|
95
|
+
chainIds.arcTestnet,
|
|
96
|
+
erc20Tokens,
|
|
97
|
+
);
|
|
98
|
+
const nonHiddenErc20Tokens = erc20Tokens.filter(
|
|
99
|
+
(token) => !lowerCaseIncludes(hiddenTokenAddresses, token.erc20TokenAddress), // filter out hidden tokens
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const erc20TokensWithIds = nonHiddenErc20Tokens.map((token) => ({
|
|
103
|
+
...token,
|
|
104
|
+
tokenIds: nftTokensInfo.find((nft) => caseInsensitiveEqual(nft.contractAddress, token.erc20TokenAddress))
|
|
105
|
+
?.tokenIds,
|
|
106
|
+
}));
|
|
107
|
+
|
|
108
|
+
await update(StorageKeys.ARC_PUBLIC_TOKENS, (pubTokens: Record<string, ERC20Token[]> = {}) => {
|
|
109
|
+
const newPublicTokens = {
|
|
110
|
+
...pubTokens,
|
|
111
|
+
[stateKey]: erc20TokensWithIds,
|
|
112
|
+
};
|
|
113
|
+
this.fetchedTokens = newPublicTokens;
|
|
114
|
+
return newPublicTokens;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private async getERC20TokenAddresses(walletAddress: string): Promise<string[]> {
|
|
119
|
+
// arc-testnet has native 18 decimal and normal 6 decimal usdc that's why we don't get balances of native usdc on arc testnet
|
|
120
|
+
const balances: { contractAddress: string; tokenBalance: string }[] = [];
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const tokenTxResponse = await axios.post<ApiResponse>(
|
|
124
|
+
`${this.API_BASE}?module=account&action=tokentx&address=${walletAddress}`,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
const tokenTxData = tokenTxResponse.data;
|
|
128
|
+
|
|
129
|
+
if (tokenTxData.status === '1' && tokenTxData.result) {
|
|
130
|
+
const tokenAddresses = [...new Set(tokenTxData.result.map(({ contractAddress }) => contractAddress))];
|
|
131
|
+
|
|
132
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
133
|
+
for (const tokenAddress of tokenAddresses) {
|
|
134
|
+
try {
|
|
135
|
+
const contract = getContractWithFetcherByChainId(
|
|
136
|
+
chainIds.arcTestnet,
|
|
137
|
+
ContractType.ERC20Contract,
|
|
138
|
+
tokenAddress as unknown as undefined,
|
|
139
|
+
);
|
|
140
|
+
// eslint-disable-next-line no-await-in-loop
|
|
141
|
+
const balance = BigInt(await contract['balanceOf'](walletAddress));
|
|
142
|
+
if (balance > 0n) {
|
|
143
|
+
balances.push({
|
|
144
|
+
contractAddress: tokenAddress,
|
|
145
|
+
tokenBalance: balance.toString(),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
Logger.error('Error fetching ARC testnet token balance:', error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
Logger.error('Error fetching ARC testnet token transactions:', error);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return balances
|
|
158
|
+
.filter(({ tokenBalance }) => Number(tokenBalance) !== 0)
|
|
159
|
+
.map(({ contractAddress }) => contractAddress);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private async getNFTTokens(walletAddress: string): Promise<{ contractAddress: string; tokenIds: string[] }[]> {
|
|
163
|
+
const baseUrl = `${this.API_BASE}/v2/addresses/${walletAddress}/nft?type=ERC-721,ERC-1155`; // https://testnet.arcscan.app/api-docs?tab=rest_api //get list of NFT owned by address
|
|
164
|
+
const allNfts: NFTResponse['items'] = [];
|
|
165
|
+
let nextPageParams: NextPageParams | undefined;
|
|
166
|
+
|
|
167
|
+
do {
|
|
168
|
+
const query = nextPageParams ? `&${new URLSearchParams(nextPageParams)}` : '';
|
|
169
|
+
// eslint-disable-next-line no-await-in-loop
|
|
170
|
+
const { data } = await axios.get<NFTResponse>(`${baseUrl}${query}`);
|
|
171
|
+
|
|
172
|
+
const { items = [], next_page_params: nextPageParamsResponse } = data;
|
|
173
|
+
allNfts.push(...items);
|
|
174
|
+
nextPageParams = nextPageParamsResponse
|
|
175
|
+
? {
|
|
176
|
+
token_contract_address_hash: nextPageParamsResponse.token_contract_address_hash,
|
|
177
|
+
token_id: nextPageParamsResponse.token_id,
|
|
178
|
+
token_type: nextPageParamsResponse.token_type,
|
|
179
|
+
}
|
|
180
|
+
: undefined;
|
|
181
|
+
} while (nextPageParams);
|
|
182
|
+
|
|
183
|
+
const groupedByContract = allNfts.reduce((acc: Map<string, string[]>, item) => {
|
|
184
|
+
const contractAddress = item.token.address_hash.toLowerCase();
|
|
185
|
+
const tokenId = item.id;
|
|
186
|
+
if (!acc.has(contractAddress)) acc.set(contractAddress, []);
|
|
187
|
+
acc.get(contractAddress)?.push(tokenId);
|
|
188
|
+
return acc;
|
|
189
|
+
}, new Map<string, string[]>());
|
|
190
|
+
|
|
191
|
+
return Array.from(groupedByContract.entries()).map(([contractAddress, tokenIds]) => ({
|
|
192
|
+
contractAddress,
|
|
193
|
+
tokenIds,
|
|
194
|
+
}));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export const arcPublicTokensDB = new ArcPublicTokensDB();
|