diff --git a/.env.example b/.env.example index b05f4c8..0e20491 100644 --- a/.env.example +++ b/.env.example @@ -43,4 +43,43 @@ EVM_ETHER_TRANSFER_TX='0x566002399664e92f82ed654c181095bdd7ff3d3f1921d9632575858 EVM_TOKEN_TRANSFER_TX='0xdabda3905e585db91768f2ef877f7fbef7c0e8612c0a09c7b379981bdbc48975' EVM_NFT_TRANSFER_TX='0x272a4698cd2062f2463481cf9eb78b68b35d59938383679b7642e6d669ac87eb' # Models -# EVM CHAINS \ No newline at end of file +# EVM CHAINS + +#TRON +# Assets +TRON_COIN_TRANSFER_TEST_IS_ACTIVE=false +TRON_TOKEN_TRANSFER_TEST_IS_ACTIVE=false +TRON_TOKEN_APPROVE_TEST_IS_ACTIVE=false +TRON_TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE=false +TRON_NFT_TRANSACTION_TEST_IS_ACTIVE=false +TRON_TRANSACTION_LISTENER_TEST_IS_ACTIVE=false + +TRON_COIN_BALANCE_TEST_AMOUNT=10 +TRON_TOKEN_BALANCE_TEST_AMOUNT=20 +TRON_NFT_BALANCE_TEST_AMOUNT=2 +TRON_TRANSFER_TEST_AMOUNT=0.0001 +TRON_TOKEN_TRANSFER_TEST_AMOUNT=1 +TRON_TOKEN_APPROVE_TEST_AMOUNT=10 +TRON_NFT_TRANSFER_ID=7 + +TRON_BALANCE_TEST_ADDRESS='TS1WYZNoNw32hog68m5GyhwZnkhf6HNzhi' +TRON_SENDER_PRIVATE_KEY='aba68e5764a8bf9bdcf711f83bab9395317b8acb17298ca487c1aede3ed0e6cf' +TRON_RECEIVER_PRIVATE_KEY='318bfadf97af289888f4a3864002322535e1ee95b5a7b5abdf76602513dd8b69' +TRON_SENDER_TEST_ADDRESS='TNukrtF5dwy77dWKaVSKocWsGWpQ53iffj' +TRON_RECEIVER_TEST_ADDRESS='TSVufyvTBhWPMbvAaZr6ESYszpzXfBs8WA' +TRON_TOKEN_TEST_ADDRESS='TJkmHT9gWNyELDaCbz9ui5PPQ6EPezgegu' +TRON_NFT_TEST_ADDRESS='TPnBfSVwZHaGUfjXNzsnHbnyJ8Ui13x27P' +# Assets + +# Models +TRON_NFT_ID=8 +TRON_TOKEN_AMOUNT=20 +TRON_COIN_AMOUNT=10 + +TRON_MODEL_TEST_SENDER='TNukrtF5dwy77dWKaVSKocWsGWpQ53iffj' +TRON_MODEL_TEST_RECEIVER='TS1WYZNoNw32hog68m5GyhwZnkhf6HNzhi' + +TRON_TRX_TRANSFER_TX='8697ad2c4e1713227c16a65a5845636458df2d3db3adf526e07e17699bc6b3c4' +TRON_TOKEN_TRANSFER_TX='bd0ba6ebb8d2f910b27de1565c66cc89337b792dfdb6484847c817ccbd240760' +TRON_NFT_TRANSFER_TX='d5dd97c09efdb93f36808a9f8e14642ef226880aa91a846583d4ce98c0084637' +#TRON \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 4fa3012..4fc768f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,6 +23,12 @@ }, "plugins": ["prettier", "filenames"], "rules": { + "@typescript-eslint/no-misused-promises": [ + "error", + { + "checksVoidReturn": false + } + ], "filenames/match-exported": ["error", "pascal"] }, "ignorePatterns": [ diff --git a/packages/networks/boilerplate/package.json b/packages/networks/boilerplate/package.json index 1cac0e3..28fc135 100644 --- a/packages/networks/boilerplate/package.json +++ b/packages/networks/boilerplate/package.json @@ -17,6 +17,14 @@ "default": "./dist/index.cjs", "types": "./dist/index.d.ts" } + }, + "./node": { + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + }, + "./browser": { + "require": "./dist/index.umd.js", + "types": "./dist/browser/index.d.ts" } }, "files": [ @@ -25,6 +33,7 @@ "!tsconfig.tsbuildinfo" ], "scripts": { + "dev": "vite", "clean": "rm -rf dist", "watch": "tsc --watch", "build:vite": "vite build", @@ -52,7 +61,7 @@ "url": "https://github.com/MultipleChain/js/issues" }, "dependencies": { - "@multiplechain/types": "^0.1.53", + "@multiplechain/types": "^0.1.55", "@multiplechain/utils": "^0.1.18" } } \ No newline at end of file diff --git a/packages/networks/boilerplate/pnpm-lock.yaml b/packages/networks/boilerplate/pnpm-lock.yaml index ff48dd3..aae81e5 100644 --- a/packages/networks/boilerplate/pnpm-lock.yaml +++ b/packages/networks/boilerplate/pnpm-lock.yaml @@ -6,16 +6,16 @@ settings: dependencies: '@multiplechain/types': - specifier: ^0.1.53 - version: 0.1.53 + specifier: ^0.1.55 + version: 0.1.55 '@multiplechain/utils': specifier: ^0.1.18 version: 0.1.18 packages: - /@multiplechain/types@0.1.53: - resolution: {integrity: sha512-brF6CtNDUwTChwZBy0pTEvf4QdwAK3sL2kvVXE9rARAroK8qUU4Skn5NAHpr2W1ubmuhDezgHDS4XhEdr8BsgA==} + /@multiplechain/types@0.1.55: + resolution: {integrity: sha512-9fYrLaDxX2pj9zfIbmvk1hPF3FH/bK+Q3uTF+k3zdsitP/HzQ1S9zImNz20Tvoqkk1ns+/8ecE0Y6GNowsDOQA==} dev: false /@multiplechain/utils@0.1.18: diff --git a/packages/networks/boilerplate/src/assets/Coin.ts b/packages/networks/boilerplate/src/assets/Coin.ts index 778ebd8..1c2d8b3 100644 --- a/packages/networks/boilerplate/src/assets/Coin.ts +++ b/packages/networks/boilerplate/src/assets/Coin.ts @@ -1,6 +1,6 @@ import { Provider } from '../services/Provider.ts' -import { TransactionSigner } from '../services/TransactionSigner.ts' -import type { CoinInterface, TransactionSignerInterface } from '@multiplechain/types' +import type { CoinInterface } from '@multiplechain/types' +import { CoinTransactionSigner } from '../services/TransactionSigner.ts' export class Coin implements CoinInterface { /** @@ -54,7 +54,7 @@ export class Coin implements CoinInterface { sender: string, receiver: string, amount: number - ): Promise { - return new TransactionSigner('example') + ): Promise { + return new CoinTransactionSigner('example') } } diff --git a/packages/networks/boilerplate/src/assets/Contract.ts b/packages/networks/boilerplate/src/assets/Contract.ts index d8c2edd..ee3a295 100644 --- a/packages/networks/boilerplate/src/assets/Contract.ts +++ b/packages/networks/boilerplate/src/assets/Contract.ts @@ -45,4 +45,14 @@ export class Contract implements ContractInterface { async getMethodData(method: string, ...args: any[]): Promise { return {} } + + /** + * @param {string} method Method name + * @param {string} from Sender wallet address + * @param {any[]} args Method parameters + * @returns {Promise} Encoded method data + */ + async createTransactionData(method: string, from: string, ...args: any[]): Promise { + return '' + } } diff --git a/packages/networks/boilerplate/src/assets/NFT.ts b/packages/networks/boilerplate/src/assets/NFT.ts index f3da454..0a89a51 100644 --- a/packages/networks/boilerplate/src/assets/NFT.ts +++ b/packages/networks/boilerplate/src/assets/NFT.ts @@ -1,6 +1,6 @@ import { Contract } from './Contract.ts' -import { TransactionSigner } from '../services/TransactionSigner.ts' -import type { NftInterface, TransactionSignerInterface } from '@multiplechain/types' +import type { NftInterface } from '@multiplechain/types' +import { NftTransactionSigner } from '../services/TransactionSigner.ts' export class NFT extends Contract implements NftInterface { /** @@ -26,71 +26,71 @@ export class NFT extends Contract implements NftInterface { } /** - * @param {number} nftId NFT ID + * @param {number | string} nftId NFT ID * @returns {Promise} Wallet address of the owner of the NFT */ - async getOwner(nftId: number): Promise { + async getOwner(nftId: number | string): Promise { return 'example' } /** - * @param {number} nftId NFT ID + * @param {number | string} nftId NFT ID * @returns {Promise} URI of the NFT */ - async getTokenURI(nftId: number): Promise { + async getTokenURI(nftId: number | string): Promise { return 'example' } /** - * @param {number} nftId ID of the NFT that will be transferred - * @returns {Promise} Wallet address of the approved spender + * @param {number | string} nftId ID of the NFT that will be transferred + * @returns {Promise} Wallet address of the approved spender */ - async getApproved(nftId: number): Promise { + async getApproved(nftId: number | string): Promise { return 'example' } /** * @param {string} sender Sender address * @param {string} receiver Receiver address - * @param {number} nftId NFT ID - * @returns {Promise} Transaction signer + * @param {number | string} nftId NFT ID + * @returns {Promise} Transaction signer */ async transfer( sender: string, receiver: string, - nftId: number - ): Promise { - return new TransactionSigner('example') + nftId: number | string + ): Promise { + return new NftTransactionSigner('example') } /** * @param {string} spender Spender address * @param {string} owner Owner address * @param {string} receiver Receiver address - * @param {number} nftId NFT ID - * @returns {Promise} Transaction signer + * @param {number | string} nftId NFT ID + * @returns {Promise} Transaction signer */ async transferFrom( spender: string, owner: string, receiver: string, - nftId: number - ): Promise { - return new TransactionSigner('example') + nftId: number | string + ): Promise { + return new NftTransactionSigner('example') } /** * Gives permission to the spender to spend owner's tokens * @param {string} owner Address of owner of the tokens that will be used * @param {string} spender Address of the spender that will use the tokens of owner - * @param {number} nftId ID of the NFT that will be transferred + * @param {number | string} nftId ID of the NFT that will be transferred * @returns {Promise} Transaction signer */ async approve( owner: string, spender: string, - nftId: number - ): Promise { - return new TransactionSigner('example') + nftId: number | string + ): Promise { + return new NftTransactionSigner('example') } } diff --git a/packages/networks/boilerplate/src/assets/Token.ts b/packages/networks/boilerplate/src/assets/Token.ts index 285183a..8d30a0d 100644 --- a/packages/networks/boilerplate/src/assets/Token.ts +++ b/packages/networks/boilerplate/src/assets/Token.ts @@ -1,6 +1,6 @@ import { Contract } from './Contract.ts' -import { TransactionSigner } from '../services/TransactionSigner.ts' -import type { TokenInterface, TransactionSignerInterface } from '@multiplechain/types' +import type { TokenInterface } from '@multiplechain/types' +import { TokenTransactionSigner } from '../services/TransactionSigner.ts' export class Token extends Contract implements TokenInterface { /** @@ -59,8 +59,8 @@ export class Token extends Contract implements TokenInterface { sender: string, receiver: string, amount: number - ): Promise { - return new TransactionSigner('example') + ): Promise { + return new TokenTransactionSigner('example') } /** @@ -68,15 +68,15 @@ export class Token extends Contract implements TokenInterface { * @param {string} owner Sender wallet address * @param {string} receiver Receiver wallet address * @param {number} amount Amount of tokens that will be transferred - * @returns {Promise} Transaction signer + * @returns {Promise} Transaction signer */ async transferFrom( spender: string, owner: string, receiver: string, amount: number - ): Promise { - return new TransactionSigner('example') + ): Promise { + return new TokenTransactionSigner('example') } /** @@ -90,7 +90,7 @@ export class Token extends Contract implements TokenInterface { owner: string, spender: string, amount: number - ): Promise { - return new TransactionSigner('example') + ): Promise { + return new TokenTransactionSigner('example') } } diff --git a/packages/networks/boilerplate/src/browser/Wallet.ts b/packages/networks/boilerplate/src/browser/Wallet.ts index ac2d5cd..652d8a1 100644 --- a/packages/networks/boilerplate/src/browser/Wallet.ts +++ b/packages/networks/boilerplate/src/browser/Wallet.ts @@ -2,7 +2,8 @@ import type { WalletInterface, WalletAdapterInterface, WalletPlatformEnum, - TransactionSignerInterface + TransactionSignerInterface, + ProviderInterface } from '@multiplechain/types' import { Provider } from '../services/Provider' @@ -40,7 +41,7 @@ export class Wallet implements WalletInterface { * @returns {string} */ getIcon(): string { - return this.adapter.name + return this.adapter.icon } /** @@ -71,10 +72,11 @@ export class Wallet implements WalletInterface { } /** - * connect to adapter + * @param {ProviderInterface} provider + * @param {Object} ops * @returns {Promise} */ - async connect(): Promise { + async connect(provider?: ProviderInterface, ops?: object): Promise { await this.adapter.connect() return 'wallet address' } diff --git a/packages/networks/boilerplate/src/models/NftTransaction.ts b/packages/networks/boilerplate/src/models/NftTransaction.ts index 57cf99a..09b8d80 100644 --- a/packages/networks/boilerplate/src/models/NftTransaction.ts +++ b/packages/networks/boilerplate/src/models/NftTransaction.ts @@ -34,7 +34,7 @@ export class NftTransaction extends ContractTransaction implements NftTransactio async verifyTransfer( direction: AssetDirectionEnum, address: string, - nftId: number + nftId: number | string ): Promise { return TransactionStatusEnum.PENDING } diff --git a/packages/networks/boilerplate/src/services/TransactionListener.ts b/packages/networks/boilerplate/src/services/TransactionListener.ts index fd17438..47ee7d8 100644 --- a/packages/networks/boilerplate/src/services/TransactionListener.ts +++ b/packages/networks/boilerplate/src/services/TransactionListener.ts @@ -44,10 +44,10 @@ export class TransactionListener /** * @param {T} type - Transaction type - * @param {Provider} provider - Provider * @param {DynamicTransactionListenerFilterType} filter - Transaction listener filter + * @param {Provider} provider - Provider */ - constructor(type: T, provider?: Provider, filter?: DynamicTransactionListenerFilterType) { + constructor(type: T, filter?: DynamicTransactionListenerFilterType, provider?: Provider) { this.type = type this.filter = filter this.provider = provider ?? Provider.instance @@ -87,10 +87,11 @@ export class TransactionListener /** * Listen to the transaction events * @param {TransactionListenerCallbackType} callback - Transaction listener callback - * @returns {void} + * @returns {Promise} */ - on(callback: TransactionListenerCallbackType): void { + async on(callback: TransactionListenerCallbackType): Promise { this.callbacks.push(callback) + return true } /** diff --git a/packages/networks/evm-chains/.eslintrc.json b/packages/networks/evm-chains/.eslintrc.json index e7ed887..3614d50 100644 --- a/packages/networks/evm-chains/.eslintrc.json +++ b/packages/networks/evm-chains/.eslintrc.json @@ -1,12 +1,4 @@ { - "rules": { - "@typescript-eslint/no-misused-promises": [ - "error", - { - "checksVoidReturn": false - } - ] - }, "extends": ["plugin:require-extensions/recommended", "../../../.eslintrc.json"], "plugins": ["require-extensions"] } diff --git a/packages/networks/evm-chains/package.json b/packages/networks/evm-chains/package.json index 4995b02..3774ff0 100644 --- a/packages/networks/evm-chains/package.json +++ b/packages/networks/evm-chains/package.json @@ -1,6 +1,6 @@ { "name": "@multiplechain/evm-chains", - "version": "0.3.42", + "version": "0.3.45", "type": "module", "main": "dist/index.cjs", "module": "dist/index.es.js", @@ -17,6 +17,14 @@ "default": "./dist/index.cjs", "types": "./dist/index.d.ts" } + }, + "./node": { + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + }, + "./browser": { + "require": "./dist/index.umd.js", + "types": "./dist/browser/index.d.ts" } }, "files": [ @@ -56,7 +64,7 @@ "url": "https://github.com/MultipleChain/js/issues" }, "dependencies": { - "@multiplechain/types": "^0.1.53", + "@multiplechain/types": "^0.1.55", "@multiplechain/utils": "^0.1.18", "@wagmi/chains": "^1.8.0", "@walletconnect/ethereum-provider": "^2.12.2", diff --git a/packages/networks/evm-chains/pnpm-lock.yaml b/packages/networks/evm-chains/pnpm-lock.yaml index ecb1cea..356b610 100644 --- a/packages/networks/evm-chains/pnpm-lock.yaml +++ b/packages/networks/evm-chains/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@multiplechain/types': - specifier: ^0.1.53 - version: 0.1.53 + specifier: ^0.1.55 + version: 0.1.55 '@multiplechain/utils': specifier: ^0.1.18 version: 0.1.18 @@ -236,8 +236,8 @@ packages: tslib: 2.4.0 dev: false - /@multiplechain/types@0.1.53: - resolution: {integrity: sha512-brF6CtNDUwTChwZBy0pTEvf4QdwAK3sL2kvVXE9rARAroK8qUU4Skn5NAHpr2W1ubmuhDezgHDS4XhEdr8BsgA==} + /@multiplechain/types@0.1.55: + resolution: {integrity: sha512-9fYrLaDxX2pj9zfIbmvk1hPF3FH/bK+Q3uTF+k3zdsitP/HzQ1S9zImNz20Tvoqkk1ns+/8ecE0Y6GNowsDOQA==} dev: false /@multiplechain/utils@0.1.18: diff --git a/packages/networks/evm-chains/src/assets/NFT.ts b/packages/networks/evm-chains/src/assets/NFT.ts index 6d03b69..1e44b93 100644 --- a/packages/networks/evm-chains/src/assets/NFT.ts +++ b/packages/networks/evm-chains/src/assets/NFT.ts @@ -55,10 +55,11 @@ export class NFT extends Contract implements NftInterface { /** * @param {number | string} nftId ID of the NFT that will be transferred - * @returns {Promise} Wallet address of the approved spender + * @returns {Promise} Wallet address of the approved spender */ - async getApproved(nftId: number | string): Promise { - return await this.callMethod('getApproved', nftId) + async getApproved(nftId: number | string): Promise { + const address = await this.callMethod('getApproved', nftId) + return address === '0x0000000000000000000000000000000000000000' ? null : address } /** diff --git a/packages/networks/evm-chains/src/browser/Wallet.ts b/packages/networks/evm-chains/src/browser/Wallet.ts index 420645a..d87d0e4 100644 --- a/packages/networks/evm-chains/src/browser/Wallet.ts +++ b/packages/networks/evm-chains/src/browser/Wallet.ts @@ -270,6 +270,10 @@ export class Wallet implements Omit { * @returns {void} */ on(eventName: string, callback: (...args: any[]) => void): void { - this.walletProvider.on(eventName, callback) + if (this.adapter?.provider?.on !== undefined) { + this.adapter.provider.on(eventName, callback) + } else { + this.walletProvider.on(eventName, callback) + } } } diff --git a/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts b/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts index eead4b8..eb9cee5 100644 --- a/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts +++ b/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts @@ -5,8 +5,6 @@ import type { EIP1193Provider } from './EIP6963.ts' import { WalletPlatformEnum } from '@multiplechain/types' import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' -const metamaskProvider = window?.ethereum as unknown as WindowEthereum - const MetaMask: WalletAdapterInterface = { id: 'metamask', name: 'MetaMask', @@ -14,13 +12,20 @@ const MetaMask: WalletAdapterInterface = { provider: window.ethereum, downloadLink: 'https://metamask.io/download/', platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], - isDetected: () => Boolean(metamaskProvider.isMetaMask), + isDetected: () => Boolean((window?.ethereum as unknown as WindowEthereum).isMetaMask), createDeepLink: (url: string): string => `https://metamask.app.link/dapp/${url}`, isConnected: async () => { - return Boolean((await metamaskProvider.request({ method: 'eth_accounts' })).length) + return Boolean( + ( + await (window?.ethereum as unknown as WindowEthereum).request({ + method: 'eth_accounts' + }) + ).length + ) }, connect: async (provider?: ProviderInterface): Promise => { return await new Promise((resolve, reject) => { + const metamaskProvider = window?.ethereum as unknown as WindowEthereum try { metamaskProvider ?.request({ method: 'eth_requestAccounts' }) diff --git a/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts b/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts index 529b6db..00a7927 100644 --- a/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts +++ b/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts @@ -5,23 +5,31 @@ import type { EIP1193Provider } from './EIP6963.ts' import { WalletPlatformEnum } from '@multiplechain/types' import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' -// eslint-disable-next-line -const trustWalletProvider = (window?.ethereum?.isTrust ? window.ethereum : window.trustwallet) as unknown as WindowEthereum - const TrustWallet: WalletAdapterInterface = { id: 'trustwallet', name: 'TrustWallet', icon: icons.trustWallet, - provider: trustWalletProvider, + // eslint-disable-next-line + provider: (window?.ethereum?.isTrust + ? window.ethereum + : window.trustwallet) as unknown as WindowEthereum, downloadLink: 'https://trustwallet.com/download', platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], isDetected: () => Boolean(window?.ethereum?.isTrust ?? window?.trustwallet), isConnected: async () => { + // eslint-disable-next-line + const trustWalletProvider = (window?.ethereum?.isTrust + ? window.ethereum + : window.trustwallet) as unknown as WindowEthereum return Boolean((await trustWalletProvider?.request({ method: 'eth_accounts' })).length) }, connect: async (provider?: ProviderInterface): Promise => { return await new Promise((resolve, reject) => { try { + // eslint-disable-next-line + const trustWalletProvider = (window?.ethereum?.isTrust + ? window.ethereum + : window.trustwallet) as unknown as WindowEthereum trustWalletProvider ?.request({ method: 'eth_requestAccounts' }) .then(() => { diff --git a/packages/networks/evm-chains/src/services/TransactionSigner.ts b/packages/networks/evm-chains/src/services/TransactionSigner.ts index eafeaa2..00bd28f 100644 --- a/packages/networks/evm-chains/src/services/TransactionSigner.ts +++ b/packages/networks/evm-chains/src/services/TransactionSigner.ts @@ -11,6 +11,7 @@ import { ErrorTypeEnum, type TransactionSignerInterface } from '@multiplechain/t export interface TransactionData extends TransactionRequest { gas?: BigNumberish } + export class TransactionSigner implements TransactionSignerInterface { /** * Transaction data from the blockchain network @@ -75,17 +76,17 @@ export class TransactionSigner implements TransactionSignerInterface { /** * Get the raw transaction data - * @returns {any} Transaction data + * @returns {TransactionData} Transaction data */ - getRawData(): any { + getRawData(): TransactionData { return this.rawData } /** * Get the signed transaction data - * @returns {any} Signed transaction data + * @returns {string} Signed transaction data */ - getSignedData(): any { + getSignedData(): string { return this.signedData } } diff --git a/packages/networks/evm-chains/tests/assets.spec.ts b/packages/networks/evm-chains/tests/assets.spec.ts index 4e66db1..975ec35 100644 --- a/packages/networks/evm-chains/tests/assets.spec.ts +++ b/packages/networks/evm-chains/tests/assets.spec.ts @@ -52,7 +52,7 @@ const checkSigner = async (signer: TransactionSigner, privateKey?: string): Prom const checkTx = async (transaction: Transaction): Promise => { expect(transaction).toBeInstanceOf(Transaction) - const status = await transaction.wait(10) + const status = await transaction.wait(10 * 1000) expect(status).toBe(TransactionStatusEnum.CONFIRMED) } @@ -117,7 +117,7 @@ describe('Token', () => { it('Transfer', async () => { if (!tokenTransferTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await token.transfer( senderTestAddress, @@ -138,7 +138,7 @@ describe('Token', () => { it('Approve and Allowance', async () => { if (!tokenApproveTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await token.approve( senderTestAddress, @@ -158,7 +158,7 @@ describe('Token', () => { it('Transfer from', async () => { if (!tokenTransferFromTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await token.transferFrom( receiverTestAddress, @@ -200,13 +200,13 @@ describe('Nft', () => { }) it('Approved', async () => { - expect(await nft.getApproved(5)).toBe('0x0000000000000000000000000000000000000000') + expect(await nft.getApproved(5)).toBe(null) }) it('Transfer', async () => { if (!nftTransactionTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await nft.transfer(senderTestAddress, receiverTestAddress, nftTransferId) @@ -220,7 +220,7 @@ describe('Nft', () => { it('Approve', async () => { if (!nftTransactionTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await nft.approve(receiverTestAddress, senderTestAddress, nftTransferId) @@ -234,7 +234,7 @@ describe('Nft', () => { it('Transfer from', async () => { if (!nftTransactionTestIsActive) return - await waitSecondsBeforeThanNewTx(30) + await waitSecondsBeforeThanNewTx(5) const signer = await nft.transferFrom( senderTestAddress, diff --git a/packages/networks/evm-chains/tests/models.spec.ts b/packages/networks/evm-chains/tests/models.spec.ts index 8912790..9f3e7b4 100644 --- a/packages/networks/evm-chains/tests/models.spec.ts +++ b/packages/networks/evm-chains/tests/models.spec.ts @@ -51,10 +51,9 @@ describe('Transaction', () => { expect(await tx.getBlockNumber()).toBe(5461884) }) - // Not give any response in vitest environment - // it('Block Timestamp', async () => { - // expect(await tx.getBlockTimestamp()).toBe(1710141144) - // }) + it('Block Timestamp', async () => { + expect(await tx.getBlockTimestamp()).toBe(1710141144) + }) it('Block Confirmation Count', async () => { expect(await tx.getBlockConfirmationCount()).toBeGreaterThan(129954) diff --git a/packages/networks/tron/.eslintrc.json b/packages/networks/tron/.eslintrc.json new file mode 100644 index 0000000..b62472f --- /dev/null +++ b/packages/networks/tron/.eslintrc.json @@ -0,0 +1,7 @@ +{ + "extends": [ + "plugin:require-extensions/recommended", + "../../../.eslintrc.json" + ], + "plugins": ["require-extensions"] +} \ No newline at end of file diff --git a/packages/networks/tron/.npmignore b/packages/networks/tron/.npmignore new file mode 100644 index 0000000..4f4a3d7 --- /dev/null +++ b/packages/networks/tron/.npmignore @@ -0,0 +1,6 @@ +src +tests +node_modules +.eslintrc.cjs +pnpm-lock.yaml +tsconfig.json \ No newline at end of file diff --git a/packages/networks/tron/README.md b/packages/networks/tron/README.md new file mode 100644 index 0000000..e69de29 diff --git a/packages/networks/tron/esbuild.ts b/packages/networks/tron/esbuild.ts new file mode 100644 index 0000000..5714b9c --- /dev/null +++ b/packages/networks/tron/esbuild.ts @@ -0,0 +1,3 @@ +void import('../../../esbuild.ts').then((module) => { + module.default() +}) diff --git a/packages/networks/tron/index.html b/packages/networks/tron/index.html new file mode 100644 index 0000000..12a24de --- /dev/null +++ b/packages/networks/tron/index.html @@ -0,0 +1,350 @@ + + + + + + + Browser Tests + + + + +
+
    +
+
+ +
+
+ Adapter id: +
+
+ Adapter name: +
+
+ Adapter icon: icon +
+
+ Platforms: +
+
+ Download link: +
+
+ Deep link: +
+
+ Chain id: +
+
+ Connected address: +
+ +
+ Result: +
+ +
+ Result: +
+ +
+ Result: +
+
+ + + + \ No newline at end of file diff --git a/packages/networks/tron/package.json b/packages/networks/tron/package.json new file mode 100644 index 0000000..d6069e8 --- /dev/null +++ b/packages/networks/tron/package.json @@ -0,0 +1,78 @@ +{ + "name": "@multiplechain/tron", + "version": "0.2.10", + "type": "module", + "main": "dist/index.cjs", + "module": "dist/index.es.js", + "unpkg": "dist/index.umd.js", + "browser": "dist/index.umd.js", + "jsdelivr": "dist/index.umd.js", + "exports": { + ".": { + "import": { + "default": "./dist/index.es.js", + "types": "./dist/browser/index.d.ts" + }, + "require": { + "default": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "./node": { + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + }, + "./browser": { + "require": "./dist/index.umd.js", + "types": "./dist/browser/index.d.ts" + } + }, + "files": [ + "dist", + "README.md", + "!tsconfig.tsbuildinfo" + ], + "scripts": { + "dev": "vite", + "clean": "rm -rf dist", + "watch": "tsc --watch", + "build:vite": "vite build", + "build:node": "tsx esbuild.ts", + "typecheck": "tsc --noEmit", + "lint": "eslint . --ext .ts", + "test": "vitest run --dir tests", + "prepublishOnly": "pnpm run build", + "build": "pnpm run build:vite && pnpm run build:node" + }, + "keywords": [ + "web3", + "crypto", + "blockchain", + "multiple-chain" + ], + "author": "MultipleChain", + "license": "MIT", + "homepage": "https://github.com/MultipleChain/js/tree/master/packages/networks/tron", + "repository": { + "type": "git", + "url": "git+https://github.com/MultipleChain/js.git" + }, + "bugs": { + "url": "https://github.com/MultipleChain/js/issues" + }, + "dependencies": { + "@beycandeveloper/tron-tx-decoder": "^2.0.5", + "@multiplechain/tron-walletconnect": "^0.1.0", + "@multiplechain/types": "^0.1.55", + "@multiplechain/utils": "^0.1.18", + "@noble/secp256k1": "^1.7.1", + "@tronweb3/tronwallet-adapter-bitkeep": "^1.1.1", + "@tronweb3/tronwallet-adapter-okxwallet": "^1.0.3", + "@tronweb3/tronwallet-adapter-tokenpocket": "^1.0.3", + "@tronweb3/tronwallet-adapter-tronlink": "^1.1.9", + "tronweb": "^5.3.2" + }, + "devDependencies": { + "@tronweb3/tronwallet-abstract-adapter": "^1.1.6" + } +} \ No newline at end of file diff --git a/packages/networks/tron/pnpm-lock.yaml b/packages/networks/tron/pnpm-lock.yaml new file mode 100644 index 0000000..7dc6724 --- /dev/null +++ b/packages/networks/tron/pnpm-lock.yaml @@ -0,0 +1,3251 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@beycandeveloper/tron-tx-decoder': + specifier: ^2.0.5 + version: 2.0.5 + '@multiplechain/tron-walletconnect': + specifier: ^0.1.0 + version: 0.1.0(typescript@5.4.5) + '@multiplechain/types': + specifier: ^0.1.55 + version: 0.1.55 + '@multiplechain/utils': + specifier: ^0.1.18 + version: 0.1.18 + '@noble/secp256k1': + specifier: ^1.7.1 + version: 1.7.1 + '@tronweb3/tronwallet-adapter-bitkeep': + specifier: ^1.1.1 + version: 1.1.1 + '@tronweb3/tronwallet-adapter-okxwallet': + specifier: ^1.0.3 + version: 1.0.3 + '@tronweb3/tronwallet-adapter-tokenpocket': + specifier: ^1.0.3 + version: 1.0.3 + '@tronweb3/tronwallet-adapter-tronlink': + specifier: ^1.1.9 + version: 1.1.9 + tronweb: + specifier: ^5.3.2 + version: 5.3.2 + +devDependencies: + '@tronweb3/tronwallet-abstract-adapter': + specifier: ^1.1.6 + version: 1.1.6 + +packages: + + /@adraffy/ens-normalize@1.10.1: + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + dev: false + + /@babel/helper-string-parser@7.24.1: + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier@7.24.5: + resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/parser@7.24.5: + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/runtime@7.24.5: + resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + + /@babel/types@7.24.5: + resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.24.5 + to-fast-properties: 2.0.0 + dev: false + + /@beycandeveloper/tron-tx-decoder@2.0.5: + resolution: {integrity: sha512-/ohZkz/WMTkCFMSmBm3cTABW2CfcgEnEP6gi9+CexuxGApDvhDigSP0dCRk0bz8FH0rLyalWPhDnA325KBEsww==} + dependencies: + axios: 0.21.4 + ethers: 4.0.49 + transitivePeerDependencies: + - debug + dev: false + + /@bitget-wallet/web3-sdk@0.0.8: + resolution: {integrity: sha512-WFk6URUxTCukKrU3YpTdWTCScrj6/wwd/0O7eSANeQl1KDbDs+yj/fAkN1Wy6ebI3NMcW6sqN9mrmfwz53dPMQ==} + dependencies: + '@metamask/safe-event-emitter': 3.1.1 + '@solana/web3.js': 1.91.7 + eventemitter3: 5.0.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@ethersproject/abi@5.7.0: + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + dev: false + + /@ethersproject/abstract-provider@5.7.0: + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + dev: false + + /@ethersproject/abstract-signer@5.7.0: + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + dev: false + + /@ethersproject/address@5.7.0: + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + dev: false + + /@ethersproject/base64@5.7.0: + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + dependencies: + '@ethersproject/bytes': 5.7.0 + dev: false + + /@ethersproject/bignumber@5.7.0: + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + dev: false + + /@ethersproject/bytes@5.7.0: + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + dependencies: + '@ethersproject/logger': 5.7.0 + dev: false + + /@ethersproject/constants@5.7.0: + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + dev: false + + /@ethersproject/hash@5.7.0: + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + dev: false + + /@ethersproject/keccak256@5.7.0: + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + dev: false + + /@ethersproject/logger@5.7.0: + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + dev: false + + /@ethersproject/networks@5.7.1: + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + dependencies: + '@ethersproject/logger': 5.7.0 + dev: false + + /@ethersproject/properties@5.7.0: + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + dependencies: + '@ethersproject/logger': 5.7.0 + dev: false + + /@ethersproject/rlp@5.7.0: + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + dev: false + + /@ethersproject/signing-key@5.7.0: + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + dev: false + + /@ethersproject/strings@5.7.0: + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + dev: false + + /@ethersproject/transactions@5.7.0: + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + dev: false + + /@ethersproject/web@5.7.1: + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@metamask/safe-event-emitter@3.1.1: + resolution: {integrity: sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw==} + engines: {node: '>=12.0.0'} + dev: false + + /@microsoft/api-extractor-model@7.28.13: + resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2 + transitivePeerDependencies: + - '@types/node' + dev: false + + /@microsoft/api-extractor@7.43.0: + resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==} + hasBin: true + dependencies: + '@microsoft/api-extractor-model': 7.28.13 + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2 + '@rushstack/rig-package': 0.5.2 + '@rushstack/terminal': 0.10.0 + '@rushstack/ts-command-line': 4.19.1 + lodash: 4.17.21 + minimatch: 3.0.8 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.4.2 + transitivePeerDependencies: + - '@types/node' + dev: false + + /@microsoft/tsdoc-config@0.16.2: + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + dev: false + + /@microsoft/tsdoc@0.14.2: + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + dev: false + + /@multiplechain/tron-walletconnect@0.1.0(typescript@5.4.5): + resolution: {integrity: sha512-uU6tEKtd3DQ3nlpM8RaEnhcEZkyKDWZx3XyI8W52Ti+/l9M8XLCOaS5yrvCG7Gbrb1SLyB7sWvDMdEncz5hgIg==} + dependencies: + '@tronweb3/tronwallet-abstract-adapter': 1.1.6 + '@walletconnect/legacy-modal': 2.0.0 + '@walletconnect/sign-client': 2.12.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + vite-plugin-dts: 3.9.0(typescript@5.4.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/node' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - rollup + - supports-color + - typescript + - uWebSockets.js + - utf-8-validate + - vite + dev: false + + /@multiplechain/types@0.1.55: + resolution: {integrity: sha512-9fYrLaDxX2pj9zfIbmvk1hPF3FH/bK+Q3uTF+k3zdsitP/HzQ1S9zImNz20Tvoqkk1ns+/8ecE0Y6GNowsDOQA==} + dev: false + + /@multiplechain/utils@0.1.18: + resolution: {integrity: sha512-UCoOOBJrawp/lInepxuoEiYwId0wMPg7rX8p78FLqzGl8f/b93sAtv7sP87/VVKwhdoEuNZ/uQjckycmNeks/w==} + dependencies: + '@types/ws': 8.5.10 + bignumber.js: 9.1.2 + web3-utils: 4.2.1 + ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/curves@1.3.0: + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + dependencies: + '@noble/hashes': 1.3.3 + dev: false + + /@noble/curves@1.4.0: + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + dependencies: + '@noble/hashes': 1.4.0 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@noble/hashes@1.3.3: + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + dev: false + + /@noble/hashes@1.4.0: + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + dev: false + + /@noble/secp256k1@1.7.1: + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + dev: false + + /@parcel/watcher-android-arm64@2.4.1: + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-arm64@2.4.1: + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-x64@2.4.1: + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-freebsd-x64@2.4.1: + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm-glibc@2.4.1: + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-glibc@2.4.1: + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-musl@2.4.1: + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-glibc@2.4.1: + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-musl@2.4.1: + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-wasm@2.4.1: + resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} + engines: {node: '>= 10.0.0'} + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.5 + dev: false + bundledDependencies: + - napi-wasm + + /@parcel/watcher-win32-arm64@2.4.1: + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-ia32@2.4.1: + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-x64@2.4.1: + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher@2.4.1: + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.5 + node-addon-api: 7.1.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + dev: false + + /@rollup/pluginutils@5.1.0: + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + + /@rushstack/node-core-library@4.0.2: + resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + dependencies: + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + dev: false + + /@rushstack/rig-package@0.5.2: + resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} + dependencies: + resolve: 1.22.8 + strip-json-comments: 3.1.1 + dev: false + + /@rushstack/terminal@0.10.0: + resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + dependencies: + '@rushstack/node-core-library': 4.0.2 + supports-color: 8.1.1 + dev: false + + /@rushstack/ts-command-line@4.19.1: + resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} + dependencies: + '@rushstack/terminal': 0.10.0 + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + dev: false + + /@scure/base@1.1.6: + resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==} + dev: false + + /@scure/bip32@1.3.3: + resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.6 + dev: false + + /@scure/bip39@1.2.2: + resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + dependencies: + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.6 + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.91.7: + resolution: {integrity: sha512-HqljZKDwk6Z4TajKRGhGLlRsbGK4S8EY27DA7v1z6yakewiUY3J7ZKDZRxcqz2MYV/ZXRrJ6wnnpiHFkPdv0WA==} + dependencies: + '@babel/runtime': 7.24.5 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.3.3 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.10.0 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@stablelib/aead@1.0.1: + resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} + dev: false + + /@stablelib/binary@1.0.1: + resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} + dependencies: + '@stablelib/int': 1.0.1 + dev: false + + /@stablelib/bytes@1.0.1: + resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} + dev: false + + /@stablelib/chacha20poly1305@1.0.1: + resolution: {integrity: sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==} + dependencies: + '@stablelib/aead': 1.0.1 + '@stablelib/binary': 1.0.1 + '@stablelib/chacha': 1.0.1 + '@stablelib/constant-time': 1.0.1 + '@stablelib/poly1305': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/chacha@1.0.1: + resolution: {integrity: sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/constant-time@1.0.1: + resolution: {integrity: sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==} + dev: false + + /@stablelib/ed25519@1.0.3: + resolution: {integrity: sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==} + dependencies: + '@stablelib/random': 1.0.2 + '@stablelib/sha512': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/hash@1.0.1: + resolution: {integrity: sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==} + dev: false + + /@stablelib/hkdf@1.0.1: + resolution: {integrity: sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g==} + dependencies: + '@stablelib/hash': 1.0.1 + '@stablelib/hmac': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/hmac@1.0.1: + resolution: {integrity: sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA==} + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/int@1.0.1: + resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + dev: false + + /@stablelib/keyagreement@1.0.1: + resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} + dependencies: + '@stablelib/bytes': 1.0.1 + dev: false + + /@stablelib/poly1305@1.0.1: + resolution: {integrity: sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==} + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/random@1.0.2: + resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/sha256@1.0.1: + resolution: {integrity: sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/sha512@1.0.1: + resolution: {integrity: sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/wipe@1.0.1: + resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + dev: false + + /@stablelib/x25519@1.0.3: + resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} + dependencies: + '@stablelib/keyagreement': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/wipe': 1.0.1 + dev: false + + /@tronweb3/google-protobuf@3.21.2: + resolution: {integrity: sha512-IVcT2GfWX3K6tHUVhs14NP5uzKhQt4KeDya1g9ACxuZsUzsaoGUIGzceK2Ltu7xp1YV94AaHOf4yxLAivlvEkQ==} + dev: false + + /@tronweb3/tronwallet-abstract-adapter@1.1.6: + resolution: {integrity: sha512-3T2ojxzSKIAw4ucEcg4p5Nwr4lN1g1Om8s1ty77DOHIa0oS1YDvZmlRQekptWEppKOoRDYFWST1ERCvt2Xxm0A==} + engines: {node: '>=16', pnpm: '>=7'} + dependencies: + eventemitter3: 4.0.7 + + /@tronweb3/tronwallet-adapter-bitkeep@1.1.1: + resolution: {integrity: sha512-Ny3I9ePL0R/oH2YjN7c+LTnCTPBe6SQDA3uyHYDWuH8R6Kdp8/t2n8sChDlu1NBQCUF3pt6THHQEUoXJkmjfJA==} + engines: {node: '>=16', pnpm: '>=7'} + dependencies: + '@bitget-wallet/web3-sdk': 0.0.8 + '@tronweb3/tronwallet-abstract-adapter': 1.1.6 + '@tronweb3/tronwallet-adapter-tronlink': 1.1.9 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@tronweb3/tronwallet-adapter-okxwallet@1.0.3: + resolution: {integrity: sha512-43suyRr/RuJCueRaspSlNKxd0rMt/2VTmq5tkRF/WlxGI4CTEIEYk3NqdKBrVFobfsILOXQBiQg0cI+FF5lxtw==} + engines: {node: '>=16', pnpm: '>=7'} + dependencies: + '@tronweb3/tronwallet-abstract-adapter': 1.1.6 + '@tronweb3/tronwallet-adapter-tronlink': 1.1.9 + dev: false + + /@tronweb3/tronwallet-adapter-tokenpocket@1.0.3: + resolution: {integrity: sha512-vG1JLnlH0fodTY2YdezzWJKeW2VkCERsJYTa6d9oId1dgOaiEvjIO9UbHL/kdTPs1L1M484tM6Rh6pPBJzh/gA==} + engines: {node: '>=16', pnpm: '>=7'} + dependencies: + '@tronweb3/tronwallet-abstract-adapter': 1.1.6 + '@tronweb3/tronwallet-adapter-tronlink': 1.1.9 + dev: false + + /@tronweb3/tronwallet-adapter-tronlink@1.1.9: + resolution: {integrity: sha512-fIDKt822OmESLVeYCG9XbXGI34lM/79/jzJ3rd81xOZD8y7V0/DuDLdg5gFiCH4g9OIutKslDXiwoMpQry9O3w==} + engines: {node: '>=16', pnpm: '>=7'} + dependencies: + '@tronweb3/tronwallet-abstract-adapter': 1.1.6 + dev: false + + /@types/argparse@1.0.38: + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + dev: false + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.12.7 + dev: false + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@18.15.13: + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + dev: false + + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 20.12.7 + dev: false + + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + dependencies: + '@types/node': 20.12.7 + dev: false + + /@volar/language-core@1.11.1: + resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + dependencies: + '@volar/source-map': 1.11.1 + dev: false + + /@volar/source-map@1.11.1: + resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + dependencies: + muggle-string: 0.3.1 + dev: false + + /@volar/typescript@1.11.1: + resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + dependencies: + '@volar/language-core': 1.11.1 + path-browserify: 1.0.1 + dev: false + + /@vue/compiler-core@3.4.26: + resolution: {integrity: sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==} + dependencies: + '@babel/parser': 7.24.5 + '@vue/shared': 3.4.26 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + dev: false + + /@vue/compiler-dom@3.4.26: + resolution: {integrity: sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==} + dependencies: + '@vue/compiler-core': 3.4.26 + '@vue/shared': 3.4.26 + dev: false + + /@vue/language-core@1.8.27(typescript@5.4.5): + resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@volar/language-core': 1.11.1 + '@volar/source-map': 1.11.1 + '@vue/compiler-dom': 3.4.26 + '@vue/shared': 3.4.26 + computeds: 0.0.1 + minimatch: 9.0.4 + muggle-string: 0.3.1 + path-browserify: 1.0.1 + typescript: 5.4.5 + vue-template-compiler: 2.7.16 + dev: false + + /@vue/shared@3.4.26: + resolution: {integrity: sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==} + dev: false + + /@walletconnect/core@2.12.2: + resolution: {integrity: sha512-7Adv/b3pp9F42BkvReaaM4KS8NEvlkS7AMtwO3uF/o6aRMKtcfTJq9/jgWdKJh4RP8pPRTRFjCw6XQ/RZtT4aQ==} + dependencies: + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.14 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.10 + '@walletconnect/relay-auth': 1.0.4 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + isomorphic-unfetch: 3.1.0 + lodash.isequal: 4.5.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/encoding@1.0.2: + resolution: {integrity: sha512-CrwSBrjqJ7rpGQcTL3kU+Ief+Bcuu9PH6JLOb+wM6NITX1GTxR/MfNwnQfhLKK6xpRAyj2/nM04OOH6wS8Imag==} + dependencies: + is-typedarray: 1.0.0 + tslib: 1.14.1 + typedarray-to-buffer: 3.1.5 + dev: false + + /@walletconnect/environment@1.0.1: + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/events@1.0.1: + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + dev: false + + /@walletconnect/heartbeat@1.2.1: + resolution: {integrity: sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q==} + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-provider@1.0.13: + resolution: {integrity: sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g==} + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-types@1.0.3: + resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-utils@1.0.8: + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.3 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-ws-connection@1.0.14: + resolution: {integrity: sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA==} + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@walletconnect/keyvaluestorage@1.1.1: + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.1 + unstorage: 1.10.2(idb-keyval@6.2.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/legacy-modal@2.0.0: + resolution: {integrity: sha512-jckNd8lMhm4X7dX9TDdxM3bXKJnaqkRs6K2Mo5j6GmbIF9Eyx40jZ5+q457RVxvM6ciZEDT5s1wBHWdWoOo+9Q==} + dependencies: + '@walletconnect/legacy-types': 2.0.0 + '@walletconnect/legacy-utils': 2.0.0 + copy-to-clipboard: 3.3.3 + preact: 10.21.0 + qrcode: 1.5.3 + dev: false + + /@walletconnect/legacy-types@2.0.0: + resolution: {integrity: sha512-sOVrA7HUdbI1OwKyPOQU0/DdvTSVFlsXWpAk2K2WvP2erTkBWPMTJq6cv2BmKdoJ3p6gLApT7sd+jHi3OF71uw==} + dependencies: + '@walletconnect/jsonrpc-types': 1.0.3 + dev: false + + /@walletconnect/legacy-utils@2.0.0: + resolution: {integrity: sha512-CPWxSVVXw0kgNCxvU126g4GiV3mzXmC8IPJ15twE46aJ1FX+RHEIfAzFMFz2F2+fEhBxL63A7dwNQKDXorRPcQ==} + dependencies: + '@walletconnect/encoding': 1.0.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/legacy-types': 2.0.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + detect-browser: 5.3.0 + query-string: 6.14.1 + dev: false + + /@walletconnect/logger@2.1.2: + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + dev: false + + /@walletconnect/relay-api@1.0.10: + resolution: {integrity: sha512-tqrdd4zU9VBNqUaXXQASaexklv6A54yEyQQEXYOCr+Jz8Ket0dmPBDyg19LVSNUN2cipAghQc45/KVmfFJ0cYw==} + dependencies: + '@walletconnect/jsonrpc-types': 1.0.3 + dev: false + + /@walletconnect/relay-auth@1.0.4: + resolution: {integrity: sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ==} + dependencies: + '@stablelib/ed25519': 1.0.3 + '@stablelib/random': 1.0.2 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + uint8arrays: 3.1.1 + dev: false + + /@walletconnect/safe-json@1.0.2: + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/sign-client@2.12.2: + resolution: {integrity: sha512-cM0ualXj6nVvLqS4BDNRk+ZWR+lubcsz/IHreH+3wYrQ2sV+C0fN6ctrd7MMGZss0C0qacWCx0pm62ZBuoKvqA==} + dependencies: + '@walletconnect/core': 2.12.2 + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/time@1.0.2: + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/types@2.12.2: + resolution: {integrity: sha512-9CmwTlPbrFTzayTL9q7xM7s3KTJkS6kYFtH2m1/fHFgALs6pIUjf1qAx1TF2E4tv7SEzLAIzU4NqgYUt2vWXTg==} + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/utils@2.12.2: + resolution: {integrity: sha512-zf50HeS3SfoLv1N9GPl2IXTZ9TsXfet4usVAsZmX9P6/Xzq7d/7QakjVQCHH/Wk1O9XkcsfeoZoUhRxoMJ5uJw==} + dependencies: + '@stablelib/chacha20poly1305': 1.0.1 + '@stablelib/hkdf': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/sha256': 1.0.1 + '@stablelib/x25519': 1.0.3 + '@walletconnect/relay-api': 1.0.10 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/window-getters@1.0.1: + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/window-metadata@1.0.1: + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + dev: false + + /aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: false + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: false + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: false + + /axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + dependencies: + follow-redirects: 1.15.6 + transitivePeerDependencies: + - debug + dev: false + + /axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: false + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + dev: false + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + dev: false + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: false + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: false + + /brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + dev: false + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.8.1 + dev: false + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + dev: false + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: false + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + dependencies: + consola: 3.2.3 + dev: false + + /clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} + engines: {node: '>=18'} + dependencies: + execa: 8.0.1 + is-wsl: 3.1.0 + is64bit: 2.0.0 + dev: false + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + requiresBuild: true + dev: false + optional: true + + /computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: false + + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + dev: false + + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: false + + /cookie-es@1.1.0: + resolution: {integrity: sha512-L2rLOcK0wzWSfSDA33YR+PUHDG10a8px7rUHKWbGLP4YfbsMed2KFUw5fczvDPbT98DDe3LEzviswl810apTEw==} + dev: false + + /copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + dependencies: + toggle-selection: 1.0.6 + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: false + + /crossws@0.2.4: + resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} + peerDependencies: + uWebSockets.js: '*' + peerDependenciesMeta: + uWebSockets.js: + optional: true + dev: false + + /de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: false + + /decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + dev: false + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: false + + /defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + dev: false + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + dev: false + + /detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + dev: false + + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + dev: false + + /dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dev: false + + /duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + dev: false + + /elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + dev: false + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: false + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + + /ethereum-cryptography@2.1.3: + resolution: {integrity: sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 + dev: false + + /ethers@4.0.49: + resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==} + dependencies: + aes-js: 3.0.0 + bn.js: 4.12.0 + elliptic: 6.5.4 + hash.js: 1.1.3 + js-sha3: 0.5.7 + scrypt-js: 2.0.4 + setimmediate: 1.0.4 + uuid: 2.0.1 + xmlhttprequest: 1.8.0 + dev: false + + /ethers@6.12.1: + resolution: {integrity: sha512-j6wcVoZf06nqEcBbDWkKg8Fp895SS96dSnTCjiXT+8vt2o02raTn4Lo9ERUuIVU5bAjoPYeA+7ytQFexFmLuVw==} + engines: {node: '>=14.0.0'} + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /eventemitter3@3.1.2: + resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==} + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: false + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: false + + /fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: false + + /filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + dev: false + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: false + + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: false + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + dev: false + + /get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + dev: false + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: false + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: false + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: false + + /h3@1.11.1: + resolution: {integrity: sha512-AbaH6IDnZN6nmbnJOH72y3c5Wwh9P97soSVdGSBbcDACRdkC0FEWf25pzx4f/NuOCK6quHmW18yF2Wx+G4Zi1A==} + dependencies: + cookie-es: 1.1.0 + crossws: 0.2.4 + defu: 6.1.4 + destr: 2.0.3 + iron-webcrypto: 1.1.1 + ohash: 1.1.3 + radix3: 1.1.2 + ufo: 1.5.3 + uncrypto: 0.1.3 + unenv: 1.9.0 + transitivePeerDependencies: + - uWebSockets.js + dev: false + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: false + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: false + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: false + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: false + + /hash.js@1.1.3: + resolution: {integrity: sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: false + + /hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: false + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: false + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: false + + /hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: false + + /http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: false + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /injectpromise@1.0.0: + resolution: {integrity: sha512-qNq5wy4qX4uWHcVFOEU+RqZkoVG65FhvGkyDWbuBxILMjK6A1LFf5A1mgXZkD4nRx5FCorD81X/XvPKp/zVfPA==} + dev: false + + /iron-webcrypto@1.1.1: + resolution: {integrity: sha512-5xGwQUWHQSy039rFr+5q/zOmj7GP0Ypzvo34Ep+61bPIhaLduEDp/PvLGlU3awD2mzWUR0weN2vJ1mILydFPEg==} + dev: false + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: false + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + dev: false + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: false + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 + dev: false + + /is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dev: false + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: false + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: false + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: false + + /is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + dependencies: + is-docker: 3.0.0 + dev: false + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: false + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.15 + dev: false + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: false + + /is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + dependencies: + is-inside-container: 1.0.0 + dev: false + + /is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} + dependencies: + system-architecture: 0.1.0 + dev: false + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: false + + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + dependencies: + node-fetch: 2.7.0 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + dev: false + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: false + + /jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + dev: false + + /js-sha3@0.5.7: + resolution: {integrity: sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==} + dev: false + + /js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + dev: false + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + dev: false + + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: false + + /listhen@1.7.2: + resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} + hasBin: true + dependencies: + '@parcel/watcher': 2.4.1 + '@parcel/watcher-wasm': 2.4.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.2.3 + crossws: 0.2.4 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.11.1 + http-shutdown: 1.2.2 + jiti: 1.21.0 + mlly: 1.7.0 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.7.0 + ufo: 1.5.3 + untun: 0.1.3 + uqr: 0.1.2 + transitivePeerDependencies: + - uWebSockets.js + dev: false + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: false + + /lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + dev: false + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: false + + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: false + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: false + + /minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: false + + /minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + dev: false + + /minimatch@3.0.8: + resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} + dependencies: + brace-expansion: 1.1.11 + dev: false + + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /mlly@1.7.0: + resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.0 + ufo: 1.5.3 + dev: false + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /muggle-string@0.3.1: + resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + dev: false + + /multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + dev: false + + /node-addon-api@7.1.0: + resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==} + engines: {node: ^16 || ^18 || >= 20} + dev: false + + /node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: false + + /node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + requiresBuild: true + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: false + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: false + + /ofetch@1.3.4: + resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.3 + dev: false + + /ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + dev: false + + /on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: false + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: false + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: false + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: false + + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: false + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: false + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: false + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: false + + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: false + + /pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + dev: false + + /pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + dev: false + + /pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + dev: false + + /pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} + dependencies: + confbox: 0.1.7 + mlly: 1.7.0 + pathe: 1.1.2 + dev: false + + /pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + dev: false + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: false + + /preact@10.21.0: + resolution: {integrity: sha512-aQAIxtzWEwH8ou+OovWVSVNlFImL7xUCwJX3YMqA3U8iKCNC34999fFOnWjYNsylgfPgMexpbk7WYOLtKr/mxg==} + dev: false + + /process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: false + + /qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + dev: false + + /query-string@6.14.1: + resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} + engines: {node: '>=6'} + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + dev: false + + /query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + dev: false + + /querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + dev: false + + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + + /radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + dev: false + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: false + + /real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + dev: false + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: false + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: false + + /resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + dev: false + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: false + + /rpc-websockets@7.10.0: + resolution: {integrity: sha512-cemZ6RiDtYZpPiBzYijdOrkQQzmBCmug0E9SdRH2gIUNT15ql4mwCYWIp0VnSZq6Qrw/JkGUygp4PrK1y9KfwQ==} + dependencies: + '@babel/runtime': 7.24.5 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + + /scrypt-js@2.0.4: + resolution: {integrity: sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==} + dev: false + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + dev: false + + /setimmediate@1.0.4: + resolution: {integrity: sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==} + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: false + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: false + + /sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: false + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: false + + /split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + dev: false + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: false + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: false + + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: false + + /stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + dev: false + + /strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + dev: false + + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: false + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: false + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: false + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + dependencies: + real-require: 0.1.0 + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: false + + /toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /tronweb@5.3.2: + resolution: {integrity: sha512-iPcIjMCxb6H7FXMntAj47F3L+7jSideyQ7ZOvRj9MeZBh46SHevMrDDR57HzakUa/tT8VvlPFHtqFK4hzTLkXw==} + dependencies: + '@babel/runtime': 7.24.5 + '@ethersproject/abi': 5.7.0 + '@tronweb3/google-protobuf': 3.21.2 + axios: 1.6.8 + bignumber.js: 9.1.2 + ethereum-cryptography: 2.1.3 + ethers: 6.12.1 + eventemitter3: 3.1.2 + injectpromise: 1.0.0 + lodash: 4.17.21 + querystring-es3: 0.2.1 + semver: 5.7.2 + validator: 13.11.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + dev: false + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: false + + /tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: false + + /typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + dev: false + + /uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + dependencies: + multiformats: 9.9.0 + dev: false + + /uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + dev: false + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + + /unenv@1.9.0: + resolution: {integrity: sha512-QKnFNznRxmbOF1hDgzpqrlIf6NC5sbZ2OJ+5Wl3OX8uM+LUJXbj4TXvLJCtwbPTmbMHCLIz6JLKNinNsMShK9g==} + dependencies: + consola: 3.2.3 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.4 + pathe: 1.1.2 + dev: false + + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + dev: false + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: false + + /unstorage@1.10.2(idb-keyval@6.2.1): + resolution: {integrity: sha512-cULBcwDqrS8UhlIysUJs2Dk0Mmt8h7B0E6mtR+relW9nZvsf/u4SkAYyNliPiPW7XtFNb5u3IUMkxGxFTTRTgQ==} + peerDependencies: + '@azure/app-configuration': ^1.5.0 + '@azure/cosmos': ^4.0.0 + '@azure/data-tables': ^13.2.2 + '@azure/identity': ^4.0.1 + '@azure/keyvault-secrets': ^4.8.0 + '@azure/storage-blob': ^12.17.0 + '@capacitor/preferences': ^5.0.7 + '@netlify/blobs': ^6.5.0 || ^7.0.0 + '@planetscale/database': ^1.16.0 + '@upstash/redis': ^1.28.4 + '@vercel/kv': ^1.0.1 + idb-keyval: ^6.2.1 + ioredis: ^5.3.2 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/kv': + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + dependencies: + anymatch: 3.1.3 + chokidar: 3.6.0 + destr: 2.0.3 + h3: 1.11.1 + idb-keyval: 6.2.1 + listhen: 1.7.2 + lru-cache: 10.2.2 + mri: 1.2.0 + node-fetch-native: 1.6.4 + ofetch: 1.3.4 + ufo: 1.5.3 + transitivePeerDependencies: + - uWebSockets.js + dev: false + + /untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + dependencies: + citty: 0.1.6 + consola: 3.2.3 + pathe: 1.1.2 + dev: false + + /uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + dev: false + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: false + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.8.1 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + dev: false + + /uuid@2.0.1: + resolution: {integrity: sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + engines: {node: '>= 0.10'} + dev: false + + /vite-plugin-dts@3.9.0(typescript@5.4.5): + resolution: {integrity: sha512-pwFIEYQ3LZvMafkEGvNnileb6af5JuyZsBfYQrTDYxdeGEy0OS4B4hCsLPo5YGnhK5k9EzyO6BXVO6y+Lt5T2A==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + '@microsoft/api-extractor': 7.43.0 + '@rollup/pluginutils': 5.1.0 + '@vue/language-core': 1.8.27(typescript@5.4.5) + debug: 4.3.4 + kolorist: 1.8.0 + magic-string: 0.30.10 + typescript: 5.4.5 + vue-tsc: 1.8.27(typescript@5.4.5) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + dev: false + + /vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + dev: false + + /vue-tsc@1.8.27(typescript@5.4.5): + resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} + hasBin: true + peerDependencies: + typescript: '*' + dependencies: + '@volar/typescript': 1.11.1 + '@vue/language-core': 1.8.27(typescript@5.4.5) + semver: 7.6.0 + typescript: 5.4.5 + dev: false + + /web3-errors@1.1.4: + resolution: {integrity: sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + dependencies: + web3-types: 1.5.0 + dev: false + + /web3-types@1.5.0: + resolution: {integrity: sha512-geWuMIeegQ8AedKAO6wO4G4j1gyQ1F/AyKLMw2vud4bsfZayyzWJgCMDZtjYMm5uo2a7i8j1W3/4QFmzlSy5cw==} + engines: {node: '>=14', npm: '>=6.12.0'} + dev: false + + /web3-utils@4.2.1: + resolution: {integrity: sha512-Fk29BlEqD9Q9Cnw4pBkKw7czcXiRpsSco/BzEUl4ye0ZTSHANQFfjsfQmNm4t7uY11u6Ah+8F3tNjBeU4CA80A==} + engines: {node: '>=14', npm: '>=6.12.0'} + dependencies: + ethereum-cryptography: 2.1.3 + eventemitter3: 5.0.1 + web3-errors: 1.1.4 + web3-types: 1.5.0 + web3-validator: 2.0.4 + dev: false + + /web3-validator@2.0.4: + resolution: {integrity: sha512-qRxVePwdW+SByOmTpDZFWHIUAa7PswvxNszrOua6BoGqAhERo5oJZBN+EbWtK/+O+ApNxt5FR3nCPmiZldiOQA==} + engines: {node: '>=14', npm: '>=6.12.0'} + dependencies: + ethereum-cryptography: 2.1.3 + util: 0.12.5 + web3-errors: 1.1.4 + web3-types: 1.5.0 + zod: 3.22.4 + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: false + + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: false + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: false + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /ws@8.5.0: + resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /xmlhttprequest@1.8.0: + resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} + engines: {node: '>=0.4.0'} + dev: false + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: false + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: false + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: false + + /z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.11.0 + optionalDependencies: + commander: 9.5.0 + dev: false + + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: false diff --git a/packages/networks/tron/resources/TRC1155.json b/packages/networks/tron/resources/TRC1155.json new file mode 100644 index 0000000..6bd090d --- /dev/null +++ b/packages/networks/tron/resources/TRC1155.json @@ -0,0 +1,514 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC1155InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC1155InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idsLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "valuesLength", + "type": "uint256" + } + ], + "name": "ERC1155InvalidArrayLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "ERC1155InvalidOperator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC1155InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC1155InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC1155MissingApprovalForAll", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newuri", + "type": "string" + } + ], + "name": "setURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/networks/tron/resources/TRC20.json b/packages/networks/tron/resources/TRC20.json new file mode 100644 index 0000000..7085ecf --- /dev/null +++ b/packages/networks/tron/resources/TRC20.json @@ -0,0 +1,525 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ERC2612ExpiredSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC2612InvalidSigner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentNonce", + "type": "uint256" + } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidShortString", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "str", + "type": "string" + } + ], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/networks/tron/resources/TRC721.json b/packages/networks/tron/resources/TRC721.json new file mode 100644 index 0000000..7151efa --- /dev/null +++ b/packages/networks/tron/resources/TRC721.json @@ -0,0 +1,440 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC721IncorrectOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721InsufficientApproval", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC721InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "ERC721InvalidOperator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC721InvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC721InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC721InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721NonexistentToken", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/networks/tron/src/assets/Coin.ts b/packages/networks/tron/src/assets/Coin.ts new file mode 100644 index 0000000..5e791ce --- /dev/null +++ b/packages/networks/tron/src/assets/Coin.ts @@ -0,0 +1,81 @@ +import { Provider } from '../services/Provider.ts' +import { CoinTransactionSigner, type TransactionData } from '../services/TransactionSigner.ts' +import { ErrorTypeEnum, type CoinInterface } from '@multiplechain/types' + +export class Coin implements CoinInterface { + /** + * Blockchain network provider + */ + provider: Provider + + /** + * @param {Provider} provider network provider + */ + constructor(provider?: Provider) { + this.provider = provider ?? Provider.instance + } + + /** + * @returns {string} Coin name + */ + getName(): string { + return 'Tron' + } + + /** + * @returns {string} Coin symbol + */ + getSymbol(): string { + return 'TRX' + } + + /** + * @returns {number} Decimal value of the coin + */ + getDecimals(): number { + return 6 + } + + /** + * @param {string} owner Wallet address + * @returns {Promise} Wallet balance as currency of COIN + */ + async getBalance(owner: string): Promise { + const balance = await this.provider.tronWeb.trx.getBalance(owner) + return parseFloat(this.provider.tronWeb.fromSun(balance) as unknown as string) + } + + /** + * @param {string} sender Sender wallet address + * @param {string} receiver Receiver wallet address + * @param {number} amount Amount of assets that will be transferred + * @returns {Promise} Transaction signer + */ + async transfer( + sender: string, + receiver: string, + amount: number + ): Promise { + if (amount < 0) { + throw new Error(ErrorTypeEnum.INVALID_AMOUNT) + } + + if (amount > (await this.getBalance(sender))) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + if (sender === receiver) { + throw new Error(ErrorTypeEnum.INVALID_ADDRESS) + } + + const sunFormat = this.provider.tronWeb.toSun(amount) + + return new CoinTransactionSigner( + (await this.provider.tronWeb.transactionBuilder.sendTrx( + receiver, + sunFormat, + sender + )) as TransactionData + ) + } +} diff --git a/packages/networks/tron/src/assets/Contract.ts b/packages/networks/tron/src/assets/Contract.ts new file mode 100644 index 0000000..8bcc2ae --- /dev/null +++ b/packages/networks/tron/src/assets/Contract.ts @@ -0,0 +1,178 @@ +import { Provider } from '../services/Provider.ts' +import type { ContractInterface } from '@multiplechain/types' +import type { TronWeb } from '../services/TronWeb.ts' + +interface InputOutputInterface { + internalType: string + name: string + type: string +} + +interface FunctionInterface { + type: string + name?: string + indexed?: boolean + payable?: boolean + constant?: boolean + anonymous?: boolean + stateMutability?: string + inputs: InputOutputInterface[] + outputs?: InputOutputInterface[] +} + +export type InterfaceAbi = FunctionInterface[] + +type TronContract = Record { call: () => any }> + +export interface TransactionDataOptions { + feeLimit?: number + callValue?: number + tokenValue?: number + tokenId?: number +} + +export type TransactionDataParameters = ReadonlyArray<{ + type: string + value: string | number +}> + +export interface TransactionRawData { + address: string + method: string + options: TransactionDataOptions + parameters: TransactionDataParameters + from: string +} + +export class Contract implements ContractInterface { + /** + * Contract address + */ + address: string + + /** + * Blockchain network provider + */ + provider: Provider + + /** + * Contract ABI + */ + ABI: InterfaceAbi + + /** + * TronWeb service + */ + tronWeb: TronWeb + + /** + * Tron contract + */ + tronContract: TronContract + + /** + * @param {string} address Contract address + * @param {Provider} provider Blockchain network provider + * @param {InterfaceAbi} ABI Contract ABI + */ + constructor(address: string, provider?: Provider, ABI?: InterfaceAbi) { + this.ABI = ABI ?? [] + this.address = address + this.provider = provider ?? Provider.instance + this.tronWeb = this.provider.tronWeb + } + + /** + * @returns {Promise} Set Tron contract + */ + async setTronContract(): Promise { + if (this.tronContract !== undefined) return + this.tronWeb.setAddress(this.address) + this.tronContract = await this.tronWeb.contract(this.ABI).at(this.address) + } + + /** + * @returns {string} Contract address + */ + getAddress(): string { + return this.address + } + + /** + * @param {string} method Method name + * @param {any[]} args Method parameters + * @returns {Promise} Method result + */ + async callMethod(method: string, ...args: any[]): Promise { + await this.setTronContract() + return this.tronContract[method](...args).call() // eslint-disable-line + } + + /** + * @param {string} _method Method name + * @param {any[]} _args Sender wallet address + * @returns {Promise} Encoded method data + */ + async getMethodData(_method: string, ..._args: any[]): Promise { + throw new Error('Method not implemented.') + } + + /** + * @param {string} method Method name + * @returns {string} Method output + */ + generateFunction(method: string): string { + const matchedItem = this.ABI.find((func: FunctionInterface) => func.name === method) + if (matchedItem !== undefined) { + let output = matchedItem.name + '(' + const inputs = matchedItem.inputs ?? [] + inputs.forEach((input, index) => { + if (index > 0) { + output += ',' + } + output += input.type + }) + output += ')' + return output + } else { + return 'No matching function found.' + } + } + + generateParameters(method: string, ...args: any[]): any { + const matchedItem = this.ABI.find((func: FunctionInterface) => func.name === method) + if (matchedItem !== undefined) { + const inputs = matchedItem.inputs ?? [] + const parameters = [] as any[] + inputs.forEach((input, index) => { + parameters.push({ + type: input.type, + value: args[index] + }) + }) + return parameters + } else { + return 'No matching function found.' + } + } + + /** + * @param {string} method Method name + * @param {string} from Sender wallet address + * @param {any[]} args Method parameters + * @returns {Promise} Encoded method data + */ + async createTransactionData( + method: string, + from: string, + ...args: any[] + ): Promise { + return { + address: this.address, + method: this.generateFunction(method), + options: {}, + parameters: this.generateParameters(method, ...args), // eslint-disable-line + from + } + } +} diff --git a/packages/networks/tron/src/assets/NFT.ts b/packages/networks/tron/src/assets/NFT.ts new file mode 100644 index 0000000..f2fb446 --- /dev/null +++ b/packages/networks/tron/src/assets/NFT.ts @@ -0,0 +1,169 @@ +import TRC721 from '../../resources/TRC721.json' +import type { Provider } from '../services/Provider.ts' +import { Contract, type InterfaceAbi } from './Contract.ts' +import { NftTransactionSigner } from '../services/TransactionSigner.ts' +import { ErrorTypeEnum, type NftInterface } from '@multiplechain/types' + +export class NFT extends Contract implements NftInterface { + /** + * @param {string} address Contract address + * @param {Provider} provider Blockchain network provider + * @param {InterfaceAbi} ABI Contract ABI + */ + constructor(address: string, provider?: Provider, ABI?: InterfaceAbi) { + super(address, provider, ABI ?? TRC721) + } + + /** + * @returns {Promise} NFT name + */ + async getName(): Promise { + return await this.callMethod('name') + } + + /** + * @returns {Promise} NFT symbol + */ + async getSymbol(): Promise { + return await this.callMethod('symbol') + } + + /** + * @param {string} owner Wallet address + * @returns {Promise} Wallet balance as currency of NFT + */ + async getBalance(owner: string): Promise { + return Number(await this.callMethod('balanceOf', owner)) + } + + /** + * @param {number | string} nftId NFT ID + * @returns {Promise} Wallet address of the owner of the NFT + */ + async getOwner(nftId: number | string): Promise { + return this.provider.tronWeb.address.fromHex(await this.callMethod('ownerOf', nftId)) + } + + /** + * @param {number | string} nftId NFT ID + * @returns {Promise} URI of the NFT + */ + async getTokenURI(nftId: number | string): Promise { + return await this.callMethod('tokenURI', nftId) + } + + /** + * @param {number | string} nftId ID of the NFT that will be transferred + * @returns {Promise} Wallet address of the approved spender + */ + async getApproved(nftId: number | string): Promise { + const address = await this.callMethod('getApproved', nftId) + if (address !== '410000000000000000000000000000000000000000') { + return this.provider.tronWeb.address.fromHex(address) + } + return null + } + + /** + * @param {string} sender Sender address + * @param {string} receiver Receiver address + * @param {number | string} nftId NFT ID + * @returns {Promise} Transaction signer + */ + async transfer( + sender: string, + receiver: string, + nftId: number | string + ): Promise { + return await this.transferFrom(sender, sender, receiver, nftId) + } + + /** + * @param {string} spender Spender address + * @param {string} owner Owner address + * @param {string} receiver Receiver address + * @param {number | string} nftId NFT ID + * @returns {Promise} Transaction signer + */ + async transferFrom( + spender: string, + owner: string, + receiver: string, + nftId: number | string + ): Promise { + const balance = await this.getBalance(owner) + + if (balance <= 0) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + // Check ownership + const originalOwner = await this.getOwner(nftId) + if (originalOwner !== owner) { + throw new Error(ErrorTypeEnum.UNAUTHORIZED_ADDRESS) + } + + // check if spender different from owner + if (spender !== owner) { + const approved = await this.getApproved(nftId) + if (approved !== spender) { + throw new Error(ErrorTypeEnum.UNAUTHORIZED_ADDRESS) + } + } + + const data = await this.createTransactionData( + 'transferFrom', + spender, + owner, + receiver, + nftId + ) + + data.options.feeLimit = 100000000 + + const result = await this.provider.tronWeb.triggerContract(data) + + if (result === false) { + throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + } + + return new NftTransactionSigner(result) + } + + /** + * Gives permission to the spender to spend owner's tokens + * @param {string} owner Address of owner of the tokens that will be used + * @param {string} spender Address of the spender that will use the tokens of owner + * @param {number | string} nftId ID of the NFT that will be transferred + * @returns {Promise} Transaction signer + */ + async approve( + owner: string, + spender: string, + nftId: number | string + ): Promise { + // Check if tokens exist + const balance = await this.getBalance(owner) + + if (balance <= 0) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + // Check ownership + const originalOwner = await this.getOwner(nftId) + if (originalOwner !== owner) { + throw new Error(ErrorTypeEnum.UNAUTHORIZED_ADDRESS) + } + + const data = await this.createTransactionData('approve', owner, spender, nftId) + data.options.feeLimit = 100000000 + + const result = await this.provider.tronWeb.triggerContract(data) + + if (result === false) { + throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + } + + return new NftTransactionSigner(result) + } +} diff --git a/packages/networks/tron/src/assets/Token.ts b/packages/networks/tron/src/assets/Token.ts new file mode 100644 index 0000000..975ae51 --- /dev/null +++ b/packages/networks/tron/src/assets/Token.ts @@ -0,0 +1,196 @@ +import { Contract, type InterfaceAbi } from './Contract.ts' +import { TokenTransactionSigner } from '../services/TransactionSigner.ts' +import { ErrorTypeEnum, type TokenInterface } from '@multiplechain/types' +import { hexToNumber, numberToHex } from '@multiplechain/utils' +import type { Provider } from '../services/Provider.ts' +import TRC20 from '../../resources/TRC20.json' + +export class Token extends Contract implements TokenInterface { + /** + * @param {string} address Contract address + * @param {Provider} provider Blockchain network provider + * @param {InterfaceAbi} ABI Contract ABI + */ + constructor(address: string, provider?: Provider, ABI?: InterfaceAbi) { + super(address, provider, ABI ?? TRC20) + } + + /** + * @returns {Promise} Token name + */ + async getName(): Promise { + return await this.callMethod('name') + } + + /** + * @returns {Promise} Token symbol + */ + async getSymbol(): Promise { + return await this.callMethod('symbol') + } + + /** + * @returns {Promise} Decimal value of the token + */ + async getDecimals(): Promise { + return await this.callMethod('decimals') + } + + /** + * @param {string} owner Wallet address + * @returns {Promise} Wallet balance as currency of TOKEN + */ + async getBalance(owner: string): Promise { + const [decimals, balance] = await Promise.all([ + this.getDecimals(), + this.callMethod('balanceOf', owner) + ]) + return hexToNumber(balance as string, decimals) + } + + /** + * @returns {Promise} Total supply of the token + */ + async getTotalSupply(): Promise { + const [decimals, totalSupply] = await Promise.all([ + this.getDecimals(), + this.callMethod('totalSupply') + ]) + return hexToNumber(totalSupply as string, decimals) + } + + /** + * @param {string} owner Address of owner of the tokens that is being used + * @param {string} spender Address of the spender that is using the tokens of owner + * @returns {Promise} Amount of tokens that the spender is allowed to spend + */ + async getAllowance(owner: string, spender: string): Promise { + const [decimals, allowance] = await Promise.all([ + this.getDecimals(), + await this.callMethod('allowance', owner, spender) + ]) + return hexToNumber(allowance as string, decimals) + } + + /** + * transfer() method is the main method for processing transfers for fungible assets (TOKEN, COIN) + * @param {string} sender Sender wallet address + * @param {string} receiver Receiver wallet address + * @param {number} amount Amount of assets that will be transferred + * @returns {Promise} Transaction signer + */ + async transfer( + sender: string, + receiver: string, + amount: number + ): Promise { + if (amount <= 0) { + throw new Error(ErrorTypeEnum.INVALID_AMOUNT) + } + + const balance = await this.getBalance(sender) + + if (amount > balance) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + const hexAmount = numberToHex(amount, await this.getDecimals()) + + const data = await this.createTransactionData('transfer', sender, receiver, hexAmount) + data.options.feeLimit = 100000000 + + const result = await this.provider.tronWeb.triggerContract(data) + + if (result === false) { + throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + } + + return new TokenTransactionSigner(result) + } + + /** + * @param {string} spender Address of the spender of transaction + * @param {string} owner Sender wallet address + * @param {string} receiver Receiver wallet address + * @param {number} amount Amount of tokens that will be transferred + * @returns {Promise} Transaction signer + */ + async transferFrom( + spender: string, + owner: string, + receiver: string, + amount: number + ): Promise { + if (amount < 0) { + throw new Error(ErrorTypeEnum.INVALID_AMOUNT) + } + + const balance = await this.getBalance(owner) + + if (amount > balance) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + const allowance = await this.getAllowance(owner, spender) + + if (allowance === 0) { + throw new Error(ErrorTypeEnum.UNAUTHORIZED_ADDRESS) + } + + if (amount > allowance) { + throw new Error(ErrorTypeEnum.INVALID_AMOUNT) + } + + const hexAmount = numberToHex(amount, await this.getDecimals()) + + const data = await this.createTransactionData( + 'transferFrom', + spender, + owner, + receiver, + hexAmount + ) + + data.options.feeLimit = 100000000 + + const result = await this.provider.tronWeb.triggerContract(data) + + if (result === false) { + throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + } + + return new TokenTransactionSigner(result) + } + + /** + * Gives permission to the spender to spend owner's tokens + * @param {string} owner Address of owner of the tokens that will be used + * @param {string} spender Address of the spender that will use the tokens of owner + * @param {number} amount Amount of the tokens that will be used + * @returns {Promise} Transaction signer + */ + async approve(owner: string, spender: string, amount: number): Promise { + if (amount < 0) { + throw new Error(ErrorTypeEnum.INVALID_AMOUNT) + } + + const balance = await this.getBalance(owner) + + if (amount > balance) { + throw new Error(ErrorTypeEnum.INSUFFICIENT_BALANCE) + } + + const hexAmount = numberToHex(amount, await this.getDecimals()) + + const data = await this.createTransactionData('approve', owner, spender, hexAmount) + data.options.feeLimit = 100000000 + + const result = await this.provider.tronWeb.triggerContract(data) + + if (result === false) { + throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + } + + return new TokenTransactionSigner(result) + } +} diff --git a/packages/networks/tron/src/assets/index.ts b/packages/networks/tron/src/assets/index.ts new file mode 100644 index 0000000..7ea522f --- /dev/null +++ b/packages/networks/tron/src/assets/index.ts @@ -0,0 +1,4 @@ +export * from './NFT.ts' +export * from './Coin.ts' +export * from './Token.ts' +export * from './Contract.ts' diff --git a/packages/networks/tron/src/browser/Wallet.ts b/packages/networks/tron/src/browser/Wallet.ts new file mode 100644 index 0000000..5cb8c47 --- /dev/null +++ b/packages/networks/tron/src/browser/Wallet.ts @@ -0,0 +1,216 @@ +import { + type WalletInterface, + type WalletAdapterInterface, + type WalletPlatformEnum, + type TransactionSignerInterface, + ErrorTypeEnum, + type ProviderInterface +} from '@multiplechain/types' +import { Provider } from '../services/Provider.ts' +import type { Adapter, AdapterEvents, Transaction } from '@tronweb3/tronwallet-abstract-adapter' + +export interface CustomAdapter extends Adapter { + network?: () => Promise +} + +const rejectMap = (error: any, reject: (a: any) => any): any => { + console.error('MultipleChain Tron Wallet Error:', error) + + const errorMessage = String(error.message ?? '') + + if (error === 'Cannot transfer TRX to the same account') { + return reject(new Error(ErrorTypeEnum.WALLET_CONNECTION_FAILED)) + } + + if (typeof error === 'object') { + if ( + error.name === 'WalletSignTransactionError' || + errorMessage.includes('Confirmation declined by user') || + errorMessage.includes('User rejected the request.') || + errorMessage.includes('The user rejected connection.') || + errorMessage.includes('Modal is closed.') || + errorMessage.includes('User canceled') || + errorMessage.includes('User rejected') + ) { + return reject(new Error(ErrorTypeEnum.WALLET_REQUEST_REJECTED)) + } else if (errorMessage.includes('The wallet is not found.')) { + return reject(new Error(ErrorTypeEnum.WALLET_CONNECTION_FAILED)) + } else if (errorMessage.includes('User disapproved requested chains')) { + return reject(new Error(ErrorTypeEnum.UNACCEPTED_CHAIN)) + } else if (errorMessage.includes('The QR window is closed.')) { + return reject(new Error(ErrorTypeEnum.CLOSED_WALLETCONNECT_MODAL)) + } + } + + return reject(error) +} + +export class Wallet implements WalletInterface { + adapter: WalletAdapterInterface + + walletProvider: CustomAdapter + + networkProvider: Provider + + /** + * @param {WalletAdapterInterface} adapter + */ + constructor(adapter: WalletAdapterInterface, provider?: Provider) { + this.adapter = adapter + this.networkProvider = provider ?? Provider.instance + } + + /** + * @returns {string} + */ + getId(): string { + return this.adapter.id + } + + /** + * @returns {string} + */ + getName(): string { + return this.adapter.name + } + + /** + * @returns {string} + */ + getIcon(): string { + return this.adapter.icon + } + + /** + * @returns {WalletPlatformEnum[]} + */ + getPlatforms(): WalletPlatformEnum[] { + return this.adapter.platforms + } + + /** + * @returns {string | undefined} + */ + getDownloadLink(): string | undefined { + return this.adapter.downloadLink + } + + /** + * @param {string} url + * @param {object} ops + * @returns {string} + */ + createDeepLink(url: string, ops?: object): string | null { + if (this.adapter.createDeepLink === undefined) { + return null + } + + return this.adapter.createDeepLink(url, ops) + } + + /** + * @param {ProviderInterface} provider + * @param {Object} ops + * @returns {Promise} + */ + async connect(provider?: ProviderInterface, ops?: object): Promise { + return await new Promise((resolve, reject) => { + this.adapter + .connect(provider, ops) + .then(async (provider) => { + this.walletProvider = provider as CustomAdapter + + if ( + this.walletProvider.network !== undefined && + this.networkProvider.node.id !== + (await this.walletProvider.network()).chainId + ) { + reject(ErrorTypeEnum.UNACCEPTED_CHAIN) + return + } + + resolve(await this.getAddress()) + }) + .catch((error) => { + const customReject = (error: any): void => { + if (error.message === ErrorTypeEnum.WALLET_REQUEST_REJECTED) { + reject(new Error(ErrorTypeEnum.WALLET_CONNECT_REJECTED)) + } else { + reject(error) + } + } + rejectMap(error, customReject) + }) + }) + } + + /** + * @returns {boolean} + */ + async isDetected(): Promise { + return await this.adapter.isDetected() + } + + /** + * @returns {boolean} + */ + async isConnected(): Promise { + return await this.adapter.isConnected() + } + + /** + * @returns {Promise} + */ + async getChainId(): Promise { + return this.networkProvider.node.id + } + + /** + * @returns {Promise} + */ + async getAddress(): Promise { + return this.walletProvider.address ?? '' + } + + /** + * @param {string} message + */ + async signMessage(message: string): Promise { + return await new Promise((resolve, reject) => { + this.walletProvider + .signMessage(message) + .then((signature: string) => { + resolve(signature) + }) + .catch((error: any) => { + reject(error) + }) + }) + } + + /** + * @param {TransactionSignerInterface} transactionSigner + * @returns {Promise} + */ + async sendTransaction(transactionSigner: TransactionSignerInterface): Promise { + const signedTx = await this.walletProvider.signTransaction( + transactionSigner.getRawData() as Transaction + ) + const { transaction } = await this.networkProvider.tronWeb.trx.sendRawTransaction(signedTx) + if (transaction === undefined) throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + return transaction.txID as string + } + + /** + * @param {string} eventName + * @param {Function} callback + * @returns {void} + */ + on(eventName: string, callback: (...args: any[]) => void): void { + if (this.adapter?.provider?.on !== undefined) { + this.adapter.provider.on(eventName, callback) + } else { + this.walletProvider.on(eventName as keyof AdapterEvents, callback) + } + } +} diff --git a/packages/networks/tron/src/browser/adapters/BitgetWallet.ts b/packages/networks/tron/src/browser/adapters/BitgetWallet.ts new file mode 100644 index 0000000..51254a9 --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/BitgetWallet.ts @@ -0,0 +1,46 @@ +import type { CustomAdapter } from '../Wallet.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import { BitKeepAdapter } from '@tronweb3/tronwallet-adapter-bitkeep' +import type { ProviderInterface, WalletAdapterInterface } from '@multiplechain/types' + +const walletProvider = new BitKeepAdapter() + +declare global { + interface Window { + bitkeep?: { + tronLink?: boolean + } + } +} + +const BitgetWallet: WalletAdapterInterface = { + id: 'bitgetwallet', + name: 'BitgetWallet', + icon: walletProvider.icon, + provider: walletProvider, + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + downloadLink: 'https://web3.bitget.com/en/wallet-download?type=3', + createDeepLink(url: string): string { + return 'https://bkcode.vip?action=dapp&url=' + url + }, + isDetected: () => Boolean(window.bitkeep?.tronLink), + isConnected: () => Boolean(walletProvider.connected), + connect: async (_provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + try { + walletProvider + .connect() + .then(async () => { + resolve(walletProvider) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default BitgetWallet diff --git a/packages/networks/tron/src/browser/adapters/OkxWallet.ts b/packages/networks/tron/src/browser/adapters/OkxWallet.ts new file mode 100644 index 0000000..cb4d1e8 --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/OkxWallet.ts @@ -0,0 +1,38 @@ +import type { CustomAdapter } from '../Wallet.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import { OkxWalletAdapter } from '@tronweb3/tronwallet-adapter-okxwallet' +import type { ProviderInterface, WalletAdapterInterface } from '@multiplechain/types' + +const walletProvider = new OkxWalletAdapter() + +const OkxWallet: WalletAdapterInterface = { + id: 'okxwallet', + name: 'OkxWallet', + icon: walletProvider.icon, + provider: walletProvider, + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + downloadLink: 'https://www.okx.com/download', + createDeepLink(url: string): string { + return 'okx://wallet/dapp/details?dappUrl=' + url + }, + isDetected: () => Boolean(window.okxwallet?.tronLink), + isConnected: () => Boolean(walletProvider.connected), + connect: async (_provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + try { + walletProvider + .connect() + .then(async () => { + resolve(walletProvider as CustomAdapter) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default OkxWallet diff --git a/packages/networks/tron/src/browser/adapters/TokenPocket.ts b/packages/networks/tron/src/browser/adapters/TokenPocket.ts new file mode 100644 index 0000000..5d16381 --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/TokenPocket.ts @@ -0,0 +1,53 @@ +import type { CustomAdapter } from '../Wallet.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import { TokenPocketAdapter } from '@tronweb3/tronwallet-adapter-tokenpocket' +import type { ProviderInterface, WalletAdapterInterface } from '@multiplechain/types' + +const walletProvider = new TokenPocketAdapter() + +declare global { + interface Window { + tokenpocket?: { + tron: any + } + } +} + +const TokenPocket: WalletAdapterInterface = { + id: 'tokenpocket', + name: 'TokenPocket', + icon: walletProvider.icon, + provider: walletProvider, + platforms: [WalletPlatformEnum.MOBILE], + downloadLink: 'https://www.tokenpocket.pro/en/download/app', + createDeepLink(url: string): string { + return ( + 'tpdapp://open?params=' + + JSON.stringify({ + url, + chain: 'Tron', + source: url + }) + ) + }, + isDetected: () => Boolean(window.tokenpocket?.tron), + isConnected: () => Boolean(walletProvider.connected), + connect: async (_provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + try { + walletProvider + .connect() + .then(async () => { + resolve(walletProvider as CustomAdapter) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default TokenPocket diff --git a/packages/networks/tron/src/browser/adapters/TronLink.ts b/packages/networks/tron/src/browser/adapters/TronLink.ts new file mode 100644 index 0000000..2ce0a65 --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/TronLink.ts @@ -0,0 +1,53 @@ +import { sleep } from '@multiplechain/utils' +import type { CustomAdapter } from '../Wallet.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { Provider } from '../../services/Provider.ts' +import { TronLinkAdapter } from '@tronweb3/tronwallet-adapter-tronlink' +import type { ProviderInterface, WalletAdapterInterface } from '@multiplechain/types' + +const walletProvider = new TronLinkAdapter() + +const TronLink: WalletAdapterInterface = { + id: 'tronlink', + name: 'TronLink', + icon: walletProvider.icon, + provider: walletProvider, + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + downloadLink: 'https://www.tronlink.org/dlDetails/', + createDeepLink(url: string): string { + return ( + 'tronlinkoutside://pull.activity?param=' + + JSON.stringify({ + url, + action: 'open', + protocol: 'tronlink', + version: '1.0' + }) + ) + }, + isDetected: () => Boolean(window.tronLink), + isConnected: () => Boolean(walletProvider.connected), + connect: async (_provider?: ProviderInterface): Promise => { + const provider = _provider as Provider + return await new Promise((resolve, reject) => { + try { + walletProvider + .connect() + .then(async () => { + if (provider.node.id !== (await walletProvider.network()).chainId) { + await walletProvider.switchChain(provider.node.id) + } + await sleep(500) + resolve(walletProvider) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default TronLink diff --git a/packages/networks/tron/src/browser/adapters/WalletConnect.ts b/packages/networks/tron/src/browser/adapters/WalletConnect.ts new file mode 100644 index 0000000..2766b2f --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/WalletConnect.ts @@ -0,0 +1,95 @@ +import type { CustomAdapter } from '../Wallet.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import { WalletConnectAdapter } from '@multiplechain/tron-walletconnect' +import type { + ProviderInterface, + WalletAdapterInterface, + WalletConnectOps +} from '@multiplechain/types' + +const icon = + 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJiYXNpYyIgaWQ9IkxheWVyXzEiCgkgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAzODcuNiAyMzcuNiIKCSB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHBhdGggaWQ9IldhbGxldENvbm5lY3RfMDAwMDAwNzM3MDMwNjM0MzgyMjA2NDI3MzAwMDAwMDI5MTc3MTc1NTIyMzY0NzI0OTZfIiBmaWxsPSIjM0I5OUZDIiBkPSJNNzkuNCw0Ni40CgljNjMuMi02MS45LDE2NS43LTYxLjksMjI4LjksMGw3LjYsNy40YzMuMiwzLjEsMy4yLDguMSwwLDExLjJsLTI2LDI1LjVjLTEuNiwxLjUtNC4xLDEuNS01LjcsMGwtMTAuNS0xMC4zCgljLTQ0LjEtNDMuMi0xMTUuNi00My4yLTE1OS43LDBsLTExLjIsMTFjLTEuNiwxLjUtNC4xLDEuNS01LjcsMEw3MSw2NS44Yy0zLjItMy4xLTMuMi04LjEsMC0xMS4yTDc5LjQsNDYuNHogTTM2Mi4xLDk5LjFsMjMuMiwyMi43CgljMy4yLDMuMSwzLjIsOC4xLDAsMTEuMkwyODAuOCwyMzUuM2MtMy4yLDMuMS04LjMsMy4xLTExLjQsMGMwLDAsMCwwLDAsMGwtNzQuMS03Mi42Yy0wLjgtMC44LTIuMS0wLjgtMi45LDBjMCwwLDAsMCwwLDAKCWwtNzQuMSw3Mi42Yy0zLjIsMy4xLTguMywzLjEtMTEuNCwwYzAsMCwwLDAsMCwwTDIuNCwxMzNjLTMuMi0zLjEtMy4yLTguMSwwLTExLjJsMjMuMi0yMi43YzMuMi0zLjEsOC4zLTMuMSwxMS40LDBsNzQuMSw3Mi42CgljMC44LDAuOCwyLjEsMC44LDIuOSwwYzAsMCwwLDAsMCwwbDc0LjEtNzIuNmMzLjItMy4xLDguMy0zLjEsMTEuNCwwYzAsMCwwLDAsMCwwbDc0LjEsNzIuNmMwLjgsMC44LDIuMSwwLjgsMi45LDBsNzQuMS03Mi42CglDMzUzLjgsOTYsMzU4LjksOTYsMzYyLjEsOTkuMXoiLz4KPC9zdmc+' + +let isConnected = false + +const WalletConnect: WalletAdapterInterface = { + icon, + id: 'walletconnect', + name: 'WalletConnect', + platforms: [WalletPlatformEnum.UNIVERSAL], + downloadLink: 'https://www.tronlink.org/dlDetails/', + createDeepLink(url: string): string { + return ( + 'tronlinkoutside://pull.activity?param=' + + JSON.stringify({ + url, + action: 'open', + protocol: 'tronlink', + version: '1.0' + }) + ) + }, + isDetected: () => true, + isConnected: () => isConnected, + disconnect: async () => { + isConnected = false + Object.keys(localStorage) + .filter((x) => x.startsWith('wc@2')) + .forEach((x) => { + localStorage.removeItem(x) + }) + localStorage.removeItem('walletconnect') + localStorage.removeItem('WALLETCONNECT_DEEPLINK_CHOICE') + document.cookie = 'wl-connected' + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;' + }, + connect: async ( + provider?: ProviderInterface, + _ops?: WalletConnectOps | object + ): Promise => { + return await new Promise((resolve, reject) => { + const ops = _ops as WalletConnectOps + + if (provider === undefined) { + throw new Error('Provider is required') + } + + if (ops === undefined) { + throw new Error('Ops is required') + } + + if (ops.projectId === undefined) { + throw new Error('Project ID is required') + } + + const walletProvider = new WalletConnectAdapter({ + network: provider.isTestnet() ? 'Nile' : 'Mainnet', + options: { + relayUrl: 'wss://relay.walletconnect.com', + projectId: ops.projectId + }, + qrcodeModalOptions: { + mobileLinks: ['trust'], + desktopLinks: [ + // 'zerion', + // 'ledger' + ] + } + }) + + try { + walletProvider + .connect() + .then(async () => { + resolve(walletProvider as CustomAdapter) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default WalletConnect diff --git a/packages/networks/tron/src/browser/adapters/index.ts b/packages/networks/tron/src/browser/adapters/index.ts new file mode 100644 index 0000000..2342ba1 --- /dev/null +++ b/packages/networks/tron/src/browser/adapters/index.ts @@ -0,0 +1,5 @@ +export { default as TronLink } from './TronLink.ts' +export { default as OkxWallet } from './OkxWallet.ts' +export { default as TokenPocket } from './TokenPocket.ts' +export { default as BitgetWallet } from './BitgetWallet.ts' +export { default as WalletConnect } from './WalletConnect.ts' diff --git a/packages/networks/tron/src/browser/index.ts b/packages/networks/tron/src/browser/index.ts new file mode 100644 index 0000000..787e9bd --- /dev/null +++ b/packages/networks/tron/src/browser/index.ts @@ -0,0 +1,25 @@ +import { Wallet } from './Wallet.ts' +import * as adapterList from './adapters/index.ts' +import type { + WalletAdapterListType, + WalletAdapterInterface, + RegisterWalletAdapterType +} from '@multiplechain/types' + +const adapters: WalletAdapterListType = {} + +const registerAdapter: RegisterWalletAdapterType = (adapter: WalletAdapterInterface): void => { + if (Object.values(adapters).find((a) => a.id === adapter.id) !== undefined) { + throw new Error(`Adapter with id ${adapter.id} already exists`) + } + + adapters[adapter.id] = adapter +} + +export * from '../index.ts' + +export const browser = { + Wallet, + registerAdapter, + adapters: Object.assign(adapters, adapterList) +} diff --git a/packages/networks/tron/src/index.ts b/packages/networks/tron/src/index.ts new file mode 100644 index 0000000..668ab52 --- /dev/null +++ b/packages/networks/tron/src/index.ts @@ -0,0 +1,8 @@ +export * from './services/Provider.ts' + +export * as assets from './assets/index.ts' +export * as models from './models/index.ts' +export * as services from './services/index.ts' + +export * as utils from '@multiplechain/utils' +export * as types from '@multiplechain/types' diff --git a/packages/networks/tron/src/models/CoinTransaction.ts b/packages/networks/tron/src/models/CoinTransaction.ts new file mode 100644 index 0000000..e90ecb9 --- /dev/null +++ b/packages/networks/tron/src/models/CoinTransaction.ts @@ -0,0 +1,68 @@ +import { Transaction } from './Transaction.ts' +import { TransactionStatusEnum } from '@multiplechain/types' +import { AssetDirectionEnum, type CoinTransactionInterface } from '@multiplechain/types' + +export class CoinTransaction extends Transaction implements CoinTransactionInterface { + /** + * @returns {Promise} Wallet address of the receiver of transaction + */ + async getReceiver(): Promise { + const data = await this.getData() + return this.provider.tronWeb.address.fromHex( + data?.raw_data.contract[0].parameter.value.to_address ?? '' + ) + } + + /** + * @returns {Promise} Wallet address of the sender of transaction + */ + async getSender(): Promise { + return await this.getSigner() + } + + /** + * @returns {Promise} Amount of coin that will be transferred + */ + async getAmount(): Promise { + const data = await this.getData() + return parseFloat( + this.provider.tronWeb.fromSun( + data?.raw_data.contract[0].parameter.value.amount ?? 0 + ) as unknown as string + ) + } + + /** + * @param {AssetDirectionEnum} direction - Direction of the transaction (asset) + * @param {string} address - Wallet address of the receiver or sender of the transaction, dependant on direction + * @param {number} amount Amount of assets that will be transferred + * @returns {Promise} Status of the transaction + */ + async verifyTransfer( + direction: AssetDirectionEnum, + address: string, + amount: number + ): Promise { + const status = await this.getStatus() + + if (status === TransactionStatusEnum.PENDING) { + return TransactionStatusEnum.PENDING + } + + if ((await this.getAmount()) !== amount) { + return TransactionStatusEnum.FAILED + } + + if (direction === AssetDirectionEnum.INCOMING) { + if ((await this.getReceiver()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } else { + if ((await this.getSender()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } + + return TransactionStatusEnum.CONFIRMED + } +} diff --git a/packages/networks/tron/src/models/ContractTransaction.ts b/packages/networks/tron/src/models/ContractTransaction.ts new file mode 100644 index 0000000..07885d1 --- /dev/null +++ b/packages/networks/tron/src/models/ContractTransaction.ts @@ -0,0 +1,43 @@ +// @ts-expect-error no need type +import TxDecoder from '@beycandeveloper/tron-tx-decoder' +import { Transaction, type TransactionData } from './Transaction.ts' +import type { ContractTransactionInterface } from '@multiplechain/types' + +export interface DecodedInputData { + methodName: string + inputNames: string[] + inputTypes: string[] + decodedInput: { + [key: string]: any + _length: number + } +} + +export class ContractTransaction extends Transaction implements ContractTransactionInterface { + /** + * @returns {Promise} Contract address of the transaction + */ + async getAddress(): Promise { + const data = await this.getData() + return this.provider.tronWeb.address.fromHex( + data?.raw_data.contract[0].parameter.value.contract_address ?? '' + ) + } + + /** + * @param {TransactionData} txData Transaction data + * @returns {Promise} Decoded transaction data + */ + async decodeData(txData?: TransactionData): Promise { + if (txData === undefined) { + const data = await this.getData() + if (data === null) return null + txData = data + } + + const decoder = new TxDecoder(this.provider.node.host) + const decodeData = await decoder.decodeInputById(this.id) + + return decodeData as DecodedInputData + } +} diff --git a/packages/networks/tron/src/models/NftTransaction.ts b/packages/networks/tron/src/models/NftTransaction.ts new file mode 100644 index 0000000..26b12f1 --- /dev/null +++ b/packages/networks/tron/src/models/NftTransaction.ts @@ -0,0 +1,81 @@ +import { ContractTransaction } from './ContractTransaction.ts' +import { TransactionStatusEnum } from '@multiplechain/types' +import { type NftTransactionInterface, AssetDirectionEnum } from '@multiplechain/types' + +export class NftTransaction extends ContractTransaction implements NftTransactionInterface { + /** + * @returns {Promise} Receiver wallet address + */ + async getReceiver(): Promise { + const decoded = await this.decodeData() + + if (decoded === null) { + return '' + } + + if (decoded.methodName === 'transferFrom') { + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[1]) + } + + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[0]) + } + + /** + * @returns {Promise} Wallet address of the sender of transaction + */ + async getSender(): Promise { + const decoded = await this.decodeData() + + if (decoded === null) { + return '' + } + + if (decoded.methodName === 'transferFrom') { + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[0]) + } + + return await this.getSigner() + } + + /** + * @returns {Promise} NFT ID + */ + async getNftId(): Promise { + return Number((await this.decodeData())?.decodedInput[2] ?? 0) + } + + /** + * @param {AssetDirectionEnum} direction - Direction of the transaction (nft) + * @param {string} address - Wallet address of the receiver or sender of the transaction, dependant on direction + * @param {number} nftId ID of the NFT that will be transferred + * @override verifyTransfer() in AssetTransactionInterface + * @returns {Promise} Status of the transaction + */ + async verifyTransfer( + direction: AssetDirectionEnum, + address: string, + nftId: number | string + ): Promise { + const status = await this.getStatus() + + if (status === TransactionStatusEnum.PENDING) { + return TransactionStatusEnum.PENDING + } + + if ((await this.getNftId()) !== nftId) { + return TransactionStatusEnum.FAILED + } + + if (direction === AssetDirectionEnum.INCOMING) { + if ((await this.getReceiver()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } else { + if ((await this.getSender()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } + + return TransactionStatusEnum.CONFIRMED + } +} diff --git a/packages/networks/tron/src/models/TokenTransaction.ts b/packages/networks/tron/src/models/TokenTransaction.ts new file mode 100644 index 0000000..709eb6c --- /dev/null +++ b/packages/networks/tron/src/models/TokenTransaction.ts @@ -0,0 +1,94 @@ +import { hexToNumber } from '@multiplechain/utils' +import { Token } from '../assets/Token.ts' +import { ContractTransaction } from './ContractTransaction.ts' +import { TransactionStatusEnum } from '@multiplechain/types' +import { AssetDirectionEnum, type TokenTransactionInterface } from '@multiplechain/types' + +export class TokenTransaction extends ContractTransaction implements TokenTransactionInterface { + /** + * @returns {Promise} Wallet address of the receiver of transaction + */ + async getReceiver(): Promise { + const decoded = await this.decodeData() + + if (decoded === null) { + return '' + } + + if (decoded.methodName === 'transferFrom') { + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[1]) + } + + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[0]) + } + + /** + * @returns {Promise} Wallet address of the sender of transaction + */ + async getSender(): Promise { + const decoded = await this.decodeData() + + if (decoded === null) { + return '' + } + + if (decoded.methodName === 'transferFrom') { + return this.provider.tronWeb.address.fromHex(decoded.decodedInput[0]) + } + + return await this.getSigner() + } + + /** + * @returns {Promise} Amount of tokens that will be transferred + */ + async getAmount(): Promise { + const token = new Token(await this.getAddress()) + const decoded = await this.decodeData() + if (decoded === null) { + return 0 + } + + if (decoded.methodName === 'transferFrom') { + const amount = decoded.decodedInput[2] as bigint + return hexToNumber(amount.toString(), await token.getDecimals()) + } + + const amount = decoded.decodedInput[1] as bigint + return hexToNumber(amount.toString(), await token.getDecimals()) + } + + /** + * @param {AssetDirectionEnum} direction - Direction of the transaction (token) + * @param {string} address - Wallet address of the owner or spender of the transaction, dependant on direction + * @param {number} amount Amount of tokens that will be approved + * @returns {Promise} Status of the transaction + */ + async verifyTransfer( + direction: AssetDirectionEnum, + address: string, + amount: number + ): Promise { + const status = await this.getStatus() + + if (status === TransactionStatusEnum.PENDING) { + return TransactionStatusEnum.PENDING + } + + if ((await this.getAmount()) !== amount) { + return TransactionStatusEnum.FAILED + } + + if (direction === AssetDirectionEnum.INCOMING) { + if ((await this.getReceiver()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } else { + if ((await this.getSender()).toLowerCase() !== address.toLowerCase()) { + return TransactionStatusEnum.FAILED + } + } + + return TransactionStatusEnum.CONFIRMED + } +} diff --git a/packages/networks/tron/src/models/Transaction.ts b/packages/networks/tron/src/models/Transaction.ts new file mode 100644 index 0000000..23bc227 --- /dev/null +++ b/packages/networks/tron/src/models/Transaction.ts @@ -0,0 +1,216 @@ +import { Provider } from '../services/Provider.ts' +import type { TransactionInterface } from '@multiplechain/types' +import { ErrorTypeEnum, TransactionStatusEnum } from '@multiplechain/types' + +interface RetObject { + contractRet: string +} + +interface ContractObject { + parameter: { + value: { + data?: string + owner_address: string + contract_address?: string + to_address?: string + amount?: number + } + type_url: string + } + type: string +} + +interface LogObject { + address: string + topics: string[] + data: string +} + +export interface TransactionData { + ret: RetObject[] + signature: string[] + txID: string + raw_data: { + contract: ContractObject[] + ref_block_bytes: string + ref_block_hash: string + expiration: number + timestamp: number + fee_limit?: number + } + raw_data_hex: string + info?: { + id: string + fee: number + packingFee: number + blockNumber: number + blockTimeStamp: number + contractResult: string[] + contract_address?: string + receipt: { + result?: string + net_fee: number + net_usage?: number + energy_fee?: number + energy_usage?: number + energy_usage_total?: number + energy_penalty_total?: number + } + result?: string + resMessage?: string + log?: LogObject[] + } +} + +export class Transaction implements TransactionInterface { + /** + * Each transaction has its own unique ID defined by the user + */ + id: string + + /** + * Blockchain network provider + */ + provider: Provider + + /** + * Transaction data after completed + */ + data: TransactionData + + /** + * @param {string} id Transaction id + * @param {Provider} provider Blockchain network provider + */ + constructor(id: string, provider?: Provider) { + this.id = id + this.provider = provider ?? Provider.instance + } + + /** + * @returns {Promise} Transaction data + */ + async getData(): Promise { + try { + if (this.data?.info !== undefined) { + return this.data + } + this.data = (await this.provider.tronWeb.trx.getTransaction(this.id)) ?? undefined + if (this.data === undefined) { + return null + } + const result = await this.provider.tronWeb.trx.getTransactionInfo(this.id) + this.data.info = result?.id !== undefined ? result : undefined + return this.data + } catch (error) { + throw new Error(ErrorTypeEnum.RPC_REQUEST_ERROR) + } + } + + /** + * @param {number} ms - Milliseconds to wait for the transaction to be confirmed. Default is 4000ms + * @returns {Promise} Status of the transaction + */ + async wait(ms: number = 4000): Promise { + return await new Promise((resolve, reject) => { + const check = async (): Promise => { + try { + const status = await this.getStatus() + if (status === TransactionStatusEnum.CONFIRMED) { + resolve(TransactionStatusEnum.CONFIRMED) + return + } else if (status === TransactionStatusEnum.FAILED) { + reject(TransactionStatusEnum.FAILED) + return + } + setTimeout(check, ms) + } catch (error) { + reject(TransactionStatusEnum.FAILED) + } + } + void check() + }) + } + + /** + * @returns {string} Transaction ID + */ + getId(): string { + return this.id + } + + /** + * @returns {string} Transaction URL + */ + getUrl(): string { + let explorerUrl = this.provider.node.explorer + explorerUrl += explorerUrl.endsWith('/') ? '' : '/' + explorerUrl += '#/transaction/' + this.id + return explorerUrl + } + + /** + * @returns {Promise} Wallet address of the sender of transaction + */ + async getSigner(): Promise { + const data = await this.getData() + return this.provider.tronWeb.address.fromHex( + data?.raw_data.contract[0].parameter.value.owner_address ?? '' + ) + } + + /** + * @returns {Promise} Transaction fee + */ + async getFee(): Promise { + const data = await this.getData() + return parseFloat(this.provider.tronWeb.fromSun(data?.info?.fee ?? 0) as unknown as string) + } + + /** + * @returns {Promise} Block number that transaction + */ + async getBlockNumber(): Promise { + const data = await this.getData() + return data?.info?.blockNumber ?? 0 + } + + /** + * @returns {Promise} Block timestamp that transaction + */ + async getBlockTimestamp(): Promise { + const data = await this.getData() + return parseInt((data?.info?.blockTimeStamp ?? 0).toString().replace(/0+$/, '')) + } + + /** + * @returns {Promise} Confirmation count of the block + */ + async getBlockConfirmationCount(): Promise { + const data = await this.getData() + const blockNumber = data?.info?.blockNumber ?? 0 + const latestBlock = await this.provider.tronWeb.trx.getCurrentBlock() + return latestBlock.block_header.raw_data.number - blockNumber + } + + /** + * @returns {Promise} Status of the transaction + */ + async getStatus(): Promise { + const data = await this.getData() + if (data === null) { + return TransactionStatusEnum.PENDING + } else if (data?.ret.length > 0 && data.info !== undefined) { + if (this.data.info?.blockNumber !== undefined) { + if (this.data.ret[0].contractRet === 'REVERT') { + return TransactionStatusEnum.FAILED + } else if (this.data.info.result === 'FAILED') { + return TransactionStatusEnum.FAILED + } else { + return TransactionStatusEnum.CONFIRMED + } + } + } + return TransactionStatusEnum.PENDING + } +} diff --git a/packages/networks/tron/src/models/index.ts b/packages/networks/tron/src/models/index.ts new file mode 100644 index 0000000..cc0a27c --- /dev/null +++ b/packages/networks/tron/src/models/index.ts @@ -0,0 +1,5 @@ +export * from './Transaction.ts' +export * from './NftTransaction.ts' +export * from './CoinTransaction.ts' +export * from './TokenTransaction.ts' +export * from './ContractTransaction.ts' diff --git a/packages/networks/tron/src/services/Provider.ts b/packages/networks/tron/src/services/Provider.ts new file mode 100644 index 0000000..84e350f --- /dev/null +++ b/packages/networks/tron/src/services/Provider.ts @@ -0,0 +1,135 @@ +import { + ErrorTypeEnum, + type NetworkConfigInterface, + type ProviderInterface +} from '@multiplechain/types' +import { TronWeb } from './TronWeb.ts' + +export interface TronNodeInfoInterface { + id: string + node: string + name: string + host: string + event: string + explorer: string +} + +export type TronNodeInfoListInterface = Record + +export class Provider implements ProviderInterface { + /** + * Network configuration of the provider + */ + network: NetworkConfigInterface + + /** + * Node list + */ + nodes: TronNodeInfoListInterface = { + mainnet: { + id: '0x2b6653dc', + node: 'mainnet', + name: 'TronGrid Mainnet', + host: 'https://api.trongrid.io', + event: 'https://api.trongrid.io', + explorer: 'https://tronscan.org/' + }, + testnet: { + id: '0xcd8690dc', + node: 'testnet', + name: 'TronGrid Nile Testnet', + host: 'https://nile.trongrid.io', + event: 'https://event.nileex.io', + explorer: 'https://nile.tronscan.org/' + } + } + + /** + * Node information + */ + node: TronNodeInfoInterface + + /** + * TronWeb instance + */ + tronWeb: TronWeb + + /** + * Static instance of the provider + */ + private static _instance: Provider + + /** + * @param network - Network configuration of the provider + */ + constructor(network: NetworkConfigInterface) { + this.network = network + this.update(network) + } + + /** + * Get the static instance of the provider + * @returns {Provider} Provider + */ + static get instance(): Provider { + if (Provider._instance === undefined) { + throw new Error(ErrorTypeEnum.PROVIDER_IS_NOT_INITIALIZED) + } + return Provider._instance + } + + /** + * Initialize the static instance of the provider + * @param {NetworkConfigInterface} network - Network configuration of the provider + * @returns {void} + */ + static initialize(network: NetworkConfigInterface): void { + if (Provider._instance !== undefined) { + throw new Error(ErrorTypeEnum.PROVIDER_IS_ALREADY_INITIALIZED) + } + Provider._instance = new Provider(network) + } + + /** + * Check RPC connection + * @param {string} _url - RPC URL + * @returns {Promise} + */ + async checkRpcConnection(_url?: string): Promise { + return (await this.tronWeb.isConnected()).fullNode + } + + /** + * Check WS connection + * @param {string} _url - Websocket URL + * @returns {Promise} + */ + async checkWsConnection(_url?: string): Promise { + return (await this.tronWeb.isConnected()).eventServer + } + + /** + * Update network configuration of the provider + * @param network - Network configuration of the provider + */ + update(network: NetworkConfigInterface): void { + this.network = network + Provider._instance = this + this.node = this.nodes[network.testnet ?? false ? 'testnet' : 'mainnet'] + this.node.host = this.network.rpcUrl ?? this.node.host + this.node.event = this.network.wsUrl ?? this.node.event + this.tronWeb = new TronWeb({ + fullNode: this.node.host, + solidityNode: this.node.host, + eventServer: this.node.event + }) + } + + /** + * Get the current network configuration is testnet or not + * @returns boolean + */ + isTestnet(): boolean { + return this.network?.testnet ?? false + } +} diff --git a/packages/networks/tron/src/services/TransactionListener.ts b/packages/networks/tron/src/services/TransactionListener.ts new file mode 100644 index 0000000..6ee6505 --- /dev/null +++ b/packages/networks/tron/src/services/TransactionListener.ts @@ -0,0 +1,157 @@ +import type { + TransactionTypeEnum, + DynamicTransactionType, + TransactionListenerInterface, + TransactionListenerCallbackType, + DynamicTransactionListenerFilterType +} from '@multiplechain/types' + +import { Provider } from './Provider.ts' +import { TransactionListenerProcessIndex } from '@multiplechain/types' + +export class TransactionListener + implements TransactionListenerInterface +{ + /** + * Transaction type + */ + type: T + + /** + * Transaction listener callback + */ + callbacks: TransactionListenerCallbackType[] = [] + + /** + * Transaction listener filter + */ + filter?: DynamicTransactionListenerFilterType + + /** + * Provider + */ + provider: Provider + + /** + * Listener status + */ + status: boolean = false + + /** + * Triggered transactions + */ + triggeredTransactions: string[] = [] + + /** + * Dynamic stop method + */ + dynamicStop: () => void = () => {} + + /** + * @param {T} type - Transaction type + * @param {DynamicTransactionListenerFilterType} filter - Transaction listener filter + * @param {Provider} provider - Provider + */ + constructor(type: T, filter?: DynamicTransactionListenerFilterType, provider?: Provider) { + this.type = type + this.filter = filter + this.provider = provider ?? Provider.instance + throw new Error('This class is not implemented for Tron') + } + + /** + * Close the listener + * @returns {void} + */ + stop(): void { + if (this.status) { + this.status = false + this.dynamicStop() + } + } + + /** + * Start the listener + * @returns {void} + */ + start(): void { + if (!this.status) { + this.status = true + // @ts-expect-error allow dynamic access + this[TransactionListenerProcessIndex[this.type]]() + } + } + + /** + * Get the listener status + * @returns {boolean} Listener status + */ + getStatus(): boolean { + return this.status + } + + /** + * Listen to the transaction events + * @param {TransactionListenerCallbackType} callback - Transaction listener callback + * @returns {Promise} + */ + async on(callback: TransactionListenerCallbackType): Promise { + this.start() + this.callbacks.push(callback) + return true + } + + /** + * Trigger the event when a transaction is detected + * @param {DynamicTransactionType} transaction - Transaction data + * @returns {void} + */ + trigger(transaction: DynamicTransactionType): void { + if (!this.triggeredTransactions.includes(transaction.id)) { + this.triggeredTransactions.push(transaction.id) + this.callbacks.forEach((callback) => { + callback(transaction) + }) + } + } + + /** + * General transaction process + * @returns {void} + */ + generalProcess(): void { + // General transaction process + } + + /** + * Contract transaction process + * @returns {void} + */ + contractProcess(): void { + // Contract transaction process + } + + /** + * Coin transaction process + * @returns {void} + */ + coinProcess(): void { + // Coin transaction process + } + + /** + * Token transaction process + * @returns {void} + */ + tokenProcess(): void { + // Token transaction process + } + + /** + * NFT transaction process + * @returns {void} + */ + nftProcess(): void { + // NFT transaction process + } +} diff --git a/packages/networks/tron/src/services/TransactionSigner.ts b/packages/networks/tron/src/services/TransactionSigner.ts new file mode 100644 index 0000000..9f44ac1 --- /dev/null +++ b/packages/networks/tron/src/services/TransactionSigner.ts @@ -0,0 +1,131 @@ +import { Provider } from '../services/Provider.ts' +import { Transaction } from '../models/Transaction.ts' +import { NftTransaction } from '../models/NftTransaction.ts' +import { CoinTransaction } from '../models/CoinTransaction.ts' +import { TokenTransaction } from '../models/TokenTransaction.ts' +import { ErrorTypeEnum, type TransactionSignerInterface } from '@multiplechain/types' + +interface ParameterInterface { + value: { + data: string + token_id: number + owner_address: string + call_token_value: number + contract_address: string + } + type_url: string +} + +interface ContractDataInterface { + parameter: ParameterInterface + type: string +} + +export interface TransactionData { + visible: boolean + txID: string + raw_data: { + contract: ContractDataInterface[] + ref_block_bytes: string + ref_block_hash: string + expiration: number + fee_limit: number + timestamp: number + } + raw_data_hex: string +} + +export interface SignedTransactionData extends TransactionData { + signature: string[] +} + +export class TransactionSigner implements TransactionSignerInterface { + /** + * Transaction data from the blockchain network + */ + rawData: TransactionData + + /** + * Signed transaction data + */ + signedData: SignedTransactionData + + /** + * Blockchain network provider + */ + provider: Provider + + /** + * @param {TransactionData} rawData - Transaction data + */ + constructor(rawData: TransactionData, provider?: Provider) { + this.rawData = rawData + this.provider = provider ?? Provider.instance + } + + /** + * Sign the transaction + * @param {string} privateKey - Transaction data + * @returns {Promise} Signed transaction data + */ + async sign(privateKey: string): Promise { + this.signedData = await this.provider.tronWeb.trx.sign(this.rawData, privateKey) + return this + } + + /** + * Send the transaction to the blockchain network + * @returns {Promise} + */ + async send(): Promise { + const { transaction } = await this.provider.tronWeb.trx.sendRawTransaction(this.signedData) + if (transaction === undefined) throw new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED) + return new Transaction(transaction.txID as string) + } + + /** + * Get the raw transaction data + * @returns Transaction data + */ + getRawData(): TransactionData { + return this.rawData + } + + /** + * Get the signed transaction data + * @returns Signed transaction data + */ + getSignedData(): SignedTransactionData { + return this.signedData + } +} + +export class CoinTransactionSigner extends TransactionSigner { + /** + * Send the transaction to the blockchain network + * @returns {Promise} Transaction data + */ + async send(): Promise { + return new CoinTransaction((await super.send()).getId()) + } +} + +export class TokenTransactionSigner extends TransactionSigner { + /** + * Send the transaction to the blockchain network + * @returns {Promise} Transaction data + */ + async send(): Promise { + return new TokenTransaction((await super.send()).getId()) + } +} + +export class NftTransactionSigner extends TransactionSigner { + /** + * Send the transaction to the blockchain network + * @returns {Promise} Transaction data + */ + async send(): Promise { + return new NftTransaction((await super.send()).getId()) + } +} diff --git a/packages/networks/tron/src/services/TronWeb.ts b/packages/networks/tron/src/services/TronWeb.ts new file mode 100644 index 0000000..10ee335 --- /dev/null +++ b/packages/networks/tron/src/services/TronWeb.ts @@ -0,0 +1,21 @@ +import TronWebBase from 'tronweb' +import type { TransactionRawData } from '../assets/Contract.ts' +import type { TransactionData } from './TransactionSigner.ts' + +export class TronWeb extends TronWebBase { + async triggerContract(data: TransactionRawData): Promise { + const response = await this.transactionBuilder.triggerSmartContract( + data.address, + data.method, + data.options, + data.parameters, + data.from + ) + + if (response?.result?.result !== true) { + return false + } + + return response.transaction as TransactionData + } +} diff --git a/packages/networks/tron/src/services/index.ts b/packages/networks/tron/src/services/index.ts new file mode 100644 index 0000000..549a382 --- /dev/null +++ b/packages/networks/tron/src/services/index.ts @@ -0,0 +1,2 @@ +export * from './TransactionSigner.ts' +export * from './TransactionListener.ts' diff --git a/packages/networks/tron/src/services/tronweb.d.ts b/packages/networks/tron/src/services/tronweb.d.ts new file mode 100644 index 0000000..8ebd0db --- /dev/null +++ b/packages/networks/tron/src/services/tronweb.d.ts @@ -0,0 +1,126 @@ +/// +declare module 'tronweb' { + + export interface TronWebConfigInterface { + fullNode: string + solidityNode: string + eventServer: string + } + + export class TronWeb { + constructor(config: TronWebConfigInterface); + contract(...args: any[]): any; + currentProvider(): any; + currentProviders(): any; + getEventByTransactionID(transactionID: string, callback?: any): any; + getEventResult(...args: any[]): any; + isConnected(callback?: any): any; + isValidProvider(provider: any): any; + setAddress(address: any): void; + setDefaultBlock(blockID: any): any; + setEventServer(eventServer: any): any; + setFullNode(fullNode: any): void; + setPrivateKey(privateKey: any): void; + setSolidityNode(solidityNode: any): void; + createAccount(callback?: any): Promise; + fromAscii(string: any, padding: any): any; + fromDecimal(value: any): any; + fromSun(sun: number): number; + fromUtf8(string: any): any; + isAddress(address: string): any; + sha3(string: any, prefix?: boolean): any; + toAscii(hex: any): any; + toBigNumber(amount: number): any; + toDecimal(value: any): any; + toHex(val: any): any; + toSun(trx: any): any; + toUtf8(hex: any): any; + trx: { + parseToken(token: any): any; + getCurrentBlock(callback?: any): Promise; + getBlock(block: any, callback?: any): Promise; + getBlockByHash(blockHash: any, callback?: any): Promise; + getBlockByNumber(blockID: any, callback?: any): Promise; + getBlockTransactionCount(block: any, callback?: any): Promise; + getTransactionFromBlock(block: any, index: number, callback?: any): Promise; + getTransaction(transactionID: any, callback?: any): Promise; + getConfirmedTransaction(transactionID: any, callback?: any): Promise; + getTransactionInfo(transactionID: any, callback?: any): Promise; + getTransactionsToAddress(address: any, limit: number, offset: number, callback?: any): Promise; + getTransactionsFromAddress(address: any, limit: number, offset: number, callback?: any): Promise; + getTransactionsRelated(address: any, direction: any, limit: number, offset: number, callback?: any): Promise; + getAccount(address: any, callback?: any): Promise; + getBalance(address: any, callback?: any): Promise; + getUnconfirmedAccount(address: any, callback?: any): Promise; + getUnconfirmedBalance(address: any, callback?: any): Promise; + getBandwidth(address: any, callback?: any): Promise; + getTokensIssuedByAddress(address: any, callback?: any): Promise; + getTokenFromID(tokenID: any, callback?: any): Promise; + listNodes(callback?: any): Promise; + getBlockRange(start: number, end: number, callback?: any): Promise; + listSuperRepresentatives(callback?: any): Promise; + listTokens(limit?: number, offset?: number, callback?: any): Promise; + timeUntilNextVoteCycle(callback?: any): Promise; + getContract(contractAddress: any, callback?: any): Promise; + verifyMessage(message: any, signature: any, address: any, useTronHeader: any, callback?: any): Promise; + sign(transaction: any, privateKey: any, useTronHeader?: boolean, callback?: any): Promise; + sendRawTransaction(signedTransaction: any, options?: any, callback?: any): Promise; + sendTransaction(to: any, amount: any, options: any, callback?: any): Promise; + sendToken(to: any, amount: any, tokenID: any, options: any, callback?: any): Promise; + freezeBalance(amount: any, duration: number, resource: string, options: any, callback?: any): Promise; + unfreezeBalance(resource: string, options: any, callback?: any): Promise; + updateAccount(accountName: string, options: any, callback?: any): Promise; + signMessage(...args: any[]): Promise; + sendAsset(...args: any[]): Promise; + send(...args: any[]): Promise; + sendTrx(...args: any[]): Promise; + broadcast(...args: any[]): Promise; + signTransaction(...args: any[]): Promise; + getProposal(proposalID: any, callback?: any): Promise; + listProposals(callback: any): Promise; + getChainParameters(callback: any): Promise; + getAccountResources(address: any, callback?: any): Promise; + getExchangeByID(exchangeID: any, callback?: any): Promise; + listExchanges(callback?: any): Promise; + listExchangesPaginated(limit: number, offset: number, callback?: any): Promise; + } + transactionBuilder: { + sendTrx(to: any, amount: any, from: any, callback?: any): Promise; + sendToken(to: any, amount: any, tokenID: any, from: any, callback?: any): Promise; + purchaseToken(issuerAddress: any, tokenID: any, amount: any, buyer: any, callback?: any): Promise; + freezeBalance(amount: any, duration: number, resource: string, address: any, callback?: any): Promise; + unfreezeBalance(resource: string, address: any, callback?: any): Promise; + withdrawBlockRewards(address: any, callback?: any): Promise; + applyForSR(address: any, url: any, callback?: any): Promise; + vote(votes: any, voterAddress: any, callback?: any): Promise; + createToken(options: any, issuerAddress: any, callback?: any): Promise; + updateAccount(accountName: any, address: any, callback?: any): Promise; + updateToken(options: any, issuerAddress: any, callback?: any): Promise; + sendAsset(...args: any[]): Promise; + purchaseAsset(...args: any[]): Promise; + createAsset(...args: any[]): Promise; + updateAsset(...args: any[]): Promise; + createProposal(parameters: any, issuerAddress: any, callback?: any): Promise; + deleteProposal(proposalID: any, issuerAddress: any, callback?: any): Promise; + voteProposal(proposalID: any, isApproval: any, voterAddress: any, callback?: any): Promise; + createTRXExchange(tokenName: any, tokenBalance: any, trxBalance: any, ownerAddress: any): Promise; + createTokenExchange(firstTokenName: any, firstTokenBalance: any, secondTokenName: any, secondTokenBalance: any, ownerAddress: any, callback?: any): Promise; + injectExchangeTokens(exchangeID: any, tokenName: any, tokenAmount: any, ownerAddress: any, callback?: any): Promise; + withdrawExchangeTokens(exchangeID: any, tokenName: any, tokenAmount: any, ownerAddress: any, callback?: any): Promise; + tradeExchangeTokens(exchangeID: any, tokenName: any, tokenAmountSold: any, tokenAmountExpected: any, ownerAddress: any, callback?: any): Promise; + triggerSmartContract(...args: any[]): Promise<{ + transaction: any; + result: { + result: boolean; + }; + }>; + } + address: { + fromHex(e: any): any; + fromPrivateKey(e: any): any; + toHex(e: any): any; + } + } + + export default TronWeb; +} \ No newline at end of file diff --git a/packages/networks/tron/tests/assets.spec.ts b/packages/networks/tron/tests/assets.spec.ts new file mode 100644 index 0000000..721192e --- /dev/null +++ b/packages/networks/tron/tests/assets.spec.ts @@ -0,0 +1,254 @@ +import { describe, it, expect, assert } from 'vitest' + +import { NFT } from '../src/assets/NFT.ts' +import { Coin } from '../src/assets/Coin.ts' +import { math } from '@multiplechain/utils' +import { Token } from '../src/assets/Token.ts' +import { Transaction } from '../src/models/Transaction.ts' +import { TransactionStatusEnum } from '@multiplechain/types' +import { TransactionSigner } from '../src/services/TransactionSigner.ts' + +const coinBalanceTestAmount = Number(process.env.TRON_COIN_BALANCE_TEST_AMOUNT) +const tokenBalanceTestAmount = Number(process.env.TRON_TOKEN_BALANCE_TEST_AMOUNT) +const nftBalanceTestAmount = Number(process.env.TRON_NFT_BALANCE_TEST_AMOUNT) +const transferTestAmount = Number(process.env.TRON_TRANSFER_TEST_AMOUNT) +const tokenTransferTestAmount = Number(process.env.TRON_TOKEN_TRANSFER_TEST_AMOUNT) +const tokenApproveTestAmount = Number(process.env.TRON_TOKEN_APPROVE_TEST_AMOUNT) +const nftTransferId = Number(process.env.TRON_NFT_TRANSFER_ID) + +const coinTransferTestIsActive = Boolean(process.env.TRON_COIN_TRANSFER_TEST_IS_ACTIVE !== 'false') +const tokenTransferTestIsActive = Boolean( + process.env.TRON_TOKEN_TRANSFER_TEST_IS_ACTIVE !== 'false' +) +const tokenApproveTestIsActive = Boolean(process.env.TRON_TOKEN_APPROVE_TEST_IS_ACTIVE !== 'false') +const nftTransactionTestIsActive = Boolean( + process.env.TRON_NFT_TRANSACTION_TEST_IS_ACTIVE !== 'false' +) +const tokenTransferFromTestIsActive = Boolean( + process.env.TRON_TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE !== 'false' +) + +const balanceTestAddress = String(process.env.TRON_BALANCE_TEST_ADDRESS) +const senderPrivateKey = String(process.env.TRON_SENDER_PRIVATE_KEY) +const receiverPrivateKey = String(process.env.TRON_RECEIVER_PRIVATE_KEY) +const senderTestAddress = String(process.env.TRON_SENDER_TEST_ADDRESS) +const receiverTestAddress = String(process.env.TRON_RECEIVER_TEST_ADDRESS) +const tokenTestAddress = String(process.env.TRON_TOKEN_TEST_ADDRESS) +const nftTestAddress = String(process.env.TRON_NFT_TEST_ADDRESS) + +const waitSecondsBeforeThanNewTx = async (seconds: number): Promise => { + return await new Promise((resolve) => setTimeout(resolve, seconds * 1000)) +} + +const checkSigner = async (signer: TransactionSigner, privateKey?: string): Promise => { + expect(signer).toBeInstanceOf(TransactionSigner) + + const rawData = signer.getRawData() + + assert.isObject(rawData) + + await signer.sign(privateKey ?? senderPrivateKey) + + assert.isObject(signer.getSignedData()) +} + +const checkTx = async (transaction: Transaction): Promise => { + expect(transaction).toBeInstanceOf(Transaction) + const status = await transaction.wait(10 * 1000) + expect(status).toBe(TransactionStatusEnum.CONFIRMED) +} + +describe('Coin', () => { + const coin = new Coin() + it('Name and symbol', () => { + expect(coin.getName()).toBe('Tron') + expect(coin.getSymbol()).toBe('TRX') + }) + + it('Decimals', () => { + expect(coin.getDecimals()).toBe(6) + }) + + it('Balance', async () => { + const balance = await coin.getBalance(balanceTestAddress) + expect(balance).toBe(coinBalanceTestAmount) + }) + + it('Transfer', async () => { + if (!coinTransferTestIsActive) return + + const signer = await coin.transfer( + senderTestAddress, + receiverTestAddress, + transferTestAmount + ) + + await checkSigner(signer) + + const beforeBalance = await coin.getBalance(receiverTestAddress) + + await checkTx(await signer.send()) + + const afterBalance = await coin.getBalance(receiverTestAddress) + expect(afterBalance).toBe(math.add(beforeBalance, transferTestAmount)) + }) +}) + +describe('Token', () => { + const token = new Token(tokenTestAddress) + + it('Name and symbol', async () => { + expect(await token.getName()).toBe('SampleToken') + expect(await token.getSymbol()).toBe('SMP') + }) + + it('Decimals', async () => { + expect(await token.getDecimals()).toBe(18) + }) + + it('Balance', async () => { + const balance = await token.getBalance(balanceTestAddress) + expect(balance).toBe(tokenBalanceTestAmount) + }) + + it('Total supply', async () => { + const totalSupply = await token.getTotalSupply() + expect(totalSupply).toBe(1000000) + }) + + it('Transfer', async () => { + if (!tokenTransferTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await token.transfer( + senderTestAddress, + receiverTestAddress, + tokenTransferTestAmount + ) + + await checkSigner(signer) + + const beforeBalance = await token.getBalance(receiverTestAddress) + + await checkTx(await signer.send()) + + const afterBalance = await token.getBalance(receiverTestAddress) + expect(afterBalance).toBe(math.add(beforeBalance, tokenTransferTestAmount)) + }) + + it('Approve and Allowance', async () => { + if (!tokenApproveTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await token.approve( + senderTestAddress, + receiverTestAddress, + tokenApproveTestAmount + ) + + await checkSigner(signer) + + await checkTx(await signer.send()) + + expect(await token.getAllowance(senderTestAddress, receiverTestAddress)).toBe( + tokenApproveTestAmount + ) + }) + + it('Transfer from', async () => { + if (!tokenTransferFromTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await token.transferFrom( + receiverTestAddress, + senderTestAddress, + receiverTestAddress, + 2 + ) + + await checkSigner(signer, receiverPrivateKey) + + const beforeBalance = await token.getBalance(receiverTestAddress) + + await checkTx(await signer.send()) + + const afterBalance = await token.getBalance(receiverTestAddress) + expect(afterBalance).toBe(math.add(beforeBalance, 2)) + }) +}) + +describe('Nft', () => { + const nft = new NFT(nftTestAddress) + + it('Name and symbol', async () => { + expect(await nft.getName()).toBe('MyNFT') + expect(await nft.getSymbol()).toBe('MNFT') + }) + + it('Balance', async () => { + const balance = await nft.getBalance(balanceTestAddress) + expect(balance).toBe(nftBalanceTestAmount) + }) + + it('Owner', async () => { + expect(await nft.getOwner(5)).toBe(senderTestAddress) + }) + + it('Token URI', async () => { + expect(await nft.getTokenURI(5)).toBe('') + }) + + it('Approved', async () => { + expect(await nft.getApproved(5)).toBe(null) + }) + + it('Transfer', async () => { + if (!nftTransactionTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await nft.transfer(senderTestAddress, receiverTestAddress, nftTransferId) + + await checkSigner(signer) + + await checkTx(await signer.send()) + + expect(await nft.getOwner(nftTransferId)).toBe(receiverTestAddress) + }) + + it('Approve', async () => { + if (!nftTransactionTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await nft.approve(receiverTestAddress, senderTestAddress, nftTransferId) + + await checkSigner(signer, receiverPrivateKey) + + await checkTx(await signer.send()) + + expect(await nft.getApproved(nftTransferId)).toBe(senderTestAddress) + }) + + it('Transfer from', async () => { + if (!nftTransactionTestIsActive) return + + await waitSecondsBeforeThanNewTx(5) + + const signer = await nft.transferFrom( + senderTestAddress, + receiverTestAddress, + senderTestAddress, + nftTransferId + ) + + await checkSigner(signer) + + await checkTx(await signer.send()) + + expect(await nft.getOwner(nftTransferId)).toBe(senderTestAddress) + }) +}) diff --git a/packages/networks/tron/tests/models.spec.ts b/packages/networks/tron/tests/models.spec.ts new file mode 100644 index 0000000..896157b --- /dev/null +++ b/packages/networks/tron/tests/models.spec.ts @@ -0,0 +1,145 @@ +import { describe, it, expect } from 'vitest' + +import { Transaction } from '../src/models/Transaction.ts' +import { NftTransaction } from '../src/models/NftTransaction.ts' +import { CoinTransaction } from '../src/models/CoinTransaction.ts' +import { TokenTransaction } from '../src/models/TokenTransaction.ts' +import { AssetDirectionEnum, TransactionStatusEnum } from '@multiplechain/types' + +const nftId = Number(process.env.TRON_NFT_ID) +const tokenAmount = Number(process.env.TRON_TOKEN_AMOUNT) +const coinAmount = Number(process.env.TRON_COIN_AMOUNT) + +const trxTransferTx = String(process.env.TRON_TRX_TRANSFER_TX) +const tokenTransferTx = String(process.env.TRON_TOKEN_TRANSFER_TX) +const nftTransferTx = String(process.env.TRON_NFT_TRANSFER_TX) + +const testSender = String(process.env.TRON_MODEL_TEST_SENDER) +const testReceiver = String(process.env.TRON_MODEL_TEST_RECEIVER) + +describe('Transaction', () => { + const tx = new Transaction(trxTransferTx) + it('Id', async () => { + expect(tx.getId()).toBe(trxTransferTx) + }) + + it('Data', async () => { + expect(await tx.getData()).toBeTypeOf('object') + }) + + it('URL', async () => { + expect(tx.getUrl()).toBe( + 'https://nile.tronscan.org/#/transaction/8697ad2c4e1713227c16a65a5845636458df2d3db3adf526e07e17699bc6b3c4' + ) + }) + + it('Sender', async () => { + expect(await tx.getSigner()).toBe(testSender) + }) + + it('Fee', async () => { + expect(await tx.getFee()).toBe(1.1) + }) + + it('Block Number', async () => { + expect(await tx.getBlockNumber()).toBe(46506377) + }) + + it('Block Timestamp', async () => { + expect(await tx.getBlockTimestamp()).toBe(1714619148) + }) + + it('Block Confirmation Count', async () => { + expect(await tx.getBlockConfirmationCount()).toBeGreaterThan(199) + }) + + it('Status', async () => { + expect(await tx.getStatus()).toBe(TransactionStatusEnum.CONFIRMED) + }) +}) + +describe('Coin Transaction', () => { + const tx = new CoinTransaction(trxTransferTx) + + it('Receiver', async () => { + expect((await tx.getReceiver()).toLowerCase()).toBe(testReceiver.toLowerCase()) + }) + + it('Amount', async () => { + expect(await tx.getAmount()).toBe(coinAmount) + }) + + it('Verify Transfer', async () => { + expect(await tx.verifyTransfer(AssetDirectionEnum.INCOMING, testReceiver, coinAmount)).toBe( + TransactionStatusEnum.CONFIRMED + ) + + expect(await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testSender, coinAmount)).toBe( + TransactionStatusEnum.CONFIRMED + ) + + expect(await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testReceiver, coinAmount)).toBe( + TransactionStatusEnum.FAILED + ) + }) +}) + +describe('Token Transaction', () => { + const tx = new TokenTransaction(tokenTransferTx) + + it('Receiver', async () => { + expect((await tx.getReceiver()).toLowerCase()).toBe(testReceiver.toLowerCase()) + }) + + it('Amount', async () => { + expect(await tx.getAmount()).toBe(tokenAmount) + }) + + it('Verify Transfer', async () => { + expect( + await tx.verifyTransfer(AssetDirectionEnum.INCOMING, testReceiver, tokenAmount) + ).toBe(TransactionStatusEnum.CONFIRMED) + + expect(await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testSender, tokenAmount)).toBe( + TransactionStatusEnum.CONFIRMED + ) + + expect( + await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testReceiver, tokenAmount) + ).toBe(TransactionStatusEnum.FAILED) + }) +}) + +describe('NFT Transaction', () => { + const tx = new NftTransaction(nftTransferTx) + + it('Receiver', async () => { + expect((await tx.getReceiver()).toLowerCase()).toBe(testReceiver.toLowerCase()) + }) + + it('Signer', async () => { + expect((await tx.getSigner()).toLowerCase()).toBe(testSender.toLowerCase()) + }) + + it('Sender', async () => { + expect((await tx.getSender()).toLowerCase()).toBe(testSender.toLowerCase()) + }) + + it('NFT ID', async () => { + expect(await tx.getNftId()).toBe(nftId) + }) + + it('Verify Transfer', async () => { + expect(await tx.verifyTransfer(AssetDirectionEnum.INCOMING, testReceiver, nftId)).toBe( + TransactionStatusEnum.CONFIRMED + ) + + expect(await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testSender, nftId)).toBe( + TransactionStatusEnum.CONFIRMED + ) + + expect(await tx.verifyTransfer(AssetDirectionEnum.OUTGOING, testReceiver, nftId)).toBe( + TransactionStatusEnum.FAILED + ) + }) +}) diff --git a/packages/networks/tron/tests/services.spec.ts b/packages/networks/tron/tests/services.spec.ts new file mode 100644 index 0000000..e94f8f9 --- /dev/null +++ b/packages/networks/tron/tests/services.spec.ts @@ -0,0 +1,26 @@ +import { describe, it, expect } from 'vitest' + +import { provider } from './setup.ts' +import { Provider } from '../src/services/Provider.ts' + +describe('Provider', () => { + it('isTestnet', () => { + expect(provider.isTestnet()).toBe(true) + }) + + it('instance', () => { + expect(Provider.instance).toBe(provider) + }) + + it('checkRpcConnection', async () => { + expect( + await provider.checkRpcConnection(process.env.EVM_RPC_URL as unknown as string) + ).toBe(true) + }) + + it('checkWsConnection', async () => { + expect(await provider.checkWsConnection(process.env.EVM_WS_URL as unknown as string)).toBe( + true + ) + }) +}) diff --git a/packages/networks/tron/tests/setup.ts b/packages/networks/tron/tests/setup.ts new file mode 100644 index 0000000..6c04b6b --- /dev/null +++ b/packages/networks/tron/tests/setup.ts @@ -0,0 +1,13 @@ +import { Provider } from '../src/services/Provider.ts' + +let provider: Provider + +try { + provider = Provider.instance +} catch (e) { + provider = new Provider({ + testnet: true + }) +} + +export { provider } diff --git a/packages/networks/tron/tsconfig.json b/packages/networks/tron/tsconfig.json new file mode 100644 index 0000000..909f140 --- /dev/null +++ b/packages/networks/tron/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "noEmit": true, + "composite": true, + "declaration": true, + "outDir": "./dist/esm", + "declarationDir": "./dist/types" + }, + "extends": "../../../tsconfig.json", + "files": [ + "src/services/tronweb.d.ts", + ], + "include": [ + "src", + ".eslintrc.json", + "tests", + "vite.config.ts", + "esbuild.ts", + "vitest.config.ts", + "resources/*.json", + "../../../esbuild.ts", + "../../../vite.config.ts", + "../../../vitest.config.ts", + ] +} diff --git a/packages/networks/tron/vite.config.ts b/packages/networks/tron/vite.config.ts new file mode 100644 index 0000000..be98636 --- /dev/null +++ b/packages/networks/tron/vite.config.ts @@ -0,0 +1,10 @@ +import { mergeConfig } from 'vite' +import mainConfig from '../../../vite.config.ts' + +export default mergeConfig(mainConfig, { + build: { + lib: { + name: 'Tron' + } + } +}) diff --git a/packages/networks/tron/vite.svg b/packages/networks/tron/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/packages/networks/tron/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/networks/tron/vitest.config.ts b/packages/networks/tron/vitest.config.ts new file mode 100644 index 0000000..433e719 --- /dev/null +++ b/packages/networks/tron/vitest.config.ts @@ -0,0 +1,12 @@ +import { mergeConfig, defineConfig } from 'vitest/config' +import mainConfig from '../../../vite.config.ts' + +export default mergeConfig( + mainConfig, + defineConfig({ + test: { + testTimeout: 180000, + setupFiles: ['./tests/setup.ts'] + } + }) +) diff --git a/packages/types/package.json b/packages/types/package.json index a9fc6e9..e086b85 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@multiplechain/types", - "version": "0.1.53", + "version": "0.1.55", "type": "module", "main": "./src/index.ts", "types": "./src/index.ts", diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index a023e37..71f5ed8 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -161,9 +161,9 @@ export interface NftInterface /** * @param {number | string} nftId ID of the NFT that will be transferred - * @returns {Promise} Amount of the tokens that is being used by spender + * @returns {Promise} Amount of the tokens that is being used by spender */ - getApproved: (nftId: number | string) => Promise + getApproved: (nftId: number | string) => Promise /** * Transfers an NFT diff --git a/packages/types/src/models.ts b/packages/types/src/models.ts index 9d8df91..417114b 100644 --- a/packages/types/src/models.ts +++ b/packages/types/src/models.ts @@ -7,9 +7,10 @@ export interface TransactionInterface { id: string /** + * @param {number} ms - Milliseconds to wait * @returns {Promise} Promise of the transaction status */ - wait: () => Promise + wait: (ms?: number) => Promise /** * @returns {Promise} Raw transaction data that is taken by blockchain network via RPC. diff --git a/vite.config.ts b/vite.config.ts index e20eca5..5ed7853 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,13 +1,15 @@ import { defineConfig } from 'vite' import dts from 'vite-plugin-dts' import envCompatible from 'vite-plugin-env-compatible' +import { nodePolyfills } from 'vite-plugin-node-polyfills' export default defineConfig({ plugins: [ dts({ entryRoot: './src' }), - envCompatible() + envCompatible(), + nodePolyfills() ], build: { minify: true, diff --git a/vitest.config.ts b/vitest.config.ts index 2c90caf..401badf 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,7 +11,10 @@ export default mergeConfig( environment: 'node', exclude: [...configDefaults.exclude, 'e2e/*'], root: fileURLToPath(new URL('./', import.meta.url)), - setupFiles: ['./packages/networks/evm-chains/tests/setup.ts'] + setupFiles: [ + './packages/networks/evm-chains/tests/setup.ts', + './packages/networks/tron/tests/setup.ts' + ] } }) )