diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 3e958920..04c471cc 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -316,6 +316,16 @@ "count": 2 } }, + "packages/tron-wallet-snap/src/services/assets/mapControllerAsset.test.ts": { + "import-x/no-extraneous-dependencies": { + "count": 1 + } + }, + "packages/tron-wallet-snap/src/services/assets/mapControllerAsset.ts": { + "import-x/no-extraneous-dependencies": { + "count": 1 + } + }, "packages/tron-wallet-snap/src/services/config/ConfigProvider.ts": { "import-x/no-extraneous-dependencies": { "count": 1 diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index 71db1a30..b9b0cf6d 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -7,8 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `AssetsService.getAccountAssetsByScope` for instant controller-backed fungible asset reads by network. +- Route fungible asset reads (TRX, TRC10, TRC20) through `AssetsController:getAsset`. Protocol assets (energy, bandwidth, staking, lock/withdrawal, rewards) remain Snap-owned. + ### Changed +- Batch fungible asset reads through `AssetsController:getAssets` instead of per-asset `getAsset` loops. Account sync now fetches and persists only snap-owned protocol assets; fungibles are owned by Core `AssetsController`. +- Reorganize snap handlers into `assets`, `cronjob`, `keyring`, and `user-input` folders. +- Rename `AssetsService` account asset readers to `getAccountAssetByID`, `getAccountAssetsByIDs`, and `getAccountAssets`. - Bump `@metamask/keyring-api` from `^23.2.0` to `^23.7.0` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) - Bump `@metamask/keyring-snap-sdk` from `^8.0.0` to `^9.2.1` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) - Bump `@metamask/snaps-cli` from `^8.3.0` to `^8.4.1` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) diff --git a/packages/tron-wallet-snap/package.json b/packages/tron-wallet-snap/package.json index df2092c4..3d9b66a7 100644 --- a/packages/tron-wallet-snap/package.json +++ b/packages/tron-wallet-snap/package.json @@ -48,10 +48,12 @@ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch" }, "devDependencies": { + "@metamask/assets-controller": "11.2.0", "@metamask/auto-changelog": "^6.1.1", "@metamask/key-tree": "^10.1.1", "@metamask/keyring-api": "^23.7.0", "@metamask/keyring-snap-sdk": "^9.2.1", + "@metamask/messenger": "^2.0.0", "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", "@metamask/snaps-sdk": "^11.2.0", diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index e13773c8..bc13f90e 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "tcnp/6xxntfergEzeQYc7k96SfveVo+5kBQHGEXqZkQ=", + "shasum": "8SP19+soWqCyOukLqweBmUY1FK0v/fVvVhpf4/OiP58=", "location": { "npm": { "filePath": "dist/bundle.js", @@ -48,6 +48,9 @@ }, "endowment:assets": { "scopes": ["tron:728126428"] + }, + "endowment:messenger": { + "actions": ["AssetsController:getAsset", "AssetsController:getAssets"] } }, "platformVersion": "11.2.0", diff --git a/packages/tron-wallet-snap/src/clients/price-api/PriceApiClient.ts b/packages/tron-wallet-snap/src/clients/price-api/PriceApiClient.ts index 4f42f0b8..4f7a92d0 100644 --- a/packages/tron-wallet-snap/src/clients/price-api/PriceApiClient.ts +++ b/packages/tron-wallet-snap/src/clients/price-api/PriceApiClient.ts @@ -7,7 +7,7 @@ import { mapKeys } from 'lodash'; import type { ICache } from '../../caching/ICache'; import { useCache } from '../../caching/useCache'; -import { SPECIAL_ASSETS } from '../../constants'; +import { SNAP_OWNED_ASSETS } from '../../constants'; import type { ConfigProvider } from '../../services/config'; import { buildUrl } from '../../utils/buildUrl'; import type { ILogger } from '../../utils/logger'; @@ -257,7 +257,7 @@ export class PriceApiClient { assert(vsCurrency, VsCurrencyParamStruct); const filteredTokens = tokenCaip19Types.filter( - (tokenCaip19Type) => !SPECIAL_ASSETS.includes(tokenCaip19Type), + (tokenCaip19Type) => !SNAP_OWNED_ASSETS.includes(tokenCaip19Type), ); return this.#getMultipleSpotPrices_CACHE(filteredTokens, vsCurrency); diff --git a/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts b/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts index 0d3c1c93..b40710fc 100644 --- a/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts +++ b/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts @@ -3,7 +3,7 @@ import { array, assert } from '@metamask/superstruct'; import type { Infer } from '@metamask/superstruct'; import { CaipAssetTypeStruct, parseCaipAssetType } from '@metamask/utils'; -import { Network, SPECIAL_ASSETS } from '../../constants'; +import { Network, SNAP_OWNED_ASSETS } from '../../constants'; import type { TokenCaipAssetType } from '../../services/assets/types'; import { TokenCaipAssetTypeStruct } from '../../services/assets/types'; import type { ConfigProvider } from '../../services/config'; @@ -94,7 +94,7 @@ export class TokenApiClient { * Exclude TRON resource tokens (energy and bandwidth), staked tokens, and tokens not from supported networks. */ const supportedAssetTypes = assetTypes.filter((assetType) => { - if (SPECIAL_ASSETS.includes(assetType)) { + if (SNAP_OWNED_ASSETS.includes(assetType)) { return false; } const { chainId } = parseCaipAssetType(assetType); diff --git a/packages/tron-wallet-snap/src/constants/index.ts b/packages/tron-wallet-snap/src/constants/index.ts index 7dbb15d0..4b46a8cf 100644 --- a/packages/tron-wallet-snap/src/constants/index.ts +++ b/packages/tron-wallet-snap/src/constants/index.ts @@ -389,7 +389,7 @@ export const Networks = { }, } as const; -export const SPECIAL_ASSETS: string[] = [ +export const SNAP_OWNED_ASSETS: string[] = [ KnownCaip19Id.TrxStakedForBandwidthMainnet, KnownCaip19Id.TrxStakedForBandwidthNile, KnownCaip19Id.TrxStakedForBandwidthShasta, @@ -419,9 +419,12 @@ export const SPECIAL_ASSETS: string[] = [ KnownCaip19Id.MaximumEnergyShasta, ]; +/** @deprecated Use {@link SNAP_OWNED_ASSETS} instead. */ +export const SPECIAL_ASSETS = SNAP_OWNED_ASSETS; + export const ESSENTIAL_ASSETS: string[] = [ KnownCaip19Id.TrxMainnet, KnownCaip19Id.TrxNile, KnownCaip19Id.TrxShasta, - ...SPECIAL_ASSETS, + ...SNAP_OWNED_ASSETS, ]; diff --git a/packages/tron-wallet-snap/src/context.ts b/packages/tron-wallet-snap/src/context.ts index 029ec8eb..e63ce13f 100644 --- a/packages/tron-wallet-snap/src/context.ts +++ b/packages/tron-wallet-snap/src/context.ts @@ -1,3 +1,5 @@ +import { getMessenger } from '@metamask/snaps-sdk'; + import { InMemoryCache } from './caching/InMemoryCache'; import { StateCache } from './caching/StateCache'; import { PriceApiClient } from './clients/price-api/PriceApiClient'; @@ -7,12 +9,12 @@ import { TokenApiClient } from './clients/token-api/TokenApiClient'; import { TronHttpClient } from './clients/tron-http/TronHttpClient'; import { TrongridApiClient } from './clients/trongrid/TrongridApiClient'; import { TronWebFactory } from './clients/tronweb/TronWebFactory'; -import { AssetsHandler } from './handlers/assets'; +import { AssetsHandler } from './handlers/assets/assets'; import { ClientRequestHandler } from './handlers/clientRequest/clientRequest'; -import { CronHandler } from './handlers/cronjob'; -import { KeyringHandler } from './handlers/keyring'; +import { CronHandler } from './handlers/cronjob/cronjob'; +import { KeyringHandler } from './handlers/keyring/keyring'; import { RpcHandler } from './handlers/rpc/rpc'; -import { UserInputHandler } from './handlers/userInput'; +import { UserInputHandler } from './handlers/user-input/userInput'; import { AccountsRepository } from './services/accounts/AccountsRepository'; import { AccountsService } from './services/accounts/AccountsService'; import { AssetsRepository } from './services/assets/AssetsRepository'; @@ -29,6 +31,7 @@ import { TransactionScanService } from './services/transaction-scan/TransactionS import { TransactionsRepository } from './services/transactions/TransactionsRepository'; import { TransactionsService } from './services/transactions/TransactionsService'; import { WalletService } from './services/wallet/WalletService'; +import type { CoreMessenger } from './types/core-messenger'; import logger, { noOpLogger } from './utils/logger'; /** @@ -82,6 +85,8 @@ const priceApiClient = new PriceApiClient(configProvider, priceCache); // Token API client const tokenApiClient = new TokenApiClient(configProvider); +const coreMessenger = getMessenger(); + // Security Alerts API client const securityAlertsApiClient = new SecurityAlertsApiClient( configProvider, @@ -98,6 +103,7 @@ const assetsService = new AssetsService({ priceApiClient, tokenApiClient, snapClient, + coreMessenger, }); const transactionsService = new TransactionsService({ diff --git a/packages/tron-wallet-snap/src/handlers/assets.ts b/packages/tron-wallet-snap/src/handlers/assets/assets.ts similarity index 90% rename from packages/tron-wallet-snap/src/handlers/assets.ts rename to packages/tron-wallet-snap/src/handlers/assets/assets.ts index d0d72324..f7cc5428 100644 --- a/packages/tron-wallet-snap/src/handlers/assets.ts +++ b/packages/tron-wallet-snap/src/handlers/assets/assets.ts @@ -9,9 +9,9 @@ import type { OnAssetsMarketDataResponse, } from '@metamask/snaps-sdk'; -import type { AssetsService } from '../services/assets/AssetsService'; -import type { ILogger } from '../utils/logger'; -import { createPrefixedLogger } from '../utils/logger'; +import type { AssetsService } from '../../services/assets/AssetsService'; +import type { ILogger } from '../../utils/logger'; +import { createPrefixedLogger } from '../../utils/logger'; export class AssetsHandler { readonly #logger: ILogger; diff --git a/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.test.ts b/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.test.ts index 5719c0e7..ca80490a 100644 --- a/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.test.ts +++ b/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.test.ts @@ -38,7 +38,7 @@ import type { TransactionRawData } from '../../services/transaction-expiration-r import type { TransactionsService } from '../../services/transactions/TransactionsService'; import { trxToSun } from '../../utils/conversion'; import { mockLogger } from '../../utils/mockLogger'; -import { BackgroundEventMethod } from '../cronjob'; +import { BackgroundEventMethod } from '../cronjob/cronjob'; import { ClientRequestHandler } from './clientRequest'; import { ClientRequestMethod, SendErrorCodes } from './types'; import type { OnAmountInputRequestStruct } from './validation'; @@ -115,7 +115,7 @@ type WithClientRequestHandlerCallback = (payload: { Pick >; mockAssetsService: jest.Mocked< - Pick + Pick >; mockSendService: jest.Mocked< Pick< @@ -165,10 +165,10 @@ async function withClientRequestHandler( }; const mockAssetsService: jest.Mocked< - Pick + Pick > = { - getAssetsByAccountId: jest.fn(), - getAssetByAccountId: jest.fn(), + getAccountAssetsByIDs: jest.fn(), + getAccountAssetByID: jest.fn(), }; const mockSendService: jest.Mocked< @@ -304,7 +304,7 @@ describe('ClientRequestHandler', () => { } as unknown as jest.Mocked; mockAssetsService = { - getAssetsByAccountId: jest.fn(), + getAccountAssetsByIDs: jest.fn(), } as unknown as jest.Mocked; mockSendService = {} as unknown as jest.Mocked; @@ -736,7 +736,7 @@ describe('ClientRequestHandler', () => { mockTronWeb.trx.sign.mockResolvedValue(signedTransaction); // Mock available resources - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { rawAmount: '5000' }, // Bandwidth { rawAmount: '100000' }, // Energy ] as any); @@ -781,7 +781,7 @@ describe('ClientRequestHandler', () => { ).toHaveBeenCalledWith('TriggerSmartContract', expect.any(String)); // trx.sign is NOT called - fee computation uses unsigned transactions expect(mockTronWeb.trx.sign).not.toHaveBeenCalled(); - expect(mockAssetsService.getAssetsByAccountId).toHaveBeenCalledWith( + expect(mockAssetsService.getAccountAssetsByIDs).toHaveBeenCalledWith( TEST_ACCOUNT_ID, [Networks[scope].bandwidth.id, Networks[scope].energy.id], ); @@ -873,7 +873,7 @@ describe('ClientRequestHandler', () => { }; mockTronWeb.trx.sign.mockResolvedValue(signedTransaction); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { rawAmount: '1000' }, // Bandwidth { rawAmount: '0' }, // Energy (not needed for native transfer) ] as any); @@ -966,7 +966,7 @@ describe('ClientRequestHandler', () => { }); // No resources available - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ undefined, // No bandwidth asset undefined, // No energy asset ] as any); @@ -1490,7 +1490,7 @@ describe('ClientRequestHandler - signAndSendTransaction', () => { } as unknown as jest.Mocked; mockAssetsService = { - getAssetsByAccountId: jest.fn(), + getAccountAssetsByIDs: jest.fn(), } as unknown as jest.Mocked; mockSendService = {} as unknown as jest.Mocked; @@ -1762,7 +1762,7 @@ describe('ClientRequestHandler - onAmountInput', () => { ]; mockAccountsService.findById.mockResolvedValue(mockAccount); - mockAssetsService.getAssetsByAccountId.mockResolvedValue(mockAssets); + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue(mockAssets); const result = await handler.handle(request); @@ -1820,7 +1820,7 @@ describe('ClientRequestHandler - onAmountInput', () => { ]; mockAccountsService.findById.mockResolvedValue(mockAccount); - mockAssetsService.getAssetsByAccountId.mockResolvedValue(mockAssets); + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue(mockAssets); mockSendService.buildTransaction.mockResolvedValue(builtTransaction); mockFeeCalculatorService.computeFee.mockResolvedValue(mockFees); @@ -1892,7 +1892,7 @@ describe('ClientRequestHandler - onAmountInput', () => { ]; mockAccountsService.findById.mockResolvedValue(mockAccount); - mockAssetsService.getAssetsByAccountId.mockResolvedValue(mockAssets); + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue(mockAssets); mockSendService.buildTransaction.mockResolvedValue(builtTransaction); mockFeeCalculatorService.computeFee.mockResolvedValue(mockFees); @@ -1943,7 +1943,7 @@ describe('ClientRequestHandler - onAmountInput', () => { ]; mockAccountsService.findById.mockResolvedValue(mockAccount); - mockAssetsService.getAssetsByAccountId.mockResolvedValue(mockAssets); + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue(mockAssets); const result = await handler.handle(request); @@ -2004,7 +2004,7 @@ describe('ClientRequestHandler - onAmountInput', () => { ]; mockAccountsService.findById.mockResolvedValue(mockAccount); - mockAssetsService.getAssetsByAccountId.mockResolvedValue(mockAssets); + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue(mockAssets); mockSendService.buildTransaction.mockResolvedValue(builtTransaction); mockFeeCalculatorService.computeFee.mockResolvedValue(mockFees); @@ -2094,10 +2094,10 @@ describe('ClientRequestHandler - computeStakeFee', () => { const nativeAssetId = Networks[scope].nativeToken.id; // Mock native balance and resources - mockAssetsService.getAssetByAccountId.mockResolvedValue({ + mockAssetsService.getAccountAssetByID.mockResolvedValue({ uiAmount: '100', } as AssetEntity); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { rawAmount: '5000' }, // Bandwidth { rawAmount: '100000' }, // Energy ] as AssetEntity[]); @@ -2130,11 +2130,11 @@ describe('ClientRequestHandler - computeStakeFee', () => { 'ENERGY', 'TGJn1wnUYHJbvN88cynZbsAz2EMeZq73yx', ); - expect(mockAssetsService.getAssetByAccountId).toHaveBeenCalledWith( + expect(mockAssetsService.getAccountAssetByID).toHaveBeenCalledWith( TEST_ACCOUNT_ID, nativeAssetId, ); - expect(mockAssetsService.getAssetsByAccountId).toHaveBeenCalledWith( + expect(mockAssetsService.getAccountAssetsByIDs).toHaveBeenCalledWith( TEST_ACCOUNT_ID, [Networks[scope].bandwidth.id, Networks[scope].energy.id], ); @@ -2179,7 +2179,7 @@ describe('ClientRequestHandler - computeStakeFee', () => { } as any); // Account has only 5 TRX - mockAssetsService.getAssetByAccountId.mockResolvedValue({ + mockAssetsService.getAccountAssetByID.mockResolvedValue({ uiAmount: '5', } as AssetEntity); @@ -2237,7 +2237,7 @@ describe('ClientRequestHandler - confirmSend validation', () => { uiAmount: '100', rawAmount: '100000000', } as NativeAsset; - mockAssetsService.getAssetByAccountId.mockResolvedValue(mockAsset); + mockAssetsService.getAccountAssetByID.mockResolvedValue(mockAsset); // validateSend returns insufficient balance mockSendService.validateSend.mockResolvedValue({ @@ -2306,7 +2306,7 @@ describe('ClientRequestHandler - confirmSend validation', () => { uiAmount: '100', rawAmount: '100000000', } as NativeAsset; - mockAssetsService.getAssetByAccountId.mockResolvedValue(mockAsset); + mockAssetsService.getAccountAssetByID.mockResolvedValue(mockAsset); // validateSend returns insufficient balance to cover fee mockSendService.validateSend.mockResolvedValue({ @@ -2368,13 +2368,13 @@ describe('ClientRequestHandler - confirmSend validation', () => { uiAmount: '100', rawAmount: '100000000', } as NativeAsset; - mockAssetsService.getAssetByAccountId.mockResolvedValue(mockAsset); + mockAssetsService.getAccountAssetByID.mockResolvedValue(mockAsset); // validateSend returns valid. mockSendService.validateSend.mockResolvedValue({ valid: true }); // Mock the rest of the flow. - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { rawAmount: '1000' }, // Bandwidth { rawAmount: '50000' }, // Energy ] as any); @@ -2530,7 +2530,7 @@ describe('ClientRequestHandler - confirmSend validation', () => { } as any); // Asset not found - (mockAssetsService.getAssetByAccountId as jest.Mock).mockResolvedValue( + (mockAssetsService.getAccountAssetByID as jest.Mock).mockResolvedValue( null, ); diff --git a/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.ts b/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.ts index bca2223d..4cf1594b 100644 --- a/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.ts +++ b/packages/tron-wallet-snap/src/handlers/clientRequest/clientRequest.ts @@ -46,7 +46,7 @@ import { assertTransactionSignerConsistency, assertTransactionStructure, } from '../../validation/transaction'; -import { BackgroundEventMethod } from '../cronjob'; +import { BackgroundEventMethod } from '../cronjob/cronjob'; import { ClientRequestMethod, SendErrorCodes } from './types'; import { ClaimTrxStakingRewardsRequestStruct, @@ -370,7 +370,7 @@ export class ClientRequestHandler { const scope = chainId as Network; const [asset, nativeTokenAsset, bandwidthAsset, energyAsset] = - await this.#assetsService.getAssetsByAccountId(accountId, [ + await this.#assetsService.getAccountAssetsByIDs(accountId, [ assetId, Networks[scope].nativeToken.id, Networks[scope].bandwidth.id, @@ -483,7 +483,7 @@ export class ClientRequestHandler { }; } - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( fromAccountId, assetId, ); @@ -527,7 +527,7 @@ export class ClientRequestHandler { /** * Get available Energy and Bandwidth from account assets. */ - this.#assetsService.getAssetsByAccountId(fromAccountId, [ + this.#assetsService.getAccountAssetsByIDs(fromAccountId, [ Networks[scope].bandwidth.id, Networks[scope].energy.id, ]), @@ -673,7 +673,7 @@ export class ClientRequestHandler { * Get available Energy and Bandwidth from account assets. */ const [bandwidthAsset, energyAsset] = - await this.#assetsService.getAssetsByAccountId(accountId, [ + await this.#assetsService.getAccountAssetsByIDs(accountId, [ Networks[scope].bandwidth.id, Networks[scope].energy.id, ]); @@ -728,7 +728,7 @@ export class ClientRequestHandler { const scope = Network.Mainnet; - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( fromAccountId, Networks[scope].nativeToken.id, ); @@ -759,7 +759,7 @@ export class ClientRequestHandler { * Get available Energy and Bandwidth from account assets. */ const [bandwidthAsset, energyAsset] = - await this.#assetsService.getAssetsByAccountId(fromAccountId, [ + await this.#assetsService.getAccountAssetsByIDs(fromAccountId, [ Networks[scope].bandwidth.id, Networks[scope].energy.id, ]); @@ -804,7 +804,7 @@ export class ClientRequestHandler { const { accountId, assetId, value } = request.params; await this.#accountsService.findByIdOrThrow(accountId); - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( accountId, assetId, ); @@ -851,7 +851,7 @@ export class ClientRequestHandler { const account = await this.#accountsService.findByIdOrThrow(fromAccountId); - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( fromAccountId, assetId, ); @@ -913,7 +913,7 @@ export class ClientRequestHandler { const stakedAssetId = `${assetId}-staked-for-${purpose.toLowerCase()}`; await this.#accountsService.findByIdOrThrow(accountId); - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( accountId, stakedAssetId, ); @@ -967,7 +967,7 @@ export class ClientRequestHandler { const account = await this.#accountsService.findByIdOrThrow(accountId); - const asset = await this.#assetsService.getAssetByAccountId( + const asset = await this.#assetsService.getAccountAssetByID( accountId, stakedAssetId, ); diff --git a/packages/tron-wallet-snap/src/handlers/cronjob.test.tsx b/packages/tron-wallet-snap/src/handlers/cronjob/cronjob.test.tsx similarity index 96% rename from packages/tron-wallet-snap/src/handlers/cronjob.test.tsx rename to packages/tron-wallet-snap/src/handlers/cronjob/cronjob.test.tsx index f00cacc2..fd4123d9 100644 --- a/packages/tron-wallet-snap/src/handlers/cronjob.test.tsx +++ b/packages/tron-wallet-snap/src/handlers/cronjob/cronjob.test.tsx @@ -1,24 +1,24 @@ -import type { PriceApiClient } from '../clients/price-api/PriceApiClient'; -import type { SnapClient } from '../clients/snap/SnapClient'; -import type { TronHttpClient } from '../clients/tron-http/TronHttpClient'; -import type { TronWebFactory } from '../clients/tronweb/TronWebFactory'; +import type { PriceApiClient } from '../../clients/price-api/PriceApiClient'; +import type { SnapClient } from '../../clients/snap/SnapClient'; +import type { TronHttpClient } from '../../clients/tron-http/TronHttpClient'; +import type { TronWebFactory } from '../../clients/tronweb/TronWebFactory'; import { Network, TRACK_TX_INTERVAL, TRACK_TX_MAX_ATTEMPTS, -} from '../constants'; -import type { AccountsService } from '../services/accounts/AccountsService'; -import type { State, UnencryptedStateValue } from '../services/state/State'; -import { TransactionExpirationRefresherService } from '../services/transaction-expiration-refresher/TransactionExpirationRefresherService'; -import type { JsonTransactionRawData } from '../services/transaction-expiration-refresher/types'; -import type { TransactionScanService } from '../services/transaction-scan/TransactionScanService'; -import { SimulationStatus } from '../services/transaction-scan/types'; -import type { TransactionScanResult } from '../services/transaction-scan/types'; -import { FetchStatus } from '../types/snap'; -import { CONFIRM_SIGN_TRANSACTION_INTERFACE_NAME } from '../ui/confirmation/views/ConfirmSignTransaction/types'; -import type { ConfirmSignTransactionContext } from '../ui/confirmation/views/ConfirmSignTransaction/types'; -import type { ConfirmTransactionRequestContext } from '../ui/confirmation/views/ConfirmTransactionRequest/types'; -import type { ILogger } from '../utils/logger'; +} from '../../constants'; +import type { AccountsService } from '../../services/accounts/AccountsService'; +import type { State, UnencryptedStateValue } from '../../services/state/State'; +import { TransactionExpirationRefresherService } from '../../services/transaction-expiration-refresher/TransactionExpirationRefresherService'; +import type { JsonTransactionRawData } from '../../services/transaction-expiration-refresher/types'; +import type { TransactionScanService } from '../../services/transaction-scan/TransactionScanService'; +import { SimulationStatus } from '../../services/transaction-scan/types'; +import type { TransactionScanResult } from '../../services/transaction-scan/types'; +import { FetchStatus } from '../../types/snap'; +import { CONFIRM_SIGN_TRANSACTION_INTERFACE_NAME } from '../../ui/confirmation/views/ConfirmSignTransaction/types'; +import type { ConfirmSignTransactionContext } from '../../ui/confirmation/views/ConfirmSignTransaction/types'; +import type { ConfirmTransactionRequestContext } from '../../ui/confirmation/views/ConfirmTransactionRequest/types'; +import type { ILogger } from '../../utils/logger'; import { BackgroundEventMethod, CronHandler } from './cronjob'; /** diff --git a/packages/tron-wallet-snap/src/handlers/cronjob.tsx b/packages/tron-wallet-snap/src/handlers/cronjob/cronjob.tsx similarity index 92% rename from packages/tron-wallet-snap/src/handlers/cronjob.tsx rename to packages/tron-wallet-snap/src/handlers/cronjob/cronjob.tsx index 05b5d5a2..bcc30cbf 100644 --- a/packages/tron-wallet-snap/src/handlers/cronjob.tsx +++ b/packages/tron-wallet-snap/src/handlers/cronjob/cronjob.tsx @@ -1,29 +1,29 @@ import type { JsonRpcRequest } from '@metamask/snaps-sdk'; -import type { PriceApiClient } from '../clients/price-api/PriceApiClient'; -import type { SnapClient } from '../clients/snap/SnapClient'; -import type { TronHttpClient } from '../clients/tron-http/TronHttpClient'; -import type { Network } from '../constants'; -import { TRACK_TX_INTERVAL, TRACK_TX_MAX_ATTEMPTS } from '../constants'; -import type { TronKeyringAccount } from '../entities/keyring-account'; -import type { AccountsService } from '../services/accounts/AccountsService'; -import type { State, UnencryptedStateValue } from '../services/state/State'; -import type { TransactionExpirationRefresherService } from '../services/transaction-expiration-refresher/TransactionExpirationRefresherService'; +import type { PriceApiClient } from '../../clients/price-api/PriceApiClient'; +import type { SnapClient } from '../../clients/snap/SnapClient'; +import type { TronHttpClient } from '../../clients/tron-http/TronHttpClient'; +import type { Network } from '../../constants'; +import { TRACK_TX_INTERVAL, TRACK_TX_MAX_ATTEMPTS } from '../../constants'; +import type { TronKeyringAccount } from '../../entities/keyring-account'; +import type { AccountsService } from '../../services/accounts/AccountsService'; +import type { State, UnencryptedStateValue } from '../../services/state/State'; +import type { TransactionExpirationRefresherService } from '../../services/transaction-expiration-refresher/TransactionExpirationRefresherService'; import type { JsonTransactionRawData, TransactionRawData, -} from '../services/transaction-expiration-refresher/types'; -import { EXPIRED_TRANSACTION_SCAN } from '../services/transaction-scan/buildExpiredScanResult'; -import type { TransactionScanService } from '../services/transaction-scan/TransactionScanService'; -import { FetchStatus } from '../types/snap'; -import { ConfirmSignTransaction } from '../ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction'; -import { CONFIRM_SIGN_TRANSACTION_INTERFACE_NAME } from '../ui/confirmation/views/ConfirmSignTransaction/types'; -import type { ConfirmSignTransactionContext } from '../ui/confirmation/views/ConfirmSignTransaction/types'; -import { ConfirmTransactionRequest } from '../ui/confirmation/views/ConfirmTransactionRequest/ConfirmTransactionRequest'; -import { CONFIRM_TRANSACTION_INTERFACE_NAME } from '../ui/confirmation/views/ConfirmTransactionRequest/types'; -import type { ConfirmTransactionRequestContext } from '../ui/confirmation/views/ConfirmTransactionRequest/types'; -import type { ILogger } from '../utils/logger'; -import { createPrefixedLogger } from '../utils/logger'; +} from '../../services/transaction-expiration-refresher/types'; +import { EXPIRED_TRANSACTION_SCAN } from '../../services/transaction-scan/buildExpiredScanResult'; +import type { TransactionScanService } from '../../services/transaction-scan/TransactionScanService'; +import { FetchStatus } from '../../types/snap'; +import { ConfirmSignTransaction } from '../../ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction'; +import { CONFIRM_SIGN_TRANSACTION_INTERFACE_NAME } from '../../ui/confirmation/views/ConfirmSignTransaction/types'; +import type { ConfirmSignTransactionContext } from '../../ui/confirmation/views/ConfirmSignTransaction/types'; +import { ConfirmTransactionRequest } from '../../ui/confirmation/views/ConfirmTransactionRequest/ConfirmTransactionRequest'; +import { CONFIRM_TRANSACTION_INTERFACE_NAME } from '../../ui/confirmation/views/ConfirmTransactionRequest/types'; +import type { ConfirmTransactionRequestContext } from '../../ui/confirmation/views/ConfirmTransactionRequest/types'; +import type { ILogger } from '../../utils/logger'; +import { createPrefixedLogger } from '../../utils/logger'; export enum CronjobMethod { ContinuouslySynchronizeSelectedAccounts = 'onSynchronizeSelectedAccountsCronjob', diff --git a/packages/tron-wallet-snap/src/handlers/keyring-types.ts b/packages/tron-wallet-snap/src/handlers/keyring/keyring-types.ts similarity index 100% rename from packages/tron-wallet-snap/src/handlers/keyring-types.ts rename to packages/tron-wallet-snap/src/handlers/keyring/keyring-types.ts diff --git a/packages/tron-wallet-snap/src/handlers/keyring.test.ts b/packages/tron-wallet-snap/src/handlers/keyring/keyring.test.ts similarity index 97% rename from packages/tron-wallet-snap/src/handlers/keyring.test.ts rename to packages/tron-wallet-snap/src/handlers/keyring/keyring.test.ts index b3c68105..35a6f9d7 100644 --- a/packages/tron-wallet-snap/src/handlers/keyring.test.ts +++ b/packages/tron-wallet-snap/src/handlers/keyring/keyring.test.ts @@ -9,15 +9,15 @@ import { } from '@metamask/snaps-sdk'; import { bytesToBase64, bytesToHex, stringToBytes } from '@metamask/utils'; -import type { SnapClient } from '../clients/snap/SnapClient'; -import { Network } from '../constants'; -import type { TronKeyringAccount } from '../entities/keyring-account'; -import type { AccountsService } from '../services/accounts/AccountsService'; -import type { AssetsService } from '../services/assets/AssetsService'; -import type { ConfirmationHandler } from '../services/confirmation/ConfirmationHandler'; -import type { TransactionsService } from '../services/transactions/TransactionsService'; -import type { WalletService } from '../services/wallet/WalletService'; -import { mockLogger } from '../utils/mockLogger'; +import type { SnapClient } from '../../clients/snap/SnapClient'; +import { Network } from '../../constants'; +import type { TronKeyringAccount } from '../../entities/keyring-account'; +import type { AccountsService } from '../../services/accounts/AccountsService'; +import type { AssetsService } from '../../services/assets/AssetsService'; +import type { ConfirmationHandler } from '../../services/confirmation/ConfirmationHandler'; +import type { TransactionsService } from '../../services/transactions/TransactionsService'; +import type { WalletService } from '../../services/wallet/WalletService'; +import { mockLogger } from '../../utils/mockLogger'; import { KeyringHandler } from './keyring'; import { TronMultichainMethod } from './keyring-types'; diff --git a/packages/tron-wallet-snap/src/handlers/keyring.ts b/packages/tron-wallet-snap/src/handlers/keyring/keyring.ts similarity index 92% rename from packages/tron-wallet-snap/src/handlers/keyring.ts rename to packages/tron-wallet-snap/src/handlers/keyring/keyring.ts index 7864a0c6..0e6f63f5 100644 --- a/packages/tron-wallet-snap/src/handlers/keyring.ts +++ b/packages/tron-wallet-snap/src/handlers/keyring/keyring.ts @@ -34,20 +34,20 @@ import type { } from '@metamask/utils'; import { sortBy } from 'lodash'; -import type { SnapClient } from '../clients/snap/SnapClient'; -import { ESSENTIAL_ASSETS } from '../constants'; -import type { Network } from '../constants'; -import { asStrictKeyringAccount } from '../entities/keyring-account'; -import type { TronKeyringAccount } from '../entities/keyring-account'; -import type { AccountsService } from '../services/accounts/AccountsService'; -import type { CreateAccountOptions } from '../services/accounts/types'; -import type { AssetsService } from '../services/assets/AssetsService'; -import type { ConfirmationHandler } from '../services/confirmation/ConfirmationHandler'; -import type { TransactionsService } from '../services/transactions/TransactionsService'; -import type { WalletService } from '../services/wallet/WalletService'; -import { sanitizeSensitiveError } from '../utils/errors'; -import { createPrefixedLogger } from '../utils/logger'; -import type { ILogger } from '../utils/logger'; +import type { SnapClient } from '../../clients/snap/SnapClient'; +import { ESSENTIAL_ASSETS } from '../../constants'; +import type { Network } from '../../constants'; +import { asStrictKeyringAccount } from '../../entities/keyring-account'; +import type { TronKeyringAccount } from '../../entities/keyring-account'; +import type { AccountsService } from '../../services/accounts/AccountsService'; +import type { CreateAccountOptions } from '../../services/accounts/types'; +import type { AssetsService } from '../../services/assets/AssetsService'; +import type { ConfirmationHandler } from '../../services/confirmation/ConfirmationHandler'; +import type { TransactionsService } from '../../services/transactions/TransactionsService'; +import type { WalletService } from '../../services/wallet/WalletService'; +import { sanitizeSensitiveError } from '../../utils/errors'; +import { createPrefixedLogger } from '../../utils/logger'; +import type { ILogger } from '../../utils/logger'; import { CreateAccountOptionsStruct, DeleteAccountStruct, @@ -60,14 +60,14 @@ import { SignTransactionRequestStruct, TronKeyringRequestStruct, UuidStruct, -} from '../validation/structs'; -import type { TronWalletKeyringRequest } from '../validation/structs'; +} from '../../validation/structs'; +import type { TronWalletKeyringRequest } from '../../validation/structs'; import { validateOrigin, validateRequest, validateResponse, -} from '../validation/validators'; -import { BackgroundEventMethod } from './cronjob'; +} from '../../validation/validators'; +import { BackgroundEventMethod } from '../cronjob/cronjob'; import { TronMultichainMethod } from './keyring-types'; export class KeyringHandler implements Keyring { diff --git a/packages/tron-wallet-snap/src/handlers/userInput.ts b/packages/tron-wallet-snap/src/handlers/user-input/userInput.ts similarity index 83% rename from packages/tron-wallet-snap/src/handlers/userInput.ts rename to packages/tron-wallet-snap/src/handlers/user-input/userInput.ts index 4aadc48e..a90ce451 100644 --- a/packages/tron-wallet-snap/src/handlers/userInput.ts +++ b/packages/tron-wallet-snap/src/handlers/user-input/userInput.ts @@ -1,11 +1,11 @@ import type { InterfaceContext, UserInputEvent } from '@metamask/snaps-sdk'; -import type { SnapClient } from '../clients/snap/SnapClient'; -import { createEventHandlers as createSignMessageEvents } from '../ui/confirmation/views/ConfirmSignMessage/events'; -import { createEventHandlers as createSignTransactionEvents } from '../ui/confirmation/views/ConfirmSignTransaction/events'; -import { createEventHandlers as createTransactionConfirmationEvents } from '../ui/confirmation/views/ConfirmTransactionRequest/events'; -import { createPrefixedLogger } from '../utils/logger'; -import type { ILogger } from '../utils/logger'; +import type { SnapClient } from '../../clients/snap/SnapClient'; +import { createEventHandlers as createSignMessageEvents } from '../../ui/confirmation/views/ConfirmSignMessage/events'; +import { createEventHandlers as createSignTransactionEvents } from '../../ui/confirmation/views/ConfirmSignTransaction/events'; +import { createEventHandlers as createTransactionConfirmationEvents } from '../../ui/confirmation/views/ConfirmTransactionRequest/events'; +import { createPrefixedLogger } from '../../utils/logger'; +import type { ILogger } from '../../utils/logger'; export class UserInputHandler { readonly #logger: ILogger; diff --git a/packages/tron-wallet-snap/src/services/assets/AssetsService.test.ts b/packages/tron-wallet-snap/src/services/assets/AssetsService.test.ts index b41e8c7d..7ab26821 100644 --- a/packages/tron-wallet-snap/src/services/assets/AssetsService.test.ts +++ b/packages/tron-wallet-snap/src/services/assets/AssetsService.test.ts @@ -1,17 +1,18 @@ +import type { Asset } from '@metamask/assets-controller'; import type { KeyringAccount } from '@metamask/keyring-api'; import { KeyringEvent } from '@metamask/keyring-api'; import { emitSnapKeyringEvent } from '@metamask/keyring-snap-sdk'; import type { PriceApiClient } from '../../clients/price-api/PriceApiClient'; -import type { SpotPrices } from '../../clients/price-api/types'; import type { SnapClient } from '../../clients/snap/SnapClient'; import type { TokenApiClient } from '../../clients/token-api/TokenApiClient'; import type { AccountResources, TronHttpClient } from '../../clients/tron-http'; import { TrongridAccountNotFoundError } from '../../clients/trongrid/errors'; import type { TrongridApiClient } from '../../clients/trongrid/TrongridApiClient'; -import type { Trc20Balance, TronAccount } from '../../clients/trongrid/types'; -import { KnownCaip19Id, Network } from '../../constants'; +import type { TronAccount } from '../../clients/trongrid/types'; +import { KnownCaip19Id, Network, SNAP_OWNED_ASSETS } from '../../constants'; import type { AssetEntity } from '../../entities/assets'; +import type { CoreMessengerCaller } from '../../types/core-messenger'; import { mockLogger } from '../../utils/mockLogger'; import type { AssetsRepository } from './AssetsRepository'; import type { NativeCaipAssetType, TokenCaipAssetType } from './types'; @@ -51,6 +52,52 @@ jest.mock('@metamask/keyring-snap-sdk', () => ({ // eslint-disable-next-line @typescript-eslint/no-require-imports const { AssetsService } = require('./AssetsService'); +function snapOwnedAssetsOnly(assets: AssetEntity[]): AssetEntity[] { + return assets.filter((asset) => SNAP_OWNED_ASSETS.includes(asset.assetType)); +} + +function createMessengerCallMock( + getAsset: jest.Mock, + getAssets: jest.Mock = jest.fn().mockResolvedValue({}), +): (method: string, ...args: unknown[]) => Promise { + return async (method: string, ...args: unknown[]) => { + switch (method) { + case 'AssetsController:getAsset': + return getAsset(...args); + case 'AssetsController:getAssets': + return getAssets(...args); + default: + return undefined; + } + }; +} + +function buildControllerAsset( + assetId: string, + amount: string, + metadata: { + symbol: string; + name: string; + decimals: number; + image?: string; + }, +): Asset { + return { + id: assetId as Asset['id'], + chainId: Network.Mainnet as Asset['chainId'], + balance: { amount }, + metadata: { + type: 'fungible', + symbol: metadata.symbol, + name: metadata.name, + decimals: metadata.decimals, + image: metadata.image, + }, + price: { price: 0, lastUpdated: 0 }, + fiatValue: 0, + } as Asset; +} + const mockAccount: KeyringAccount = { id: 'test-account-id', address: 'TGJn1wnUYHJbvN88cynZbsAz2EMeZq73yx', @@ -72,22 +119,6 @@ const emptyAccountResources: AccountResources = { TotalEnergyWeight: 0, }; -/** - * Creates properly typed SpotPrices for tests. - * - * @param entries - Map of asset ID to price info. - * @returns SpotPrices object. - */ -const createSpotPrices = ( - entries: Record, -): SpotPrices => - Object.fromEntries( - Object.entries(entries).map(([key, value]) => [ - key, - { id: value.id, price: value.price }, - ]), - ); - /** * Creates a properly typed TronAccount for tests. * Uses snake_case property names to match Tron API response format. @@ -187,6 +218,7 @@ type WithAssetsServiceCallback = (payload: { >; mockTokenApiClient: jest.Mocked>; mockSnapClient: jest.Mocked>; + mockCoreMessenger: jest.Mocked; }) => Promise | ReturnValue; /** @@ -259,6 +291,11 @@ async function withAssetsService( trackError: jest.fn().mockResolvedValue(undefined), }; + const mockGetAsset = jest.fn(); + const mockCoreMessenger: jest.Mocked = { + call: jest.fn().mockImplementation(createMessengerCallMock(mockGetAsset)), + }; + const assetsService = new AssetsService({ logger: mockLogger, assetsRepository: mockAssetsRepository, @@ -268,6 +305,7 @@ async function withAssetsService( priceApiClient: mockPriceApiClient, tokenApiClient: mockTokenApiClient, snapClient: mockSnapClient, + coreMessenger: mockCoreMessenger, }); return await testFunction({ @@ -279,19 +317,19 @@ async function withAssetsService( mockPriceApiClient, mockTokenApiClient, mockSnapClient, + mockCoreMessenger, }); } describe('AssetsService', () => { describe('fetchAssetsAndBalancesForAccount', () => { describe('inactive account fallback', () => { - it('falls back to TRC20 balance endpoint when account info fails (inactive account)', async () => { + it('skips TRC20 fallback and returns protocol assets only when account info fails', async () => { await withAssetsService( async ({ assetsService, mockTrongridApiClient, mockTronHttpClient, - mockPriceApiClient, }) => { mockTrongridApiClient.getAccountInfoByAddress.mockRejectedValue( new TrongridAccountNotFoundError(), @@ -300,20 +338,6 @@ describe('AssetsService', () => { emptyAccountResources, ); - const trc20Balances = [ - { TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: '24249143' }, - ]; - mockTrongridApiClient.getTrc20BalancesByAddress.mockResolvedValue( - trc20Balances, - ); - - const trc20AssetId = `${String(Network.Mainnet)}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; - mockPriceApiClient.getMultipleSpotPrices.mockResolvedValue( - createSpotPrices({ - [trc20AssetId]: { id: trc20AssetId, price: 1.0 }, - }), - ); - const assets = await assetsService.fetchAssetsAndBalancesForAccount( Network.Mainnet, mockAccount, @@ -321,27 +345,22 @@ describe('AssetsService', () => { expect( mockTrongridApiClient.getTrc20BalancesByAddress, - ).toHaveBeenCalledWith(Network.Mainnet, mockAccount.address); - - const trxAsset = assets.find( - (asset: AssetEntity) => - asset.assetType === KnownCaip19Id.TrxMainnet, - ); - expect(trxAsset).toBeDefined(); - expect(trxAsset?.rawAmount).toBe('0'); - - const expectedTrc20AssetType = `${String(Network.Mainnet)}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; - const trc20Asset = assets.find( - (asset: AssetEntity) => - asset.assetType === expectedTrc20AssetType, - ); - expect(trc20Asset).toBeDefined(); - expect(trc20Asset?.rawAmount).toBe('24249143'); + ).not.toHaveBeenCalled(); + expect( + assets.every((asset) => + SNAP_OWNED_ASSETS.includes(asset.assetType), + ), + ).toBe(true); + expect( + assets.some( + (asset) => asset.assetType === KnownCaip19Id.TrxMainnet, + ), + ).toBe(false); }, ); }); - it('returns zero TRX and resources when fallback also returns empty', async () => { + it('returns protocol resources when inactive account has empty resources', async () => { await withAssetsService( async ({ assetsService, @@ -354,9 +373,6 @@ describe('AssetsService', () => { mockTronHttpClient.getAccountResources.mockResolvedValue( emptyAccountResources, ); - mockTrongridApiClient.getTrc20BalancesByAddress.mockResolvedValue( - [], - ); const assets = await assetsService.fetchAssetsAndBalancesForAccount( Network.Mainnet, @@ -365,14 +381,7 @@ describe('AssetsService', () => { expect( mockTrongridApiClient.getTrc20BalancesByAddress, - ).toHaveBeenCalledWith(Network.Mainnet, mockAccount.address); - - const trxAsset = assets.find( - (asset: AssetEntity) => - asset.assetType === KnownCaip19Id.TrxMainnet, - ); - expect(trxAsset).toBeDefined(); - expect(trxAsset?.rawAmount).toBe('0'); + ).not.toHaveBeenCalled(); const bandwidthAsset = assets.find( (asset: AssetEntity) => @@ -388,75 +397,12 @@ describe('AssetsService', () => { ); }); - it('gracefully handles fallback endpoint failure', async () => { - await withAssetsService( - async ({ - assetsService, - mockTrongridApiClient, - mockTronHttpClient, - }) => { - mockTrongridApiClient.getAccountInfoByAddress.mockRejectedValue( - new TrongridAccountNotFoundError(), - ); - mockTronHttpClient.getAccountResources.mockResolvedValue( - emptyAccountResources, - ); - mockTrongridApiClient.getTrc20BalancesByAddress.mockRejectedValue( - new Error('Network error'), - ); - - const assets = await assetsService.fetchAssetsAndBalancesForAccount( - Network.Mainnet, - mockAccount, - ); - - const trxAsset = assets.find( - (asset: AssetEntity) => - asset.assetType === KnownCaip19Id.TrxMainnet, - ); - expect(trxAsset).toBeDefined(); - expect(trxAsset?.rawAmount).toBe('0'); - }, - ); - }); - - it('tracks fallback endpoint errors', async () => { - await withAssetsService( - async ({ - assetsService, - mockSnapClient, - mockTrongridApiClient, - mockTronHttpClient, - }) => { - const error = new Error('Network error'); - - mockTrongridApiClient.getAccountInfoByAddress.mockRejectedValue( - new Error('Account not found or no data returned'), - ); - mockTronHttpClient.getAccountResources.mockResolvedValue( - emptyAccountResources, - ); - mockTrongridApiClient.getTrc20BalancesByAddress.mockRejectedValue( - error, - ); - - await assetsService.fetchAssetsAndBalancesForAccount( - Network.Mainnet, - mockAccount, - ); - - expect(mockSnapClient.trackError).toHaveBeenCalledWith(error); - }, - ); - }); - - it('filters out TRC20 tokens without price data from inactive account', async () => { + it('returns protocol assets when inactive account info fails', async () => { await withAssetsService( async ({ assetsService, mockTrongridApiClient, mockTronHttpClient, - mockPriceApiClient, }) => { mockTrongridApiClient.getAccountInfoByAddress.mockRejectedValue( new TrongridAccountNotFoundError(), @@ -465,50 +411,29 @@ describe('AssetsService', () => { emptyAccountResources, ); - const trc20BalancesWithSpam: Trc20Balance[] = [ - { TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: '24249143' }, // USDT - has price - { TSpamToken123456789: '1000000000' }, // Spam token - no price - ]; - mockTrongridApiClient.getTrc20BalancesByAddress.mockResolvedValue( - trc20BalancesWithSpam, - ); - - const usdtAssetId = `${String(Network.Mainnet)}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; - mockPriceApiClient.getMultipleSpotPrices.mockResolvedValue( - createSpotPrices({ - [usdtAssetId]: { id: usdtAssetId, price: 1.0 }, - }), - ); - const assets = await assetsService.fetchAssetsAndBalancesForAccount( Network.Mainnet, mockAccount, ); - const usdtAssetType = `${String(Network.Mainnet)}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; - const usdtAsset = assets.find( - (asset: AssetEntity) => asset.assetType === usdtAssetType, - ); - expect(usdtAsset).toBeDefined(); - - const spamAssetType = `${String(Network.Mainnet)}/trc20:TSpamToken123456789`; - const spamAsset = assets.find( - (asset: AssetEntity) => asset.assetType === spamAssetType, - ); - expect(spamAsset).toBeUndefined(); + expect(assets.length).toBeGreaterThan(0); + expect( + assets.every((asset) => + SNAP_OWNED_ASSETS.includes(asset.assetType), + ), + ).toBe(true); }, ); }); }); describe('partial failure handling', () => { - it('uses fallback when account info fails even if resources succeed (inactive account)', async () => { + it('returns protocol assets when account info fails even if resources succeed (inactive account)', async () => { await withAssetsService( async ({ assetsService, mockTrongridApiClient, mockTronHttpClient, - mockPriceApiClient, }) => { mockTrongridApiClient.getAccountInfoByAddress.mockRejectedValue( new TrongridAccountNotFoundError(), @@ -520,20 +445,6 @@ describe('AssetsService', () => { EnergyLimit: 0, }); - const trc20Balances = [ - { TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: '100000' }, - ]; - mockTrongridApiClient.getTrc20BalancesByAddress.mockResolvedValue( - trc20Balances, - ); - - const trc20AssetId = `${String(Network.Mainnet)}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; - mockPriceApiClient.getMultipleSpotPrices.mockResolvedValue( - createSpotPrices({ - [trc20AssetId]: { id: trc20AssetId, price: 1.0 }, - }), - ); - const assets = await assetsService.fetchAssetsAndBalancesForAccount( Network.Mainnet, mockAccount, @@ -541,20 +452,19 @@ describe('AssetsService', () => { expect( mockTrongridApiClient.getTrc20BalancesByAddress, - ).toHaveBeenCalledWith(Network.Mainnet, mockAccount.address); + ).not.toHaveBeenCalled(); + expect( + assets.every((asset) => + SNAP_OWNED_ASSETS.includes(asset.assetType), + ), + ).toBe(true); - const trxAsset = assets.find( + const bandwidthAsset = assets.find( (asset: AssetEntity) => - asset.assetType === KnownCaip19Id.TrxMainnet, - ); - expect(trxAsset).toBeDefined(); - expect(trxAsset?.rawAmount).toBe('0'); - - const trc20Asset = assets.find( - (asset: AssetEntity) => asset.assetType === trc20AssetId, + asset.assetType === KnownCaip19Id.BandwidthMainnet, ); - expect(trc20Asset).toBeDefined(); - expect(trc20Asset?.rawAmount).toBe('100000'); + expect(bandwidthAsset).toBeDefined(); + expect(bandwidthAsset?.rawAmount).toBe('600'); }, ); }); @@ -582,12 +492,11 @@ describe('AssetsService', () => { mockAccount, ); - const trxAsset = assets.find( - (asset: AssetEntity) => - asset.assetType === KnownCaip19Id.TrxMainnet, - ); - expect(trxAsset).toBeDefined(); - expect(trxAsset?.rawAmount).toBe('1000000'); + expect( + assets.some( + (asset) => asset.assetType === KnownCaip19Id.TrxMainnet, + ), + ).toBe(false); const bandwidthAsset = assets.find( (asset: AssetEntity) => @@ -598,38 +507,6 @@ describe('AssetsService', () => { }, ); }); - - it('tracks spot price errors', async () => { - await withAssetsService( - async ({ - assetsService, - mockSnapClient, - mockTrongridApiClient, - mockTronHttpClient, - mockPriceApiClient, - }) => { - const error = new Error('Spot price endpoint unavailable'); - - mockTrongridApiClient.getAccountInfoByAddress.mockResolvedValue( - createMockTronAccount({ - address: mockAccount.address, - balance: 1000000, - }), - ); - mockTronHttpClient.getAccountResources.mockResolvedValue( - emptyAccountResources, - ); - mockPriceApiClient.getMultipleSpotPrices.mockRejectedValue(error); - - await assetsService.fetchAssetsAndBalancesForAccount( - Network.Mainnet, - mockAccount, - ); - - expect(mockSnapClient.trackError).toHaveBeenCalledWith(error); - }, - ); - }); }); describe('bandwidth', () => { @@ -1510,7 +1387,9 @@ describe('AssetsService', () => { await assetsService.saveMany(assets); - expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith(assets); + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( + snapOwnedAssetsOnly(assets), + ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, @@ -1518,7 +1397,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, KnownCaip19Id.BandwidthMainnet, ]), @@ -1564,17 +1442,10 @@ describe('AssetsService', () => { await assetsService.saveMany(assets); expect(await assetsService.getAll()).toStrictEqual(assets); - expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect(emitSnapKeyringEvent).not.toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, - { - assets: { - [mockAccount.id]: { - added: [KnownCaip19Id.TrxMainnet], - removed: [trc20AssetId], - }, - }, - }, + expect.anything(), ); }); }); @@ -1606,26 +1477,7 @@ describe('AssetsService', () => { }, ]; const finalSavedAssets: AssetEntity[] = [ - { - assetType: KnownCaip19Id.TrxMainnet as NativeCaipAssetType, - keyringAccountId: mockAccount.id, - network: Network.Mainnet, - symbol: 'TRX', - decimals: 6, - rawAmount: '1000000', - uiAmount: '1', - iconUrl: '', - }, - { - assetType: trc20AssetId as TokenCaipAssetType, - keyringAccountId: mockAccount.id, - network: Network.Mainnet, - symbol: 'USDT', - decimals: 6, - rawAmount: '0', - uiAmount: '0', - iconUrl: '', - }, + savedAssets[0] as AssetEntity, ]; const updatedAssets: AssetEntity[] = [savedAssets[0] as AssetEntity]; @@ -1634,44 +1486,18 @@ describe('AssetsService', () => { [mockAccount.id]: savedAssets, }); - // If an asset is missing from the received list - // - emits the event 'notify:accountAssetListUpdated' with the asset in the 'removed' property - // - emits the event 'notify:accountBalancesUpdated' with the balance for the removed asset sets to 0 await assetsService.saveMany(updatedAssets); - expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - finalSavedAssets, - ); - expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith([]); + expect(emitSnapKeyringEvent).not.toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, - { - assets: { - [mockAccount.id]: { - added: [KnownCaip19Id.TrxMainnet], - removed: [trc20AssetId], - }, - }, - }, + expect.anything(), ); - - expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect(emitSnapKeyringEvent).not.toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountBalancesUpdated, - { - balances: { - [mockAccount.id]: { - [KnownCaip19Id.TrxMainnet]: { - unit: 'TRX', - amount: '1', - }, - [trc20AssetId]: { - unit: 'USDT', - amount: '0', - }, - }, - }, - }, + expect.anything(), ); }, ); @@ -1717,7 +1543,9 @@ describe('AssetsService', () => { await assetsService.saveMany(assets); - expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith(assets); + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( + snapOwnedAssetsOnly(assets), + ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, @@ -1725,7 +1553,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.MaximumEnergyMainnet, KnownCaip19Id.MaximumBandwidthMainnet, ]), @@ -1778,7 +1605,9 @@ describe('AssetsService', () => { await assetsService.saveMany(assets); - expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith(assets); + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( + snapOwnedAssetsOnly(assets), + ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, @@ -1786,7 +1615,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.TrxStakedForBandwidthMainnet, KnownCaip19Id.TrxStakedForEnergyMainnet, ]), @@ -1829,7 +1657,9 @@ describe('AssetsService', () => { await assetsService.saveMany(assets); - expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith(assets); + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( + snapOwnedAssetsOnly(assets), + ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, @@ -1837,7 +1667,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.TrxReadyForWithdrawalMainnet, ]), removed: [], @@ -1906,7 +1735,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -1915,7 +1744,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, ]), removed: [], @@ -1983,7 +1811,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -1992,7 +1820,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.BandwidthMainnet, ]), removed: [], @@ -2062,22 +1889,12 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); - expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect(emitSnapKeyringEvent).not.toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, - { - assets: { - [mockAccount.id]: { - added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, - trc20AssetId, - ]), - removed: [], - }, - }, - }, + expect.anything(), ); }, ); @@ -2181,7 +1998,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2190,10 +2007,8 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, KnownCaip19Id.BandwidthMainnet, - trc20AssetId, ]), removed: [], }, @@ -2260,7 +2075,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2269,7 +2084,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.TrxStakedForEnergyMainnet, ]), removed: [], @@ -2339,7 +2153,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2348,7 +2162,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, ]), removed: [], @@ -2363,10 +2176,6 @@ describe('AssetsService', () => { { balances: { [mockAccount.id]: { - [KnownCaip19Id.TrxMainnet]: { - unit: 'TRX', - amount: '1', - }, [KnownCaip19Id.EnergyMainnet]: { unit: 'ENERGY', amount: '35000', @@ -2435,7 +2244,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2444,7 +2253,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.BandwidthMainnet, ]), removed: [], @@ -2459,10 +2267,6 @@ describe('AssetsService', () => { { balances: { [mockAccount.id]: { - [KnownCaip19Id.TrxMainnet]: { - unit: 'TRX', - amount: '1', - }, [KnownCaip19Id.BandwidthMainnet]: { unit: 'BANDWIDTH', amount: '4700', @@ -2533,22 +2337,12 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); - expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect(emitSnapKeyringEvent).not.toHaveBeenCalledWith( expect.anything(), KeyringEvent.AccountAssetListUpdated, - { - assets: { - [mockAccount.id]: { - added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, - trc20AssetId, - ]), - removed: [], - }, - }, - }, + expect.anything(), ); }, ); @@ -2610,7 +2404,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2619,7 +2413,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, ]), removed: [], @@ -2687,7 +2480,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2696,7 +2489,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.BandwidthMainnet, ]), removed: [], @@ -2784,7 +2576,7 @@ describe('AssetsService', () => { await assetsService.saveMany(updatedAssets); expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith( - updatedAssets, + snapOwnedAssetsOnly(updatedAssets), ); expect(emitSnapKeyringEvent).toHaveBeenCalledWith( expect.anything(), @@ -2793,7 +2585,6 @@ describe('AssetsService', () => { assets: { [mockAccount.id]: { added: expect.arrayContaining([ - KnownCaip19Id.TrxMainnet, KnownCaip19Id.EnergyMainnet, KnownCaip19Id.BandwidthMainnet, ]), @@ -2809,10 +2600,6 @@ describe('AssetsService', () => { { balances: { [mockAccount.id]: { - [KnownCaip19Id.TrxMainnet]: { - unit: 'TRX', - amount: '2', - }, [KnownCaip19Id.EnergyMainnet]: { unit: 'ENERGY', amount: '45000', @@ -2830,4 +2617,357 @@ describe('AssetsService', () => { }); }); }); + + describe('getAssetsMetadata', () => { + it('resolves metadata for native, protocol, and token asset types', async () => { + await withAssetsService(async ({ assetsService, mockTokenApiClient }) => { + const trc20 = + `${Network.Mainnet}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` as TokenCaipAssetType; + const trc10 = `${Network.Mainnet}/trc10:1002000` as TokenCaipAssetType; + + mockTokenApiClient.getTokensMetadata.mockResolvedValue({ + [trc20]: { + fungible: { symbol: 'USDT', name: 'Tether', decimals: 6 }, + }, + [trc10]: { + fungible: { symbol: 'T', name: 'Token', decimals: 0 }, + }, + }); + + const assetTypes = [ + KnownCaip19Id.TrxMainnet, + KnownCaip19Id.TrxStakedForBandwidthMainnet, + KnownCaip19Id.TrxStakedForEnergyMainnet, + KnownCaip19Id.TrxReadyForWithdrawalMainnet, + KnownCaip19Id.TrxInLockPeriodMainnet, + KnownCaip19Id.TrxStakingRewardsMainnet, + KnownCaip19Id.EnergyMainnet, + KnownCaip19Id.MaximumEnergyMainnet, + KnownCaip19Id.BandwidthMainnet, + KnownCaip19Id.MaximumBandwidthMainnet, + trc10, + trc20, + ]; + + const metadata = await assetsService.getAssetsMetadata(assetTypes); + + expect(metadata[KnownCaip19Id.TrxMainnet]?.symbol).toBe('TRX'); + expect(metadata[KnownCaip19Id.EnergyMainnet]?.symbol).toBe('ENERGY'); + expect(metadata[trc20]?.fungible?.symbol).toBe('USDT'); + expect(mockTokenApiClient.getTokensMetadata).toHaveBeenCalledWith([ + trc10, + trc20, + ]); + }); + }); + }); + + describe('controller asset reads', () => { + const accountId = mockAccount.id; + const fungibleAssetId = KnownCaip19Id.TrxMainnet; + const snapAssetId = KnownCaip19Id.EnergyMainnet; + + it('fetchAssetsAndBalancesForAccount returns protocol assets only', async () => { + await withAssetsService( + async ({ + assetsService, + mockTrongridApiClient, + mockTronHttpClient, + }) => { + mockTrongridApiClient.getAccountInfoByAddress.mockResolvedValue( + createMockTronAccount({ + address: mockAccount.address, + balance: 1_000_000, + trc20: [{ TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: '1000' }], + }), + ); + mockTronHttpClient.getAccountResources.mockResolvedValue( + emptyAccountResources, + ); + + const assets = await assetsService.fetchAssetsAndBalancesForAccount( + Network.Mainnet, + mockAccount, + ); + + expect( + assets.every((asset) => + SNAP_OWNED_ASSETS.includes(asset.assetType), + ), + ).toBe(true); + expect( + assets.some((asset) => asset.assetType === fungibleAssetId), + ).toBe(false); + }, + ); + }); + + it('routes snap-owned reads through the repository', async () => { + await withAssetsService( + async ({ assetsService, mockAssetsRepository, mockCoreMessenger }) => { + const snapAsset: AssetEntity = { + assetType: snapAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'ENERGY', + decimals: 0, + rawAmount: '100', + uiAmount: '100', + iconUrl: '', + }; + mockAssetsRepository.getByAccountIdAndAssetType.mockResolvedValue( + snapAsset, + ); + + const asset = await assetsService.getAccountAssetByID( + accountId, + snapAssetId, + ); + + expect(asset).toStrictEqual(snapAsset); + expect(mockCoreMessenger.call).not.toHaveBeenCalledWith( + 'AssetsController:getAsset', + expect.anything(), + expect.anything(), + ); + }, + ); + }); + + it('routes fungible reads through AssetsController', async () => { + await withAssetsService(async ({ assetsService, mockCoreMessenger }) => { + mockCoreMessenger.call.mockImplementation( + createMessengerCallMock( + jest.fn().mockResolvedValue( + buildControllerAsset(fungibleAssetId, '2000000', { + symbol: 'TRX', + name: 'TRON', + decimals: 6, + }), + ), + ), + ); + + const asset = await assetsService.getAccountAssetByID( + accountId, + fungibleAssetId, + ); + + expect(asset).toMatchObject({ + assetType: fungibleAssetId, + rawAmount: '2000000', + uiAmount: '2', + }); + }); + }); + + it('getAccountAssetsByIDs uses a single AssetsController:getAssets call for fungibles', async () => { + await withAssetsService(async ({ assetsService, mockCoreMessenger }) => { + const trx = KnownCaip19Id.TrxMainnet; + const usdt = `${Network.Mainnet}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`; + + mockCoreMessenger.call.mockImplementation( + async (method: string, ...args: unknown[]) => { + if (method === 'AssetsController:getAssets') { + const accountIdArg = (args[0] as [{ id: string }])[0].id; + return { + [accountIdArg]: { + [trx]: buildControllerAsset(trx, '1000000', { + symbol: 'TRX', + name: 'TRON', + decimals: 6, + }), + [usdt]: buildControllerAsset(usdt, '500000', { + symbol: 'USDT', + name: 'Tether', + decimals: 6, + }), + }, + }; + } + return undefined; + }, + ); + + const results = await assetsService.getAccountAssetsByIDs(accountId, [ + trx, + usdt, + ]); + + expect(mockCoreMessenger.call).toHaveBeenCalledTimes(1); + expect(mockCoreMessenger.call).toHaveBeenCalledWith( + 'AssetsController:getAssets', + [{ id: accountId }], + { chainIds: [Network.Mainnet] }, + ); + expect(results[0]?.rawAmount).toBe('1000000'); + expect(results[1]?.rawAmount).toBe('500000'); + }); + }); + + it('getAccountAssetsByIDs batches snap-owned reads without calling AssetsController', async () => { + await withAssetsService( + async ({ assetsService, mockAssetsRepository, mockCoreMessenger }) => { + const snapAsset: AssetEntity = { + assetType: snapAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'ENERGY', + decimals: 0, + rawAmount: '100', + uiAmount: '100', + iconUrl: '', + }; + mockAssetsRepository.getByAccountIdAndAssetTypes.mockResolvedValue([ + snapAsset, + ]); + + const results = await assetsService.getAccountAssetsByIDs(accountId, [ + snapAssetId, + ]); + + expect(results[0]).toStrictEqual(snapAsset); + expect(mockCoreMessenger.call).not.toHaveBeenCalled(); + }, + ); + }); + + it('getAccountAssetsByIDs merges snap-owned and fungible reads in request order', async () => { + await withAssetsService( + async ({ assetsService, mockAssetsRepository, mockCoreMessenger }) => { + const snapAsset: AssetEntity = { + assetType: snapAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'ENERGY', + decimals: 0, + rawAmount: '250', + uiAmount: '250', + iconUrl: '', + }; + mockAssetsRepository.getByAccountIdAndAssetTypes.mockResolvedValue([ + snapAsset, + ]); + + mockCoreMessenger.call.mockImplementation( + async (method: string, ...args: unknown[]) => { + if (method === 'AssetsController:getAssets') { + const accountIdArg = (args[0] as [{ id: string }])[0].id; + return { + [accountIdArg]: { + [fungibleAssetId]: buildControllerAsset( + fungibleAssetId, + '3000000', + { + symbol: 'TRX', + name: 'TRON', + decimals: 6, + }, + ), + }, + }; + } + return undefined; + }, + ); + + const results = await assetsService.getAccountAssetsByIDs(accountId, [ + fungibleAssetId, + snapAssetId, + ]); + + expect(results[0]?.rawAmount).toBe('3000000'); + expect(results[1]).toStrictEqual(snapAsset); + expect(mockCoreMessenger.call).toHaveBeenCalledTimes(1); + }, + ); + }); + + it('getByKeyringAccountId excludes fungibles', async () => { + await withAssetsService( + async ({ assetsService, mockAssetsRepository }) => { + mockAssetsRepository.getByAccountId.mockResolvedValue([ + { + assetType: fungibleAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'TRX', + decimals: 6, + rawAmount: '1000000', + uiAmount: '1', + iconUrl: '', + }, + { + assetType: snapAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'ENERGY', + decimals: 0, + rawAmount: '100', + uiAmount: '100', + iconUrl: '', + }, + ]); + + const assets = await assetsService.getByKeyringAccountId(accountId); + + expect( + assets.some((asset) => asset.assetType === fungibleAssetId), + ).toBe(false); + expect(assets.some((asset) => asset.assetType === snapAssetId)).toBe( + true, + ); + }, + ); + }); + + it('saveMany emits only snap-owned assets', async () => { + await withAssetsService( + async ({ assetsService, mockState, mockAssetsRepository }) => { + mockState.getKey.mockResolvedValue({}); + + const assets: AssetEntity[] = [ + { + assetType: fungibleAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'TRX', + decimals: 6, + rawAmount: '1000000', + uiAmount: '1', + iconUrl: '', + }, + { + assetType: snapAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'ENERGY', + decimals: 0, + rawAmount: '100', + uiAmount: '100', + iconUrl: '', + }, + ]; + + await assetsService.saveMany(assets); + + expect(mockAssetsRepository.saveMany).toHaveBeenCalledWith([ + assets[1], + ]); + expect(emitSnapKeyringEvent).toHaveBeenCalledWith( + expect.anything(), + KeyringEvent.AccountAssetListUpdated, + { + assets: { + [accountId]: { + added: [snapAssetId], + removed: [], + }, + }, + }, + ); + }, + ); + }); + }); }); diff --git a/packages/tron-wallet-snap/src/services/assets/AssetsService.ts b/packages/tron-wallet-snap/src/services/assets/AssetsService.ts index 4675a349..9aeab9f3 100644 --- a/packages/tron-wallet-snap/src/services/assets/AssetsService.ts +++ b/packages/tron-wallet-snap/src/services/assets/AssetsService.ts @@ -1,9 +1,11 @@ +import type { Asset, Caip19AssetId } from '@metamask/assets-controller'; import { KeyringEvent } from '@metamask/keyring-api'; import type { AccountAssetListUpdatedEvent, AccountBalancesUpdatedEvent, KeyringAccount, } from '@metamask/keyring-api'; +import type { InternalAccount } from '@metamask/keyring-internal-api'; import { emitSnapKeyringEvent } from '@metamask/keyring-snap-sdk'; import type { AssetConversion, @@ -19,11 +21,7 @@ import { BigNumber } from 'bignumber.js'; import { pick } from 'lodash'; import type { PriceApiClient } from '../../clients/price-api/PriceApiClient'; -import type { - FiatTicker, - SpotPrice, - SpotPrices, -} from '../../clients/price-api/types'; +import type { FiatTicker, SpotPrice } from '../../clients/price-api/types'; import { GET_HISTORICAL_PRICES_RESPONSE_NULL_OBJECT, VsCurrencyParamStruct, @@ -35,7 +33,6 @@ import type { TronHttpClient } from '../../clients/tron-http/TronHttpClient'; import type { TrongridApiClient } from '../../clients/trongrid/TrongridApiClient'; import type { RawTronUnfrozenV2, - Trc20Balance, TronAccount, } from '../../clients/trongrid/types'; import type { KnownCaip19Id, Network } from '../../constants'; @@ -56,11 +53,14 @@ import { } from '../../constants'; import { configProvider } from '../../context'; import type { AssetEntity } from '../../entities/assets'; +import type { CoreMessengerCaller } from '../../types/core-messenger'; import { toUiAmount } from '../../utils/conversion'; import { createPrefixedLogger } from '../../utils/logger'; import type { ILogger } from '../../utils/logger'; import type { State, UnencryptedStateValue } from '../state/State'; import type { AssetsRepository } from './AssetsRepository'; +import { mapControllerAsset } from './mapControllerAsset'; +import { isSnapOwnedAsset } from './snapOwnedAssets'; import type { InLockPeriodCaipAssetType, NativeCaipAssetType, @@ -73,17 +73,10 @@ import type { } from './types'; /** - * Normalized account data structure that provides a consistent shape for both - * active and inactive accounts. This allows extraction functions to work - * without needing to know the account's activation state. + * Slim account data shape for snap-owned asset extraction. + * Provides a consistent shape for both active and inactive accounts. */ -type NormalizedAccountData = { - /** Native TRX balance in sun (0 for inactive accounts). */ - nativeBalance: number; - /** TRC10 token balances as `{ key: tokenId, value: balance }[]` (empty for inactive accounts). */ - trc10Balances: TronAccount['assetV2']; - /** TRC20 token balances from either account info or fallback endpoint. */ - trc20Balances: Trc20Balance[]; +type SnapOwnedAccountData = { /** Staking data including frozen balances and delegated resources. */ stakedData: { frozenV2: TronAccount['frozenV2']; @@ -113,6 +106,8 @@ export class AssetsService { readonly #snapClient: SnapClient; + readonly #coreMessenger: CoreMessengerCaller; + readonly cacheTtlsMilliseconds: { fiatExchangeRates: number; spotPrices: number; @@ -128,6 +123,7 @@ export class AssetsService { priceApiClient, tokenApiClient, snapClient, + coreMessenger, }: { logger: ILogger; assetsRepository: AssetsRepository; @@ -137,6 +133,7 @@ export class AssetsService { priceApiClient: PriceApiClient; tokenApiClient: TokenApiClient; snapClient: SnapClient; + coreMessenger: CoreMessengerCaller; }) { this.#logger = createPrefixedLogger(logger, '[🪙 AssetsService]'); this.#assetsRepository = assetsRepository; @@ -146,6 +143,7 @@ export class AssetsService { this.#priceApiClient = priceApiClient; this.#tokenApiClient = tokenApiClient; this.#snapClient = snapClient; + this.#coreMessenger = coreMessenger; const { cacheTtlsMilliseconds } = configProvider.get().priceApi; this.cacheTtlsMilliseconds = cacheTtlsMilliseconds; @@ -155,55 +153,139 @@ export class AssetsService { return caipAssetId.includes('swift:0/iso4217:'); } - async getAllAssetsByAccountId(accountId: string): Promise { + async getAccountAssets(accountId: string): Promise { return this.#assetsRepository.getByAccountId(accountId); } - async getAssetsByAccountId( + async getAccountAssetsByIDs( accountId: string, assetTypes: string[], ): Promise<(AssetEntity | null)[]> { - return this.#assetsRepository.getByAccountIdAndAssetTypes( - accountId, - assetTypes, + const snapOwnedTypes = assetTypes.filter(isSnapOwnedAsset); + const controllerTypes = assetTypes.filter( + (type) => !isSnapOwnedAsset(type), + ); + + const snapOwnedByType = new Map(); + if (snapOwnedTypes.length > 0) { + const snapOwnedResults = + await this.#assetsRepository.getByAccountIdAndAssetTypes( + accountId, + snapOwnedTypes, + ); + snapOwnedTypes.forEach((assetType, index) => { + snapOwnedByType.set(assetType, snapOwnedResults[index] ?? null); + }); + } + + const controllerByType = new Map(); + if (controllerTypes.length > 0) { + const chainIds = [ + ...new Set( + controllerTypes.map( + (assetType) => + parseCaipAssetType(assetType as CaipAssetType).chainId, + ), + ), + ]; + + const controllerAssets = await this.#coreMessenger.call( + 'AssetsController:getAssets', + [{ id: accountId }] as unknown as InternalAccount[], + { chainIds }, + ); + + const accountAssets = + (controllerAssets as Record>)[ + accountId + ] ?? {}; + + for (const assetType of controllerTypes) { + const controllerAsset = accountAssets[assetType]; + controllerByType.set( + assetType, + controllerAsset + ? mapControllerAsset(accountId, assetType, controllerAsset) + : null, + ); + } + } + + return assetTypes.map( + (assetType) => + snapOwnedByType.get(assetType) ?? + controllerByType.get(assetType) ?? + null, ); } - async getAssetByAccountId( + async getAccountAssetByID( accountId: string, assetType: string, ): Promise { - return this.#assetsRepository.getByAccountIdAndAssetType( + if (isSnapOwnedAsset(assetType)) { + return this.#assetsRepository.getByAccountIdAndAssetType( + accountId, + assetType, + ); + } + + const result = await this.#coreMessenger.call( + 'AssetsController:getAsset', accountId, - assetType, + assetType as Caip19AssetId, + ); + + if (!result) { + return null; + } + + return mapControllerAsset(accountId, assetType, result); + } + + /** + * Returns all controller-backed assets for an account on the given network. + * + * @param scope - CAIP-2 chain ID to filter controller results. + * @param accountId - Keyring account ID. + * @returns Mapped fungible assets present in AssetsController state. + */ + async getAccountAssetsByScope( + scope: Network, + accountId: string, + ): Promise { + const controllerAssets = await this.#coreMessenger.call( + 'AssetsController:getAssets', + [{ id: accountId }] as unknown as InternalAccount[], + { chainIds: [scope] }, + ); + + const accountAssets = + (controllerAssets as Record>)[accountId] ?? + {}; + + return Object.entries(accountAssets).map(([assetId, asset]) => + mapControllerAsset(accountId, assetId, asset), ); } /** - * Fetches all assets and balances for an account. + * Fetches snap-owned assets and balances for an account. * * Data Sources: - * - `getAccountInfoByAddress`: TRX balance, TRC10 tokens, TRC20 tokens (active accounts only) + * - `getAccountInfoByAddress`: Staking data (active accounts only) * - `getAccountResources`: Energy and Bandwidth (returns {} for inactive accounts) - * - `getTrc20BalancesByAddress`: TRC20 balances fallback (works for inactive accounts) - * - * Logic Flow: - * 1. Fetch account info, resources, and TRC20 fallback (for inactive accounts) - * 2. Normalize data into consistent shape via `#buildAccountData` - * 3. Extract all assets via `#extractAssets` - * 4. Fetch metadata and prices in parallel - * 5. Enrich assets with metadata via `#enrichAssetsWithMetadata` - * 6. Filter spam tokens via `#filterTokensWithoutPriceData` + * - `getReward`: Unclaimed staking rewards * * @param scope - The network to query. * @param account - The keyring account. - * @returns Promise - Array of assets with balances. + * @returns Promise - Array of snap-owned assets with balances. */ async fetchAssetsAndBalancesForAccount( scope: Network, account: KeyringAccount, ): Promise { - this.#logger.info('Fetching assets and balances by account', { + this.#logger.info('Fetching snap-owned assets and balances by account', { account, scope, }); @@ -218,103 +300,40 @@ export class AssetsService { this.#tronHttpClient.getReward(scope, account.address), ]); - const isInactiveAccount = tronAccountInfoRequest.status === 'rejected'; - if (isInactiveAccount) { + if (tronAccountInfoRequest.status === 'rejected') { this.#logger.info( 'Account info request failed, treating as inactive account', { account, scope }, ); } - const trc20BalancesFallback = isInactiveAccount - ? await this.#trongridApiClient - .getTrc20BalancesByAddress(scope, account.address) - .catch(async (error) => { - await this.#snapClient.trackError(error as Error); - this.#logger.warn( - 'Failed to fetch TRC20 balances for inactive account', - { error, account, scope }, - ); - return []; - }) - : []; - - const accountData = this.#buildAccountData({ + const accountData = this.#buildSnapOwnedAccountData({ tronAccountInfoRequest, tronAccountResourcesRequest, - trc20BalancesFallback, stakingRewardsRequest, }); - const rawAssets = this.#extractAssets(account, scope, accountData); - - const assetTypes = rawAssets.map((asset) => asset.assetType); - const priceableAssetTypes = this.#getPriceableAssetTypes(rawAssets); - - const [assetsMetadata, spotPrices] = await Promise.all([ - this.getAssetsMetadata(assetTypes), - this.#priceApiClient - .getMultipleSpotPrices(priceableAssetTypes, 'usd') - .catch(async (error) => { - await this.#snapClient.trackError(error as Error); - return {}; - }), - ]); - - const enrichedAssets = this.#enrichAssetsWithMetadata( - rawAssets, - assetsMetadata, - ); - return this.#filterTokensWithoutPriceData(enrichedAssets, spotPrices); - } - - /** - * Filters out spam tokens (those without price data). - * Essential assets are always kept. Tokens need price data to be included. - * - * @param assets - The assets to filter. - * @param spotPrices - Pre-fetched USD prices for assets. - * @returns The filtered assets. - */ - #filterTokensWithoutPriceData( - assets: AssetEntity[], - spotPrices: SpotPrices | Record, - ): AssetEntity[] { - const filtered = assets.filter((asset) => { - // Essential assets (TRX, staked, energy, bandwidth) are always kept - if (ESSENTIAL_ASSETS.includes(asset.assetType)) { - return true; - } - // Tokens: keep only if they have price data - const spotPrice = (spotPrices as SpotPrices)[asset.assetType]; - return typeof spotPrice?.price === 'number'; - }); - - return filtered; + return this.#extractSnapOwnedAssets(account, scope, accountData); } /** - * Normalizes raw API responses into a consistent shape for both active and inactive accounts. - * This allows extraction functions to work without needing to know the account's activation state. + * Normalizes raw API responses into a slim shape for snap-owned asset extraction. * * @param params - The raw API responses to normalize. * @param params.tronAccountInfoRequest - The settled promise result from getAccountInfoByAddress. * @param params.tronAccountResourcesRequest - The settled promise result from getAccountResources. - * @param params.trc20BalancesFallback - TRC20 balances from fallback endpoint (empty for active accounts). * @param params.stakingRewardsRequest - The settled promise result from getReward. - * @returns NormalizedAccountData - Consistent data shape for extraction. + * @returns SnapOwnedAccountData - Consistent data shape for snap-owned extraction. */ - #buildAccountData({ + #buildSnapOwnedAccountData({ tronAccountInfoRequest, tronAccountResourcesRequest, - trc20BalancesFallback, stakingRewardsRequest, }: { tronAccountInfoRequest: PromiseSettledResult; tronAccountResourcesRequest: PromiseSettledResult; - trc20BalancesFallback: Trc20Balance[]; stakingRewardsRequest: PromiseSettledResult; - }): NormalizedAccountData { + }): SnapOwnedAccountData { const isInactiveAccount = tronAccountInfoRequest.status === 'rejected'; const resources = tronAccountResourcesRequest.status === 'fulfilled' @@ -327,9 +346,6 @@ export class AssetsService { if (isInactiveAccount) { return { - nativeBalance: 0, - trc10Balances: [], - trc20Balances: trc20BalancesFallback, stakedData: { frozenV2: [], unfrozenV2: [], @@ -342,9 +358,6 @@ export class AssetsService { const tronAccountInfo = tronAccountInfoRequest.value; return { - nativeBalance: tronAccountInfo.balance ?? 0, - trc10Balances: tronAccountInfo.assetV2 ?? [], - trc20Balances: tronAccountInfo.trc20 ?? [], stakedData: { frozenV2: tronAccountInfo.frozenV2 ?? [], unfrozenV2: tronAccountInfo.unfrozenV2 ?? [], @@ -355,28 +368,16 @@ export class AssetsService { }; } - /** - * Extracts all assets from normalized account data. - * Coordinates calls to individual extraction functions. - * - * @param account - The keyring account. - * @param scope - The network. - * @param data - Normalized account data. - * @returns AssetEntity[] - Array of all extracted assets. - */ - #extractAssets( + #extractSnapOwnedAssets( account: KeyringAccount, scope: Network, - data: NormalizedAccountData, + data: SnapOwnedAccountData, ): AssetEntity[] { return [ - this.#extractNativeAsset(account, scope, data.nativeBalance), ...this.#extractStakedNativeAssets(account, scope, data.stakedData), this.#extractReadyForWithdrawalAsset(account, scope, data.stakedData), this.#extractInLockPeriodAsset(account, scope, data.stakedData), this.#extractStakingRewardsAsset(account, scope, data.stakingRewards), - ...this.#extractTrc10Assets(account, scope, data.trc10Balances), - ...this.#extractTrc20Assets(account, scope, data.trc20Balances), ...this.#extractBandwidth({ account, scope, @@ -390,100 +391,6 @@ export class AssetsService { ]; } - /** - * Returns the asset types that can be priced (native, TRC10, TRC20). - * Staked, energy, and bandwidth assets have non-compliant CAIP IDs that would fail the Price API. - * - * @param assets - Array of assets to filter. - * @returns CaipAssetType[] - Array of priceable asset types. - */ - #getPriceableAssetTypes(assets: AssetEntity[]): CaipAssetType[] { - return assets - .filter( - (asset) => - asset.assetType.includes('/slip44:') || - asset.assetType.includes('/trc10:') || - asset.assetType.includes('/trc20:'), - ) - .map((asset) => asset.assetType); - } - - /** - * Enriches assets with metadata (symbol, decimals, iconUrl) and calculates uiAmount. - * - * @param assets - Raw assets to enrich. - * @param assetsMetadata - Metadata lookup by asset type. - * @returns AssetEntity[] - Enriched assets. - */ - #enrichAssetsWithMetadata( - assets: AssetEntity[], - assetsMetadata: Record, - ): AssetEntity[] { - return assets.map((asset) => { - const metadata = assetsMetadata[ - asset.assetType - ] as FungibleAssetMetadata | null; - - const { - symbol: initialSymbol, - decimals: initialDecimals = 0, - iconUrl: initialIconUrl, - } = asset; - let symbol = initialSymbol; - let decimals = initialDecimals; - let iconUrl = initialIconUrl; - - if (metadata?.fungible) { - const unit = metadata.units?.[0]; - if (unit) { - symbol = unit.symbol ?? metadata.symbol ?? symbol; - decimals = unit.decimals ?? decimals; - } else { - symbol = metadata?.symbol ?? symbol; - } - iconUrl = metadata.iconUrl ?? iconUrl; - } - - const uiAmount = toUiAmount(asset.rawAmount, decimals).toString(); - - return { - ...asset, - symbol, - decimals, - uiAmount, - iconUrl, - }; - }); - } - - /** - * Extracts the native TRX asset from the balance. - * - * @param account - The keyring account. - * @param scope - The network. - * @param balance - The native balance in sun. - * @returns AssetEntity - The native TRX asset. - */ - #extractNativeAsset( - account: KeyringAccount, - scope: Network, - balance: number, - ): AssetEntity { - return { - assetType: Networks[scope].nativeToken.id, - keyringAccountId: account.id, - network: scope, - symbol: Networks[scope].nativeToken.symbol, - decimals: Networks[scope].nativeToken.decimals, - rawAmount: balance.toString(), - uiAmount: toUiAmount( - balance, - Networks[scope].nativeToken.decimals, - ).toString(), - iconUrl: Networks[scope].nativeToken.iconUrl, - }; - } - /** * Extracts staked TRX assets (for bandwidth and energy). * @@ -495,7 +402,7 @@ export class AssetsService { #extractStakedNativeAssets( account: KeyringAccount, scope: Network, - stakedData: NormalizedAccountData['stakedData'], + stakedData: SnapOwnedAccountData['stakedData'], ): AssetEntity[] { const assets: AssetEntity[] = []; @@ -563,7 +470,7 @@ export class AssetsService { #extractReadyForWithdrawalAsset( account: KeyringAccount, scope: Network, - stakedData: NormalizedAccountData['stakedData'], + stakedData: SnapOwnedAccountData['stakedData'], ): AssetEntity { const currentTimestamp = Date.now(); let readyForWithdrawalAmount = 0; @@ -633,7 +540,7 @@ export class AssetsService { #extractInLockPeriodAsset( account: KeyringAccount, scope: Network, - stakedData: NormalizedAccountData['stakedData'], + stakedData: SnapOwnedAccountData['stakedData'], ): AssetEntity { const currentTimestamp = Date.now(); let inLockPeriodAmount = 0; @@ -763,66 +670,6 @@ export class AssetsService { ]; } - /** - * Extracts TRC10 assets from the balances array. - * - * @param account - The keyring account. - * @param scope - The network. - * @param trc10Balances - TRC10 token balances as `{ key: tokenId, value: balance }[]`. - * @returns AssetEntity[] - Array of TRC10 asset entities. - */ - #extractTrc10Assets( - account: KeyringAccount, - scope: Network, - trc10Balances: TronAccount['assetV2'], - ): AssetEntity[] { - return ( - trc10Balances?.flatMap((tokenObject) => { - // assetV2 has structure: { "key": "token_id", "value": "balance" } - return { - assetType: `${scope}/trc10:${tokenObject.key}` as TokenCaipAssetType, - keyringAccountId: account.id, - network: scope, - symbol: '', - decimals: 0, - rawAmount: tokenObject.value?.toString() ?? '0', - uiAmount: '0', - iconUrl: '', // Will be enriched with metadata later - }; - }) ?? [] - ); - } - - /** - * Extracts TRC20 assets from a balances array. - * Works with both active accounts (tronAccountInfo.trc20) and inactive accounts (getTrc20BalancesByAddress). - * - * @param account - The keyring account. - * @param scope - The network. - * @param trc20Balances - Array of `Record` objects (e.g., `[{ "TContractAddr": "1000" }]`). - * @returns AssetEntity[] - Array of TRC20 asset entities. - */ - #extractTrc20Assets( - account: KeyringAccount, - scope: Network, - trc20Balances: Trc20Balance[], - ): AssetEntity[] { - return trc20Balances.flatMap((tokenObject) => { - return Object.entries(tokenObject).map(([address, balance]) => { - return { - assetType: `${scope}/trc20:${address}` as TokenCaipAssetType, - keyringAccountId: account.id, - network: scope, - symbol: '', - decimals: 0, - rawAmount: balance, - uiAmount: '0', - iconUrl: '', // Will be enriched with metadata later - }; - }); - }); - } - async getAssetsMetadata( assetTypes: CaipAssetType[], ): Promise> { @@ -1261,6 +1108,9 @@ export class AssetsService { async saveMany(assets: AssetEntity[]): Promise { this.#logger.info('Saving assets', assets); + const shouldEmitAsset = (asset: AssetEntity): boolean => + isSnapOwnedAsset(asset.assetType); + const hasZeroAmount = (asset: AssetEntity): boolean => asset.rawAmount === '0' || asset.uiAmount === '0'; @@ -1268,6 +1118,9 @@ export class AssetsService { const isEssentialAsset = (asset: AssetEntity): boolean => ESSENTIAL_ASSETS.includes(asset.assetType); + const isProtectedAsset = (asset: AssetEntity): boolean => + isSnapOwnedAsset(asset.assetType); + // Track only the account/network pairs refreshed in this run. // That prevents us from treating assets from untouched networks as disappeared. const syncedNetworksByAccount = assets.reduce>>( @@ -1292,11 +1145,15 @@ export class AssetsService { if ( !syncedNetworks?.has(savedAsset.network) || - isEssentialAsset(savedAsset) + isProtectedAsset(savedAsset) ) { return false; } + if (!isSnapOwnedAsset(savedAsset.assetType)) { + return false; + } + return !incomingAssetKeys.has( `${savedAsset.keyringAccountId}:${savedAsset.assetType}`, ); @@ -1320,23 +1177,23 @@ export class AssetsService { // snapshot entirely // 2. fold in the current assets to report additions and explicit zero-balance // removals in the same event - const assetListUpdatedPayload = disappearedAssets.reduce< - AccountAssetListUpdatedEvent['params']['assets'] - >( - (acc, asset) => ({ - ...acc, - [asset.keyringAccountId]: { - added: [...(acc[asset.keyringAccountId]?.added ?? [])], - removed: [ - ...(acc[asset.keyringAccountId]?.removed ?? []), - asset.assetType, - ], - }, - }), - {}, - ); + const assetListUpdatedPayload = disappearedAssets + .filter(shouldEmitAsset) + .reduce( + (acc, asset) => ({ + ...acc, + [asset.keyringAccountId]: { + added: [...(acc[asset.keyringAccountId]?.added ?? [])], + removed: [ + ...(acc[asset.keyringAccountId]?.removed ?? []), + asset.assetType, + ], + }, + }), + {}, + ); - for (const asset of assets) { + for (const asset of assets.filter(shouldEmitAsset)) { // Merge the current snapshot into the pre-seeded payload so each account // ends up with one consolidated added/removed diff. assetListUpdatedPayload[asset.keyringAccountId] = { @@ -1367,21 +1224,27 @@ export class AssetsService { // Emit synthetic zero-balance entries for disappeared assets so clients can // clear cached balances even when the backend omits zero-balance tokens // instead of returning them explicitly. - const removedAssetsWithZeroBalance = disappearedAssets.map((asset) => ({ - ...asset, - rawAmount: '0', - uiAmount: '0', - })); + const removedAssetsWithZeroBalance = disappearedAssets + .filter(shouldEmitAsset) + .map((asset) => ({ + ...asset, + rawAmount: '0', + uiAmount: '0', + })); - const assetsToSave = [...assets, ...removedAssetsWithZeroBalance]; + const assetsToSave = [ + ...assets.filter(shouldEmitAsset), + ...removedAssetsWithZeroBalance, + ]; // Save assets using repository await this.#assetsRepository.saveMany(assetsToSave); // Broadcast the current snapshot plus synthetic zero-balance removals so the // client can reconcile both visible assets and cached balances in one pass. - const balancesUpdatedPayload = assetsToSave.reduce< - AccountBalancesUpdatedEvent['params']['balances'] - >( + const balancesUpdatedPayload = [ + ...assets.filter(shouldEmitAsset), + ...removedAssetsWithZeroBalance, + ].reduce( (acc, asset) => ({ ...acc, [asset.keyringAccountId]: { @@ -1448,6 +1311,10 @@ export class AssetsService { const savedAssets = await this.#assetsRepository.getByAccountId(keyringAccountId); + const visibleSavedAssets = savedAssets.filter((asset) => + isSnapOwnedAsset(asset.assetType), + ); + /** * Ensure the special assets are always present whether they have been synced or not. * These are assets that should be visible to the user even with zero balance. @@ -1455,6 +1322,10 @@ export class AssetsService { const missingEssentialAssets: AssetEntity[] = []; for (const essentialAssetId of ESSENTIAL_ASSETS) { + if (!isSnapOwnedAsset(essentialAssetId)) { + continue; + } + const savedAsset = savedAssets.find( (asset) => (asset.assetType as string) === essentialAssetId, ); @@ -1468,7 +1339,7 @@ export class AssetsService { } } - return [...savedAssets, ...missingEssentialAssets]; + return [...visibleSavedAssets, ...missingEssentialAssets]; } /** diff --git a/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.test.ts b/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.test.ts new file mode 100644 index 00000000..7c96647b --- /dev/null +++ b/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.test.ts @@ -0,0 +1,87 @@ +import type { Asset } from '@metamask/assets-controller'; +import type { CaipAssetType } from '@metamask/utils'; +import { parseCaipAssetType } from '@metamask/utils'; + +import { KnownCaip19Id, Network, TokenMetadata } from '../../constants'; +import { mapControllerAsset } from './mapControllerAsset'; + +describe('mapControllerAsset', () => { + const accountId = 'account-id'; + const knownAssetId = KnownCaip19Id.TrxMainnet; + const unknownAssetId = 'tron:728126428/trc20:unknown'; + + it('maps controller metadata when present', () => { + const asset = { + id: unknownAssetId, + chainId: Network.Mainnet, + balance: { amount: '1234567' }, + metadata: { + type: 'fungible', + symbol: 'TKN', + name: 'Token', + decimals: 6, + image: 'https://example.com/token.png', + }, + price: { price: 0, lastUpdated: 0 }, + fiatValue: 0, + } as unknown as Asset; + + expect(mapControllerAsset(accountId, unknownAssetId, asset)).toStrictEqual({ + assetType: unknownAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: 'TKN', + decimals: 6, + rawAmount: '1234567', + uiAmount: '1.234567', + iconUrl: 'https://example.com/token.png', + }); + }); + + it('falls back to TokenMetadata when controller metadata is missing', () => { + const asset = { + id: knownAssetId, + chainId: Network.Mainnet, + balance: { amount: '2000000' }, + metadata: { type: 'fungible', name: 'TRON' }, + price: { price: 0, lastUpdated: 0 }, + fiatValue: 0, + } as unknown as Asset; + + expect(mapControllerAsset(accountId, knownAssetId, asset)).toStrictEqual({ + assetType: knownAssetId, + keyringAccountId: accountId, + network: Network.Mainnet, + symbol: TokenMetadata[knownAssetId].symbol, + decimals: TokenMetadata[knownAssetId].decimals, + rawAmount: '2000000', + uiAmount: '2', + iconUrl: TokenMetadata[knownAssetId].iconUrl, + }); + }); + + it('uses empty defaults when metadata is missing everywhere', () => { + const assetId = 'tron:728126428/trc20:missing' as CaipAssetType; + const asset = { + id: assetId, + chainId: Network.Mainnet, + balance: { amount: '42' }, + metadata: { type: 'fungible', name: 'Missing' }, + price: { price: 0, lastUpdated: 0 }, + fiatValue: 0, + } as unknown as Asset; + + const { chainId } = parseCaipAssetType(assetId); + + expect(mapControllerAsset(accountId, assetId, asset)).toStrictEqual({ + assetType: assetId, + keyringAccountId: accountId, + network: chainId, + symbol: '', + decimals: 0, + rawAmount: '42', + uiAmount: '42', + iconUrl: '', + }); + }); +}); diff --git a/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.ts b/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.ts new file mode 100644 index 00000000..24cdf276 --- /dev/null +++ b/packages/tron-wallet-snap/src/services/assets/mapControllerAsset.ts @@ -0,0 +1,39 @@ +import type { Asset } from '@metamask/assets-controller'; +import type { CaipAssetType } from '@metamask/utils'; +import { parseCaipAssetType } from '@metamask/utils'; + +import { Network, TokenMetadata } from '../../constants'; +import type { AssetEntity } from '../../entities/assets'; +import { toUiAmount } from '../../utils/conversion'; + +/** + * Maps an AssetsController asset to the Snap's {@link AssetEntity} shape. + * + * @param accountId - Keyring account ID. + * @param assetId - CAIP-19 asset ID. + * @param asset - Asset returned by AssetsController. + * @returns Mapped asset entity. + */ +export function mapControllerAsset( + accountId: string, + assetId: string, + asset: Asset, +): AssetEntity { + const { chainId } = parseCaipAssetType(assetId as CaipAssetType); + const knownMetadata = TokenMetadata[assetId as keyof typeof TokenMetadata]; + const decimals = asset.metadata.decimals ?? knownMetadata?.decimals ?? 0; + const symbol = asset.metadata.symbol ?? knownMetadata?.symbol ?? ''; + const iconUrl = asset.metadata.image ?? knownMetadata?.iconUrl ?? ''; + const { amount } = asset.balance; + + return { + assetType: assetId, + keyringAccountId: accountId, + network: chainId as Network, + symbol, + decimals, + rawAmount: amount, + uiAmount: toUiAmount(amount, decimals).toString(), + iconUrl, + } as AssetEntity; +} diff --git a/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.test.ts b/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.test.ts new file mode 100644 index 00000000..84a8b4ee --- /dev/null +++ b/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.test.ts @@ -0,0 +1,34 @@ +import { KnownCaip19Id, SNAP_OWNED_ASSETS } from '../../constants'; +import { isSnapOwnedAsset } from './snapOwnedAssets'; + +describe('isSnapOwnedAsset', () => { + it.each(SNAP_OWNED_ASSETS)( + 'returns true for snap-owned asset %s', + (assetId) => { + expect(isSnapOwnedAsset(assetId)).toBe(true); + }, + ); + + it('returns false for native TRX', () => { + expect(isSnapOwnedAsset(KnownCaip19Id.TrxMainnet)).toBe(false); + expect(isSnapOwnedAsset(KnownCaip19Id.TrxNile)).toBe(false); + expect(isSnapOwnedAsset(KnownCaip19Id.TrxShasta)).toBe(false); + }); + + it('returns false for TRC20 tokens', () => { + expect(isSnapOwnedAsset(KnownCaip19Id.UsdtMainnet)).toBe(false); + expect( + isSnapOwnedAsset( + `${KnownCaip19Id.TrxMainnet.split('/')[0]}/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t`, + ), + ).toBe(false); + }); + + it('returns false for TRC10 tokens', () => { + expect( + isSnapOwnedAsset( + `${KnownCaip19Id.TrxMainnet.split('/')[0]}/trc10:1002000`, + ), + ).toBe(false); + }); +}); diff --git a/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.ts b/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.ts new file mode 100644 index 00000000..c8d44a17 --- /dev/null +++ b/packages/tron-wallet-snap/src/services/assets/snapOwnedAssets.ts @@ -0,0 +1,18 @@ +import { SNAP_OWNED_ASSETS } from '../../constants'; + +const SNAP_OWNED_ASSET_IDS = new Set(SNAP_OWNED_ASSETS); + +/** + * Returns whether an asset remains exclusively managed by the Snap. + * + * AssetsController does not persist certain Tron protocol assets, including + * staking positions and account resources. These assets must always be read, + * synchronized, persisted, and published by the Snap, regardless of the + * assets migration stage. + * + * @param assetId - CAIP-19 asset ID. + * @returns Whether the asset is exclusively managed by the Snap. + */ +export function isSnapOwnedAsset(assetId: string): boolean { + return SNAP_OWNED_ASSET_IDS.has(assetId); +} diff --git a/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.test.ts b/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.test.ts index e7551f30..6df1bffa 100644 --- a/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.test.ts +++ b/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.test.ts @@ -6,7 +6,7 @@ import type { TronWebFactory } from '../../clients/tronweb/TronWebFactory'; import { KnownCaip19Id, Network, Networks, ZERO } from '../../constants'; import type { AssetEntity, ResourceAsset } from '../../entities/assets'; import type { TronKeyringAccount } from '../../entities/keyring-account'; -import { TronMultichainMethod } from '../../handlers/keyring-types'; +import { TronMultichainMethod } from '../../handlers/keyring/keyring-types'; import { getIconUrlForKnownAsset } from '../../ui/confirmation/utils/getIconUrlForKnownAsset'; import { render as renderConfirmSignTransaction } from '../../ui/confirmation/views/ConfirmSignTransaction/render'; import { render as renderConfirmTransactionRequest } from '../../ui/confirmation/views/ConfirmTransactionRequest/render'; @@ -106,7 +106,7 @@ type WithConfirmationHandlerCallback = (payload: { }; }; }; - mockAssetsService: jest.Mocked>; + mockAssetsService: jest.Mocked>; mockFeeCalculatorService: jest.Mocked< Pick >; @@ -142,9 +142,9 @@ async function withConfirmationHandler( }; const mockAssetsService: jest.Mocked< - Pick + Pick > = { - getAssetsByAccountId: jest.fn().mockResolvedValue([null, null]), + getAccountAssetsByIDs: jest.fn().mockResolvedValue([null, null]), }; const mockFeeCalculatorService: jest.Mocked< @@ -260,7 +260,7 @@ describe('ConfirmationHandler', () => { scope: Network.Mainnet, }); - expect(mockAssetsService.getAssetsByAccountId).toHaveBeenCalledWith( + expect(mockAssetsService.getAccountAssetsByIDs).toHaveBeenCalledWith( TEST_ACCOUNT_ID, [ Networks[Network.Mainnet].bandwidth.id, @@ -273,7 +273,7 @@ describe('ConfirmationHandler', () => { it('uses ZERO when bandwidth and energy assets are null', async () => { await withConfirmationHandler( async ({ handler, mockAssetsService, mockFeeCalculatorService }) => { - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ null, null, ]); @@ -317,7 +317,7 @@ describe('ConfirmationHandler', () => { uiAmount: '3000', iconUrl: '', }; - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ bandwidthAsset, energyAsset, ]); diff --git a/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.ts b/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.ts index f90078d2..2d4daae9 100644 --- a/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.ts +++ b/packages/tron-wallet-snap/src/services/confirmation/ConfirmationHandler.ts @@ -9,7 +9,7 @@ import { Networks, ZERO } from '../../constants'; import type { Network } from '../../constants'; import type { AssetEntity } from '../../entities/assets'; import type { TronKeyringAccount } from '../../entities/keyring-account'; -import { TronMultichainMethod } from '../../handlers/keyring-types'; +import { TronMultichainMethod } from '../../handlers/keyring/keyring-types'; import { TRX_IMAGE_SVG } from '../../static/tron-logo'; import { FetchStatus } from '../../types/snap'; import { getIconUrlForKnownAsset } from '../../ui/confirmation/utils/getIconUrlForKnownAsset'; @@ -235,7 +235,7 @@ export class ConfirmationHandler { ); const [bandwidthAsset, energyAsset] = - await this.#assetsService.getAssetsByAccountId(account.id, [ + await this.#assetsService.getAccountAssetsByIDs(account.id, [ Networks[scope].bandwidth.id, Networks[scope].energy.id, ]); diff --git a/packages/tron-wallet-snap/src/services/send/SendService.test.ts b/packages/tron-wallet-snap/src/services/send/SendService.test.ts index 1bd026a9..4fc2c234 100644 --- a/packages/tron-wallet-snap/src/services/send/SendService.test.ts +++ b/packages/tron-wallet-snap/src/services/send/SendService.test.ts @@ -12,7 +12,7 @@ import { } from '../../constants'; import type { AssetEntity } from '../../entities/assets'; import { SendErrorCodes } from '../../handlers/clientRequest/types'; -import { BackgroundEventMethod } from '../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../handlers/cronjob/cronjob'; import { mockLogger } from '../../utils/mockLogger'; import { TransactionExpirationRefresherService } from '../transaction-expiration-refresher/TransactionExpirationRefresherService'; import { SendService } from './SendService'; @@ -82,7 +82,7 @@ describe('SendService', () => { }; mockAssetsService = { - getAssetsByAccountId: jest.fn(), + getAccountAssetsByIDs: jest.fn(), }; mockTronWeb = { @@ -297,7 +297,7 @@ describe('SendService', () => { }; mockAssetsService = { - getAssetsByAccountId: jest.fn(), + getAccountAssetsByIDs: jest.fn(), }; mockTronWeb = { @@ -360,7 +360,7 @@ describe('SendService', () => { const amount = new BigNumber(10); // Sending 10 TRX // User has 100 TRX, 1000 bandwidth, 0 energy - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (asset being sent) { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (native token) { rawAmount: '1000' }, // Bandwidth @@ -398,7 +398,7 @@ describe('SendService', () => { }); expect(result).toStrictEqual({ valid: true }); - expect(mockAssetsService.getAssetsByAccountId).toHaveBeenCalledWith( + expect(mockAssetsService.getAccountAssetsByIDs).toHaveBeenCalledWith( TEST_ACCOUNT_ID, [nativeTokenId, nativeTokenId, bandwidthId, energyId], ); @@ -409,7 +409,7 @@ describe('SendService', () => { const amount = new BigNumber(100); // Trying to send 100 TRX // User only has 50 TRX - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '50', rawAmount: '50000000' }, // TRX balance (asset being sent) { uiAmount: '50', rawAmount: '50000000' }, // TRX balance (native token) { rawAmount: '1000' }, // Bandwidth @@ -437,7 +437,7 @@ describe('SendService', () => { const amount = new BigNumber(99); // Sending 99 TRX // User has 100 TRX but no bandwidth (fees will be charged in TRX) - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (asset being sent) { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (native token) { rawAmount: '0' }, // No bandwidth @@ -477,7 +477,7 @@ describe('SendService', () => { const amount = new BigNumber(98); // Sending 98 TRX // User has 100 TRX, no bandwidth - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // TRX balance { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (native token) { rawAmount: '0' }, // No bandwidth @@ -516,7 +516,7 @@ describe('SendService', () => { const amount = new BigNumber(50); // Sending 50 USDT // User has 100 USDT, 10 TRX for fees, some energy - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // USDT balance (asset being sent) { uiAmount: '10', rawAmount: '10000000' }, // TRX balance (native token for fees) { rawAmount: '500' }, // Bandwidth @@ -570,7 +570,7 @@ describe('SendService', () => { const amount = new BigNumber(100); // Trying to send 100 USDT // User only has 50 USDT - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '50', rawAmount: '50000000' }, // USDT balance (not enough) { uiAmount: '100', rawAmount: '100000000' }, // TRX balance (plenty for fees) { rawAmount: '1000' }, // Bandwidth @@ -597,7 +597,7 @@ describe('SendService', () => { const amount = new BigNumber(50); // Sending 50 USDT // User has 100 USDT but only 1 TRX (not enough for fees) - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // USDT balance (plenty) { uiAmount: '1', rawAmount: '1000000' }, // TRX balance (not enough for fees) { rawAmount: '0' }, // No bandwidth @@ -636,7 +636,7 @@ describe('SendService', () => { const amount = new BigNumber(50); // Sending 50 USDT // User has 100 USDT and exactly 5 TRX for fees - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // USDT balance { uiAmount: '5', rawAmount: '5000000' }, // TRX balance (exact for fees) { rawAmount: '0' }, // No bandwidth @@ -674,7 +674,7 @@ describe('SendService', () => { const amount = new BigNumber(10); // All balances are undefined - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ undefined, // No asset balance undefined, // No native token balance undefined, // No bandwidth @@ -700,7 +700,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber(0); // Sending 0 TRX - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '1', rawAmount: '1000000' }, // 1 TRX balance { uiAmount: '1', rawAmount: '1000000' }, // 1 TRX native { rawAmount: '0' }, // No bandwidth @@ -736,7 +736,7 @@ describe('SendService', () => { const asset = createTrc20Asset(); const amount = new BigNumber(10); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, // USDT balance { uiAmount: '0', rawAmount: '0' }, // 0 TRX balance { rawAmount: '10000' }, // Plenty of bandwidth @@ -790,7 +790,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber(1); // Sending 1 TRX to new account - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '2', rawAmount: '2000000' }, // 2 TRX balance { uiAmount: '2', rawAmount: '2000000' }, // 2 TRX native { rawAmount: '1000' }, // Bandwidth (enough) @@ -835,7 +835,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber(1.5); // Sending 1.5 TRX to new account - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '2', rawAmount: '2000000' }, // 2 TRX balance { uiAmount: '2', rawAmount: '2000000' }, // 2 TRX native { rawAmount: '1000' }, // Bandwidth (enough) @@ -885,7 +885,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber(10); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, { uiAmount: '100', rawAmount: '100000000' }, { rawAmount: '1000' }, @@ -932,7 +932,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber('0.99'); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, { uiAmount: '100', rawAmount: '100000000' }, { rawAmount: '1000' }, @@ -971,7 +971,7 @@ describe('SendService', () => { const asset = createTrc20Asset(); const amount = new BigNumber('0.99'); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, { uiAmount: '100', rawAmount: '100000000' }, { rawAmount: '1000' }, @@ -1017,7 +1017,7 @@ describe('SendService', () => { const asset = createNativeAsset(); const amount = new BigNumber(10); - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { uiAmount: '100', rawAmount: '100000000' }, { uiAmount: '100', rawAmount: '100000000' }, { rawAmount: '1000' }, diff --git a/packages/tron-wallet-snap/src/services/send/SendService.ts b/packages/tron-wallet-snap/src/services/send/SendService.ts index 3e988e4f..b897a939 100644 --- a/packages/tron-wallet-snap/src/services/send/SendService.ts +++ b/packages/tron-wallet-snap/src/services/send/SendService.ts @@ -15,7 +15,7 @@ import type { Network } from '../../constants'; import { Networks, TRACK_TX_INTERVAL, ZERO } from '../../constants'; import type { AssetEntity } from '../../entities/assets'; import { SendErrorCodes } from '../../handlers/clientRequest/types'; -import { BackgroundEventMethod } from '../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../handlers/cronjob/cronjob'; import { toRawAmount, trxToSun } from '../../utils/conversion'; import { createPrefixedLogger } from '../../utils/logger'; import type { ILogger } from '../../utils/logger'; @@ -112,7 +112,7 @@ export class SendService { * Get the user's current balances for the asset being sent and TRX (for fees). */ const [assetBalance, nativeTokenAsset, bandwidthAsset, energyAsset] = - await this.#assetsService.getAssetsByAccountId(fromAccountId, [ + await this.#assetsService.getAccountAssetsByIDs(fromAccountId, [ asset.assetType, nativeTokenId, Networks[scope].bandwidth.id, diff --git a/packages/tron-wallet-snap/src/services/staking/StakingService.test.ts b/packages/tron-wallet-snap/src/services/staking/StakingService.test.ts index 985a8366..ba4f770c 100644 --- a/packages/tron-wallet-snap/src/services/staking/StakingService.test.ts +++ b/packages/tron-wallet-snap/src/services/staking/StakingService.test.ts @@ -8,7 +8,7 @@ import { Network, } from '../../constants'; import type { TronKeyringAccount } from '../../entities/keyring-account'; -import { BackgroundEventMethod } from '../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../handlers/cronjob/cronjob'; import { trxToSun } from '../../utils/conversion'; import { mockLogger } from '../../utils/mockLogger'; import type { AccountsService } from '../accounts/AccountsService'; diff --git a/packages/tron-wallet-snap/src/services/wallet/README.md b/packages/tron-wallet-snap/src/services/wallet/README.md index 507dcb6f..4da222a5 100644 --- a/packages/tron-wallet-snap/src/services/wallet/README.md +++ b/packages/tron-wallet-snap/src/services/wallet/README.md @@ -144,7 +144,7 @@ yarn test WalletService.test.ts ## Related Files -- `handlers/keyring.ts` - KeyringHandler that uses this service -- `handlers/keyring-types.ts` - Method and error type definitions +- `handlers/keyring/keyring.ts` - KeyringHandler that uses this service +- `handlers/keyring/keyring-types.ts` - Method and error type definitions - `validation/structs.ts` - Validation schemas - `services/confirmation/ConfirmationHandler.ts` - User confirmation handling diff --git a/packages/tron-wallet-snap/src/services/wallet/WalletService.test.ts b/packages/tron-wallet-snap/src/services/wallet/WalletService.test.ts index 02ce29c1..32fe424d 100644 --- a/packages/tron-wallet-snap/src/services/wallet/WalletService.test.ts +++ b/packages/tron-wallet-snap/src/services/wallet/WalletService.test.ts @@ -8,7 +8,7 @@ import type { TronKeyringAccount } from '../../entities/keyring-account'; import { TronMultichainErrors, TronMultichainMethod, -} from '../../handlers/keyring-types'; +} from '../../handlers/keyring/keyring-types'; import { mockLogger } from '../../utils/mockLogger'; import type { AccountsService } from '../accounts/AccountsService'; import { WalletService } from './WalletService'; diff --git a/packages/tron-wallet-snap/src/services/wallet/WalletService.ts b/packages/tron-wallet-snap/src/services/wallet/WalletService.ts index 168a10ba..ebfbbefb 100644 --- a/packages/tron-wallet-snap/src/services/wallet/WalletService.ts +++ b/packages/tron-wallet-snap/src/services/wallet/WalletService.ts @@ -9,7 +9,7 @@ import type { TronKeyringAccount } from '../../entities/keyring-account'; import { TronMultichainErrors, TronMultichainMethod, -} from '../../handlers/keyring-types'; +} from '../../handlers/keyring/keyring-types'; import { createPrefixedLogger } from '../../utils/logger'; import type { ILogger } from '../../utils/logger'; import { diff --git a/packages/tron-wallet-snap/src/types/core-messenger.ts b/packages/tron-wallet-snap/src/types/core-messenger.ts new file mode 100644 index 00000000..f6e712f7 --- /dev/null +++ b/packages/tron-wallet-snap/src/types/core-messenger.ts @@ -0,0 +1,26 @@ +import type { + AssetsControllerGetAssetAction, + AssetsControllerGetAssetsAction, +} from '@metamask/assets-controller'; +import type { Messenger } from '@metamask/messenger'; +import type { AsyncMessenger } from '@metamask/snaps-sdk'; + +export type { AssetsControllerGetAssetAction, AssetsControllerGetAssetsAction }; + +export type CoreMessengerActions = + | AssetsControllerGetAssetAction + | AssetsControllerGetAssetsAction; + +/** + * Typed messenger for Core controller actions available to this Snap via + * `endowment:messenger` / `getMessenger`. + */ +export type CoreMessenger = Messenger; + +/** + * Narrow dependency for services that only need to invoke Core actions. + * + * Prefer this over injecting the full messenger so constructors only receive + * the surface they use. + */ +export type CoreMessengerCaller = Pick, 'call'>; diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignMessage/render.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignMessage/render.test.tsx index ae7f5826..37b3f0de 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignMessage/render.test.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignMessage/render.test.tsx @@ -4,7 +4,7 @@ import { bytesToBase64, stringToBytes } from '@metamask/utils'; import type { SnapClient } from '../../../../clients/snap/SnapClient'; import { Network } from '../../../../constants'; import type { TronKeyringAccount } from '../../../../entities/keyring-account'; -import { TronMultichainMethod } from '../../../../handlers/keyring-types'; +import { TronMultichainMethod } from '../../../../handlers/keyring/keyring-types'; import type { Preferences } from '../../../../types/snap'; import { render } from './render'; diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx index 158199ba..af658109 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx @@ -1,6 +1,6 @@ import { Network } from '../../../../constants'; import type { TronKeyringAccount } from '../../../../entities/keyring-account'; -import { TronMultichainMethod } from '../../../../handlers/keyring-types'; +import { TronMultichainMethod } from '../../../../handlers/keyring/keyring-types'; import { TRANSACTION_TAPOS_EXPIRED } from '../../../../services/transaction-scan/isTransactionDeadlinePassedError'; import { SimulationStatus } from '../../../../services/transaction-scan/types'; import type { diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.test.tsx index 2a11d7db..5a12d65c 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.test.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.test.tsx @@ -6,7 +6,7 @@ import { Network } from '../../../../constants'; import type { SnapExecutionContext } from '../../../../context'; import type { AssetEntity } from '../../../../entities/assets'; import type { TronKeyringAccount } from '../../../../entities/keyring-account'; -import { TronMultichainMethod } from '../../../../handlers/keyring-types'; +import { TronMultichainMethod } from '../../../../handlers/keyring/keyring-types'; import type { AssetsService } from '../../../../services/assets/AssetsService'; import type { FeeCalculatorService } from '../../../../services/send/FeeCalculatorService'; import type { @@ -142,7 +142,7 @@ type WithSnapContextCallback = (payload: { isTransactionExpired: jest.Mock; }; mockState: { setKey: jest.Mock }; - mockAssetsService: jest.Mocked>; + mockAssetsService: jest.Mocked>; mockFeeCalculatorService: jest.Mocked< Pick >; @@ -162,9 +162,9 @@ async function withSnapContext( testFunction: WithSnapContextCallback, ): Promise { const mockAssetsService: jest.Mocked< - Pick + Pick > = { - getAssetsByAccountId: jest.fn().mockResolvedValue(mockAssets), + getAccountAssetsByIDs: jest.fn().mockResolvedValue(mockAssets), }; const mockFeeCalculatorService: jest.Mocked< @@ -706,7 +706,7 @@ describe('ConfirmSignTransaction render', () => { it('sets isInsufficientBalance when the TRX balance cannot cover the transaction and fee', async () => { await withSnapContext(async ({ mockSnapClient, mockAssetsService }) => { - mockAssetsService.getAssetsByAccountId.mockResolvedValue([ + mockAssetsService.getAccountAssetsByIDs.mockResolvedValue([ { rawAmount: '50000', uiAmount: '0.05' } as AssetEntity, // TRX ...mockAssets.slice(1), ]); diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.tsx index 8340ce50..c93b40b4 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/render.tsx @@ -8,7 +8,7 @@ import type { Transaction } from 'tronweb/lib/esm/types'; import { Network, Networks, ZERO } from '../../../../constants'; import snapContext from '../../../../context'; import type { TronKeyringAccount } from '../../../../entities/keyring-account'; -import { BackgroundEventMethod } from '../../../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../../../handlers/cronjob/cronjob'; import { EXPIRED_TRANSACTION_SCAN } from '../../../../services/transaction-scan/buildExpiredScanResult'; import type { TransactionScanResult } from '../../../../services/transaction-scan/types'; import { TRX_IMAGE_SVG } from '../../../../static/tron-logo'; @@ -93,7 +93,7 @@ export async function render( // Parallelize: Get preferences + Fetch account assets const [preferences, accountAssets] = await Promise.all([ snapClient.getPreferences().catch(() => DEFAULT_CONTEXT.preferences), - assetsService.getAssetsByAccountId(account.id, [ + assetsService.getAccountAssetsByIDs(account.id, [ Networks[scope as Network].nativeToken.id, Networks[scope as Network].bandwidth.id, Networks[scope as Network].energy.id, diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.test.tsx index ad441bab..f318478b 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.test.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.test.tsx @@ -7,7 +7,7 @@ import { import type { SnapClient } from '../../../../clients/snap/SnapClient'; import { Network } from '../../../../constants'; import type { AssetEntity } from '../../../../entities/assets'; -import { BackgroundEventMethod } from '../../../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../../../handlers/cronjob/cronjob'; import type { State, UnencryptedStateValue, diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.tsx index 7e6bbf86..5e87a09f 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmTransactionRequest/render.tsx @@ -6,7 +6,7 @@ import { Network } from '../../../../constants'; import snapContext from '../../../../context'; import type { AssetEntity } from '../../../../entities/assets'; import type { TronKeyringAccount } from '../../../../entities/keyring-account'; -import { BackgroundEventMethod } from '../../../../handlers/cronjob'; +import { BackgroundEventMethod } from '../../../../handlers/cronjob/cronjob'; import type { ComputeFeeResult } from '../../../../services/send/types'; import type { State, diff --git a/packages/tron-wallet-snap/src/utils/executeOnChainActions.ts b/packages/tron-wallet-snap/src/utils/executeOnChainActions.ts index 1911cf04..4c3e142a 100644 --- a/packages/tron-wallet-snap/src/utils/executeOnChainActions.ts +++ b/packages/tron-wallet-snap/src/utils/executeOnChainActions.ts @@ -4,7 +4,7 @@ import type { SnapClient } from '../clients/snap/SnapClient'; import type { TronWebFactory } from '../clients/tronweb/TronWebFactory'; import type { Network } from '../constants'; import type { TronKeyringAccount } from '../entities/keyring-account'; -import { BackgroundEventMethod } from '../handlers/cronjob'; +import { BackgroundEventMethod } from '../handlers/cronjob/cronjob'; import type { AccountsService } from '../services/accounts/AccountsService'; /** diff --git a/packages/tron-wallet-snap/src/validation/keyring-structs.test.ts b/packages/tron-wallet-snap/src/validation/keyring-structs.test.ts index 25bdf178..e4e656c8 100644 --- a/packages/tron-wallet-snap/src/validation/keyring-structs.test.ts +++ b/packages/tron-wallet-snap/src/validation/keyring-structs.test.ts @@ -2,7 +2,7 @@ import { assert, StructError } from '@metamask/superstruct'; import { bytesToBase64, bytesToHex, stringToBytes } from '@metamask/utils'; import { Network } from '../constants'; -import { TronMultichainMethod } from '../handlers/keyring-types'; +import { TronMultichainMethod } from '../handlers/keyring/keyring-types'; import { SignMessageRequestStruct, SignTransactionRequestStruct, diff --git a/packages/tron-wallet-snap/src/validation/structs.ts b/packages/tron-wallet-snap/src/validation/structs.ts index 093d05b3..2ce737cb 100644 --- a/packages/tron-wallet-snap/src/validation/structs.ts +++ b/packages/tron-wallet-snap/src/validation/structs.ts @@ -28,7 +28,7 @@ import { import { TronWeb } from 'tronweb'; import { Network } from '../constants'; -import { TronMultichainMethod } from '../handlers/keyring-types'; +import { TronMultichainMethod } from '../handlers/keyring/keyring-types'; import { MaximumResourceCaipAssetTypeStruct, NativeCaipAssetTypeStruct, diff --git a/yarn.lock b/yarn.lock index 5fd773e5..8271abb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -839,7 +839,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abi@npm:^5.7.0": +"@ethersproject/abi@npm:^5.7.0, @ethersproject/abi@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/abi@npm:5.8.0" dependencies: @@ -884,7 +884,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/address@npm:^5.8.0": +"@ethersproject/address@npm:^5.7.0, @ethersproject/address@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/address@npm:5.8.0" dependencies: @@ -906,7 +906,17 @@ __metadata: languageName: node linkType: hard -"@ethersproject/bignumber@npm:^5.8.0": +"@ethersproject/basex@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/basex@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + checksum: 10/1a8d48a9397461ea42ec43b69a15a0d13ba0b9192695713750d9d391503c55b258cca435fa78a4014d23a813053f1a471593b89c7c0d89351639a78d50a12ef2 + languageName: node + linkType: hard + +"@ethersproject/bignumber@npm:^5.7.0, @ethersproject/bignumber@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/bignumber@npm:5.8.0" dependencies: @@ -935,6 +945,24 @@ __metadata: languageName: node linkType: hard +"@ethersproject/contracts@npm:^5.7.0": + version: 5.8.0 + resolution: "@ethersproject/contracts@npm:5.8.0" + dependencies: + "@ethersproject/abi": "npm:^5.8.0" + "@ethersproject/abstract-provider": "npm:^5.8.0" + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/constants": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + checksum: 10/839f8211f5e560f15468ae843ba316ffeacab5cebcece1eec76bc5714472ebfe3453484f283d3e46b9d3faaffef1e17cc3583cf24e01638a1fd52f69012cf8d4 + languageName: node + linkType: hard + "@ethersproject/hash@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/hash@npm:5.8.0" @@ -952,6 +980,47 @@ __metadata: languageName: node linkType: hard +"@ethersproject/hdnode@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/hdnode@npm:5.8.0" + dependencies: + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/basex": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/pbkdf2": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/sha2": "npm:^5.8.0" + "@ethersproject/signing-key": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + "@ethersproject/wordlists": "npm:^5.8.0" + checksum: 10/55b35cf30f0dd40e2d5ecd4b2f005ebea82a85a440717a61d4a483074f652d2c7063e9c704272b894bfdd500f7883aa36692931c6808591f702c1da7107ebb61 + languageName: node + linkType: hard + +"@ethersproject/json-wallets@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/json-wallets@npm:5.8.0" + dependencies: + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/hdnode": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/pbkdf2": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/random": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + aes-js: "npm:3.0.0" + scrypt-js: "npm:3.0.1" + checksum: 10/5cbf7e698ee7f26f54fceb672d9824b01816cd785182e638cb5cd1eaed5d80d8a4576e3cad92af46ac6d23404a806a47a72d5dee908af42322d091553a0d8da6 + languageName: node + linkType: hard + "@ethersproject/keccak256@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/keccak256@npm:5.8.0" @@ -978,6 +1047,16 @@ __metadata: languageName: node linkType: hard +"@ethersproject/pbkdf2@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/pbkdf2@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/sha2": "npm:^5.8.0" + checksum: 10/203bb992eec3042256702f4c8259a37202af7b341cc6e370614cdc52541042fc3b795fb040592bd6be8b67376a798c45312ca1e6d5d179c3e8eb7431882f1fd1 + languageName: node + linkType: hard + "@ethersproject/properties@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/properties@npm:5.8.0" @@ -987,6 +1066,44 @@ __metadata: languageName: node linkType: hard +"@ethersproject/providers@npm:^5.7.0, @ethersproject/providers@npm:^5.7.2": + version: 5.8.0 + resolution: "@ethersproject/providers@npm:5.8.0" + dependencies: + "@ethersproject/abstract-provider": "npm:^5.8.0" + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/base64": "npm:^5.8.0" + "@ethersproject/basex": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/constants": "npm:^5.8.0" + "@ethersproject/hash": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/networks": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/random": "npm:^5.8.0" + "@ethersproject/rlp": "npm:^5.8.0" + "@ethersproject/sha2": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + "@ethersproject/web": "npm:^5.8.0" + bech32: "npm:1.1.4" + ws: "npm:8.18.0" + checksum: 10/7d40fc0abb78fc9e69b71cb560beb2a93cf1da2cf978a061031a34c0ed76c2f5936ed8c0bdb9aa1307fe5308d0159e429b83b779dbd550639a886a88d6d17817 + languageName: node + linkType: hard + +"@ethersproject/random@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/random@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10/47c34a72c81183ac13a1b4635bb9d5cf1456e6329276f50c9e12711f404a9eb4536db824537ed05ef8839a0a358883dc3342d3ea83147b8bafeb767dc8f57e23 + languageName: node + linkType: hard + "@ethersproject/rlp@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/rlp@npm:5.8.0" @@ -997,6 +1114,17 @@ __metadata: languageName: node linkType: hard +"@ethersproject/sha2@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/sha2@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + hash.js: "npm:1.1.7" + checksum: 10/ef8916e3033502476fba9358ba1993722ac3bb99e756d5681e4effa3dfa0f0bf0c29d3fa338662830660b45dd359cccb06ba40bc7b62cfd44f4a177b25829404 + languageName: node + linkType: hard + "@ethersproject/signing-key@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/signing-key@npm:5.8.0" @@ -1039,6 +1167,29 @@ __metadata: languageName: node linkType: hard +"@ethersproject/wallet@npm:^5.7.0": + version: 5.8.0 + resolution: "@ethersproject/wallet@npm:5.8.0" + dependencies: + "@ethersproject/abstract-provider": "npm:^5.8.0" + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/hash": "npm:^5.8.0" + "@ethersproject/hdnode": "npm:^5.8.0" + "@ethersproject/json-wallets": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/random": "npm:^5.8.0" + "@ethersproject/signing-key": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + "@ethersproject/wordlists": "npm:^5.8.0" + checksum: 10/354c8985a74b1bb0a8ba80f374c1af882f7657716b974dda235184ee98151e30741b24f58a93c84693aa6e72a8a5c3ae62143966967f40f52f62093559388e6a + languageName: node + linkType: hard + "@ethersproject/web@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/web@npm:5.8.0" @@ -1052,6 +1203,19 @@ __metadata: languageName: node linkType: hard +"@ethersproject/wordlists@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/wordlists@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/hash": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + checksum: 10/b8e6aa7d2195bb568847f360f6525ddc3d145404fbd4553e2e05daf4a95f58167591feb69e16e3398a28114ea85e1895fc8f5bd1c0cbf8b578123d7c1d21c32d + languageName: node + linkType: hard + "@humanfs/core@npm:^0.19.1": version: 0.19.1 resolution: "@humanfs/core@npm:0.19.1" @@ -1690,6 +1854,90 @@ __metadata: languageName: node linkType: hard +"@metamask/abi-utils@npm:^2.0.3": + version: 2.0.4 + resolution: "@metamask/abi-utils@npm:2.0.4" + dependencies: + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^9.0.0" + checksum: 10/3d32d42c6e98fc4719b2b53597e573764b80936c7cc31d884c87729c4c4f74a30e93096db87aaa7cbcec9d3bb7d22b1adfc98a8bcb4c7c2f17bfbddaa4367d34 + languageName: node + linkType: hard + +"@metamask/abi-utils@npm:^3.0.0": + version: 3.0.0 + resolution: "@metamask/abi-utils@npm:3.0.0" + dependencies: + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.0.1" + checksum: 10/068b98185148b9e185b4af4392c6a6f82f1d4b1ff60013c57679c618f37afe9030e3ccc940e1a8b690be6f62ea91115ab18b73f3c3c09f4eff1794e31ababb9b + languageName: node + linkType: hard + +"@metamask/account-api@npm:^1.1.1": + version: 1.1.1 + resolution: "@metamask/account-api@npm:1.1.1" + dependencies: + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-utils": "npm:^4.0.0" + uuid: "npm:^9.0.1" + checksum: 10/2991dbfbbbe12437c2267c8be7f52f2eea8f6c3a021bcc21c30a07506a02894b207f29775be5e4e81a7453fc23dbafe94013fe1f48a3d6044d4527f95ae91827 + languageName: node + linkType: hard + +"@metamask/account-tree-controller@npm:^7.5.5": + version: 7.5.5 + resolution: "@metamask/account-tree-controller@npm:7.5.5" + dependencies: + "@metamask/accounts-controller": "npm:^39.0.5" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/multichain-account-service": "npm:^13.0.0" + "@metamask/profile-sync-controller": "npm:^28.3.0" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.1.2" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + fast-deep-equal: "npm:^3.1.3" + lodash: "npm:^4.17.21" + peerDependencies: + "@metamask/providers": ^22.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/18913a9cdf65a5ab640d2cb608f6fb46b0f4ebce1537d4ed3e6502392efb15acb45b0648319a861421e6f527a40c7574e9e505fc4cefdc4f9fde0a06df1e428e + languageName: node + linkType: hard + +"@metamask/accounts-controller@npm:^39.0.4, @metamask/accounts-controller@npm:^39.0.5": + version: 39.0.5 + resolution: "@metamask/accounts-controller@npm:39.0.5" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/eth-snap-keyring": "npm:^23.0.0" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/keyring-internal-api": "npm:^11.0.1" + "@metamask/keyring-sdk": "npm:^2.2.0" + "@metamask/keyring-utils": "npm:^3.3.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + deepmerge: "npm:^4.2.2" + ethereum-cryptography: "npm:^2.1.2" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/providers": ^22.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/5d505931fa24d9d091b4822fe3d640d712b0a65d97886ca4b50b7842613326e160d6b48ac23dcf5ac5a1507bf4c8207748d238fca1998ac90e86f5eaa02f74fc + languageName: node + linkType: hard + "@metamask/action-utils@npm:^1.0.0": version: 1.1.1 resolution: "@metamask/action-utils@npm:1.1.1" @@ -1701,6 +1949,18 @@ __metadata: languageName: node linkType: hard +"@metamask/address-book-controller@npm:^7.1.2": + version: 7.1.2 + resolution: "@metamask/address-book-controller@npm:7.1.2" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.0.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.9.0" + checksum: 10/e15140418452a80d51fec783003144add72a50a4fe362377481de83c7858860f641a3cfb1575f4b802b1eb1e873b3efd03bb4183afcbee77f95c7525e05aaed4 + languageName: node + linkType: hard + "@metamask/analytics-controller@npm:^1.1.1": version: 1.2.1 resolution: "@metamask/analytics-controller@npm:1.2.1" @@ -1734,6 +1994,101 @@ __metadata: languageName: node linkType: hard +"@metamask/assets-controller@npm:11.2.0": + version: 11.2.0 + resolution: "@metamask/assets-controller@npm:11.2.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@ethersproject/abi": "npm:^5.7.0" + "@ethersproject/providers": "npm:^5.7.0" + "@metamask/account-tree-controller": "npm:^7.5.5" + "@metamask/accounts-controller": "npm:^39.0.5" + "@metamask/assets-controllers": "npm:^110.0.0" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/client-controller": "npm:^1.0.1" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/core-backend": "npm:^7.0.0" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/keyring-internal-api": "npm:^11.0.1" + "@metamask/keyring-snap-client": "npm:^9.2.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/network-enablement-controller": "npm:^5.6.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/phishing-controller": "npm:^17.3.0" + "@metamask/polling-controller": "npm:^16.0.8" + "@metamask/preferences-controller": "npm:^23.1.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-utils": "npm:^12.1.2" + "@metamask/transaction-controller": "npm:^69.2.1" + "@metamask/utils": "npm:^11.11.0" + async-mutex: "npm:^0.5.0" + bignumber.js: "npm:^9.1.2" + lodash: "npm:^4.17.21" + p-limit: "npm:^3.1.0" + checksum: 10/45f420415b569badbbbf36c25851a4e658b45c904ff11411bb610fdc5e258e40fbded13c9f413834f5d38ce2e7aa31449490c8e925c3bf5bc2c7ae6c7c42f675 + languageName: node + linkType: hard + +"@metamask/assets-controllers@npm:^110.0.0": + version: 110.0.2 + resolution: "@metamask/assets-controllers@npm:110.0.2" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@ethersproject/abi": "npm:^5.7.0" + "@ethersproject/address": "npm:^5.7.0" + "@ethersproject/bignumber": "npm:^5.7.0" + "@ethersproject/contracts": "npm:^5.7.0" + "@ethersproject/providers": "npm:^5.7.0" + "@metamask/abi-utils": "npm:^2.0.3" + "@metamask/account-tree-controller": "npm:^7.5.5" + "@metamask/accounts-controller": "npm:^39.0.5" + "@metamask/approval-controller": "npm:^9.0.2" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/contract-metadata": "npm:^2.4.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/core-backend": "npm:^8.0.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/keyring-api": "npm:^23.7.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/metamask-eth-abis": "npm:^3.1.1" + "@metamask/multichain-account-service": "npm:^13.0.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/network-enablement-controller": "npm:^6.0.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/phishing-controller": "npm:^17.3.0" + "@metamask/polling-controller": "npm:^16.0.8" + "@metamask/preferences-controller": "npm:^23.1.0" + "@metamask/profile-sync-controller": "npm:^28.3.0" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.1.2" + "@metamask/storage-service": "npm:^1.0.2" + "@metamask/transaction-controller": "npm:^69.3.0" + "@metamask/utils": "npm:^11.11.0" + "@tanstack/query-core": "npm:^5.62.16" + "@types/bn.js": "npm:^5.1.5" + "@types/uuid": "npm:^8.3.0" + async-mutex: "npm:^0.5.0" + bitcoin-address-validation: "npm:^2.2.3" + bn.js: "npm:^5.2.1" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + multiformats: "npm:^9.9.0" + reselect: "npm:^5.1.1" + single-call-balance-checker-abi: "npm:^1.0.0" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/providers": ^22.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/b1ba364105db912eeb3a1dbe43c11bf0c8af7ce0c5f685d09d3f4cdeade9d99d3e5f6e4d2f9b62901fdb670e6adc3fcd9babfd296ed512ffbceac080f3950484 + languageName: node + linkType: hard + "@metamask/auto-changelog@npm:^6.1.1": version: 6.1.1 resolution: "@metamask/auto-changelog@npm:6.1.1" @@ -1806,6 +2161,15 @@ __metadata: languageName: node linkType: hard +"@metamask/browser-passworder@npm:^6.0.0": + version: 6.0.0 + resolution: "@metamask/browser-passworder@npm:6.0.0" + dependencies: + "@metamask/utils": "npm:^11.0.1" + checksum: 10/44b31729ccd52e62df27a948fbea2320a11861d6465128b1626a723fc47e25f9e3a8c3bdc09329f3f270b5d9e023107cb439cfb6961a3614c6daa58ea4524f00 + languageName: node + linkType: hard + "@metamask/chain-agnostic-permission@npm:^1.6.2": version: 1.7.0 resolution: "@metamask/chain-agnostic-permission@npm:1.7.0" @@ -1820,6 +2184,51 @@ __metadata: languageName: node linkType: hard +"@metamask/client-controller@npm:^1.0.1": + version: 1.0.1 + resolution: "@metamask/client-controller@npm:1.0.1" + dependencies: + "@metamask/base-controller": "npm:^9.0.1" + "@metamask/messenger": "npm:^1.0.0" + checksum: 10/7a3db2c30c6217a018a7cc36cb40b0be21ec66d1816327619ca91e843657ea684a2194fd27a6d58cb2f9e6f5736e44277c9eb026e9606dd2ae522be68affc912 + languageName: node + linkType: hard + +"@metamask/config-registry-controller@npm:^1.0.0": + version: 1.0.0 + resolution: "@metamask/config-registry-controller@npm:1.0.0" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/polling-controller": "npm:^16.0.8" + "@metamask/profile-sync-controller": "npm:^28.3.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + reselect: "npm:^5.1.1" + checksum: 10/d02172b4b58e74e87c76c067c0197eebf20365d4bccb9d5307e6f275dc6bfb7f65f11286493da4cbc26ed513df6be73db7f02929a3d60a231ea2bc0fee877abd + languageName: node + linkType: hard + +"@metamask/connectivity-controller@npm:^0.2.0": + version: 0.2.0 + resolution: "@metamask/connectivity-controller@npm:0.2.0" + dependencies: + "@metamask/base-controller": "npm:^9.0.1" + "@metamask/messenger": "npm:^1.0.0" + checksum: 10/586c80931341375c713aa5a474725ec88174e6e885d5f75d23b6458b734ec0e912a8c47996bea94a82f9549c9598ba982ac99aaeccac1fd92002c35a38f5397f + languageName: node + linkType: hard + +"@metamask/contract-metadata@npm:^2.4.0": + version: 2.5.0 + resolution: "@metamask/contract-metadata@npm:2.5.0" + checksum: 10/462b3ec7b32311ff5e6eec001abf25143e67ee667c70e0b9a3dee7545e7fc245b8098856ae79fef9758ef1db4930fa1d1d7681410995520935f2885bdb9641d2 + languageName: node + linkType: hard + "@metamask/controller-utils@npm:^11.19.0": version: 11.20.0 resolution: "@metamask/controller-utils@npm:11.20.0" @@ -1841,7 +2250,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^12.0.0, @metamask/controller-utils@npm:^12.3.0": +"@metamask/controller-utils@npm:^12.0.0, @metamask/controller-utils@npm:^12.1.0, @metamask/controller-utils@npm:^12.3.0": version: 12.3.0 resolution: "@metamask/controller-utils@npm:12.3.0" dependencies: @@ -1863,6 +2272,42 @@ __metadata: languageName: node linkType: hard +"@metamask/core-backend@npm:^7.0.0": + version: 7.0.0 + resolution: "@metamask/core-backend@npm:7.0.0" + dependencies: + "@metamask/account-tree-controller": "npm:^7.5.5" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/profile-sync-controller": "npm:^28.3.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/utils": "npm:^11.11.0" + "@tanstack/query-core": "npm:^5.62.16" + async-mutex: "npm:^0.5.0" + uuid: "npm:^8.3.2" + checksum: 10/306ccde8856832b236984dcd6ae7044b8664c6319a80f199b23a2cd91883188d921968387bb515defe8d36cd3d06d3f9db0144e821248a844ad1907ca9ec902b + languageName: node + linkType: hard + +"@metamask/core-backend@npm:^8.0.0": + version: 8.0.0 + resolution: "@metamask/core-backend@npm:8.0.0" + dependencies: + "@metamask/account-tree-controller": "npm:^7.5.5" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/profile-sync-controller": "npm:^28.3.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/utils": "npm:^11.11.0" + "@tanstack/query-core": "npm:^5.62.16" + async-mutex: "npm:^0.5.0" + uuid: "npm:^8.3.2" + checksum: 10/5b35e69b72340904f12a2c1f2fd46dbf5006242cfc4470a32379457ffe4a885718c4e20c6555eeb42da814d4f2596988a60549a37216143c076ee4e26a2e28d4 + languageName: node + linkType: hard + "@metamask/create-release-branch@npm:^4.2.1": version: 4.2.1 resolution: "@metamask/create-release-branch@npm:4.2.1" @@ -1957,6 +2402,93 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-block-tracker@npm:^15.0.1": + version: 15.0.1 + resolution: "@metamask/eth-block-tracker@npm:15.0.1" + dependencies: + "@metamask/eth-json-rpc-provider": "npm:^6.0.0" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^11.9.0" + json-rpc-random-id: "npm:^1.0.1" + checksum: 10/8c0e0f5bde00fb40aa240fc562c29d0ce84156402132705d387c95453c6f265b3b738c9b649510771965d8b5b8036c2bdc6406142ff634383bf60df3741bdbfe + languageName: node + linkType: hard + +"@metamask/eth-hd-keyring@npm:^14.1.1": + version: 14.1.2 + resolution: "@metamask/eth-hd-keyring@npm:14.1.2" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/key-tree": "npm:^10.0.2" + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-sdk": "npm:^2.3.0" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/scure-bip39": "npm:^2.1.1" + "@metamask/superstruct": "npm:^3.4.1" + "@metamask/utils": "npm:^11.11.0" + ethereum-cryptography: "npm:^2.2.1" + checksum: 10/077d6aacc674903d737948dfb5a3215e912e73afabad14429614ca643269150604b8ded8cbd48601f99b532c07e51c8d6b1036bad304a21a5b2ded3ea7d06c02 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-infura@npm:^10.3.0": + version: 10.3.0 + resolution: "@metamask/eth-json-rpc-infura@npm:10.3.0" + dependencies: + "@metamask/eth-json-rpc-provider": "npm:^5.0.0" + "@metamask/json-rpc-engine": "npm:^10.1.0" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.0.1" + checksum: 10/164c9ef1285a0895db668f3949d9258df721d348c857c4337b964f147000221d69fd103851c6483d8dd6bfe851c76cc5299155a8818eac0b92334469c40ccaef + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-middleware@npm:^23.1.3": + version: 23.1.3 + resolution: "@metamask/eth-json-rpc-middleware@npm:23.1.3" + dependencies: + "@metamask/eth-block-tracker": "npm:^15.0.1" + "@metamask/eth-json-rpc-provider": "npm:^6.0.1" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/json-rpc-engine": "npm:^10.2.4" + "@metamask/message-manager": "npm:^14.1.1" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.9.0" + klona: "npm:^2.0.6" + pify: "npm:^5.0.0" + safe-stable-stringify: "npm:^2.4.3" + checksum: 10/aee4866afa78cb21aed9daa1211ee9a3515cb9549d9b325d5904b8769fb54790296224b58ec3555eb34a7125d2fd5180d6cba915bb1ca8dc3f04bf75e502c6b0 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-provider@npm:^5.0.0": + version: 5.0.1 + resolution: "@metamask/eth-json-rpc-provider@npm:5.0.1" + dependencies: + "@metamask/json-rpc-engine": "npm:^10.1.1" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^11.8.1" + uuid: "npm:^8.3.2" + checksum: 10/1b874b04a0d8c53edf7036c8dbf4403101afba548cfd3bfc1fa969b893905a72e44c36a17b60ccb202f14a8e012b08031b4649c2ee77d604dc84dfbc6c88b812 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-provider@npm:^6.0.0, @metamask/eth-json-rpc-provider@npm:^6.0.1": + version: 6.0.1 + resolution: "@metamask/eth-json-rpc-provider@npm:6.0.1" + dependencies: + "@metamask/json-rpc-engine": "npm:^10.2.4" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.9.0" + nanoid: "npm:^3.3.8" + checksum: 10/06078a9e43b02f35387a3ccfe09733c7eeac2a732dee1f1be53254fc05719e230776b8512b13702a178fb692088fc7da46f727c5064550d65f51ac59d44f9d83 + languageName: node + linkType: hard + "@metamask/eth-query@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/eth-query@npm:4.0.0" @@ -1967,6 +2499,126 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-sig-util@npm:^8.2.0": + version: 8.2.0 + resolution: "@metamask/eth-sig-util@npm:8.2.0" + dependencies: + "@ethereumjs/rlp": "npm:^4.0.1" + "@ethereumjs/util": "npm:^8.1.0" + "@metamask/abi-utils": "npm:^3.0.0" + "@metamask/utils": "npm:^11.0.1" + "@scure/base": "npm:~1.1.3" + ethereum-cryptography: "npm:^2.1.2" + tweetnacl: "npm:^1.0.3" + checksum: 10/385df1ec541116e1bd725a1df1a519996bad167f99d1b2677126e398cdfda6fc3f03d2ff8f1ca523966bc0aae3ea92a9050953a45d5a7711f4128aacf9242bfc + languageName: node + linkType: hard + +"@metamask/eth-simple-keyring@npm:^12.0.2": + version: 12.0.2 + resolution: "@metamask/eth-simple-keyring@npm:12.0.2" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/keyring-api": "npm:^23.1.0" + "@metamask/keyring-sdk": "npm:^2.0.2" + "@metamask/utils": "npm:^11.11.0" + ethereum-cryptography: "npm:^2.2.1" + randombytes: "npm:^2.1.0" + checksum: 10/ac8a3a5871fb1b7503ae8714beaad07102ad473522f1c65cf09786a3f3498564763d96a51569ed712702f3a62dfaada4c9342def4d48e2c5a1f0985b5cd49725 + languageName: node + linkType: hard + +"@metamask/eth-snap-keyring@npm:^23.0.0": + version: 23.0.2 + resolution: "@metamask/eth-snap-keyring@npm:23.0.2" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/keyring-internal-api": "npm:^11.0.2" + "@metamask/keyring-internal-snap-client": "npm:^10.0.6" + "@metamask/keyring-sdk": "npm:^2.3.0" + "@metamask/keyring-snap-sdk": "npm:^9.2.1" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/messenger": "npm:^1.1.1" + "@metamask/snaps-controllers": "npm:^19.0.1" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.2.1" + "@metamask/superstruct": "npm:^3.4.1" + "@metamask/utils": "npm:^11.11.0" + "@types/uuid": "npm:^9.0.8" + async-mutex: "npm:^0.5.0" + uuid: "npm:^9.0.1" + peerDependencies: + "@metamask/keyring-api": ^23.0.0 + checksum: 10/a8763d5ec3c8863a6a623bd58b3328b06adba6435ea73b5f0b987f6ae2b8fa7a95a9464cc9d9a9ffec11d2183d36b1947251761328d15fb10038f368f6f7ffc5 + languageName: node + linkType: hard + +"@metamask/ethjs-contract@npm:^0.4.1": + version: 0.4.1 + resolution: "@metamask/ethjs-contract@npm:0.4.1" + dependencies: + "@metamask/ethjs-filter": "npm:^0.3.0" + "@metamask/ethjs-util": "npm:^0.3.0" + ethjs-abi: "npm:^0.2.0" + js-sha3: "npm:^0.9.2" + promise-to-callback: "npm:^1.0.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/2187f62336c2afd46b51bda87b96e1537dd7dfe0f621defc3cb5ccb68add482004674f3c11ced95c65b7ecbe845592541f1b268c97b0b42c939d8d5677523097 + languageName: node + linkType: hard + +"@metamask/ethjs-filter@npm:^0.3.0": + version: 0.3.0 + resolution: "@metamask/ethjs-filter@npm:0.3.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/1b7565045e638f60d39ae8d8ca020b6e3ac2e4e91f220f343e499b09a7adeb9e4273249e3c3f7366acc2e44bc0b7fe3dd3ac84c66e9a0853352bfb0e116c1d87 + languageName: node + linkType: hard + +"@metamask/ethjs-format@npm:^0.3.0": + version: 0.3.0 + resolution: "@metamask/ethjs-format@npm:0.3.0" + dependencies: + "@metamask/ethjs-util": "npm:^0.3.0" + "@metamask/number-to-bn": "npm:^1.7.1" + bn.js: "npm:^5.2.1" + ethjs-schema: "npm:0.2.1" + is-hex-prefixed: "npm:1.0.0" + strip-hex-prefix: "npm:1.0.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/4ae73716e0dd76f7b780ede79b3989d241ee8654b7aa9ec23678529a1916f77ab101552f7aabe56c8e26506a33f34181f40624a68a317e7cd3ae45fb0da2fa73 + languageName: node + linkType: hard + +"@metamask/ethjs-query@npm:^0.7.1": + version: 0.7.1 + resolution: "@metamask/ethjs-query@npm:0.7.1" + dependencies: + "@metamask/ethjs-format": "npm:^0.3.0" + "@metamask/ethjs-rpc": "npm:^0.4.0" + promise-to-callback: "npm:^1.0.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/a9d54677cf062267f7e781996edfadfc2a5a2f3589266b7f20386e8109b7cecdfdc47c6aba4bb68d0c4cb387cfdb463d6316d506c06138531ca1e81ab201e5dc + languageName: node + linkType: hard + +"@metamask/ethjs-rpc@npm:^0.4.0": + version: 0.4.0 + resolution: "@metamask/ethjs-rpc@npm:0.4.0" + dependencies: + promise-to-callback: "npm:^1.0.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/e126535ff7599ef584b0084dae846294d505b69141a143543d7580cdce4b297646e796fbd0cecc5a824dce8b5e3b179bb177ceff06fd50ad584e7fce00ab081f + languageName: node + linkType: hard + "@metamask/ethjs-unit@npm:^0.3.0": version: 0.3.0 resolution: "@metamask/ethjs-unit@npm:0.3.0" @@ -1979,6 +2631,40 @@ __metadata: languageName: node linkType: hard +"@metamask/ethjs-util@npm:^0.3.0": + version: 0.3.0 + resolution: "@metamask/ethjs-util@npm:0.3.0" + dependencies: + is-hex-prefixed: "npm:1.0.0" + strip-hex-prefix: "npm:1.0.0" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/aaecae091dd16362f048cbba27629d67d10530c704facf80f430db546c8ea32fa627cd9560bd3eca1e6ce651d2b7a7df9fdc3677e0ae2814954e3c950cee70da + languageName: node + linkType: hard + +"@metamask/gas-fee-controller@npm:^26.3.0": + version: 26.3.0 + resolution: "@metamask/gas-fee-controller@npm:26.3.0" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/ethjs-unit": "npm:^0.3.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/polling-controller": "npm:^16.0.8" + "@metamask/utils": "npm:^11.11.0" + "@types/bn.js": "npm:^5.1.5" + "@types/uuid": "npm:^8.3.0" + bn.js: "npm:^5.2.1" + uuid: "npm:^8.3.2" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/a09363e61f84287596eb31af6bc9bc77361a4f3aab4f7751aa85e7c94996bdfb088ecb2620404f1bd405129077043c9c2efd9d27f5a79a5dd5f7a7435fb02b82 + languageName: node + linkType: hard + "@metamask/internal-snaps-monorepo@workspace:.": version: 0.0.0-use.local resolution: "@metamask/internal-snaps-monorepo@workspace:." @@ -2029,7 +2715,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/json-rpc-engine@npm:^10.0.2, @metamask/json-rpc-engine@npm:^10.1.1, @metamask/json-rpc-engine@npm:^10.2.4, @metamask/json-rpc-engine@npm:^10.5.0": +"@metamask/json-rpc-engine@npm:^10.0.2, @metamask/json-rpc-engine@npm:^10.1.0, @metamask/json-rpc-engine@npm:^10.1.1, @metamask/json-rpc-engine@npm:^10.2.4, @metamask/json-rpc-engine@npm:^10.5.0": version: 10.5.0 resolution: "@metamask/json-rpc-engine@npm:10.5.0" dependencies: @@ -2056,7 +2742,7 @@ __metadata: languageName: node linkType: hard -"@metamask/key-tree@npm:^10.1.1": +"@metamask/key-tree@npm:^10.0.2, @metamask/key-tree@npm:^10.1.1": version: 10.1.1 resolution: "@metamask/key-tree@npm:10.1.1" dependencies: @@ -2069,7 +2755,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^23.7.0": +"@metamask/keyring-api@npm:^23.1.0, @metamask/keyring-api@npm:^23.3.0, @metamask/keyring-api@npm:^23.5.0, @metamask/keyring-api@npm:^23.6.0, @metamask/keyring-api@npm:^23.7.0": version: 23.7.0 resolution: "@metamask/keyring-api@npm:23.7.0" dependencies: @@ -2081,6 +2767,87 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-controller@npm:^27.1.0": + version: 27.1.0 + resolution: "@metamask/keyring-controller@npm:27.1.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/browser-passworder": "npm:^6.0.0" + "@metamask/eth-hd-keyring": "npm:^14.1.1" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/eth-simple-keyring": "npm:^12.0.2" + "@metamask/keyring-api": "npm:^23.1.0" + "@metamask/keyring-internal-api": "npm:^11.0.1" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.11.0" + async-mutex: "npm:^0.5.0" + ethereumjs-wallet: "npm:^1.0.1" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + ulid: "npm:^2.3.0" + checksum: 10/72c3cd205c88ac0becff32f1d22dae841d13a6847fc165a16782d1cd8daafb434b472ef867b94833d2f8bcb5f98a9663b630c8bed231332305ba1a395385c241 + languageName: node + linkType: hard + +"@metamask/keyring-internal-api@npm:^11.0.1, @metamask/keyring-internal-api@npm:^11.0.2": + version: 11.0.2 + resolution: "@metamask/keyring-internal-api@npm:11.0.2" + dependencies: + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/superstruct": "npm:^3.4.1" + checksum: 10/7a5d817b93d3f0bd54860d7747833ace48e46d079e700d98f87c76a79b4da25acc1ba0aec3fdc4ff49c36fb3dc0a3378d27c7b970cdb31c88f8caa13c8199086 + languageName: node + linkType: hard + +"@metamask/keyring-internal-snap-client@npm:^10.0.5, @metamask/keyring-internal-snap-client@npm:^10.0.6": + version: 10.0.6 + resolution: "@metamask/keyring-internal-snap-client@npm:10.0.6" + dependencies: + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-internal-api": "npm:^11.0.2" + "@metamask/keyring-snap-client": "npm:^9.2.1" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/messenger": "npm:^1.1.1" + checksum: 10/b2325f9e9dfae8289574799b6b3cf4aa0a6c4d83a94baae48e1b47948977ad1444adba848ef06e7eec36e966b479485be82c6f9210b3dfbb3c2cdfc2a1e81ef4 + languageName: node + linkType: hard + +"@metamask/keyring-sdk@npm:^2.0.2, @metamask/keyring-sdk@npm:^2.2.0, @metamask/keyring-sdk@npm:^2.3.0": + version: 2.3.0 + resolution: "@metamask/keyring-sdk@npm:2.3.0" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/scure-bip39": "npm:^2.1.1" + "@metamask/superstruct": "npm:^3.4.1" + "@metamask/utils": "npm:^11.11.0" + async-mutex: "npm:^0.5.0" + ethereum-cryptography: "npm:^2.2.1" + uuid: "npm:^9.0.1" + checksum: 10/38402f3834e0e364e1b17fe30ff64c1a050549239e204260081ddd0fc9228e9632d586819c551f91793d78207fb33f81e06ec3ac24537d511e8b5f1fabe57d21 + languageName: node + linkType: hard + +"@metamask/keyring-snap-client@npm:^9.2.0, @metamask/keyring-snap-client@npm:^9.2.1": + version: 9.2.1 + resolution: "@metamask/keyring-snap-client@npm:9.2.1" + dependencies: + "@metamask/keyring-api": "npm:^23.6.0" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/superstruct": "npm:^3.4.1" + "@types/uuid": "npm:^9.0.8" + uuid: "npm:^9.0.1" + webextension-polyfill: "npm:^0.12.0" + peerDependencies: + "@metamask/providers": ^19.0.0 + checksum: 10/bd4f006737598d44992e2a6283448a9cb4321fd0b5bbe59d37d8e28b1e31ad28cce997100e5af5a04c661faba1ee9f320df59ce86ef4c2a0fcbc653091b52af2 + languageName: node + linkType: hard + "@metamask/keyring-snap-sdk@npm:^9.2.1": version: 9.2.1 resolution: "@metamask/keyring-snap-sdk@npm:9.2.1" @@ -2097,6 +2864,18 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-utils@npm:^3.3.1": + version: 3.3.1 + resolution: "@metamask/keyring-utils@npm:3.3.1" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + bitcoin-address-validation: "npm:^2.2.3" + checksum: 10/d0917b2f634d9eb2f563827739fca00c1675ee90674ec49b2b68afcb604aee843d6c5be5d79e9780fa22d29f71fc876f40b2d3d0ed4cab7f5948937ddd276691 + languageName: node + linkType: hard + "@metamask/keyring-utils@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/keyring-utils@npm:4.0.0" @@ -2109,7 +2888,23 @@ __metadata: languageName: node linkType: hard -"@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": +"@metamask/message-manager@npm:^14.1.1": + version: 14.1.2 + resolution: "@metamask/message-manager@npm:14.1.2" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.0.0" + "@metamask/eth-sig-util": "npm:^8.2.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.9.0" + "@types/uuid": "npm:^8.3.0" + jsonschema: "npm:^1.4.1" + uuid: "npm:^8.3.2" + checksum: 10/82e3965069f0eb34e2141ca4dff452c118f54502d0b5d6b832af1906c6413ba1d923b13f1ed6af7f8a7b3087ef7f3b1a700bcffa56b10b06df53972ff2cf9a4f + languageName: node + linkType: hard + +"@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": version: 1.2.0 resolution: "@metamask/messenger@npm:1.2.0" dependencies: @@ -2134,6 +2929,138 @@ __metadata: languageName: node linkType: hard +"@metamask/metamask-eth-abis@npm:^3.1.1": + version: 3.1.1 + resolution: "@metamask/metamask-eth-abis@npm:3.1.1" + checksum: 10/2d456882c5180eaf02d07f578ee8b8806d18639349d086a6b3b68c87e7ea294749efc332bfe7c1d5fb700933e71f31a46d3cd07b94c4e91c80faea5f9729bf0d + languageName: node + linkType: hard + +"@metamask/multichain-account-service@npm:^13.0.0": + version: 13.0.0 + resolution: "@metamask/multichain-account-service@npm:13.0.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@metamask/accounts-controller": "npm:^39.0.5" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/eth-snap-keyring": "npm:^23.0.0" + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/keyring-internal-api": "npm:^11.0.1" + "@metamask/keyring-snap-client": "npm:^9.2.0" + "@metamask/keyring-utils": "npm:^3.3.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/snap-account-service": "npm:^2.0.0" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.1.2" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + async-mutex: "npm:^0.5.0" + lodash: "npm:^4.17.21" + peerDependencies: + "@metamask/account-api": ^1.0.4 + "@metamask/providers": ^22.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/2ecb49a620420804ff74f1e6ce9a75303f2e41a5182b8570b6bef324c63e5be149ea1870815dbe8403a87c8fe17529322896fd9015e10766095a0d74c2aebafd + languageName: node + linkType: hard + +"@metamask/multichain-network-controller@npm:^3.2.1": + version: 3.2.1 + resolution: "@metamask/multichain-network-controller@npm:3.2.1" + dependencies: + "@metamask/accounts-controller": "npm:^39.0.4" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-api": "npm:^23.3.0" + "@metamask/keyring-internal-api": "npm:^11.0.1" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.11.0" + "@solana/addresses": "npm:^2.0.0" + lodash: "npm:^4.17.21" + checksum: 10/60024909e413f4753ba7ef52295f4a5b102afc5a66cc5a5d61c15eca28a3ae452da2b081a47c4ef5c067b2faba7e69963f7da825f4fb59746cbb95ee6089f67a + languageName: node + linkType: hard + +"@metamask/network-controller@npm:^34.0.0": + version: 34.0.0 + resolution: "@metamask/network-controller@npm:34.0.0" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/connectivity-controller": "npm:^0.2.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/eth-block-tracker": "npm:^15.0.1" + "@metamask/eth-json-rpc-infura": "npm:^10.3.0" + "@metamask/eth-json-rpc-middleware": "npm:^23.1.3" + "@metamask/eth-json-rpc-provider": "npm:^6.0.1" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/json-rpc-engine": "npm:^10.5.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/swappable-obj-proxy": "npm:^2.3.0" + "@metamask/utils": "npm:^11.11.0" + fast-deep-equal: "npm:^3.1.3" + immer: "npm:^9.0.6" + loglevel: "npm:^1.8.1" + reselect: "npm:^5.1.1" + uri-js: "npm:^4.4.1" + uuid: "npm:^8.3.2" + checksum: 10/6afb874ca5702e1be616bf6ea92b35332d1969878794ce118138ca8f3733a1521a266d00bb658cf7a37e126545ac942ef5bc09bbd64159612b5424d848dbdc67 + languageName: node + linkType: hard + +"@metamask/network-enablement-controller@npm:^5.6.0": + version: 5.6.0 + resolution: "@metamask/network-enablement-controller@npm:5.6.0" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/multichain-network-controller": "npm:^3.2.1" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/slip44": "npm:^4.3.0" + "@metamask/transaction-controller": "npm:^69.0.0" + "@metamask/utils": "npm:^11.11.0" + reselect: "npm:^5.1.1" + checksum: 10/c4fbedb43bc8331c24794c10a038809ec23b40a6042f589b3d72746a28846951c2e72c359ea6703b18840fc4fae6e5ffa7906979e58a1fb8f16f1fc735bd8514 + languageName: node + linkType: hard + +"@metamask/network-enablement-controller@npm:^6.0.0": + version: 6.0.0 + resolution: "@metamask/network-enablement-controller@npm:6.0.0" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/config-registry-controller": "npm:^1.0.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/keyring-api": "npm:^23.7.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/multichain-network-controller": "npm:^3.2.1" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/slip44": "npm:^4.3.0" + "@metamask/transaction-controller": "npm:^69.3.0" + "@metamask/utils": "npm:^11.11.0" + reselect: "npm:^5.1.1" + checksum: 10/51af8efed6887f8f99232ffde46ad82042224a8863606530301eedec6ff2b876c7b1373a981e5ae646a35de4f0623d98e497a6730cc485f68d6929be54923377 + languageName: node + linkType: hard + +"@metamask/nonce-tracker@npm:^6.0.0": + version: 6.1.0 + resolution: "@metamask/nonce-tracker@npm:6.1.0" + dependencies: + "@ethersproject/providers": "npm:^5.7.2" + async-mutex: "npm:^0.5.0" + checksum: 10/a20cf7084348ef7bdcd9e57e873ca34bf8e04ee43a2ab08634a3ad47fddb632d0e170c1dff03b4ca5bac34a24c35c542fcec509f3c23ce483834082f41b50e4a + languageName: node + linkType: hard + "@metamask/number-to-bn@npm:^1.7.1": version: 1.7.1 resolution: "@metamask/number-to-bn@npm:1.7.1" @@ -2154,7 +3081,7 @@ __metadata: languageName: node linkType: hard -"@metamask/permission-controller@npm:^12.2.0": +"@metamask/permission-controller@npm:^12.2.0, @metamask/permission-controller@npm:^12.3.0": version: 12.3.0 resolution: "@metamask/permission-controller@npm:12.3.0" dependencies: @@ -2192,6 +3119,38 @@ __metadata: languageName: node linkType: hard +"@metamask/phishing-controller@npm:^17.3.0": + version: 17.3.0 + resolution: "@metamask/phishing-controller@npm:17.3.0" + dependencies: + "@metamask/address-book-controller": "npm:^7.1.2" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/transaction-controller": "npm:^69.0.0" + "@noble/hashes": "npm:^1.8.0" + "@types/punycode": "npm:^2.1.0" + ethereum-cryptography: "npm:^2.1.2" + fastest-levenshtein: "npm:^1.0.16" + punycode: "npm:^2.1.1" + checksum: 10/5c9be5dfdd76c66197cf8eaa764da04d34e3f612aded6125c66d31a001430881ed00c59b5c04f30f05e9719a29332cfda0fbcf211b25b54c3ddaf0a812b8f70a + languageName: node + linkType: hard + +"@metamask/polling-controller@npm:^16.0.8": + version: 16.0.8 + resolution: "@metamask/polling-controller@npm:16.0.8" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/utils": "npm:^11.11.0" + "@types/uuid": "npm:^8.3.0" + fast-json-stable-stringify: "npm:^2.1.0" + uuid: "npm:^8.3.2" + checksum: 10/3066522432099d9d69475f73b4468da5ce18eb92340cffba2581ed8f0c8dfdb517ae704448fb395bc9a7659409c5a94cfb8a809b56bd35d7cd87de1b2d948dd8 + languageName: node + linkType: hard + "@metamask/post-message-stream@npm:^10.0.0": version: 10.0.0 resolution: "@metamask/post-message-stream@npm:10.0.0" @@ -2202,6 +3161,40 @@ __metadata: languageName: node linkType: hard +"@metamask/preferences-controller@npm:^23.1.0": + version: 23.1.0 + resolution: "@metamask/preferences-controller@npm:23.1.0" + dependencies: + "@metamask/base-controller": "npm:^9.0.1" + "@metamask/messenger": "npm:^1.0.0" + checksum: 10/61fe1115546ea0c1e45143c2227d7907930ae881c3f14fe6bfb260d9d4e6fdfc84e3f46af69454daeef7dcbb7d02fdb204baf0c29bf05e18212479b6e96721a0 + languageName: node + linkType: hard + +"@metamask/profile-sync-controller@npm:^28.3.0": + version: 28.3.0 + resolution: "@metamask/profile-sync-controller@npm:28.3.0" + dependencies: + "@metamask/address-book-controller": "npm:^7.1.2" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.1.2" + "@metamask/utils": "npm:^11.11.0" + "@noble/ciphers": "npm:^1.3.0" + "@noble/hashes": "npm:^1.8.0" + immer: "npm:^9.0.6" + loglevel: "npm:^1.8.1" + siwe: "npm:^2.3.2" + peerDependencies: + "@metamask/providers": ^22.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/a0fa6dad8a183bcd41907e7ab5d35fcb321bd1c7040125120deebc20b3d809a0e0f076feb2e80ef70b9ce1330138a8d1c8d8b5eea18086cd765ae4301a32e2ba + languageName: node + linkType: hard + "@metamask/providers@npm:^22.1.1": version: 22.1.1 resolution: "@metamask/providers@npm:22.1.1" @@ -2223,6 +3216,19 @@ __metadata: languageName: node linkType: hard +"@metamask/remote-feature-flag-controller@npm:^4.2.2": + version: 4.2.2 + resolution: "@metamask/remote-feature-flag-controller@npm:4.2.2" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.1.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.9.0" + uuid: "npm:^8.3.2" + checksum: 10/ed03ff1ba63c7a0f2b221c3514eb71a8be4200ec543b90676a44930dc731920ac2c92dcc2b13a32ed4e4e8e7e7b28a26db443af9f4bf30f5e2b5785580b286ab + languageName: node + linkType: hard + "@metamask/rpc-errors@npm:^7.0.2, @metamask/rpc-errors@npm:^7.0.3": version: 7.0.3 resolution: "@metamask/rpc-errors@npm:7.0.3" @@ -2268,13 +3274,32 @@ __metadata: languageName: node linkType: hard -"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.5.0": +"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.3.0, @metamask/slip44@npm:^4.5.0": version: 4.5.0 resolution: "@metamask/slip44@npm:4.5.0" checksum: 10/8450d4f5afa98e8f57c67a39f12aa413888c423505f22c05a3dc181be223f7742db017f54a99852acc3826abe74b22bf7247bccd78b810e509321c075e67516f languageName: node linkType: hard +"@metamask/snap-account-service@npm:^2.0.0": + version: 2.1.0 + resolution: "@metamask/snap-account-service@npm:2.1.0" + dependencies: + "@metamask/account-api": "npm:^1.1.1" + "@metamask/eth-snap-keyring": "npm:^23.0.0" + "@metamask/keyring-api": "npm:^23.7.0" + "@metamask/keyring-controller": "npm:^27.1.0" + "@metamask/keyring-internal-snap-client": "npm:^10.0.5" + "@metamask/keyring-snap-sdk": "npm:^9.2.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/snaps-controllers": "npm:^19.0.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/utils": "npm:^11.11.0" + lodash: "npm:^4.17.21" + checksum: 10/00ad8d3c5daf0acc95c2c79ea914c5b802923441f2e0412ba01cef2226cbf2cb24bd0fb42ebb0f6078ccba5cddc39767ea3e401f24c429d3712857be401e3207 + languageName: node + linkType: hard + "@metamask/snaps-cli@npm:^8.4.1": version: 8.4.1 resolution: "@metamask/snaps-cli@npm:8.4.1" @@ -2328,6 +3353,49 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-controllers@npm:^19.0.0, @metamask/snaps-controllers@npm:^19.0.1": + version: 19.0.1 + resolution: "@metamask/snaps-controllers@npm:19.0.1" + dependencies: + "@metamask/approval-controller": "npm:^9.0.1" + "@metamask/base-controller": "npm:^9.0.1" + "@metamask/json-rpc-engine": "npm:^10.2.4" + "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/messenger": "npm:^1.1.0" + "@metamask/object-multiplex": "npm:^2.1.0" + "@metamask/permission-controller": "npm:^12.3.0" + "@metamask/post-message-stream": "npm:^10.0.0" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-registry": "npm:^4.0.0" + "@metamask/snaps-rpc-methods": "npm:^15.0.2" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-utils": "npm:^12.1.3" + "@metamask/storage-service": "npm:^1.0.1" + "@metamask/superstruct": "npm:^3.2.1" + "@metamask/utils": "npm:^11.10.0" + "@xstate/fsm": "npm:^2.0.0" + async-mutex: "npm:^0.5.0" + concat-stream: "npm:^2.0.0" + cron-parser: "npm:^4.5.0" + fast-deep-equal: "npm:^3.1.3" + get-npm-tarball-url: "npm:^2.0.3" + immer: "npm:^9.0.21" + luxon: "npm:^3.5.0" + nanoid: "npm:^3.3.10" + readable-stream: "npm:^3.6.2" + readable-web-to-node-stream: "npm:^3.0.2" + semver: "npm:^7.5.4" + tar-stream: "npm:^3.1.7" + peerDependencies: + "@metamask/snaps-execution-environments": ^11.0.2 + peerDependenciesMeta: + "@metamask/snaps-execution-environments": + optional: true + checksum: 10/e7cee816b1af1e2c4cbd25a81afff779427e6d738c1fe283a1ca9b23f67c62b5a983d6ed35e91acf0b15016e6825074557f3376d322a518c1acfc36728d36509 + languageName: node + linkType: hard + "@metamask/snaps-controllers@npm:^21.0.0": version: 21.0.0 resolution: "@metamask/snaps-controllers@npm:21.0.0" @@ -2439,6 +3507,23 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-rpc-methods@npm:^15.0.2": + version: 15.1.1 + resolution: "@metamask/snaps-rpc-methods@npm:15.1.1" + dependencies: + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/permission-controller": "npm:^12.3.0" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-sdk": "npm:^11.1.0" + "@metamask/snaps-utils": "npm:^12.2.0" + "@metamask/superstruct": "npm:^3.2.1" + "@metamask/utils": "npm:^11.11.0" + "@noble/hashes": "npm:^1.7.1" + async-mutex: "npm:^0.5.0" + checksum: 10/906eafa8a2d4944e50d73b8aa4d32a7070c33367ad3d58843e892e62b3bd8facb0a02e1d88a9245c18a281637435d97266212b7706ef67ee6a68db85a5991ea3 + languageName: node + linkType: hard + "@metamask/snaps-rpc-methods@npm:^17.0.0, @metamask/snaps-rpc-methods@npm:^17.1.0": version: 17.1.0 resolution: "@metamask/snaps-rpc-methods@npm:17.1.0" @@ -2507,7 +3592,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.1.0, @metamask/snaps-utils@npm:^12.2.1, @metamask/snaps-utils@npm:^12.3.0, @metamask/snaps-utils@npm:^12.4.0": +"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.1.0, @metamask/snaps-utils@npm:^12.1.2, @metamask/snaps-utils@npm:^12.1.3, @metamask/snaps-utils@npm:^12.2.0, @metamask/snaps-utils@npm:^12.2.1, @metamask/snaps-utils@npm:^12.3.0, @metamask/snaps-utils@npm:^12.4.0": version: 12.4.0 resolution: "@metamask/snaps-utils@npm:12.4.0" dependencies: @@ -2553,7 +3638,7 @@ __metadata: languageName: node linkType: hard -"@metamask/storage-service@npm:^1.0.2": +"@metamask/storage-service@npm:^1.0.1, @metamask/storage-service@npm:^1.0.2": version: 1.0.2 resolution: "@metamask/storage-service@npm:1.0.2" dependencies: @@ -2570,14 +3655,60 @@ __metadata: languageName: node linkType: hard +"@metamask/swappable-obj-proxy@npm:^2.3.0": + version: 2.3.0 + resolution: "@metamask/swappable-obj-proxy@npm:2.3.0" + checksum: 10/1255c599de9237f06df2390719d6dfcb1f168873df61bbaad5ce376efbc057e2030260b94855569313faeb412b7df9b062d209f4b0b163a3dc02f29d42139e1f + languageName: node + linkType: hard + +"@metamask/transaction-controller@npm:^69.0.0, @metamask/transaction-controller@npm:^69.2.1, @metamask/transaction-controller@npm:^69.3.0": + version: 69.3.0 + resolution: "@metamask/transaction-controller@npm:69.3.0" + dependencies: + "@ethereumjs/common": "npm:^4.4.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" + "@ethersproject/abi": "npm:^5.7.0" + "@ethersproject/contracts": "npm:^5.7.0" + "@ethersproject/wallet": "npm:^5.7.0" + "@metamask/accounts-controller": "npm:^39.0.5" + "@metamask/approval-controller": "npm:^9.0.2" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/core-backend": "npm:^8.0.0" + "@metamask/gas-fee-controller": "npm:^26.3.0" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/metamask-eth-abis": "npm:^3.1.1" + "@metamask/network-controller": "npm:^34.0.0" + "@metamask/nonce-tracker": "npm:^6.0.0" + "@metamask/remote-feature-flag-controller": "npm:^4.2.2" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.11.0" + async-mutex: "npm:^0.5.0" + bignumber.js: "npm:^9.1.2" + bn.js: "npm:^5.2.1" + eth-method-registry: "npm:^4.0.0" + fast-json-patch: "npm:^3.1.1" + lodash: "npm:^4.17.21" + uuid: "npm:^8.3.2" + peerDependencies: + "@babel/runtime": ^7.0.0 + "@metamask/eth-block-tracker": ">=9" + checksum: 10/93923f7e990248a7366f1ad715e8a4eda50bbd0423193e3875109d6733b8ab22d246e4167b740cb3e296bfa0eb10c69b3b7601cdb17f60e016a9837102c8f710 + languageName: node + linkType: hard + "@metamask/tron-wallet-snap@workspace:packages/tron-wallet-snap": version: 0.0.0-use.local resolution: "@metamask/tron-wallet-snap@workspace:packages/tron-wallet-snap" dependencies: + "@metamask/assets-controller": "npm:11.2.0" "@metamask/auto-changelog": "npm:^6.1.1" "@metamask/key-tree": "npm:^10.1.1" "@metamask/keyring-api": "npm:^23.7.0" "@metamask/keyring-snap-sdk": "npm:^9.2.1" + "@metamask/messenger": "npm:^2.0.0" "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" "@metamask/snaps-sdk": "npm:^11.2.0" @@ -2644,6 +3775,13 @@ __metadata: languageName: node linkType: hard +"@noble/ciphers@npm:^1.3.0": + version: 1.3.0 + resolution: "@noble/ciphers@npm:1.3.0" + checksum: 10/051660051e3e9e2ca5fb9dece2885532b56b7e62946f89afa7284a0fb8bc02e2bd1c06554dba68162ff42d295b54026456084198610f63c296873b2f1cd7a586 + languageName: node + linkType: hard + "@noble/curves@npm:1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" @@ -2685,7 +3823,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.2, @noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.2, @noble/hashes@npm:^1.7.1": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.2, @noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.2, @noble/hashes@npm:^1.7.1, @noble/hashes@npm:^1.8.0": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e @@ -3233,30 +4371,116 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.0, @sinonjs/commons@npm:^3.0.1": - version: 3.0.1 - resolution: "@sinonjs/commons@npm:3.0.1" +"@sinonjs/commons@npm:^3.0.0, @sinonjs/commons@npm:^3.0.1": + version: 3.0.1 + resolution: "@sinonjs/commons@npm:3.0.1" + dependencies: + type-detect: "npm:4.0.8" + checksum: 10/a0af217ba7044426c78df52c23cedede6daf377586f3ac58857c565769358ab1f44ebf95ba04bbe38814fba6e316ca6f02870a009328294fc2c555d0f85a7117 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^10.0.2": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" + dependencies: + "@sinonjs/commons": "npm:^3.0.0" + checksum: 10/78155c7bd866a85df85e22028e046b8d46cf3e840f72260954f5e3ed5bd97d66c595524305a6841ffb3f681a08f6e5cef572a2cce5442a8a232dc29fb409b83e + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^13.0.0": + version: 13.0.5 + resolution: "@sinonjs/fake-timers@npm:13.0.5" + dependencies: + "@sinonjs/commons": "npm:^3.0.1" + checksum: 10/11ee417968fc4dce1896ab332ac13f353866075a9d2a88ed1f6258f17cc4f7d93e66031b51fcddb8c203aa4d53fd980b0ae18aba06269f4682164878a992ec3f + languageName: node + linkType: hard + +"@solana/addresses@npm:^2.0.0": + version: 2.3.0 + resolution: "@solana/addresses@npm:2.3.0" + dependencies: + "@solana/assertions": "npm:2.3.0" + "@solana/codecs-core": "npm:2.3.0" + "@solana/codecs-strings": "npm:2.3.0" + "@solana/errors": "npm:2.3.0" + "@solana/nominal-types": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10/11ee6774f938dd2fe5174375b02c4e52063173ce80a895dd35beb84635dcf3e2ba2e3fe7c74a614b2322da10906abceab758c91a13415a9cda53faf91a8ea722 + languageName: node + linkType: hard + +"@solana/assertions@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/assertions@npm:2.3.0" + dependencies: + "@solana/errors": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10/3b430f01d5991569059fea3e6679a4548a624ff5da6db0c2eb2eba757a9ff774c9d90941a0a2335148599aaef8e8fc004a9c5996eb3627b25dca108b05591d02 + languageName: node + linkType: hard + +"@solana/codecs-core@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/codecs-core@npm:2.3.0" + dependencies: + "@solana/errors": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10/d9bba1eaa3ee38fef04e1cbfa43defeea16729a1cf1628a71cb72340558a3f2296279899680e1dda4b1756ab2b280b5f1502330c21c35e167e554f3d0c9d193d + languageName: node + linkType: hard + +"@solana/codecs-numbers@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/codecs-numbers@npm:2.3.0" + dependencies: + "@solana/codecs-core": "npm:2.3.0" + "@solana/errors": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10/e661338b5eb04268a104ff2189b5d001bd2f99e1a3726deaa7157d5acbc3b24740bc25ca03b2028c52ad21fd71d5d5aa64957411c895a9dc1c132aa3bc97b336 + languageName: node + linkType: hard + +"@solana/codecs-strings@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/codecs-strings@npm:2.3.0" dependencies: - type-detect: "npm:4.0.8" - checksum: 10/a0af217ba7044426c78df52c23cedede6daf377586f3ac58857c565769358ab1f44ebf95ba04bbe38814fba6e316ca6f02870a009328294fc2c555d0f85a7117 + "@solana/codecs-core": "npm:2.3.0" + "@solana/codecs-numbers": "npm:2.3.0" + "@solana/errors": "npm:2.3.0" + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: ">=5.3.3" + checksum: 10/a553a891ce149a87f37ff338587980e81f9752e13039cb0d02f0fc6f21ce27af8548ad10f4c9e63f9ef74786ea0e498c91a2f5e3e996a930f581f2977bb1c215 languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^10.0.2": - version: 10.3.0 - resolution: "@sinonjs/fake-timers@npm:10.3.0" +"@solana/errors@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/errors@npm:2.3.0" dependencies: - "@sinonjs/commons": "npm:^3.0.0" - checksum: 10/78155c7bd866a85df85e22028e046b8d46cf3e840f72260954f5e3ed5bd97d66c595524305a6841ffb3f681a08f6e5cef572a2cce5442a8a232dc29fb409b83e + chalk: "npm:^5.4.1" + commander: "npm:^14.0.0" + peerDependencies: + typescript: ">=5.3.3" + bin: + errors: bin/cli.mjs + checksum: 10/0e8a329790b7d38b4bfe1fa6ec2ac60be20562a610d992031395fe9886da28b578a9d0aebb318f5357ae0d4cbc8f3d323c12b9520da2cf6adc9038f96afc3fe1 languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^13.0.0": - version: 13.0.5 - resolution: "@sinonjs/fake-timers@npm:13.0.5" - dependencies: - "@sinonjs/commons": "npm:^3.0.1" - checksum: 10/11ee417968fc4dce1896ab332ac13f353866075a9d2a88ed1f6258f17cc4f7d93e66031b51fcddb8c203aa4d53fd980b0ae18aba06269f4682164878a992ec3f +"@solana/nominal-types@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/nominal-types@npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10/0594893661f4ff2f8587689cd4b61ee15c38c455fe5cbaa7ae7e416f3a483fac97cc3f5a5b3d0a7526bfb89d7da91bc2c72e7b1790bbe59b986579ef2f76689b languageName: node linkType: hard @@ -3272,6 +4496,51 @@ __metadata: languageName: node linkType: hard +"@spruceid/siwe-parser@npm:^2.1.2": + version: 2.1.2 + resolution: "@spruceid/siwe-parser@npm:2.1.2" + dependencies: + "@noble/hashes": "npm:^1.1.2" + apg-js: "npm:^4.3.0" + uri-js: "npm:^4.4.1" + valid-url: "npm:^1.0.9" + checksum: 10/48459fe3b4d4b3091375ee87af700864c9023d4a1271d34850c6d27475e5d93a45d1efe8a71da367ad838b6921ced60c387d54737edd0a7a0d8e4e0a3cc2b8b7 + languageName: node + linkType: hard + +"@stablelib/binary@npm:^1.0.1": + version: 1.0.1 + resolution: "@stablelib/binary@npm:1.0.1" + dependencies: + "@stablelib/int": "npm:^1.0.1" + checksum: 10/c5ed769e2b5d607a5cdb72d325fcf98db437627862fade839daad934bd9ccf02a6f6e34f9de8cb3b18d72fce2ba6cc019a5d22398187d7d69d2607165f27f8bf + languageName: node + linkType: hard + +"@stablelib/int@npm:^1.0.1": + version: 1.0.1 + resolution: "@stablelib/int@npm:1.0.1" + checksum: 10/65bfbf50a382eea70c68e05366bf379cfceff8fbc076f1c267ef2f2411d7aed64fd140c415cb6c29f19a3910d3b8b7805d4b32ad5721a5007a8e744a808c7ae3 + languageName: node + linkType: hard + +"@stablelib/random@npm:^1.0.1": + version: 1.0.2 + resolution: "@stablelib/random@npm:1.0.2" + dependencies: + "@stablelib/binary": "npm:^1.0.1" + "@stablelib/wipe": "npm:^1.0.1" + checksum: 10/f5ace0a588dc4c21f01cb85837892d4c872e994ae77a58a8eb7dd61aa0b26fb1e9b46b0445e71af57d963ef7d9f5965c64258fc0d04df7b2947bc48f2d3560c5 + languageName: node + linkType: hard + +"@stablelib/wipe@npm:^1.0.1": + version: 1.0.1 + resolution: "@stablelib/wipe@npm:1.0.1" + checksum: 10/287802eb146810a46ba72af70b82022caf83a8aeebde23605f5ee0decf64fe2b97a60c856e43b6617b5801287c30cfa863cfb0469e7fcde6f02d143cf0c6cbf4 + languageName: node + linkType: hard + "@swc/core-darwin-arm64@npm:1.11.31": version: 1.11.31 resolution: "@swc/core-darwin-arm64@npm:1.11.31" @@ -3404,6 +4673,13 @@ __metadata: languageName: node linkType: hard +"@tanstack/query-core@npm:^5.62.16": + version: 5.101.4 + resolution: "@tanstack/query-core@npm:5.101.4" + checksum: 10/df86031035ac9a5cf54efece85718b90e93fca62068a44a176da232b6dd49b27168840f2da18c64a0eb25d171bc3fb1aab417db4643025cd194ff887833bd73f + languageName: node + linkType: hard + "@tybys/wasm-util@npm:^0.10.3": version: 0.10.3 resolution: "@tybys/wasm-util@npm:0.10.3" @@ -3454,7 +4730,7 @@ __metadata: languageName: node linkType: hard -"@types/bn.js@npm:^5.1.5": +"@types/bn.js@npm:^5.1.0, @types/bn.js@npm:^5.1.5": version: 5.2.0 resolution: "@types/bn.js@npm:5.2.0" dependencies: @@ -3588,6 +4864,15 @@ __metadata: languageName: node linkType: hard +"@types/pbkdf2@npm:^3.0.0": + version: 3.1.2 + resolution: "@types/pbkdf2@npm:3.1.2" + dependencies: + "@types/node": "npm:*" + checksum: 10/bebe1e596cbbe5f7d2726a58859e61986c5a42459048e29cb7f2d4d764be6bbb0844572fd5d70ca8955a8a17e8b4ed80984fc4903e165d9efb8807a3fbb051aa + languageName: node + linkType: hard + "@types/prop-types@npm:*": version: 15.7.15 resolution: "@types/prop-types@npm:15.7.15" @@ -3595,6 +4880,13 @@ __metadata: languageName: node linkType: hard +"@types/punycode@npm:^2.1.0": + version: 2.1.4 + resolution: "@types/punycode@npm:2.1.4" + checksum: 10/16637bdd8e4f830243072668125f83b93b728085a05140ccc3e7801528d78c62cce5426b07d5cdc75e4f797e1644807c762777f651d1cd071ad0128835cdce5e + languageName: node + linkType: hard + "@types/react-dom@npm:18.2.4": version: 18.2.4 resolution: "@types/react-dom@npm:18.2.4" @@ -3622,6 +4914,15 @@ __metadata: languageName: node linkType: hard +"@types/secp256k1@npm:^4.0.1": + version: 4.0.7 + resolution: "@types/secp256k1@npm:4.0.7" + dependencies: + "@types/node": "npm:*" + checksum: 10/bcf7adbd953d2cb829ae98a3cd2f8eeb1e2316f4f6de720ee3863da90bd98899c08fa8c42748e8701cad16ede0898df69a6e7f22660d1fb3cb276d5c771069db + languageName: node + linkType: hard + "@types/semver@npm:^7, @types/semver@npm:^7.3.6": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -3636,6 +4937,20 @@ __metadata: languageName: node linkType: hard +"@types/uuid@npm:^8.3.0": + version: 8.3.4 + resolution: "@types/uuid@npm:8.3.4" + checksum: 10/6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f + languageName: node + linkType: hard + +"@types/uuid@npm:^9.0.8": + version: 9.0.8 + resolution: "@types/uuid@npm:9.0.8" + checksum: 10/b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.3 resolution: "@types/yargs-parser@npm:21.0.3" @@ -4271,6 +5586,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:3.0.0": + version: 3.0.0 + resolution: "aes-js@npm:3.0.0" + checksum: 10/1b3772e5ba74abdccb6c6b99bf7f50b49057b38c0db1612b46c7024414f16e65ba7f1643b2d6e38490b1870bdf3ba1b87b35e2c831fd3fdaeff015f08aad19d1 + languageName: node + linkType: hard + "aes-js@npm:4.0.0-beta.5": version: 4.0.0-beta.5 resolution: "aes-js@npm:4.0.0-beta.5" @@ -4278,6 +5600,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:^3.1.2": + version: 3.1.2 + resolution: "aes-js@npm:3.1.2" + checksum: 10/b65916767034a51375a3ac5aad62af452d89a386c1ae7b607bb9145d0bb8b8823bf2f3eba85bdfa52d61c65d5aed90ba90f677b8c826bfa1a8b7ae2fa3b54d91 + languageName: node + linkType: hard + "agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": version: 7.1.1 resolution: "agent-base@npm:7.1.1" @@ -4418,7 +5747,7 @@ __metadata: languageName: node linkType: hard -"apg-js@npm:^4.1.1": +"apg-js@npm:^4.1.1, apg-js@npm:^4.3.0": version: 4.4.0 resolution: "apg-js@npm:4.4.0" checksum: 10/425f19096026742f5f156f26542b68f55602aa60f0c4ae2d72a0a888cf15fe9622223191202262dd8979d76a6125de9d8fd164d56c95fb113f49099f405eb08c @@ -4789,7 +6118,7 @@ __metadata: languageName: node linkType: hard -"bech32@npm:^1.1.3": +"bech32@npm:1.1.4, bech32@npm:^1.1.3": version: 1.1.4 resolution: "bech32@npm:1.1.4" checksum: 10/63ff37c0ce43be914c685ce89700bba1589c319af0dac1ea04f51b33d0e5ecfd40d14c24f527350b94f0a4e236385373bb9122ec276410f354ddcdbf29ca13f4 @@ -4926,6 +6255,20 @@ __metadata: languageName: node linkType: hard +"blakejs@npm:^1.1.0": + version: 1.2.1 + resolution: "blakejs@npm:1.2.1" + checksum: 10/0638b1bd058b21892633929c43005aa6a4cc4b2ac5b338a146c3c076622f1b360795bd7a4d1f077c9b01863ed2df0c1504a81c5b520d164179120434847e6cd7 + languageName: node + linkType: hard + +"bn.js@npm:4.11.6": + version: 4.11.6 + resolution: "bn.js@npm:4.11.6" + checksum: 10/22741b015c9fff60fce32fc9988331b298eb9b6db5bfb801babb23b846eaaf894e440e0d067b2b3ae4e46aab754e90972f8f333b31bf94a686bbcb054bfa7b14 + languageName: node + linkType: hard + "bn.js@npm:5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" @@ -4940,7 +6283,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.2.1, bn.js@npm:^5.2.3": +"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1, bn.js@npm:^5.2.3": version: 5.2.5 resolution: "bn.js@npm:5.2.5" checksum: 10/10b1ac91e76fd828c1187cf65a9f1a0374e7afb9acd167e19c2d7c4108f6216841007c1e3aef145fa95cc7b3d07f705236a707184af1537667362b3a842d01ac @@ -5335,7 +6678,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:5.6.2": +"chalk@npm:5.6.2, chalk@npm:^5.4.1": version: 5.6.2 resolution: "chalk@npm:5.6.2" checksum: 10/1b2f48f6fba1370670d5610f9cd54c391d6ede28f4b7062dd38244ea5768777af72e5be6b74fb6c6d54cb84c4a2dff3f3afa9b7cb5948f7f022cfd3d087989e0 @@ -5555,6 +6898,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^14.0.0": + version: 14.0.3 + resolution: "commander@npm:14.0.3" + checksum: 10/dfa9ebe2a433d277de5cb0252d23b10a543d245d892db858d23b516336a835c50fd4f52bee4cd13c705cc8acb6f03dc632c73dd806f7d06d3353eb09953dd17a + languageName: node + linkType: hard + "commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -6779,7 +8129,19 @@ __metadata: languageName: node linkType: hard -"ethereum-cryptography@npm:2.2.1, ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.2.1": +"eth-method-registry@npm:^4.0.0": + version: 4.0.0 + resolution: "eth-method-registry@npm:4.0.0" + dependencies: + "@metamask/ethjs-contract": "npm:^0.4.1" + "@metamask/ethjs-query": "npm:^0.7.1" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/959e833327960f40fab8693997e071def75103a694e931ab11313e642b6958d4f2878000d91ddfd6ba3c158bdc3f381c63eae0dd26738790e2aca5004ceb0387 + languageName: node + linkType: hard + +"ethereum-cryptography@npm:2.2.1, ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.1.2, ethereum-cryptography@npm:^2.2.1": version: 2.2.1 resolution: "ethereum-cryptography@npm:2.2.1" dependencies: @@ -6791,6 +8153,58 @@ __metadata: languageName: node linkType: hard +"ethereum-cryptography@npm:^0.1.3": + version: 0.1.3 + resolution: "ethereum-cryptography@npm:0.1.3" + dependencies: + "@types/pbkdf2": "npm:^3.0.0" + "@types/secp256k1": "npm:^4.0.1" + blakejs: "npm:^1.1.0" + browserify-aes: "npm:^1.2.0" + bs58check: "npm:^2.1.2" + create-hash: "npm:^1.2.0" + create-hmac: "npm:^1.1.7" + hash.js: "npm:^1.1.7" + keccak: "npm:^3.0.0" + pbkdf2: "npm:^3.0.17" + randombytes: "npm:^2.1.0" + safe-buffer: "npm:^5.1.2" + scrypt-js: "npm:^3.0.0" + secp256k1: "npm:^4.0.1" + setimmediate: "npm:^1.0.5" + checksum: 10/975e476782746acd97d5b37366801ae622a52fb31e5d83f600804be230a61ef7b9d289dcecd9c308fb441967caf3a6e3768dd7c8add6441fcc60c398175d5a96 + languageName: node + linkType: hard + +"ethereumjs-util@npm:^7.1.2": + version: 7.1.5 + resolution: "ethereumjs-util@npm:7.1.5" + dependencies: + "@types/bn.js": "npm:^5.1.0" + bn.js: "npm:^5.1.2" + create-hash: "npm:^1.1.2" + ethereum-cryptography: "npm:^0.1.3" + rlp: "npm:^2.2.4" + checksum: 10/f28fc1ebb8f35bf9e418f76f51be737d94d603b912c3e014c4e87cd45ccd1b10bdfef764c8f152574b57e9faa260a18773cbc110f9e0a754d6b3730699e54dc9 + languageName: node + linkType: hard + +"ethereumjs-wallet@npm:^1.0.1": + version: 1.0.2 + resolution: "ethereumjs-wallet@npm:1.0.2" + dependencies: + aes-js: "npm:^3.1.2" + bs58check: "npm:^2.1.2" + ethereum-cryptography: "npm:^0.1.3" + ethereumjs-util: "npm:^7.1.2" + randombytes: "npm:^2.1.0" + scrypt-js: "npm:^3.0.1" + utf8: "npm:^3.0.0" + uuid: "npm:^8.3.2" + checksum: 10/0a9ad0ac0930627c15e6fa6115dde8d1dd81160e57fbdf81ef0bcd1e0edd750fe9e8b00992651e694cabefee29eef2ad651dce8b24ae5253861927d0e19b6c90 + languageName: node + linkType: hard + "ethers@npm:6.13.5": version: 6.13.5 resolution: "ethers@npm:6.13.5" @@ -6821,6 +8235,24 @@ __metadata: languageName: node linkType: hard +"ethjs-abi@npm:^0.2.0": + version: 0.2.1 + resolution: "ethjs-abi@npm:0.2.1" + dependencies: + bn.js: "npm:4.11.6" + js-sha3: "npm:0.5.5" + number-to-bn: "npm:1.7.0" + checksum: 10/733b2b95ae102f0813ad70848d42424b4b6204598892bee0e0fb435aafc7d356e479e489ee2d6b81fb2bd6e5ae6a9cdc0479bc35244b2efbe1a00a8da6735fbb + languageName: node + linkType: hard + +"ethjs-schema@npm:0.2.1": + version: 0.2.1 + resolution: "ethjs-schema@npm:0.2.1" + checksum: 10/9e2806518e208650a035aa2bc1e508a57c31ff629b46b63de4c7101e760f5e6987e6f8b70522eb44cf4a97d2c4c6348d1adaeea56915e75e4deadd1e176d5aa9 + languageName: node + linkType: hard + "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -7080,6 +8512,13 @@ __metadata: languageName: node linkType: hard +"fast-json-patch@npm:^3.1.1": + version: 3.1.1 + resolution: "fast-json-patch@npm:3.1.1" + checksum: 10/3e56304e1c95ad1862a50e5b3f557a74c65c0ff2ba5b15caab983b43e70e86ddbc5bc887e9f7064f0aacfd0f0435a29ab2f000fe463379e72b906486345e6671 + languageName: node + linkType: hard + "fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -7140,6 +8579,13 @@ __metadata: languageName: node linkType: hard +"fastest-levenshtein@npm:^1.0.16": + version: 1.0.16 + resolution: "fastest-levenshtein@npm:1.0.16" + checksum: 10/ee85d33b5cef592033f70e1c13ae8624055950b4eb832435099cd56aa313d7f251b873bedbc06a517adfaff7b31756d139535991e2406967438e03a1bf1b008e + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -7739,7 +9185,7 @@ __metadata: languageName: node linkType: hard -"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": +"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3, hash.js@npm:^1.1.7": version: 1.1.7 resolution: "hash.js@npm:1.1.7" dependencies: @@ -8072,6 +9518,13 @@ __metadata: languageName: node linkType: hard +"is-fn@npm:^1.0.0": + version: 1.0.0 + resolution: "is-fn@npm:1.0.0" + checksum: 10/eeea1e536716f93a92dc1a8550b2c0909fe74bb5144d0fb6d65e0d31eb9c06c30559f69d83a9351d2288cc7293b43bc074e0fab5fae19e312ff38aa0c7672827 + languageName: node + linkType: hard + "is-fullwidth-code-point@npm:^3.0.0": version: 3.0.0 resolution: "is-fullwidth-code-point@npm:3.0.0" @@ -9092,6 +10545,13 @@ __metadata: languageName: node linkType: hard +"js-sha3@npm:0.5.5": + version: 0.5.5 + resolution: "js-sha3@npm:0.5.5" + checksum: 10/9ce8bfabdba2cfb94b911125fc278e2f46cc01b6590c98833d9361199e2c2b4bca0427d04da6aa083f05c2c3982029200964a3d6e417b0c126c80f2e32c2d5eb + languageName: node + linkType: hard + "js-sha3@npm:0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -9106,6 +10566,13 @@ __metadata: languageName: node linkType: hard +"js-sha3@npm:^0.9.2": + version: 0.9.3 + resolution: "js-sha3@npm:0.9.3" + checksum: 10/8daacb93b18609a0dc081f2f6199b80a96df36f9975b4b9c7476ae92822e07100b9e1969fc76f4b58e703cd6175f0de7656a99cbb2335cfb554c66f988fbead5 + languageName: node + linkType: hard + "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -9180,7 +10647,7 @@ __metadata: languageName: node linkType: hard -"json-rpc-random-id@npm:^1.0.0": +"json-rpc-random-id@npm:^1.0.0, json-rpc-random-id@npm:^1.0.1": version: 1.0.1 resolution: "json-rpc-random-id@npm:1.0.1" checksum: 10/fcd2e884193a129ace4002bd65a86e9cdb206733b4693baea77bd8b372cf8de3043fbea27716a2c9a716581a908ca8d978d9dfec4847eb2cf77edb4cf4b2252c @@ -9237,6 +10704,25 @@ __metadata: languageName: node linkType: hard +"jsonschema@npm:^1.4.1": + version: 1.5.0 + resolution: "jsonschema@npm:1.5.0" + checksum: 10/46bf49b388ba922073bcb3c8d5e90af9d29fc8303dc866fd440182c88d6b4fd2807679fd39cdefb4113156d104ea47da9c0ff4bbcb0032c9fa29461cb1a92182 + languageName: node + linkType: hard + +"keccak@npm:^3.0.0": + version: 3.0.4 + resolution: "keccak@npm:3.0.4" + dependencies: + node-addon-api: "npm:^2.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.0" + readable-stream: "npm:^3.6.0" + checksum: 10/45478bb0a57e44d0108646499b8360914b0fbc8b0e088f1076659cb34faaa9eb829c40f6dd9dadb3460bb86cc33153c41fed37fe5ce09465a60e71e78c23fa55 + languageName: node + linkType: hard + "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -9347,6 +10833,13 @@ __metadata: languageName: node linkType: hard +"loglevel@npm:^1.8.1": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 10/6153d8db308323f7ee20130bc40309e7a976c30a10379d8666b596d9c6441965c3e074c8d7ee3347fe5cfc059c0375b6f3e8a10b93d5b813cc5547f5aa412a29 + languageName: node + linkType: hard + "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -9764,6 +11257,13 @@ __metadata: languageName: node linkType: hard +"multiformats@npm:^9.9.0": + version: 9.9.0 + resolution: "multiformats@npm:9.9.0" + checksum: 10/ad55c7d480d22f4258a68fd88aa2aab744fe0cb1e68d732fc886f67d858b37e3aa6c2cec12b2960ead7730d43be690931485238569952d8a3d7f90fdc726c652 + languageName: node + linkType: hard + "multimatch@npm:^5.0.0": version: 5.0.0 resolution: "multimatch@npm:5.0.0" @@ -9864,6 +11364,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^2.0.0": + version: 2.0.2 + resolution: "node-addon-api@npm:2.0.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10/e4ce4daac5b2fefa6b94491b86979a9c12d9cceba571d2c6df1eb5859f9da68e5dc198f128798e1785a88aafee6e11f4992dcccd4bf86bec90973927d158bd60 + languageName: node + linkType: hard + "node-addon-api@npm:^5.0.0": version: 5.1.0 resolution: "node-addon-api@npm:5.1.0" @@ -10019,6 +11528,16 @@ __metadata: languageName: node linkType: hard +"number-to-bn@npm:1.7.0": + version: 1.7.0 + resolution: "number-to-bn@npm:1.7.0" + dependencies: + bn.js: "npm:4.11.6" + strip-hex-prefix: "npm:1.0.0" + checksum: 10/702e8f00b6b90abd23f711056005179c3bd5ce3b063c47d468250f63ab3b9b4b82e27bff3b4642a9e71e06c717d5ed359873501746df0a64c3db1fa6d704e704 + languageName: node + linkType: hard + "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -10425,7 +11944,7 @@ __metadata: languageName: node linkType: hard -"pbkdf2@npm:^3.1.2, pbkdf2@npm:^3.1.5": +"pbkdf2@npm:^3.0.17, pbkdf2@npm:^3.1.2, pbkdf2@npm:^3.1.5": version: 3.1.6 resolution: "pbkdf2@npm:3.1.6" dependencies: @@ -10460,6 +11979,13 @@ __metadata: languageName: node linkType: hard +"pify@npm:^5.0.0": + version: 5.0.0 + resolution: "pify@npm:5.0.0" + checksum: 10/443e3e198ad6bfa8c0c533764cf75c9d5bc976387a163792fb553ffe6ce923887cf14eebf5aea9b7caa8eab930da8c33612990ae85bd8c2bc18bedb9eae94ecb + languageName: node + linkType: hard + "pirates@npm:^4.0.4, pirates@npm:^4.0.7": version: 4.0.7 resolution: "pirates@npm:4.0.7" @@ -10616,6 +12142,16 @@ __metadata: languageName: node linkType: hard +"promise-to-callback@npm:^1.0.0": + version: 1.0.0 + resolution: "promise-to-callback@npm:1.0.0" + dependencies: + is-fn: "npm:^1.0.0" + set-immediate-shim: "npm:^1.0.1" + checksum: 10/d756ad74f7a202a6725c4281813c1052896327e4036c553adb8e3bbb91d0b1ff501965e7b00997827c016609caefbf24a5efc117dccca6000b8cbbc477b31cbf + languageName: node + linkType: hard + "propagate@npm:^2.0.0": version: 2.0.1 resolution: "propagate@npm:2.0.1" @@ -10668,7 +12204,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.3.0": +"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 @@ -10903,6 +12439,13 @@ __metadata: languageName: node linkType: hard +"reselect@npm:^5.1.1": + version: 5.2.0 + resolution: "reselect@npm:5.2.0" + checksum: 10/e53d37a35f84132682b0a819d942ff7debea90fe126f4bb5eef0f21b1f48f45dec89d27990f2ef5865f5e05d64bb88fb41e4341eb276674aee6f1f7f7362c3e8 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -11059,6 +12602,17 @@ __metadata: languageName: node linkType: hard +"rlp@npm:^2.2.4": + version: 2.2.7 + resolution: "rlp@npm:2.2.7" + dependencies: + bn.js: "npm:^5.2.0" + bin: + rlp: bin/rlp + checksum: 10/cf1919a2dc99f336191b3363b76299db567c192b7ee3c6f5c722728c34f65577883c9c88eeb7a1bfcbc26693c8a4f1fb0662e79ee86f0c98dd258d6987303498 + languageName: node + linkType: hard + "router@npm:^2.2.0": version: 2.2.0 resolution: "router@npm:2.2.0" @@ -11129,6 +12683,13 @@ __metadata: languageName: node linkType: hard +"safe-stable-stringify@npm:^2.4.3": + version: 2.5.0 + resolution: "safe-stable-stringify@npm:2.5.0" + checksum: 10/2697fa186c17c38c3ca5309637b4ac6de2f1c3d282da27cd5e1e3c88eca0fb1f9aea568a6aabdf284111592c8782b94ee07176f17126031be72ab1313ed46c5c + languageName: node + linkType: hard + "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -11159,6 +12720,13 @@ __metadata: languageName: node linkType: hard +"scrypt-js@npm:3.0.1, scrypt-js@npm:^3.0.0, scrypt-js@npm:^3.0.1": + version: 3.0.1 + resolution: "scrypt-js@npm:3.0.1" + checksum: 10/2f8aa72b7f76a6f9c446bbec5670f80d47497bccce98474203d89b5667717223eeb04a50492ae685ed7adc5a060fc2d8f9fd988f8f7ebdaf3341967f3aeff116 + languageName: node + linkType: hard + "secp256k1@npm:^3.0.1": version: 3.8.1 resolution: "secp256k1@npm:3.8.1" @@ -11176,6 +12744,18 @@ __metadata: languageName: node linkType: hard +"secp256k1@npm:^4.0.1": + version: 4.0.4 + resolution: "secp256k1@npm:4.0.4" + dependencies: + elliptic: "npm:^6.5.7" + node-addon-api: "npm:^5.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.0" + checksum: 10/45000f348c853df7c1e2b67c48efb062ae78c0620ab1a5cfb02fa20d3aad39c641f4e7a18b3de3b54a7c0cc1e0addeb8ecd9d88bc332e92df17a92b60c36122a + languageName: node + linkType: hard + "secp256k1@npm:^5.0.1": version: 5.0.1 resolution: "secp256k1@npm:5.0.1" @@ -11311,7 +12891,14 @@ __metadata: languageName: node linkType: hard -"setimmediate@npm:^1.0.4": +"set-immediate-shim@npm:^1.0.1": + version: 1.0.1 + resolution: "set-immediate-shim@npm:1.0.1" + checksum: 10/98c4d6778c98363436690a340077142ef11c1a8c8c6a78118242340c8e82bb2d66a1563707ef3f5455e7ff5cbee21c87e898b333cf3e7ed241bab12d19e9eab1 + languageName: node + linkType: hard + +"setimmediate@npm:^1.0.4, setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" checksum: 10/76e3f5d7f4b581b6100ff819761f04a984fa3f3990e72a6554b57188ded53efce2d3d6c0932c10f810b7c59414f85e2ab3c11521877d1dea1ce0b56dc906f485 @@ -11448,6 +13035,13 @@ __metadata: languageName: node linkType: hard +"single-call-balance-checker-abi@npm:^1.0.0": + version: 1.0.0 + resolution: "single-call-balance-checker-abi@npm:1.0.0" + checksum: 10/d68fd83e58c42e6ccd4951d30cacffad01b4ca46595766b51ca09346f715027eac3a1d9e80e6147c7c20181ac6aca5d5330f9d1b131c91cbac3a16c1f3efbc3a + languageName: node + linkType: hard + "sirv@npm:^2.0.3": version: 2.0.4 resolution: "sirv@npm:2.0.4" @@ -11459,6 +13053,20 @@ __metadata: languageName: node linkType: hard +"siwe@npm:^2.3.2": + version: 2.3.2 + resolution: "siwe@npm:2.3.2" + dependencies: + "@spruceid/siwe-parser": "npm:^2.1.2" + "@stablelib/random": "npm:^1.0.1" + uri-js: "npm:^4.4.1" + valid-url: "npm:^1.0.9" + peerDependencies: + ethers: ^5.6.8 || ^6.0.8 + checksum: 10/6ea5ad9a9046fa916f85bf9d3092bc898f7e339d9c552714ea53ecc17daa4f78300c3cf7cc9c70fe57baf77dcee5cb38c6e1d692400b874cd84d297b1261918c + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -12181,6 +13789,13 @@ __metadata: languageName: node linkType: hard +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: 10/ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -12301,6 +13916,15 @@ __metadata: languageName: node linkType: hard +"ulid@npm:^2.3.0": + version: 2.4.0 + resolution: "ulid@npm:2.4.0" + bin: + ulid: bin/cli.js + checksum: 10/409ad0a703ea9f25d2a35cf790b767030a2c7b5ca0df6acb73669628156ab63bb97925a3fd7aaaf0b2384d39bd3ed2f7cd2c2de9f1171df6bc79b8c097865d92 + languageName: node + linkType: hard + "undici-types@npm:~6.19.2": version: 6.19.8 resolution: "undici-types@npm:6.19.8" @@ -12456,6 +14080,13 @@ __metadata: languageName: node linkType: hard +"utf8@npm:^3.0.0": + version: 3.0.0 + resolution: "utf8@npm:3.0.0" + checksum: 10/31d19c4faacbb65b09ebc1c21c32b20bdb0919c6f6773cee5001b99bb83f8e503e7233c08fc71ebb34f7cfebd95cec3243b81d90176097aa2f286cccb4ce866e + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -12883,6 +14514,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.18.0": + version: 8.18.0 + resolution: "ws@npm:8.18.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10/70dfe53f23ff4368d46e4c0b1d4ca734db2c4149c6f68bc62cb16fc21f753c47b35fcc6e582f3bdfba0eaeb1c488cddab3c2255755a5c3eecb251431e42b3ff6 + languageName: node + linkType: hard + "ws@npm:8.21.0": version: 8.21.0 resolution: "ws@npm:8.21.0"