@avalabs/svm-module 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/module.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/utils/fetch-and-verify.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../../../packages-internal/utils/src/utils/get-core-headers.ts","../manifest.json","../src/env.ts","../src/handlers/derive-address/derive-address.ts","../../../packages-internal/utils/src/utils/address-derivation.ts","../src/handlers/build-derivation-path/build-derivation-path.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/utils/get-provider.ts","../src/constants.ts","../src/handlers/get-tokens/get-tokens.ts","../src/handlers/get-tokens/spl-token-schema.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/utils/is-promise-fulfilled.ts","../src/utils/moralis-service/moralis-schemas.ts","../src/utils/moralis-service/moralis-service.ts","../src/utils/get-network-name.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-transaction-history/extract-transfer.ts","../src/handlers/get-transaction-history/get-wrapped-transactions.ts","../src/utils/has-property-defined.ts","../src/handlers/get-transaction-history/get-explorer-link.ts","../src/handlers/sign-and-send-transaction/sign-and-send-transaction.ts","../src/utils/explain/explain-transaction.ts","../src/utils/transaction-alerts.ts","../src/utils/explain/parse-transaction.ts","../src/utils/functional.ts","../src/utils/explain/instruction-parsers/sol-transfer.ts","../src/utils/explain/instruction-parsers/spl-transfer.ts","../src/utils/explain/blockaid/process-balance-change.ts","../src/utils/explain/blockaid/scan-solana-transaction.ts","../src/handlers/sign-and-send-transaction/schema.ts","../src/handlers/sign-transaction/sign-transaction.ts","../src/handlers/sign-transaction/schema.ts","../src/handlers/sign-message/sign-message.ts","../src/utils/is-transaction-bytes.ts","../src/handlers/sign-message/schema.ts"],"names":["parseManifest","RpcMethod","rpcErrors","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","RawSimplePriceResponseSchema","fetchAndVerify","fetchOptions","schema","responseJson","CoingeckoProxyClient","proxyApiUrl","params","queryParams","id","rawQueryParams","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","rawData","marketCap","vol24","change24","lastUpdated","shouldThrow","number","object","record","string","ExchangeRateSchema","DetailItemType","textItem","label","value","alignment","addressItem","addressListItem","dataItem","AppName","manifest_default","Environment","prodEnv","devEnv","getEnv","environment","NetworkVMType","base58","hex","hasDerivationDetails","buildDerivationPath","accountIndex","deriveAddress","approvalController","secretId","derivationPath","publicKeyHex","getSolanaProvider","SOLANA_MAINNET_CAIP2_ID","SOLANA_DEVNET_CAIP2_ID","SOLANA_TESTNET_CAIP2_ID","RPC_URL_PROXY_API_ENDPOINT","RPC_URL_DEVNET","getProvider","isTestnet","LamportsMultiplier","DEFAULT_PRIORITY_FEE","ensureEnoughData","fees","a","b","getNetworkFee","network","feesRaw","block","sortedFees","minFeeInRecentBlocks","maxFeeInRecentBlocks","midIndex","medianFee","presetHigh","presetMedium","presetLow","TokenType","z","SPL_TOKEN_SCHEMA","SPL_TOKENS_SCHEMA","getTokens","caip2Id","token","error","TokenUnit","isFulfilled","PORTFOLIO_SCHEMA","_baseUrl","_buildUrl","buildUrl_fn","MoralisService","address","url","__privateMethod","portfolio","message","path","getNetworkName","getBalances","addresses","tokenService","moralisService","coingeckoAssetId","coingeckoPlatformId","lowercaseCurrency","solanaNetwork","portfolioResults","mints","mint","tokenPricesPromises","nativePrice","tokenPrices","promise","portfolioAcc","nativeBalanceUnit","nativeMarketData","getMarketData","nativeBalanceInCurrency","solanaBalance","tokenBalances","tokensAcc","amountRaw","symbol","decimals","name","logo","balanceUnit","marketData","balanceInCurrency","coinIdOrAddress","prices","TransactionType","simplifyTokenBalance","balance","extractTokenTranfers","meta","preBalances","acc","owner","amount","transfers","key","preAmount","netChange","sender","k","possibleSender","mintFromPreBalance","possibleSenderPostBalance","postBalanceOwner","postBalanceMint","t","transfer","nativeTransfer","extractNativeTransfer","paidFee","postBalances","nativeBalancePre","nativeBalancePost","nativeTransferAmount","balanceDiffs","isIncoming","unit","otherAddressIndex","diff","solAddress","hasPropertyDefined","thing","getWrappedTransactions","provider","signatures","sig","tx","getExplorerLink","txHash","baseUrl","explorerLink","getTransactionHistory","isSigner","AlertType","transactionAlerts","deserializeTransactionMessage","isBalanceChangeEmpty","input","isNotNullish","identifySystemInstruction","parseTransferSolInstruction","SYSTEM_PROGRAM_ADDRESS","SystemInstruction","isInstructionForProgram","isInstructionWithAccounts","isInstructionWithData","tryToParseSolTransfer","instruction","balanceChange","account","networkToken","accounts","balanceChangeKey","parseTransferInstruction","identifyTokenInstruction","TokenInstruction","getTokenMintFromAccountInfo","tokenAccountDetails","info","tryToParseSPLTransfer","tokens","tokenMint","parseTransaction","serializedTx","transaction","details","results","processBalanceChange","simulationResult","transferedAssets","inTokenDiffDict","outTokenDiffDict","otherAffectedAddresses","asset","assetIn","assetOut","convertDiffAssetToToken","identifier","convertNativeAssetToToken","convertTokenAssetToToken","Blockaid","base64","DUMMY_API_KEY","scanSolanaTransaction","dAppUrl","blockaid","explainTransaction","simulationParams","scanResponse","simulation","validation","genericDetails","isSimulationSuccessful","alert","processedBalanceChange","parsedBalanceChange","parsedDetails","transactionSchema","paramsSchema","parseRequestParams","signAndSendTransaction","request","success","sendOptions","displayData","signingData","getTxHash","signTransaction","getCompiledTransactionMessageDecoder","isTransactionBytes","base64Payload","bytes","signMessageSchema","serializedMessage","signMessage","utf8Decoder","_approvalController","_appInfo","SvmModule","appInfo"],"mappings":"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","sourcesContent":["import {\n parseManifest,\n RpcMethod,\n type AppInfo,\n type ApprovalController,\n type BuildDerivationPathParams,\n type ConstructorParams,\n type DeriveAddressParams,\n type GetBalancesParams,\n type GetTransactionHistory,\n type Module,\n type Network,\n type NetworkFeeParam,\n type RpcRequest,\n} from '@avalabs/vm-module-types';\nimport type { SolanaProvider } from '@avalabs/core-wallets-sdk';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport { TokenService } from '@internal/utils';\n\nimport ManifestJson from '../manifest.json';\nimport { getEnv } from './env';\nimport { deriveAddress } from './handlers/derive-address';\nimport { buildDerivationPath } from './handlers/build-derivation-path';\nimport { getNetworkFee } from './handlers/get-network-fee';\nimport { getTokens } from './handlers/get-tokens';\nimport { getBalances } from './handlers/get-balances';\nimport { getProvider } from './utils/get-provider';\nimport { getTransactionHistory } from './handlers/get-transaction-history';\nimport { signAndSendTransaction } from './handlers/sign-and-send-transaction';\nimport { signTransaction } from './handlers/sign-transaction';\nimport { signMessage } from './handlers/sign-message';\n\nexport class SvmModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n #appInfo: AppInfo;\n\n constructor({ approvalController, environment, appInfo }: ConstructorParams) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#appInfo = appInfo;\n this.#proxyApiUrl = proxyApiUrl;\n this.#approvalController = approvalController;\n\n // Temporarily referencing those props here just to silence eslint,\n // as eslint-disable-... comments don't seem to work on class properties.\n this.#proxyApiUrl;\n this.#approvalController;\n this.#appInfo;\n }\n\n async getProvider(network: Network): Promise<SolanaProvider> {\n return getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl: this.#proxyApiUrl });\n }\n\n // TODO\n getAddress() {\n return Promise.resolve({});\n }\n\n buildDerivationPath(params: BuildDerivationPathParams) {\n return buildDerivationPath(params);\n }\n\n deriveAddress(params: DeriveAddressParams) {\n return deriveAddress({\n ...params,\n approvalController: this.#approvalController,\n });\n }\n\n getBalances(params: GetBalancesParams) {\n const tokenService = new TokenService({ storage: params.storage, proxyApiUrl: this.#proxyApiUrl });\n\n return getBalances({\n ...params,\n tokenService,\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getManifest() {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: NetworkFeeParam) {\n return getNetworkFee(network, this.#proxyApiUrl);\n }\n\n getTransactionHistory(params: GetTransactionHistory) {\n return getTransactionHistory({\n network: params.network,\n address: params.address,\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getTokens(network: Network) {\n if (!network.caipId) {\n return Promise.reject({ error: rpcErrors.invalidParams(`Network must have a CAIP-2 id`) });\n }\n\n return getTokens({ caip2Id: network.caipId, proxyApiUrl: this.#proxyApiUrl });\n }\n\n // TODO\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.SOLANA_SIGN_TRANSACTION: {\n return signTransaction({\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n network,\n request,\n });\n }\n case RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION: {\n return signAndSendTransaction({\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n network,\n request,\n });\n }\n case RpcMethod.SOLANA_SIGN_MESSAGE: {\n return signMessage({\n approvalController: this.#approvalController,\n network,\n request,\n });\n }\n }\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n}\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { CoingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch (err) {\n console.error(err);\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await new CoingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses({\n id: assetPlatformId,\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n });\n return this.transformSimplePriceResponse(rawData, [currency]);\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await new CoingeckoProxyClient(this.#proxyApiUrl).simplePrice({\n ids: coinIds,\n vs_currencies: currencies,\n include_market_cap: marketCap,\n include_24hr_vol: vol24,\n include_24hr_change: change24,\n include_last_updated_at: lastUpdated,\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { RawSimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nexport class CoingeckoProxyClient {\n constructor(private proxyApiUrl: string) {}\n\n simplePrice(params: {\n ids: string[];\n vs_currencies: string[];\n include_market_cap?: boolean;\n include_24hr_vol?: boolean;\n include_24hr_change?: boolean;\n include_last_updated_at?: boolean;\n }) {\n // casting params as any since typing does not allow boolean and other non-string values\n // even though NodeJS does not have this restriction itself: https://nodejs.org/api/url.html#new-urlsearchparamsobj\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const queryParams = new URLSearchParams(params as any);\n return fetchAndVerify(\n [\n `${this.proxyApiUrl}/proxy/coingecko/simple/price?${queryParams}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ],\n RawSimplePriceResponseSchema,\n );\n }\n\n simplePriceByContractAddresses(params: {\n id: string;\n contract_addresses: string[];\n vs_currencies?: string[];\n include_market_cap?: boolean;\n include_24hr_vol?: boolean;\n include_24hr_change?: boolean;\n }) {\n const { id, ...rawQueryParams } = params;\n\n // casting params as any since typing does not allow boolean and other non-string values\n // even though NodeJS does not have this restriction itself: https://nodejs.org/api/url.html#new-urlsearchparamsobj\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const queryParams = new URLSearchParams(rawQueryParams as any);\n\n return fetchAndVerify(\n [\n `${this.proxyApiUrl}/proxy/coingecko/simple/token_price/${id}?${queryParams}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ],\n RawSimplePriceResponseSchema,\n );\n }\n}\n","import z from 'zod';\nimport type { ZodSchema } from 'zod';\n\nexport async function fetchAndVerify<T extends ZodSchema>(\n fetchOptions: Parameters<typeof fetch>,\n schema: T,\n): Promise<z.infer<T>> {\n const response = await fetch(...fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}`);\n }\n\n const responseJson = await response.json();\n return schema.parse(responseJson);\n}\n","import z, { number, object, record, string } from 'zod';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_URL], ExchangeRateSchema);\n } catch {\n return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_FALLBACK_URL], ExchangeRateSchema);\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n type LinkItemValue,\n DetailItemType,\n type LinkItem,\n type FundsRecipientItem,\n type AddressListItem,\n} from '@avalabs/vm-module-types';\n\nexport const fundsRecipientItem = (\n address: string,\n amount: bigint,\n maxDecimals: number,\n symbol: string,\n): FundsRecipientItem => ({\n type: DetailItemType.FUNDS_RECIPIENT,\n label: address,\n amount,\n maxDecimals,\n symbol,\n});\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const linkItem = (label: string, value: LinkItemValue): LinkItem => ({\n label,\n value,\n type: DetailItemType.LINK,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const addressListItem = (label: string, value: string[]): AddressListItem => ({\n label,\n type: DetailItemType.ADDRESS_LIST,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import { AppName, type AppInfo } from '@avalabs/vm-module-types';\n\nexport const getCoreHeaders = ({ name, version }: AppInfo): Record<string, string> | undefined => {\n switch (name) {\n case AppName.CORE_MOBILE_IOS:\n case AppName.CORE_MOBILE_ANDROID:\n case AppName.CORE_WEB:\n case AppName.CORE_EXTENSION:\n case AppName.EXPLORER:\n return {\n 'x-application-name': name,\n 'x-application-version': version,\n };\n case AppName.OTHER:\n return undefined;\n }\n};\n","{\n \"name\": \"SVM\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/index.js\",\n \"packageName\": \"@avalabs/svm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider/index.js\",\n \"packageName\": \"@avalabs/svm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\",\n \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\",\n \"solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z\"\n ],\n \"namespaces\": [\"solana\"]\n },\n \"cointype\": \"501\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"solana_signTransaction\", \"solana_signAndSendTransaction\", \"solana_signMessage\"],\n \"nonRestrictedMethods\": []\n }\n },\n \"manifestVersion\": \"0.1\"\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","import type { ApprovalController, DeriveAddressParams, DeriveAddressResponse } from '@avalabs/vm-module-types';\nimport { NetworkVMType } from '@avalabs/vm-module-types';\nimport { base58, hex } from '@scure/base';\n\nimport { hasDerivationDetails } from '@internal/utils/src/utils/address-derivation';\nimport { buildDerivationPath } from '../build-derivation-path/build-derivation-path';\n\nexport const deriveAddress = async (\n params: DeriveAddressParams & { approvalController: ApprovalController },\n): Promise<DeriveAddressResponse> => {\n const { approvalController, secretId } = params;\n\n // When dealing with single-account private keys, we don't need the derivation path any more.\n const derivationPath = hasDerivationDetails(params) ? buildDerivationPath(params).SVM : undefined;\n const publicKeyHex = await approvalController.requestPublicKey({\n curve: 'ed25519',\n secretId,\n derivationPath,\n });\n\n return {\n [NetworkVMType.SVM]: base58.encode(hex.decode(publicKeyHex)),\n };\n};\n","import type { DeriveAddressParams, DetailedDeriveAddressParams } from '@avalabs/vm-module-types';\n\nexport const hasDerivationDetails = (params: DeriveAddressParams): params is DetailedDeriveAddressParams =>\n 'derivationPathType' in params &&\n 'accountIndex' in params &&\n typeof params.accountIndex === 'number' &&\n typeof params.derivationPathType === 'string';\n","import {\n NetworkVMType,\n type BuildDerivationPathParams,\n type BuildDerivationPathResponse,\n} from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\n/**\n * We're deriving the BTC address from the same public key as the Ethereum address,\n * so we can determine the target address when using the Avalanche Bridge.\n */\nexport const buildDerivationPath = ({\n accountIndex,\n}: BuildDerivationPathParams): Pick<BuildDerivationPathResponse, NetworkVMType.SVM> => {\n if (accountIndex < 0) {\n throw rpcErrors.invalidParams('Account index must be a non-negative integer');\n }\n\n return {\n [NetworkVMType.SVM]: `m/44'/501'/${accountIndex}'/0'`,\n };\n};\n","import { type NetworkFeeParam, type NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { SOL_DECIMALS } from '@src/constants';\n\nconst LamportsMultiplier = 1e6;\nexport const DEFAULT_PRIORITY_FEE = {\n high: 150 * LamportsMultiplier,\n medium: 75 * LamportsMultiplier,\n low: 2 * LamportsMultiplier,\n} as const;\n\ntype ValidRecentFees = [number, number, ...number[]];\n\nconst ensureEnoughData = (fees: number[]): ValidRecentFees => {\n const normalizedFees =\n fees.length === 0\n ? [DEFAULT_PRIORITY_FEE.low, DEFAULT_PRIORITY_FEE.low]\n : fees.length === 1\n ? [fees[0]!, DEFAULT_PRIORITY_FEE.low]\n : fees;\n\n return normalizedFees.slice().sort((a, b) => a - b) as ValidRecentFees;\n};\n\n/**\n * The RPC call (getRecentPrioritizationFees) returns the *lowest* priority fees (per compute unit)\n * that resulted in at least one transaction being succesfully included in the block.\n *\n * This means the request usually returns all zeroes - I've only once seen a different value,\n * for a single block out of 150 returned, and it was a 1000 MicroLamports.\n *\n * However, Phantom (the most popular Solana wallet) seems to always add at least a little bit\n * of priority fee.\n *\n * The lowest I've seen in my testing was 0.19 Lamport per compute unit, but this was an outlier.\n * I'm usually paying below 10 Lamports/cu, and sometimes as high as 150 or 300/cu -- all while\n * the RPC call returns zeroes, so it's not super reliable for determining the actual fees being paid :)\n *\n * The implementation here is by no means perfect. The way it I expect it to work is the following:\n * - with low/regular network traffic, users will be suggested to pay the default fees hardcoded below\n * (if we decide to show them at all -- Phantom does not show a widget at all)\n * - only when network congestion is super high, the RPC call will return non-zero values, and only then\n * we will suggest paying higher priority fees.\n */\nexport async function getNetworkFee(network: NetworkFeeParam, proxyApiUrl: string): Promise<NetworkFees> {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n\n const getFees = await provider.getRecentPrioritizationFees();\n const feesRaw = await getFees.send();\n\n const useDefaultFees = feesRaw.length === 0 || feesRaw.every((block) => block.prioritizationFee === 0n);\n\n if (useDefaultFees) {\n return {\n high: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.high),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.high),\n },\n medium: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.medium),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.medium),\n },\n low: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.low),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.low),\n },\n baseFee: BigInt(DEFAULT_PRIORITY_FEE.low),\n displayDecimals: SOL_DECIMALS,\n isFixedFee: false,\n };\n }\n\n const sortedFees = ensureEnoughData(feesRaw.map((block) => Number(block.prioritizationFee)));\n // We know the array is not empty and sorted, so we can safely access the first and last elements\n const minFeeInRecentBlocks = sortedFees.at(0)!;\n const maxFeeInRecentBlocks = sortedFees.at(-1)!;\n const midIndex = Math.floor(sortedFees.length / 2);\n const medianFee =\n sortedFees.length % 2 === 1\n ? (sortedFees[midIndex] as number)\n : (sortedFees[midIndex - 1]! + sortedFees[midIndex]!) / 2; // Even length: return average of middle elements\n\n // Prevent the fees from going below the default values\n // If the RPC call returned non-zero values, the network congestion is likely to be very high, so we add 5%.\n // We also prevent returning fees lower than the default, hardcoded values, as the RPC call is not very reliable.\n const presetHigh = BigInt(Math.ceil(maxFeeInRecentBlocks * 1.05));\n const presetMedium = BigInt(Math.ceil(medianFee * 1.05));\n const presetLow = BigInt(Math.ceil(minFeeInRecentBlocks * 1.05));\n\n // TODO: The shape of response here needs a general refactoring, it's not very generic.\n return {\n high: {\n maxFeePerGas: presetHigh,\n maxPriorityFeePerGas: presetHigh,\n },\n medium: {\n maxFeePerGas: presetMedium,\n maxPriorityFeePerGas: presetMedium,\n },\n low: {\n maxFeePerGas: presetLow,\n maxPriorityFeePerGas: presetLow,\n },\n baseFee: presetLow,\n displayDecimals: SOL_DECIMALS,\n isFixedFee: false,\n };\n}\n","import { getSolanaProvider, type SolanaProvider } from '@avalabs/core-wallets-sdk';\n\nimport { RPC_URL_DEVNET, RPC_URL_PROXY_API_ENDPOINT } from '../constants';\n\nexport const getProvider = ({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): SolanaProvider => {\n return getSolanaProvider({\n isTestnet,\n rpcUrl: isTestnet ? RPC_URL_DEVNET : proxyApiUrl + RPC_URL_PROXY_API_ENDPOINT,\n });\n};\n","export const SOL_DECIMALS = 9;\nexport const SOLANA_COIN_ID = 501;\n\nexport const SOLANA_MAINNET_CAIP2_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET_CAIP2_ID = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET_CAIP2_ID = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\nexport const RPC_URL_PROXY_API_ENDPOINT = '/proxy/nownodes/sol';\nexport const RPC_URL_DEVNET = 'https://api.devnet.solana.com';\nexport const RPC_URL_TESTNET = 'https://api.testnet.solana.com';\n","import type { SPLToken } from '@avalabs/vm-module-types';\nimport { fetchAndVerify } from '@internal/utils/src/utils/fetch-and-verify';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { SPL_TOKENS_SCHEMA } from './spl-token-schema';\n\nexport async function getTokens({\n caip2Id,\n proxyApiUrl,\n}: {\n caip2Id: string;\n proxyApiUrl: string;\n}): Promise<SPLToken[]> {\n try {\n const tokens = await fetchAndVerify([`${proxyApiUrl}/solana-tokens?caip2Id=${caip2Id}`], SPL_TOKENS_SCHEMA);\n\n return tokens.map((token) => ({ ...token, type: token.contractType }));\n } catch (error) {\n console.error('getTokens() failed for', caip2Id, error);\n throw rpcErrors.internal(`Failed to fetch tokens for caip2Id \"${caip2Id}\"`);\n }\n}\n","import { TokenType } from '@avalabs/vm-module-types';\nimport { z } from 'zod';\n\nexport const SPL_TOKEN_SCHEMA = z.object({\n address: z.string(),\n name: z.string(),\n symbol: z.string(),\n contractType: z.literal(TokenType.SPL),\n caip2Id: z.string().startsWith('solana:'),\n decimals: z.number(),\n chainId: z.number().optional(),\n logoUri: z.string().optional(),\n color: z.string().optional(),\n});\n\nexport const SPL_TOKENS_SCHEMA = z.array(SPL_TOKEN_SCHEMA);\n","import {\n type GetBalancesParams,\n type TokenWithBalanceSVM,\n type TokenWithBalanceSPL,\n TokenType,\n type SimplePriceResponse,\n type Error,\n} from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport type { TokenService } from '@internal/utils';\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { SOL_DECIMALS } from '@src/constants';\nimport { MoralisService } from '@src/utils/moralis-service';\nimport { getNetworkName } from '@src/utils/get-network-name';\n\ntype GetSolanaBalancesResponse = Record<\n string,\n Record<string, TokenWithBalanceSVM | TokenWithBalanceSPL | Error> | Error\n>;\n\nexport const getBalances = async ({\n addresses,\n proxyApiUrl,\n currency,\n network,\n tokenService,\n}: GetBalancesParams & {\n proxyApiUrl: string;\n tokenService: TokenService;\n}): Promise<GetSolanaBalancesResponse> => {\n const moralisService = new MoralisService({ proxyApiUrl });\n const coingeckoAssetId = network.pricingProviders?.coingecko.nativeTokenId ?? '';\n const coingeckoPlatformId = network.pricingProviders?.coingecko.assetPlatformId ?? '';\n const lowercaseCurrency = currency.toLowerCase();\n const solanaNetwork = getNetworkName(network);\n\n const portfolioResults = await Promise.all(\n addresses.map((address) => moralisService.getPortfolio({ address, network: solanaNetwork })),\n );\n\n const mints = new Set(\n portfolioResults.flatMap((result) => {\n if ('portfolio' in result) {\n return result.portfolio.tokens.map(({ mint }) => mint);\n }\n\n return [];\n }),\n );\n\n const tokenPricesPromises = await Promise.allSettled([\n coingeckoAssetId\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoAssetId],\n currencies: [lowercaseCurrency as VsCurrencyType],\n })\n : Promise.resolve(undefined),\n coingeckoPlatformId\n ? await tokenService.getPricesByAddresses(\n Array.from(mints),\n coingeckoPlatformId,\n lowercaseCurrency as VsCurrencyType,\n )\n : Promise.resolve(undefined),\n ]);\n const [nativePrice, tokenPrices] = tokenPricesPromises.map((promise) =>\n isFulfilled(promise) ? promise.value : undefined,\n );\n\n return portfolioResults.reduce((portfolioAcc, result) => {\n if ('error' in result) {\n return {\n ...portfolioAcc,\n [result.address]: {\n error: result.error,\n },\n };\n }\n\n const nativeBalanceUnit = new TokenUnit(result.portfolio.nativeBalance.lamports, SOL_DECIMALS, 'SOL');\n const nativeMarketData = getMarketData(coingeckoAssetId, lowercaseCurrency, nativePrice);\n const nativeBalanceInCurrency =\n nativeMarketData.priceInCurrency !== undefined\n ? nativeBalanceUnit.mul(nativeMarketData.priceInCurrency)\n : undefined;\n\n const solanaBalance: TokenWithBalanceSVM = {\n type: TokenType.NATIVE,\n name: network.networkToken.name,\n symbol: network.networkToken.symbol,\n decimals: network.networkToken.decimals,\n balance: nativeBalanceUnit.toSubUnit(),\n balanceDisplayValue: nativeBalanceUnit.toString(),\n balanceInCurrency: nativeBalanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: nativeBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n logoUri: network.networkToken.logoUri ?? '',\n coingeckoId: coingeckoAssetId,\n ...nativeMarketData,\n };\n\n const tokenBalances = result.portfolio.tokens.reduce(\n (tokensAcc, { amountRaw, symbol, decimals, mint, name, logo }) => {\n const balanceUnit = new TokenUnit(amountRaw, decimals, symbol);\n const marketData = getMarketData(mint, lowercaseCurrency, tokenPrices);\n const balanceInCurrency =\n marketData.priceInCurrency !== undefined ? balanceUnit.mul(marketData.priceInCurrency) : undefined;\n\n const token: TokenWithBalanceSPL = {\n type: TokenType.SPL,\n address: mint,\n name,\n symbol,\n decimals,\n balance: balanceUnit.toSubUnit(),\n balanceDisplayValue: balanceUnit.toString(),\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n logoUri: logo ?? undefined,\n reputation: null,\n ...marketData,\n };\n\n return {\n ...tokensAcc,\n [mint]: token,\n };\n },\n {} as Record<string, TokenWithBalanceSPL>,\n );\n\n return {\n ...portfolioAcc,\n [result.address]: {\n [network.networkToken.symbol]: solanaBalance,\n ...tokenBalances,\n },\n };\n }, {} as GetSolanaBalancesResponse);\n};\n\nconst getMarketData = (coinIdOrAddress: string, currency: string, prices?: SimplePriceResponse) => ({\n priceInCurrency: prices?.[coinIdOrAddress ?? '']?.[currency]?.price ?? undefined,\n marketCap: prices?.[coinIdOrAddress ?? '']?.[currency]?.marketCap ?? undefined,\n vol24: prices?.[coinIdOrAddress ?? '']?.[currency]?.vol24 ?? undefined,\n change24: prices?.[coinIdOrAddress ?? '']?.[currency]?.change24 ?? undefined,\n});\n","export const isFulfilled = <T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> =>\n result.status === 'fulfilled';\n","import { z } from 'zod';\n\nexport const PORTFOLIO_SCHEMA = z.object({\n nativeBalance: z.object({\n lamports: z.string(),\n solana: z.string(),\n }),\n nfts: z.array(\n z.object({\n associatedTokenAddress: z.string(),\n mint: z.string(),\n name: z.string(),\n symbol: z.string(),\n }),\n ),\n tokens: z.array(\n z.object({\n associatedTokenAddress: z.string(),\n mint: z.string(),\n amountRaw: z.string(),\n amount: z.string(),\n decimals: z.number(),\n name: z.string(),\n symbol: z.string(),\n logo: z.string().optional().nullable(),\n }),\n ),\n});\n\nexport type PortfolioResponse = z.infer<typeof PORTFOLIO_SCHEMA>;\n","import { fetchAndVerify } from '@internal/utils/src/utils/fetch-and-verify';\n\nimport type { SolanaNetworkName } from '@src/types';\n\nimport { PORTFOLIO_SCHEMA, type PortfolioResponse } from './moralis-schemas';\n\nexport class MoralisService {\n #baseUrl: string;\n\n constructor({ proxyApiUrl }: { proxyApiUrl: string }) {\n this.#baseUrl = `${proxyApiUrl}/proxy/moralis`;\n }\n\n async getPortfolio({\n address,\n network,\n }: {\n network: SolanaNetworkName;\n address: string;\n }): Promise<{ address: string; portfolio: PortfolioResponse } | { address: string; error: string }> {\n try {\n const url = this.#buildUrl(`/account/${network}/${address}/portfolio`);\n const portfolio = await fetchAndVerify([url], PORTFOLIO_SCHEMA);\n\n return {\n address,\n portfolio,\n };\n } catch (error) {\n console.error('getPortfolio() failed:', error);\n\n const message = error instanceof Error ? error.message : 'unknown error';\n\n return {\n address,\n error: `getPortfolio() failed: ${message}`,\n };\n }\n }\n\n #buildUrl(path: string) {\n return `${this.#baseUrl}${path}`;\n }\n}\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { SOLANA_DEVNET_CAIP2_ID, SOLANA_MAINNET_CAIP2_ID, SOLANA_TESTNET_CAIP2_ID } from '../constants';\n\nexport const getNetworkName = (network: Network) => {\n switch (network.caipId) {\n case SOLANA_MAINNET_CAIP2_ID:\n return 'mainnet';\n\n case SOLANA_DEVNET_CAIP2_ID:\n return 'devnet';\n\n case SOLANA_TESTNET_CAIP2_ID:\n return 'testnet';\n\n default:\n throw new Error('Unrecognized CAIP-2 id: ' + network.caipId);\n }\n};\n","import { TransactionType, type Network, type TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport { extractTokenTranfers, simplifyTokenBalance } from './extract-transfer';\nimport { getWrappedTransactions } from './get-wrapped-transactions';\nimport { getExplorerLink } from './get-explorer-link';\n\ntype SvmGetTransactionHistory = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport async function getTransactionHistory({\n network,\n address,\n proxyApiUrl,\n}: SvmGetTransactionHistory): Promise<TransactionHistoryResponse> {\n if (!network.caipId) {\n return Promise.reject({\n error: rpcErrors.invalidParams(`Network must have a CAIP-2 id`),\n });\n }\n\n const rawTransactions = await getWrappedTransactions({ isTestnet: Boolean(network.isTestnet), address, proxyApiUrl });\n const transactions = rawTransactions\n .map(({ txHash, tx }) => {\n if (!tx.meta) {\n return null;\n }\n\n const {\n meta,\n transaction: { message },\n } = tx;\n // Typings are wrong here, .toString() fixes it without unnecessary casting\n const addresses = message.accountKeys.map((acc) => acc.toString());\n const accountIndex = addresses.indexOf(address);\n\n // accountKeys property is sorted in Solana transactions. The signing keys\n // are always the first, and the header.numRequiredSignatures tells us how many\n // of the first keys are signers. If the lookup address is a signer, it has to be\n // one of the first N keys.\n const isSigner = accountIndex < message.header.numRequiredSignatures;\n\n const transfers = extractTokenTranfers(\n addresses,\n accountIndex,\n {\n paidFee: isSigner ? Number(meta.fee) : 0,\n preBalances: meta.preBalances.map(Number),\n postBalances: meta.postBalances.map(Number),\n preTokenBalances: (meta.preTokenBalances ?? []).map(simplifyTokenBalance),\n postTokenBalances: (meta.postTokenBalances ?? []).map(simplifyTokenBalance),\n },\n network,\n );\n\n return {\n hash: txHash,\n // We should probably be smarter about the tx type, but this should be enough for MVP\n txType: isSigner ? TransactionType.SEND : TransactionType.RECEIVE,\n gasUsed: String(tx.meta.computeUnitsConsumed ?? '0'),\n tokens: transfers,\n\n // Get to/from addresses from the token transfers if possible.\n // If not possible:\n // - default \"from\" to the signing address\n // - default \"to\" to our address if we're not the signer and leave empty if we don't know.\n from: transfers[0]?.from?.address ?? (addresses[0] as string),\n to: transfers[0]?.to?.address ?? (isSigner ? '' : address),\n isOutgoing: isSigner,\n isIncoming: !isSigner,\n isSender: isSigner,\n timestamp: Number(tx.blockTime) * 1000,\n isContractCall: false,\n gasPrice: String(Number(tx.meta.fee) / Number(tx.meta.computeUnitsConsumed)),\n chainId: String(network.chainId),\n explorerLink: getExplorerLink(txHash, network.explorerUrl),\n };\n })\n .filter(<T>(tx: T): tx is NonNullable<T> => tx !== null);\n\n return {\n transactions,\n };\n}\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport { TokenType, type Network, type SPLToken, type TxToken } from '@avalabs/vm-module-types';\nimport type { TokenBalance } from '@solana/kit';\n\nexport const simplifyTokenBalance = (balance: TokenBalance): SimpleTokenBalance => ({\n mint: balance.mint as string,\n owner: balance.owner as string,\n amount: BigInt(balance.uiTokenAmount.amount),\n decimals: balance.uiTokenAmount.decimals,\n});\n\nexport const extractTokenTranfers: ExtractTransferFn<'SPL'> = (addresses, accountIndex, meta, network): TxToken[] => {\n // Create a map of initial balances\n const preBalances: Record<string, bigint> = meta.preTokenBalances.reduce(\n (acc, { owner, mint, amount }) => ({\n ...acc,\n [`${owner}-${mint}`]: amount,\n }),\n {},\n );\n\n // Compare with post balances to determine transfers\n const transfers = meta.postTokenBalances.reduce((acc, { owner, mint, amount, decimals }) => {\n const key = `${owner}-${mint}`;\n const preAmount = preBalances[key] ?? 0n;\n const netChange = amount - preAmount;\n\n if (netChange <= 0n) {\n return acc;\n }\n\n // Find sender (the one whose balance decreased)\n const sender = Object.keys(preBalances).find((k) => {\n const [possibleSender, mintFromPreBalance] = k.split('-');\n const possibleSenderPostBalance = meta.postTokenBalances.find(\n ({ owner: postBalanceOwner, mint: postBalanceMint }) =>\n postBalanceOwner === possibleSender && postBalanceMint === mint,\n );\n\n return (\n mintFromPreBalance === mint && possibleSenderPostBalance && preBalances[k]! > possibleSenderPostBalance.amount\n );\n });\n\n if (!sender) {\n return acc;\n }\n\n const token =\n network.tokens?.filter((t): t is SPLToken => 'contractType' in t).find((t) => t.address === mint) ??\n ({\n contractType: TokenType.SPL,\n decimals,\n address: mint,\n symbol: 'Unknown',\n name: 'Unknown',\n } as SPLToken);\n const transfer: TxToken = {\n ...token,\n type: token.contractType,\n from: {\n ...token,\n address: sender.split('-')[0]!,\n },\n to: {\n ...token,\n address: owner,\n },\n amount: new TokenUnit(netChange, decimals, '').toDisplay(),\n };\n\n return [...acc, transfer];\n }, [] as TxToken[]);\n\n const nativeTransfer = extractNativeTransfer(addresses, accountIndex, meta, network);\n\n if (nativeTransfer) {\n transfers.push(nativeTransfer);\n }\n\n return transfers;\n};\n\nconst extractNativeTransfer: ExtractTransferFn<'native'> = (\n addresses,\n accountIndex,\n { paidFee, preBalances, postBalances },\n network,\n) => {\n const address = addresses[accountIndex]!;\n const nativeBalancePre = preBalances[accountIndex]!;\n const nativeBalancePost = postBalances[accountIndex]!;\n const nativeTransferAmount =\n nativeBalancePost !== nativeBalancePre ? nativeBalancePost - nativeBalancePre + paidFee : 0;\n const balanceDiffs = postBalances.map((b, i) => b - preBalances[i]!);\n\n if (!nativeTransferAmount) {\n return null;\n }\n\n const isIncoming = nativeTransferAmount > 0;\n const unit = new TokenUnit(Math.abs(nativeTransferAmount), network.networkToken.decimals, '');\n // If it's an incoming transaction, we assume it came from the transaction signer.\n // It it's an outgoing transaction, we need to find the address that received this exact amount (minus the fee).\n const otherAddressIndex = isIncoming\n ? 0\n : Math.max(\n 0,\n balanceDiffs.findIndex((diff) => diff === -nativeTransferAmount),\n );\n\n return {\n amount: unit.toDisplay(),\n from: {\n address: isIncoming ? addresses[otherAddressIndex]! : address,\n },\n to: {\n address: isIncoming ? address : addresses[otherAddressIndex]!,\n },\n name: network.networkToken.name,\n symbol: network.networkToken.symbol,\n type: TokenType.NATIVE,\n };\n};\n\ntype SimpleTokenBalance = {\n mint: string;\n owner: string;\n amount: bigint;\n decimals: number;\n};\n\ntype TxMeta = {\n paidFee: number;\n // Native SOL balances\n preBalances: number[];\n postBalances: number[];\n // SPL tokens balances\n preTokenBalances: SimpleTokenBalance[];\n postTokenBalances: SimpleTokenBalance[];\n};\n\ntype ExtractTransferFn<Type extends 'native' | 'SPL'> = (\n addresses: string[],\n accountIndex: number,\n meta: TxMeta,\n network: Network,\n) => Type extends 'native' ? TxToken | null : TxToken[];\n","import { address as solAddress, type GetTransactionApi } from '@solana/kit';\n\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { hasPropertyDefined } from '@src/utils/has-property-defined';\n\ntype ParsedTx = ReturnType<GetTransactionApi['getTransaction']>;\ntype WrappedTransaction = { txHash: string; tx: NonNullable<ParsedTx> };\n\nexport const getWrappedTransactions = async ({\n isTestnet,\n address,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n address: string;\n proxyApiUrl: string;\n}): Promise<WrappedTransaction[]> => {\n const provider = getProvider({ isTestnet, proxyApiUrl });\n\n const signaturesResponse = await provider.getSignaturesForAddress(solAddress(address), { limit: 25 }).send(); // Same as we do for Bitcoin\n const signatures = signaturesResponse.map((sig) => sig.signature);\n const txsRequests = await Promise.allSettled(\n signatures.map(async (sig) => ({\n txHash: sig.toString(),\n tx: await provider.getTransaction(sig, { encoding: 'json', maxSupportedTransactionVersion: 0 }).send(),\n })),\n );\n\n return txsRequests\n .filter(isFulfilled)\n .map((tx) => tx.value)\n .filter(hasPropertyDefined('tx'));\n};\n","export function hasPropertyDefined<T, K extends keyof T>(key: K) {\n return (thing: T): thing is T & Record<K, NonNullable<unknown>> => Boolean(thing[key]);\n}\n","export const getExplorerLink = (txHash: string, baseUrl?: string) => {\n const explorerLink = baseUrl ? new URL(baseUrl) : null;\n\n // Keep the query params in-tact: the Solana explorers like SolScan.io or explorer.solana.com\n // switch between clusters based on the `cluster` query param, not the domain.\n if (explorerLink) {\n explorerLink.pathname = `/tx/${txHash}`;\n }\n\n return explorerLink?.toString() ?? '';\n};\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { type Base64EncodedWireTransaction } from '@solana/kit';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { getNetworkName } from '@src/utils/get-network-name';\nimport { explainTransaction } from '@src/utils/explain/explain-transaction';\n\nimport { parseRequestParams, type SendOptions } from './schema';\n\nexport const signAndSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedTx, sendOptions }] = data;\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { details, isSimulationSuccessful, alert, balanceChange } = await explainTransaction({\n simulationParams: {\n dAppUrl: request.dappInfo.url,\n params: {\n account,\n chain: getNetworkName(network),\n transactionBase64: serializedTx,\n },\n proxyApiUrl,\n },\n network,\n provider,\n });\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details,\n alert,\n balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION,\n account,\n data: serializedTx,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response, sendOptions);\n } catch (error) {\n console.error(error);\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (\n provider: ReturnType<typeof getProvider>,\n response: SigningResult,\n sendOptions?: SendOptions,\n) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n // broadcast the signed transaction\n const txHash = await provider\n .sendTransaction(response.signedData as Base64EncodedWireTransaction, {\n ...sendOptions,\n encoding: 'base64',\n })\n .send();\n return txHash;\n};\n","import {\n AlertType,\n type Alert,\n type BalanceChange,\n type DetailSection,\n type Network,\n type TransactionSimulationResult,\n} from '@avalabs/vm-module-types';\n\nimport type { getProvider } from '../get-provider';\nimport { transactionAlerts } from '../transaction-alerts';\n\nimport type { ExplainTxParams } from './types';\nimport { parseTransaction } from './parse-transaction';\nimport { processBalanceChange } from './blockaid/process-balance-change';\nimport { scanSolanaTransaction } from './blockaid/scan-solana-transaction';\nimport { addressItem, dataItem } from '@internal/utils';\nimport { addressListItem } from '@internal/utils/src/utils/detail-item';\n\nexport const explainTransaction = async ({\n simulationParams,\n network,\n provider,\n}: {\n simulationParams: ExplainTxParams;\n network: Network;\n provider: ReturnType<typeof getProvider>;\n}): Promise<TransactionSimulationResult & { details: DetailSection[] }> => {\n const { params } = simulationParams;\n const scanResponse = await scanSolanaTransaction(simulationParams);\n const { simulation, validation } = scanResponse?.result ?? {};\n const genericDetails: DetailSection = {\n title: 'Transaction Details',\n items: [dataItem('Raw Data', simulationParams.params.transactionBase64)],\n };\n const details: DetailSection[] = [genericDetails];\n\n let isSimulationSuccessful = false;\n let balanceChange: BalanceChange | undefined;\n let alert: Alert | undefined;\n\n if (!validation || validation.result_type === 'Warning') {\n alert = transactionAlerts[AlertType.WARNING];\n } else if (validation.result_type === 'Malicious') {\n alert = transactionAlerts[AlertType.DANGER];\n }\n\n if (simulation) {\n const { balanceChange: processedBalanceChange, otherAffectedAddresses } = processBalanceChange(\n params.account,\n simulation,\n network,\n );\n balanceChange = processedBalanceChange;\n if (otherAffectedAddresses.length > 0) {\n // If there is one other affected address, we label the user's address as \"From\" and the other address as \"To\".\n // If there are more than 1 affected addresses, we label the user's address as \"Account\" and the others as \"Interacting with\".\n genericDetails.items.push(addressItem(otherAffectedAddresses.length === 1 ? 'From' : 'Account', params.account));\n genericDetails.items.push(\n otherAffectedAddresses.length === 1\n ? addressItem('To', otherAffectedAddresses[0]!)\n : addressListItem('Interacting with', otherAffectedAddresses),\n );\n } else {\n // Make sure to always show the user's address in the details.\n genericDetails.items.push(addressItem('Account', params.account));\n }\n isSimulationSuccessful = true;\n } else {\n // If Blockaid simulation fails, we fall back to parsing the transaction manually.\n const { balanceChange: parsedBalanceChange, details: parsedDetails } = await parseTransaction(\n params.transactionBase64,\n params.account,\n network,\n provider,\n );\n balanceChange = parsedBalanceChange;\n details.push(...parsedDetails);\n }\n\n return {\n isSimulationSuccessful,\n details,\n alert,\n balanceChange,\n };\n};\n","import { AlertType } from '@avalabs/vm-module-types';\n\nexport const transactionAlerts = {\n [AlertType.WARNING]: {\n type: AlertType.WARNING,\n details: {\n title: 'Suspicious Transaction',\n description: 'Use caution, this transaction may be malicious.',\n },\n },\n [AlertType.DANGER]: {\n type: AlertType.DANGER,\n details: {\n title: 'Scam Transaction',\n description: 'This transaction is malicious, do not proceed.',\n actionTitles: {\n reject: 'Reject Transaction',\n proceed: 'Proceed Anyway',\n },\n },\n },\n};\n","import type { BalanceChange, Network, SPLToken } from '@avalabs/vm-module-types';\nimport { deserializeTransactionMessage } from '@avalabs/core-wallets-sdk';\n\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { isNotNullish } from '../functional';\nimport type { getProvider } from '../get-provider';\nimport { tryToParseSolTransfer } from './instruction-parsers/sol-transfer';\nimport { tryToParseSPLTransfer } from './instruction-parsers/spl-transfer';\n\nexport const parseTransaction = async (\n serializedTx: string,\n account: string,\n network: Network,\n provider: ReturnType<typeof getProvider>,\n) => {\n const transaction = await deserializeTransactionMessage(serializedTx, provider);\n const balanceChange: BalanceChange = {\n ins: [],\n outs: [],\n };\n\n const details = await Promise.allSettled(\n transaction.instructions.map(async (instruction) => {\n return (\n tryToParseSolTransfer(instruction, balanceChange, account, network.networkToken) ??\n (await tryToParseSPLTransfer(provider, instruction, balanceChange, account, network.tokens as SPLToken[])) ??\n null\n );\n }),\n ).then((results) =>\n results\n .filter(isFulfilled)\n .map((result) => result.value)\n .filter(isNotNullish),\n );\n\n return {\n balanceChange,\n details,\n };\n};\n","import type { BalanceChange } from '@avalabs/vm-module-types';\n\nexport function isBalanceChangeEmpty(input: BalanceChange): boolean {\n return input.ins.length === 0 && input.outs.length === 0;\n}\n\nexport function isNotNullish<I>(input: I): input is NonNullable<I> {\n return input !== null && input !== undefined;\n}\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { BalanceChange, DetailSection, NetworkToken } from '@avalabs/vm-module-types';\nimport {\n identifySystemInstruction,\n parseTransferSolInstruction,\n SYSTEM_PROGRAM_ADDRESS,\n SystemInstruction,\n} from '@solana-program/system';\nimport {\n isInstructionForProgram,\n isInstructionWithAccounts,\n isInstructionWithData,\n type IInstruction,\n} from '@solana/kit';\n\nimport { addressItem } from '@internal/utils';\n\nexport const tryToParseSolTransfer = (\n instruction: IInstruction,\n balanceChange: BalanceChange,\n account: string,\n networkToken: NetworkToken,\n): DetailSection | null => {\n if (\n !isInstructionForProgram(instruction, SYSTEM_PROGRAM_ADDRESS) ||\n !isInstructionWithAccounts(instruction) ||\n !isInstructionWithData(instruction)\n ) {\n return null;\n }\n\n try {\n const systemInstruction = identifySystemInstruction(instruction);\n\n if (systemInstruction !== SystemInstruction.TransferSol) {\n return null;\n }\n\n const { accounts, data } = parseTransferSolInstruction({\n ...instruction,\n data: Uint8Array.from(instruction.data), // Fixing the typings here to satisfy parseTransferSolInstruction()\n });\n\n const isOutgoing = accounts.source.address === account;\n const balanceChangeKey = isOutgoing === true ? 'outs' : 'ins';\n\n balanceChange[balanceChangeKey].push({\n token: {\n ...networkToken,\n address: '',\n },\n items: [\n {\n displayValue: new TokenUnit(data.amount, networkToken.decimals, '').toString(),\n usdPrice: undefined,\n },\n ],\n });\n\n return {\n title: 'Transfer SOL',\n items: [addressItem('From', accounts.source.address), addressItem('To', accounts.destination.address)],\n };\n } catch {\n return null;\n }\n};\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { SolanaProvider } from '@avalabs/core-wallets-sdk';\nimport type { BalanceChange, DetailSection, SPLToken } from '@avalabs/vm-module-types';\nimport { parseTransferInstruction, identifyTokenInstruction, TokenInstruction } from '@solana-program/token';\nimport { isInstructionWithAccounts, isInstructionWithData, type Address, type IInstruction } from '@solana/kit';\n\nimport { addressItem } from '@internal/utils';\n\nconst getTokenMintFromAccountInfo = async (provider: SolanaProvider, account: Address): Promise<string | null> => {\n try {\n const tokenAccountDetails = await provider.getAccountInfo(account, { encoding: 'jsonParsed' }).send();\n\n if (Array.isArray(tokenAccountDetails.value?.data)) {\n return null;\n }\n\n const info = tokenAccountDetails.value?.data.parsed.info as Record<string, unknown>;\n return typeof info?.mint === 'string' ? info.mint : null;\n } catch {\n return null;\n }\n};\n\nexport const tryToParseSPLTransfer = async (\n provider: SolanaProvider,\n instruction: IInstruction,\n balanceChange: BalanceChange,\n account: string,\n tokens?: SPLToken[],\n): Promise<DetailSection | null> => {\n if (!tokens?.length || !isInstructionWithAccounts(instruction) || !isInstructionWithData(instruction)) {\n return null;\n }\n\n try {\n const tokenInstruction = identifyTokenInstruction(instruction);\n\n if (tokenInstruction !== TokenInstruction.Transfer) {\n return null;\n }\n\n const { accounts, data } = parseTransferInstruction({\n ...instruction,\n data: Uint8Array.from(instruction.data), // Fixing the typings here to satisfy parseTransferInstruction()\n });\n const tokenMint = await getTokenMintFromAccountInfo(provider, accounts.source.address);\n\n if (!tokenMint) {\n return null;\n }\n\n const token = tokens.find((t) => t.address.toLowerCase() === tokenMint.toLowerCase());\n\n if (!token) {\n return null;\n }\n\n const isOutgoing = accounts.source.address === account || accounts.authority.address === account;\n const balanceChangeKey = isOutgoing === true ? 'outs' : 'ins';\n\n balanceChange[balanceChangeKey].push({\n token,\n items: [\n {\n displayValue: new TokenUnit(data.amount, token.decimals, '').toString(),\n usdPrice: undefined,\n },\n ],\n });\n\n return {\n title: `Transfer ${token.symbol}`,\n items: [addressItem('From', accounts.source.address), addressItem('To', accounts.destination.address)],\n };\n } catch {\n return null;\n }\n};\n","import type Blockaid from '@blockaid/client';\nimport {\n TokenType,\n type BalanceChange,\n type Network,\n type NetworkToken,\n type SPLToken,\n type TokenDiff,\n} from '@avalabs/vm-module-types';\n\n// Simplify access to Blockaid's typings\ntype SolanaSimulation = Blockaid.Solana.MessageScanResponse.Result.Simulation;\ntype AccountSummaryAssetDiff = SolanaSimulation['account_summary']['account_assets_diff'];\ntype SolanaSimulationAsset = Exclude<AccountSummaryAssetDiff, undefined>[number]['asset'];\n\nexport const processBalanceChange = (\n account: string,\n simulationResult: Blockaid.Solana.Message.MessageScanResponse.Result.Simulation,\n network: Network,\n): { balanceChange: BalanceChange; otherAffectedAddresses: string[] } => {\n const transferedAssets = simulationResult.account_summary.account_assets_diff ?? [];\n\n const inTokenDiffDict: Record<string, TokenDiff> = {};\n const outTokenDiffDict: Record<string, TokenDiff> = {};\n\n const otherAffectedAddresses: string[] = Object.keys(simulationResult.assets_diff ?? {}).filter(\n (key) => key !== account,\n );\n\n transferedAssets.forEach(({ asset, in: assetIn, out: assetOut }) => {\n const token = convertDiffAssetToToken(asset, network);\n\n if (!token) {\n return;\n }\n\n const identifier = 'address' in token ? token.address : token.symbol;\n\n if (assetIn) {\n if (!inTokenDiffDict[identifier]) {\n inTokenDiffDict[identifier] = {\n token,\n items: [],\n };\n }\n\n inTokenDiffDict[identifier].items.push({\n displayValue: String(assetIn.value),\n usdPrice: typeof assetIn.usd_price === 'number' ? String(assetIn.usd_price) : undefined,\n });\n }\n\n if (assetOut) {\n if (!outTokenDiffDict[identifier]) {\n outTokenDiffDict[identifier] = {\n token,\n items: [],\n };\n }\n outTokenDiffDict[identifier].items.push({\n displayValue: String(assetOut.value),\n usdPrice: typeof assetOut.usd_price === 'number' ? String(assetOut.usd_price) : undefined,\n });\n }\n });\n\n return {\n balanceChange: {\n ins: Object.values(inTokenDiffDict),\n outs: Object.values(outTokenDiffDict),\n },\n otherAffectedAddresses,\n };\n};\n\nconst convertNativeAssetToToken = (\n asset: Blockaid.Solana.MessageScanResponse.Result.Simulation.SolanaNativeAssetDiff.Asset,\n): NetworkToken => {\n return {\n name: asset.type,\n symbol: asset.type, // It's either SOL or ETH according to types\n decimals: asset.decimals,\n description: '',\n logoUri: asset.logo ?? undefined,\n };\n};\n\nconst convertTokenAssetToToken = (\n asset: Blockaid.Solana.MessageScanResponse.Result.Simulation.SolanaSplFungibleAssetDiff.Asset,\n network: Network,\n): SPLToken => ({\n type: TokenType.SPL,\n address: asset.address,\n caip2Id: network.caipId ?? '',\n contractType: TokenType.SPL,\n decimals: asset.decimals,\n name: asset.name,\n symbol: asset.symbol,\n logoUri: asset.logo || undefined,\n});\n\nconst convertDiffAssetToToken = (asset: SolanaSimulationAsset, network: Network): SPLToken | NetworkToken | null => {\n if (asset.type === 'TOKEN') {\n return convertTokenAssetToToken(asset, network);\n }\n\n if (asset.type === 'SOL' || asset.type === 'ETH') {\n return convertNativeAssetToToken(asset);\n }\n\n return null;\n};\n","import Blockaid from '@blockaid/client';\nimport { base58, base64 } from '@scure/base';\n\nimport type { ExplainTxParams } from '../types';\n\nconst DUMMY_API_KEY = 'DUMMY_API_KEY'; // since we're using our own proxy and api key is handled there, we can use a dummy key here\n\nexport const scanSolanaTransaction = async ({\n proxyApiUrl,\n params,\n dAppUrl,\n}: ExplainTxParams): Promise<Blockaid.Solana.Message.MessageScanResponse | null> => {\n const blockaid = new Blockaid({\n baseURL: proxyApiUrl + '/proxy/blockaid/',\n apiKey: DUMMY_API_KEY,\n });\n\n try {\n return await blockaid.solana.message.scan({\n chain: params.chain,\n options: ['simulation', 'validation'],\n encoding: 'base64',\n metadata: {\n url: dAppUrl,\n },\n transactions: [params.transactionBase64],\n // We need to encode the account address to base64 as well\n account_address: base64.encode(base58.decode(params.account)),\n });\n } catch (err) {\n console.error('solana.message.scan() error', err);\n return null;\n }\n};\n","import { z } from 'zod';\n\nconst transactionSchema = z.object({\n account: z.string(),\n serializedTx: z.string().base64(),\n sendOptions: z\n .object({\n preflightCommitment: z.enum(['processed', 'confirmed', 'finalized']).optional(),\n maxRetries: z.bigint().optional(),\n minContextSlot: z.bigint().optional(),\n skipPreflight: z.boolean().optional(),\n })\n .optional(),\n});\n\nconst paramsSchema = z.tuple([transactionSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type TransactionParams = z.infer<typeof transactionSchema>;\nexport type SendOptions = z.infer<typeof transactionSchema>['sendOptions'];\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n} from '@avalabs/vm-module-types';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { isBalanceChangeEmpty } from '@src/utils/functional';\nimport { getNetworkName } from '@src/utils/get-network-name';\nimport { explainTransaction } from '@src/utils/explain/explain-transaction';\n\nimport { parseRequestParams } from './schema';\n\nexport const signTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedTx }] = data;\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { details, isSimulationSuccessful, alert, balanceChange } = await explainTransaction({\n simulationParams: {\n dAppUrl: request.dappInfo.url,\n params: {\n account,\n chain: getNetworkName(network),\n transactionBase64: serializedTx,\n },\n proxyApiUrl,\n },\n network,\n provider,\n });\n\n const displayData: DisplayData = {\n title: 'Sign Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details,\n alert,\n balanceChange: balanceChange && isBalanceChangeEmpty(balanceChange) ? undefined : balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_TRANSACTION,\n account,\n data: serializedTx,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n if (!('signedData' in response)) {\n return {\n error: rpcErrors.invalidRequest('No signed data returned'),\n };\n }\n\n return { result: response.signedData };\n};\n","import { z } from 'zod';\n\nconst transactionSchema = z.object({\n account: z.string(),\n serializedTx: z.string().base64(),\n});\n\nconst paramsSchema = z.tuple([transactionSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type TransactionParams = z.infer<typeof transactionSchema>;\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n} from '@avalabs/vm-module-types';\nimport { base64 } from '@scure/base';\n\nimport { addressItem, dataItem, textItem } from '@internal/utils';\n\nimport { parseRequestParams } from './schema';\n\nexport const signMessage = async ({\n request,\n network,\n approvalController,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Message signing params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedMessage }] = data;\n\n const utf8Decoder = new TextDecoder();\n const displayData: DisplayData = {\n title: 'Sign Message',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n dAppInfo: {\n name: request.dappInfo.name,\n action: `${request.dappInfo.name} wants you to sign the following message`,\n logoUri: request.dappInfo.icon,\n },\n disclaimer: 'Only confirm if you trust this website',\n details: [\n {\n title: 'Message Details',\n items: [\n addressItem('Account', account),\n textItem('Message', utf8Decoder.decode(base64.decode(serializedMessage))),\n dataItem('Raw Message (Base-64)', serializedMessage),\n ],\n },\n ],\n networkFeeSelector: false,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_MESSAGE,\n account,\n data: serializedMessage,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n if (!('signedData' in response)) {\n return {\n error: rpcErrors.invalidRequest('No signed data returned'),\n };\n }\n\n return { result: response.signedData };\n};\n","import { base64 } from '@scure/base';\nimport { getCompiledTransactionMessageDecoder } from '@solana/kit';\n\nexport const isTransactionBytes = (base64Payload: string): boolean => {\n try {\n const bytes = base64.decode(base64Payload);\n const decoder = getCompiledTransactionMessageDecoder();\n decoder.decode(bytes);\n return true;\n } catch {\n return false;\n }\n};\n","import { isTransactionBytes } from '@src/utils/is-transaction-bytes';\nimport { z } from 'zod';\n\nconst signMessageSchema = z\n .object({\n account: z.string(),\n serializedMessage: z.string().base64(),\n })\n .refine(({ serializedMessage }) => !isTransactionBytes(serializedMessage), {\n message: 'Cannot use signMessage() calls for signing transactions',\n });\n\nconst paramsSchema = z.tuple([signMessageSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type SignMessageParams = z.infer<typeof signMessageSchema>;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/module.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/utils/fetch-and-verify.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../../../packages-internal/utils/src/utils/get-core-headers.ts","../manifest.json","../src/env.ts","../src/handlers/derive-address/derive-address.ts","../../../packages-internal/utils/src/utils/address-derivation.ts","../src/handlers/build-derivation-path/build-derivation-path.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/utils/get-provider.ts","../src/constants.ts","../src/handlers/get-tokens/get-tokens.ts","../src/handlers/get-tokens/spl-token-schema.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/utils/is-promise-fulfilled.ts","../src/utils/moralis-service/moralis-schemas.ts","../src/utils/moralis-service/moralis-service.ts","../src/utils/get-network-name.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-transaction-history/extract-transfer.ts","../src/handlers/get-transaction-history/get-wrapped-transactions.ts","../src/utils/has-property-defined.ts","../src/handlers/get-transaction-history/get-explorer-link.ts","../src/handlers/sign-and-send-transaction/sign-and-send-transaction.ts","../src/utils/explain/explain-transaction.ts","../src/utils/transaction-alerts.ts","../src/utils/explain/parse-transaction.ts","../src/utils/functional.ts","../src/utils/explain/instruction-parsers/sol-transfer.ts","../src/utils/explain/instruction-parsers/spl-transfer.ts","../src/utils/explain/blockaid/process-balance-change.ts","../src/utils/explain/blockaid/scan-solana-transaction.ts","../src/handlers/sign-and-send-transaction/schema.ts","../src/handlers/sign-transaction/sign-transaction.ts","../src/handlers/sign-transaction/schema.ts","../src/handlers/sign-message/sign-message.ts","../src/utils/is-transaction-bytes.ts","../src/handlers/sign-message/schema.ts"],"names":["parseManifest","RpcMethod","rpcErrors","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","RawSimplePriceResponseSchema","fetchAndVerify","fetchOptions","schema","responseJson","CoingeckoProxyClient","proxyApiUrl","params","queryParams","id","rawQueryParams","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","rawData","marketCap","vol24","change24","lastUpdated","shouldThrow","number","object","record","string","ExchangeRateSchema","DetailItemType","textItem","label","value","alignment","addressItem","addressListItem","dataItem","AppName","manifest_default","Environment","prodEnv","devEnv","getEnv","environment","NetworkVMType","base58","hex","hasDerivationDetails","buildDerivationPath","accountIndex","deriveAddress","approvalController","secretId","derivationPath","publicKeyHex","getSolanaProvider","SOLANA_MAINNET_CAIP2_ID","SOLANA_DEVNET_CAIP2_ID","SOLANA_TESTNET_CAIP2_ID","RPC_URL_PROXY_API_ENDPOINT","RPC_URL_DEVNET","getProvider","isTestnet","LamportsMultiplier","DEFAULT_PRIORITY_FEE","ensureEnoughData","fees","a","b","getNetworkFee","network","feesRaw","block","sortedFees","minFeeInRecentBlocks","maxFeeInRecentBlocks","midIndex","medianFee","presetHigh","presetMedium","presetLow","TokenType","z","SPL_TOKEN_SCHEMA","SPL_TOKENS_SCHEMA","getTokens","caip2Id","token","error","TokenUnit","isFulfilled","PORTFOLIO_SCHEMA","_baseUrl","_buildUrl","buildUrl_fn","MoralisService","address","url","__privateMethod","portfolio","message","path","getNetworkName","getBalances","addresses","tokenService","moralisService","coingeckoAssetId","coingeckoPlatformId","lowercaseCurrency","solanaNetwork","portfolioResults","mints","mint","tokenPricesPromises","nativePrice","tokenPrices","promise","portfolioAcc","nativeBalanceUnit","nativeMarketData","getMarketData","nativeBalanceInCurrency","solanaBalance","tokenBalances","tokensAcc","amountRaw","symbol","decimals","name","logo","balanceUnit","marketData","balanceInCurrency","coinIdOrAddress","prices","TransactionType","simplifyTokenBalance","balance","extractTokenTranfers","meta","preBalances","acc","owner","amount","transfers","key","preAmount","netChange","sender","k","possibleSender","mintFromPreBalance","possibleSenderPostBalance","postBalanceOwner","postBalanceMint","t","transfer","nativeTransfer","extractNativeTransfer","paidFee","postBalances","nativeBalancePre","nativeBalancePost","nativeTransferAmount","balanceDiffs","isIncoming","unit","largestBeneficiary","index","change","otherAddressIndex","solAddress","hasPropertyDefined","thing","getWrappedTransactions","provider","signatures","sig","tx","getExplorerLink","txHash","baseUrl","explorerLink","getTransactionHistory","isSigner","inferTxType","AlertType","transactionAlerts","deserializeTransactionMessage","isBalanceChangeEmpty","input","isNotNullish","identifySystemInstruction","parseTransferSolInstruction","SYSTEM_PROGRAM_ADDRESS","SystemInstruction","isInstructionForProgram","isInstructionWithAccounts","isInstructionWithData","tryToParseSolTransfer","instruction","balanceChange","account","networkToken","accounts","balanceChangeKey","parseTransferInstruction","identifyTokenInstruction","TokenInstruction","getTokenMintFromAccountInfo","tokenAccountDetails","info","tryToParseSPLTransfer","tokens","tokenMint","parseTransaction","serializedTx","transaction","details","results","processBalanceChange","simulationResult","transferedAssets","inTokenDiffDict","outTokenDiffDict","otherAffectedAddresses","asset","assetIn","assetOut","convertDiffAssetToToken","identifier","convertNativeAssetToToken","convertTokenAssetToToken","Blockaid","base64","DUMMY_API_KEY","scanSolanaTransaction","dAppUrl","blockaid","explainTransaction","simulationParams","scanResponse","simulation","validation","genericDetails","isSimulationSuccessful","alert","processedBalanceChange","parsedBalanceChange","parsedDetails","transactionSchema","paramsSchema","parseRequestParams","signAndSendTransaction","request","success","sendOptions","displayData","signingData","getTxHash","signTransaction","getCompiledTransactionMessageDecoder","isTransactionBytes","base64Payload","bytes","signMessageSchema","serializedMessage","signMessage","utf8Decoder","_approvalController","_appInfo","SvmModule","appInfo"],"mappings":"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","sourcesContent":["import {\n parseManifest,\n RpcMethod,\n type AppInfo,\n type ApprovalController,\n type BuildDerivationPathParams,\n type ConstructorParams,\n type DeriveAddressParams,\n type GetBalancesParams,\n type GetTransactionHistory,\n type Module,\n type Network,\n type NetworkFeeParam,\n type RpcRequest,\n} from '@avalabs/vm-module-types';\nimport type { SolanaProvider } from '@avalabs/core-wallets-sdk';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport { TokenService } from '@internal/utils';\n\nimport ManifestJson from '../manifest.json';\nimport { getEnv } from './env';\nimport { deriveAddress } from './handlers/derive-address';\nimport { buildDerivationPath } from './handlers/build-derivation-path';\nimport { getNetworkFee } from './handlers/get-network-fee';\nimport { getTokens } from './handlers/get-tokens';\nimport { getBalances } from './handlers/get-balances';\nimport { getProvider } from './utils/get-provider';\nimport { getTransactionHistory } from './handlers/get-transaction-history';\nimport { signAndSendTransaction } from './handlers/sign-and-send-transaction';\nimport { signTransaction } from './handlers/sign-transaction';\nimport { signMessage } from './handlers/sign-message';\n\nexport class SvmModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n #appInfo: AppInfo;\n\n constructor({ approvalController, environment, appInfo }: ConstructorParams) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#appInfo = appInfo;\n this.#proxyApiUrl = proxyApiUrl;\n this.#approvalController = approvalController;\n\n // Temporarily referencing those props here just to silence eslint,\n // as eslint-disable-... comments don't seem to work on class properties.\n this.#proxyApiUrl;\n this.#approvalController;\n this.#appInfo;\n }\n\n async getProvider(network: Network): Promise<SolanaProvider> {\n return getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl: this.#proxyApiUrl });\n }\n\n // TODO\n getAddress() {\n return Promise.resolve({});\n }\n\n buildDerivationPath(params: BuildDerivationPathParams) {\n return buildDerivationPath(params);\n }\n\n deriveAddress(params: DeriveAddressParams) {\n return deriveAddress({\n ...params,\n approvalController: this.#approvalController,\n });\n }\n\n getBalances(params: GetBalancesParams) {\n const tokenService = new TokenService({ storage: params.storage, proxyApiUrl: this.#proxyApiUrl });\n\n return getBalances({\n ...params,\n tokenService,\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getManifest() {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: NetworkFeeParam) {\n return getNetworkFee(network, this.#proxyApiUrl);\n }\n\n getTransactionHistory(params: GetTransactionHistory) {\n return getTransactionHistory({\n network: params.network,\n address: params.address,\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getTokens(network: Network) {\n if (!network.caipId) {\n return Promise.reject({ error: rpcErrors.invalidParams(`Network must have a CAIP-2 id`) });\n }\n\n return getTokens({ caip2Id: network.caipId, proxyApiUrl: this.#proxyApiUrl });\n }\n\n // TODO\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.SOLANA_SIGN_TRANSACTION: {\n return signTransaction({\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n network,\n request,\n });\n }\n case RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION: {\n return signAndSendTransaction({\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n network,\n request,\n });\n }\n case RpcMethod.SOLANA_SIGN_MESSAGE: {\n return signMessage({\n approvalController: this.#approvalController,\n network,\n request,\n });\n }\n }\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n}\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { CoingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch (err) {\n console.error(err);\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await new CoingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses({\n id: assetPlatformId,\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n });\n return this.transformSimplePriceResponse(rawData, [currency]);\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await new CoingeckoProxyClient(this.#proxyApiUrl).simplePrice({\n ids: coinIds,\n vs_currencies: currencies,\n include_market_cap: marketCap,\n include_24hr_vol: vol24,\n include_24hr_change: change24,\n include_last_updated_at: lastUpdated,\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { RawSimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nexport class CoingeckoProxyClient {\n constructor(private proxyApiUrl: string) {}\n\n simplePrice(params: {\n ids: string[];\n vs_currencies: string[];\n include_market_cap?: boolean;\n include_24hr_vol?: boolean;\n include_24hr_change?: boolean;\n include_last_updated_at?: boolean;\n }) {\n // casting params as any since typing does not allow boolean and other non-string values\n // even though NodeJS does not have this restriction itself: https://nodejs.org/api/url.html#new-urlsearchparamsobj\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const queryParams = new URLSearchParams(params as any);\n return fetchAndVerify(\n [\n `${this.proxyApiUrl}/proxy/coingecko/simple/price?${queryParams}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ],\n RawSimplePriceResponseSchema,\n );\n }\n\n simplePriceByContractAddresses(params: {\n id: string;\n contract_addresses: string[];\n vs_currencies?: string[];\n include_market_cap?: boolean;\n include_24hr_vol?: boolean;\n include_24hr_change?: boolean;\n }) {\n const { id, ...rawQueryParams } = params;\n\n // casting params as any since typing does not allow boolean and other non-string values\n // even though NodeJS does not have this restriction itself: https://nodejs.org/api/url.html#new-urlsearchparamsobj\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const queryParams = new URLSearchParams(rawQueryParams as any);\n\n return fetchAndVerify(\n [\n `${this.proxyApiUrl}/proxy/coingecko/simple/token_price/${id}?${queryParams}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ],\n RawSimplePriceResponseSchema,\n );\n }\n}\n","import z from 'zod';\nimport type { ZodSchema } from 'zod';\n\nexport async function fetchAndVerify<T extends ZodSchema>(\n fetchOptions: Parameters<typeof fetch>,\n schema: T,\n): Promise<z.infer<T>> {\n const response = await fetch(...fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}`);\n }\n\n const responseJson = await response.json();\n return schema.parse(responseJson);\n}\n","import z, { number, object, record, string } from 'zod';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_URL], ExchangeRateSchema);\n } catch {\n return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_FALLBACK_URL], ExchangeRateSchema);\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n type LinkItemValue,\n DetailItemType,\n type LinkItem,\n type FundsRecipientItem,\n type AddressListItem,\n} from '@avalabs/vm-module-types';\n\nexport const fundsRecipientItem = (\n address: string,\n amount: bigint,\n maxDecimals: number,\n symbol: string,\n): FundsRecipientItem => ({\n type: DetailItemType.FUNDS_RECIPIENT,\n label: address,\n amount,\n maxDecimals,\n symbol,\n});\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const linkItem = (label: string, value: LinkItemValue): LinkItem => ({\n label,\n value,\n type: DetailItemType.LINK,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const addressListItem = (label: string, value: string[]): AddressListItem => ({\n label,\n type: DetailItemType.ADDRESS_LIST,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import { AppName, type AppInfo } from '@avalabs/vm-module-types';\n\nexport const getCoreHeaders = ({ name, version }: AppInfo): Record<string, string> | undefined => {\n switch (name) {\n case AppName.CORE_MOBILE_IOS:\n case AppName.CORE_MOBILE_ANDROID:\n case AppName.CORE_WEB:\n case AppName.CORE_EXTENSION:\n case AppName.EXPLORER:\n return {\n 'x-application-name': name,\n 'x-application-version': version,\n };\n case AppName.OTHER:\n return undefined;\n }\n};\n","{\n \"name\": \"SVM\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/index.js\",\n \"packageName\": \"@avalabs/svm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider/index.js\",\n \"packageName\": \"@avalabs/svm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\",\n \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\",\n \"solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z\"\n ],\n \"namespaces\": [\"solana\"]\n },\n \"cointype\": \"501\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"solana_signTransaction\", \"solana_signAndSendTransaction\", \"solana_signMessage\"],\n \"nonRestrictedMethods\": []\n }\n },\n \"manifestVersion\": \"0.1\"\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","import type { ApprovalController, DeriveAddressParams, DeriveAddressResponse } from '@avalabs/vm-module-types';\nimport { NetworkVMType } from '@avalabs/vm-module-types';\nimport { base58, hex } from '@scure/base';\n\nimport { hasDerivationDetails } from '@internal/utils/src/utils/address-derivation';\nimport { buildDerivationPath } from '../build-derivation-path/build-derivation-path';\n\nexport const deriveAddress = async (\n params: DeriveAddressParams & { approvalController: ApprovalController },\n): Promise<DeriveAddressResponse> => {\n const { approvalController, secretId } = params;\n\n // When dealing with single-account private keys, we don't need the derivation path any more.\n const derivationPath = hasDerivationDetails(params) ? buildDerivationPath(params).SVM : undefined;\n const publicKeyHex = await approvalController.requestPublicKey({\n curve: 'ed25519',\n secretId,\n derivationPath,\n });\n\n return {\n [NetworkVMType.SVM]: base58.encode(hex.decode(publicKeyHex)),\n };\n};\n","import type { DeriveAddressParams, DetailedDeriveAddressParams } from '@avalabs/vm-module-types';\n\nexport const hasDerivationDetails = (params: DeriveAddressParams): params is DetailedDeriveAddressParams =>\n 'derivationPathType' in params &&\n 'accountIndex' in params &&\n typeof params.accountIndex === 'number' &&\n typeof params.derivationPathType === 'string';\n","import {\n NetworkVMType,\n type BuildDerivationPathParams,\n type BuildDerivationPathResponse,\n} from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\n/**\n * We're deriving the BTC address from the same public key as the Ethereum address,\n * so we can determine the target address when using the Avalanche Bridge.\n */\nexport const buildDerivationPath = ({\n accountIndex,\n}: BuildDerivationPathParams): Pick<BuildDerivationPathResponse, NetworkVMType.SVM> => {\n if (accountIndex < 0) {\n throw rpcErrors.invalidParams('Account index must be a non-negative integer');\n }\n\n return {\n [NetworkVMType.SVM]: `m/44'/501'/${accountIndex}'/0'`,\n };\n};\n","import { type NetworkFeeParam, type NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { SOL_DECIMALS } from '@src/constants';\n\nconst LamportsMultiplier = 1e6;\nexport const DEFAULT_PRIORITY_FEE = {\n high: 150 * LamportsMultiplier,\n medium: 75 * LamportsMultiplier,\n low: 2 * LamportsMultiplier,\n} as const;\n\ntype ValidRecentFees = [number, number, ...number[]];\n\nconst ensureEnoughData = (fees: number[]): ValidRecentFees => {\n const normalizedFees =\n fees.length === 0\n ? [DEFAULT_PRIORITY_FEE.low, DEFAULT_PRIORITY_FEE.low]\n : fees.length === 1\n ? [fees[0]!, DEFAULT_PRIORITY_FEE.low]\n : fees;\n\n return normalizedFees.slice().sort((a, b) => a - b) as ValidRecentFees;\n};\n\n/**\n * The RPC call (getRecentPrioritizationFees) returns the *lowest* priority fees (per compute unit)\n * that resulted in at least one transaction being succesfully included in the block.\n *\n * This means the request usually returns all zeroes - I've only once seen a different value,\n * for a single block out of 150 returned, and it was a 1000 MicroLamports.\n *\n * However, Phantom (the most popular Solana wallet) seems to always add at least a little bit\n * of priority fee.\n *\n * The lowest I've seen in my testing was 0.19 Lamport per compute unit, but this was an outlier.\n * I'm usually paying below 10 Lamports/cu, and sometimes as high as 150 or 300/cu -- all while\n * the RPC call returns zeroes, so it's not super reliable for determining the actual fees being paid :)\n *\n * The implementation here is by no means perfect. The way it I expect it to work is the following:\n * - with low/regular network traffic, users will be suggested to pay the default fees hardcoded below\n * (if we decide to show them at all -- Phantom does not show a widget at all)\n * - only when network congestion is super high, the RPC call will return non-zero values, and only then\n * we will suggest paying higher priority fees.\n */\nexport async function getNetworkFee(network: NetworkFeeParam, proxyApiUrl: string): Promise<NetworkFees> {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n\n const getFees = await provider.getRecentPrioritizationFees();\n const feesRaw = await getFees.send();\n\n const useDefaultFees = feesRaw.length === 0 || feesRaw.every((block) => block.prioritizationFee === 0n);\n\n if (useDefaultFees) {\n return {\n high: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.high),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.high),\n },\n medium: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.medium),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.medium),\n },\n low: {\n maxFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.low),\n maxPriorityFeePerGas: BigInt(DEFAULT_PRIORITY_FEE.low),\n },\n baseFee: BigInt(DEFAULT_PRIORITY_FEE.low),\n displayDecimals: SOL_DECIMALS,\n isFixedFee: false,\n };\n }\n\n const sortedFees = ensureEnoughData(feesRaw.map((block) => Number(block.prioritizationFee)));\n // We know the array is not empty and sorted, so we can safely access the first and last elements\n const minFeeInRecentBlocks = sortedFees.at(0)!;\n const maxFeeInRecentBlocks = sortedFees.at(-1)!;\n const midIndex = Math.floor(sortedFees.length / 2);\n const medianFee =\n sortedFees.length % 2 === 1\n ? (sortedFees[midIndex] as number)\n : (sortedFees[midIndex - 1]! + sortedFees[midIndex]!) / 2; // Even length: return average of middle elements\n\n // Prevent the fees from going below the default values\n // If the RPC call returned non-zero values, the network congestion is likely to be very high, so we add 5%.\n // We also prevent returning fees lower than the default, hardcoded values, as the RPC call is not very reliable.\n const presetHigh = BigInt(Math.ceil(maxFeeInRecentBlocks * 1.05));\n const presetMedium = BigInt(Math.ceil(medianFee * 1.05));\n const presetLow = BigInt(Math.ceil(minFeeInRecentBlocks * 1.05));\n\n // TODO: The shape of response here needs a general refactoring, it's not very generic.\n return {\n high: {\n maxFeePerGas: presetHigh,\n maxPriorityFeePerGas: presetHigh,\n },\n medium: {\n maxFeePerGas: presetMedium,\n maxPriorityFeePerGas: presetMedium,\n },\n low: {\n maxFeePerGas: presetLow,\n maxPriorityFeePerGas: presetLow,\n },\n baseFee: presetLow,\n displayDecimals: SOL_DECIMALS,\n isFixedFee: false,\n };\n}\n","import { getSolanaProvider, type SolanaProvider } from '@avalabs/core-wallets-sdk';\n\nimport { RPC_URL_DEVNET, RPC_URL_PROXY_API_ENDPOINT } from '../constants';\n\nexport const getProvider = ({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): SolanaProvider => {\n return getSolanaProvider({\n isTestnet,\n rpcUrl: isTestnet ? RPC_URL_DEVNET : proxyApiUrl + RPC_URL_PROXY_API_ENDPOINT,\n });\n};\n","export const SOL_DECIMALS = 9;\nexport const SOLANA_COIN_ID = 501;\n\nexport const SOLANA_MAINNET_CAIP2_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET_CAIP2_ID = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET_CAIP2_ID = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\nexport const RPC_URL_PROXY_API_ENDPOINT = '/proxy/nownodes/sol';\nexport const RPC_URL_DEVNET = 'https://api.devnet.solana.com';\nexport const RPC_URL_TESTNET = 'https://api.testnet.solana.com';\n","import type { SPLToken } from '@avalabs/vm-module-types';\nimport { fetchAndVerify } from '@internal/utils/src/utils/fetch-and-verify';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { SPL_TOKENS_SCHEMA } from './spl-token-schema';\n\nexport async function getTokens({\n caip2Id,\n proxyApiUrl,\n}: {\n caip2Id: string;\n proxyApiUrl: string;\n}): Promise<SPLToken[]> {\n try {\n const tokens = await fetchAndVerify([`${proxyApiUrl}/solana-tokens?caip2Id=${caip2Id}`], SPL_TOKENS_SCHEMA);\n\n return tokens.map((token) => ({ ...token, type: token.contractType }));\n } catch (error) {\n console.error('getTokens() failed for', caip2Id, error);\n throw rpcErrors.internal(`Failed to fetch tokens for caip2Id \"${caip2Id}\"`);\n }\n}\n","import { TokenType } from '@avalabs/vm-module-types';\nimport { z } from 'zod';\n\nexport const SPL_TOKEN_SCHEMA = z.object({\n address: z.string(),\n name: z.string(),\n symbol: z.string(),\n contractType: z.literal(TokenType.SPL),\n caip2Id: z.string().startsWith('solana:'),\n decimals: z.number(),\n chainId: z.number().optional(),\n logoUri: z.string().optional(),\n color: z.string().optional(),\n});\n\nexport const SPL_TOKENS_SCHEMA = z.array(SPL_TOKEN_SCHEMA);\n","import {\n type GetBalancesParams,\n type TokenWithBalanceSVM,\n type TokenWithBalanceSPL,\n TokenType,\n type SimplePriceResponse,\n type Error,\n} from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport type { TokenService } from '@internal/utils';\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { SOL_DECIMALS } from '@src/constants';\nimport { MoralisService } from '@src/utils/moralis-service';\nimport { getNetworkName } from '@src/utils/get-network-name';\n\ntype GetSolanaBalancesResponse = Record<\n string,\n Record<string, TokenWithBalanceSVM | TokenWithBalanceSPL | Error> | Error\n>;\n\nexport const getBalances = async ({\n addresses,\n proxyApiUrl,\n currency,\n network,\n tokenService,\n}: GetBalancesParams & {\n proxyApiUrl: string;\n tokenService: TokenService;\n}): Promise<GetSolanaBalancesResponse> => {\n const moralisService = new MoralisService({ proxyApiUrl });\n const coingeckoAssetId = network.pricingProviders?.coingecko.nativeTokenId ?? '';\n const coingeckoPlatformId = network.pricingProviders?.coingecko.assetPlatformId ?? '';\n const lowercaseCurrency = currency.toLowerCase();\n const solanaNetwork = getNetworkName(network);\n\n const portfolioResults = await Promise.all(\n addresses.map((address) => moralisService.getPortfolio({ address, network: solanaNetwork })),\n );\n\n const mints = new Set(\n portfolioResults.flatMap((result) => {\n if ('portfolio' in result) {\n return result.portfolio.tokens.map(({ mint }) => mint);\n }\n\n return [];\n }),\n );\n\n const tokenPricesPromises = await Promise.allSettled([\n coingeckoAssetId\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoAssetId],\n currencies: [lowercaseCurrency as VsCurrencyType],\n })\n : Promise.resolve(undefined),\n coingeckoPlatformId\n ? await tokenService.getPricesByAddresses(\n Array.from(mints),\n coingeckoPlatformId,\n lowercaseCurrency as VsCurrencyType,\n )\n : Promise.resolve(undefined),\n ]);\n const [nativePrice, tokenPrices] = tokenPricesPromises.map((promise) =>\n isFulfilled(promise) ? promise.value : undefined,\n );\n\n return portfolioResults.reduce((portfolioAcc, result) => {\n if ('error' in result) {\n return {\n ...portfolioAcc,\n [result.address]: {\n error: result.error,\n },\n };\n }\n\n const nativeBalanceUnit = new TokenUnit(result.portfolio.nativeBalance.lamports, SOL_DECIMALS, 'SOL');\n const nativeMarketData = getMarketData(coingeckoAssetId, lowercaseCurrency, nativePrice);\n const nativeBalanceInCurrency =\n nativeMarketData.priceInCurrency !== undefined\n ? nativeBalanceUnit.mul(nativeMarketData.priceInCurrency)\n : undefined;\n\n const solanaBalance: TokenWithBalanceSVM = {\n type: TokenType.NATIVE,\n name: network.networkToken.name,\n symbol: network.networkToken.symbol,\n decimals: network.networkToken.decimals,\n balance: nativeBalanceUnit.toSubUnit(),\n balanceDisplayValue: nativeBalanceUnit.toString(),\n balanceInCurrency: nativeBalanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: nativeBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n logoUri: network.networkToken.logoUri ?? '',\n coingeckoId: coingeckoAssetId,\n ...nativeMarketData,\n };\n\n const tokenBalances = result.portfolio.tokens.reduce(\n (tokensAcc, { amountRaw, symbol, decimals, mint, name, logo }) => {\n const balanceUnit = new TokenUnit(amountRaw, decimals, symbol);\n const marketData = getMarketData(mint, lowercaseCurrency, tokenPrices);\n const balanceInCurrency =\n marketData.priceInCurrency !== undefined ? balanceUnit.mul(marketData.priceInCurrency) : undefined;\n\n const token: TokenWithBalanceSPL = {\n type: TokenType.SPL,\n address: mint,\n name,\n symbol,\n decimals,\n balance: balanceUnit.toSubUnit(),\n balanceDisplayValue: balanceUnit.toString(),\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n logoUri: logo ?? undefined,\n reputation: null,\n ...marketData,\n };\n\n return {\n ...tokensAcc,\n [mint]: token,\n };\n },\n {} as Record<string, TokenWithBalanceSPL>,\n );\n\n return {\n ...portfolioAcc,\n [result.address]: {\n [network.networkToken.symbol]: solanaBalance,\n ...tokenBalances,\n },\n };\n }, {} as GetSolanaBalancesResponse);\n};\n\nconst getMarketData = (coinIdOrAddress: string, currency: string, prices?: SimplePriceResponse) => ({\n priceInCurrency: prices?.[coinIdOrAddress ?? '']?.[currency]?.price ?? undefined,\n marketCap: prices?.[coinIdOrAddress ?? '']?.[currency]?.marketCap ?? undefined,\n vol24: prices?.[coinIdOrAddress ?? '']?.[currency]?.vol24 ?? undefined,\n change24: prices?.[coinIdOrAddress ?? '']?.[currency]?.change24 ?? undefined,\n});\n","export const isFulfilled = <T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> =>\n result.status === 'fulfilled';\n","import { z } from 'zod';\n\nexport const PORTFOLIO_SCHEMA = z.object({\n nativeBalance: z.object({\n lamports: z.string(),\n solana: z.string(),\n }),\n nfts: z.array(\n z.object({\n associatedTokenAddress: z.string(),\n mint: z.string(),\n name: z.string(),\n symbol: z.string(),\n }),\n ),\n tokens: z.array(\n z.object({\n associatedTokenAddress: z.string(),\n mint: z.string(),\n amountRaw: z.string(),\n amount: z.string(),\n decimals: z.number(),\n name: z.string(),\n symbol: z.string(),\n logo: z.string().optional().nullable(),\n }),\n ),\n});\n\nexport type PortfolioResponse = z.infer<typeof PORTFOLIO_SCHEMA>;\n","import { fetchAndVerify } from '@internal/utils/src/utils/fetch-and-verify';\n\nimport type { SolanaNetworkName } from '@src/types';\n\nimport { PORTFOLIO_SCHEMA, type PortfolioResponse } from './moralis-schemas';\n\nexport class MoralisService {\n #baseUrl: string;\n\n constructor({ proxyApiUrl }: { proxyApiUrl: string }) {\n this.#baseUrl = `${proxyApiUrl}/proxy/moralis`;\n }\n\n async getPortfolio({\n address,\n network,\n }: {\n network: SolanaNetworkName;\n address: string;\n }): Promise<{ address: string; portfolio: PortfolioResponse } | { address: string; error: string }> {\n try {\n const url = this.#buildUrl(`/account/${network}/${address}/portfolio`);\n const portfolio = await fetchAndVerify([url], PORTFOLIO_SCHEMA);\n\n return {\n address,\n portfolio,\n };\n } catch (error) {\n console.error('getPortfolio() failed:', error);\n\n const message = error instanceof Error ? error.message : 'unknown error';\n\n return {\n address,\n error: `getPortfolio() failed: ${message}`,\n };\n }\n }\n\n #buildUrl(path: string) {\n return `${this.#baseUrl}${path}`;\n }\n}\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { SOLANA_DEVNET_CAIP2_ID, SOLANA_MAINNET_CAIP2_ID, SOLANA_TESTNET_CAIP2_ID } from '../constants';\n\nexport const getNetworkName = (network: Network) => {\n switch (network.caipId) {\n case SOLANA_MAINNET_CAIP2_ID:\n return 'mainnet';\n\n case SOLANA_DEVNET_CAIP2_ID:\n return 'devnet';\n\n case SOLANA_TESTNET_CAIP2_ID:\n return 'testnet';\n\n default:\n throw new Error('Unrecognized CAIP-2 id: ' + network.caipId);\n }\n};\n","import { TransactionType, type Network, type TransactionHistoryResponse, type TxToken } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport { extractTokenTranfers, simplifyTokenBalance } from './extract-transfer';\nimport { getWrappedTransactions } from './get-wrapped-transactions';\nimport { getExplorerLink } from './get-explorer-link';\n\ntype SvmGetTransactionHistory = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport async function getTransactionHistory({\n network,\n address,\n proxyApiUrl,\n}: SvmGetTransactionHistory): Promise<TransactionHistoryResponse> {\n if (!network.caipId) {\n return Promise.reject({\n error: rpcErrors.invalidParams(`Network must have a CAIP-2 id`),\n });\n }\n\n const rawTransactions = await getWrappedTransactions({ isTestnet: Boolean(network.isTestnet), address, proxyApiUrl });\n const transactions = rawTransactions\n .map(({ txHash, tx }) => {\n if (!tx.meta) {\n return null;\n }\n\n const {\n meta,\n transaction: { message },\n } = tx;\n // Typings are wrong here, .toString() fixes it without unnecessary casting\n const addresses = message.accountKeys.map((acc) => acc.toString());\n const accountIndex = addresses.indexOf(address);\n\n // accountKeys property is sorted in Solana transactions. The signing keys\n // are always the first, and the header.numRequiredSignatures tells us how many\n // of the first keys are signers. If the lookup address is a signer, it has to be\n // one of the first N keys.\n const isSigner = accountIndex < message.header.numRequiredSignatures;\n\n const transfers = extractTokenTranfers(\n addresses,\n accountIndex,\n {\n paidFee: isSigner ? Number(meta.fee) : 0,\n preBalances: meta.preBalances.map(Number),\n postBalances: meta.postBalances.map(Number),\n preTokenBalances: (meta.preTokenBalances ?? []).map(simplifyTokenBalance),\n postTokenBalances: (meta.postTokenBalances ?? []).map(simplifyTokenBalance),\n },\n network,\n );\n\n return {\n hash: txHash,\n // We should probably be smarter about the tx type, but this should be enough for MVP\n txType: inferTxType(transfers, address),\n gasUsed: String(tx.meta.computeUnitsConsumed ?? '0'),\n tokens: transfers,\n\n // Get to/from addresses from the token transfers if possible.\n // If not possible:\n // - default \"from\" to the signing address\n // - default \"to\" to our address if we're not the signer and leave empty if we don't know.\n from: transfers[0]?.from?.address ?? (addresses[0] as string),\n to: transfers[0]?.to?.address ?? (isSigner ? '' : address),\n isOutgoing: isSigner,\n isIncoming: !isSigner,\n isSender: isSigner,\n timestamp: Number(tx.blockTime) * 1000,\n isContractCall: false,\n gasPrice: String(Number(tx.meta.fee) / Number(tx.meta.computeUnitsConsumed)),\n chainId: String(network.chainId),\n explorerLink: getExplorerLink(txHash, network.explorerUrl),\n };\n })\n .filter(<T>(tx: T): tx is NonNullable<T> => tx !== null);\n\n return {\n transactions,\n };\n}\n\nconst inferTxType = (transfers: TxToken[], address: string) => {\n const isSoleSender = transfers.every((t) => t.from?.address === address);\n\n if (isSoleSender) {\n return TransactionType.SEND;\n }\n\n const isSoleReceiver = transfers.every((t) => t.to?.address === address);\n\n if (isSoleReceiver) {\n return TransactionType.RECEIVE;\n }\n\n const isBothSenderAndReceiver =\n transfers.some((t) => t.from?.address === address) && transfers.some((t) => t.to?.address === address);\n\n if (isBothSenderAndReceiver) {\n return TransactionType.SWAP;\n }\n\n return TransactionType.UNKNOWN;\n};\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport { TokenType, type Network, type SPLToken, type TxToken } from '@avalabs/vm-module-types';\nimport type { TokenBalance } from '@solana/kit';\n\nexport const simplifyTokenBalance = (balance: TokenBalance): SimpleTokenBalance => ({\n mint: balance.mint as string,\n owner: balance.owner as string,\n amount: BigInt(balance.uiTokenAmount.amount),\n decimals: balance.uiTokenAmount.decimals,\n});\n\nexport const extractTokenTranfers: ExtractTransferFn<'SPL'> = (addresses, accountIndex, meta, network): TxToken[] => {\n // Create a map of initial balances\n const preBalances: Record<string, bigint> = meta.preTokenBalances.reduce(\n (acc, { owner, mint, amount }) => ({\n ...acc,\n [`${owner}-${mint}`]: amount,\n }),\n {},\n );\n\n // Compare with post balances to determine transfers\n const transfers = meta.postTokenBalances.reduce((acc, { owner, mint, amount, decimals }) => {\n const key = `${owner}-${mint}`;\n const preAmount = preBalances[key] ?? 0n;\n const netChange = amount - preAmount;\n\n if (netChange <= 0n) {\n return acc;\n }\n\n // Find sender (the one whose balance decreased)\n const sender = Object.keys(preBalances).find((k) => {\n const [possibleSender, mintFromPreBalance] = k.split('-');\n const possibleSenderPostBalance = meta.postTokenBalances.find(\n ({ owner: postBalanceOwner, mint: postBalanceMint }) =>\n postBalanceOwner === possibleSender && postBalanceMint === mint,\n );\n\n return (\n mintFromPreBalance === mint && possibleSenderPostBalance && preBalances[k]! > possibleSenderPostBalance.amount\n );\n });\n\n if (!sender) {\n return acc;\n }\n\n const token =\n network.tokens?.filter((t): t is SPLToken => 'contractType' in t).find((t) => t.address === mint) ??\n ({\n contractType: TokenType.SPL,\n decimals,\n address: mint,\n symbol: 'Unknown',\n name: 'Unknown',\n } as SPLToken);\n const transfer: TxToken = {\n ...token,\n type: token.contractType,\n from: {\n ...token,\n address: sender.split('-')[0]!,\n },\n to: {\n ...token,\n address: owner,\n },\n amount: new TokenUnit(netChange, decimals, '').toDisplay(),\n };\n\n return [...acc, transfer];\n }, [] as TxToken[]);\n\n const nativeTransfer = extractNativeTransfer(addresses, accountIndex, meta, network);\n\n if (nativeTransfer) {\n transfers.push(nativeTransfer);\n }\n\n return transfers;\n};\n\nconst extractNativeTransfer: ExtractTransferFn<'native'> = (\n addresses,\n accountIndex,\n { paidFee, preBalances, postBalances },\n network,\n) => {\n const address = addresses[accountIndex]!;\n const nativeBalancePre = preBalances[accountIndex]!;\n const nativeBalancePost = postBalances[accountIndex]!;\n const nativeTransferAmount =\n nativeBalancePost !== nativeBalancePre ? nativeBalancePost - nativeBalancePre + paidFee : 0;\n const balanceDiffs = postBalances.map((b, i) => b - preBalances[i]!);\n\n if (!nativeTransferAmount) {\n return null;\n }\n\n const isIncoming = nativeTransferAmount > 0;\n const unit = new TokenUnit(Math.abs(nativeTransferAmount), network.networkToken.decimals, '');\n // If it's an incoming transaction, we assume it came from the transaction signer.\n // It it's an outgoing transaction, we need to find the address that received the largest amount (since we only display one address).\n const largestBeneficiary = balanceDiffs.reduce(\n ({ index, change }, netChange, i) => {\n if (netChange > change) {\n return { index: i, change: netChange };\n }\n\n return { index, change };\n },\n { index: 0, change: balanceDiffs[0]! },\n );\n\n const otherAddressIndex = isIncoming ? 0 : largestBeneficiary.index;\n\n return {\n amount: unit.toDisplay(),\n from: {\n address: isIncoming ? addresses[otherAddressIndex]! : address,\n },\n to: {\n address: isIncoming ? address : addresses[otherAddressIndex]!,\n },\n name: network.networkToken.name,\n symbol: network.networkToken.symbol,\n type: TokenType.NATIVE,\n };\n};\n\ntype SimpleTokenBalance = {\n mint: string;\n owner: string;\n amount: bigint;\n decimals: number;\n};\n\ntype TxMeta = {\n paidFee: number;\n // Native SOL balances\n preBalances: number[];\n postBalances: number[];\n // SPL tokens balances\n preTokenBalances: SimpleTokenBalance[];\n postTokenBalances: SimpleTokenBalance[];\n};\n\ntype ExtractTransferFn<Type extends 'native' | 'SPL'> = (\n addresses: string[],\n accountIndex: number,\n meta: TxMeta,\n network: Network,\n) => Type extends 'native' ? TxToken | null : TxToken[];\n","import { address as solAddress, type GetTransactionApi } from '@solana/kit';\n\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { hasPropertyDefined } from '@src/utils/has-property-defined';\n\ntype ParsedTx = ReturnType<GetTransactionApi['getTransaction']>;\ntype WrappedTransaction = { txHash: string; tx: NonNullable<ParsedTx> };\n\nexport const getWrappedTransactions = async ({\n isTestnet,\n address,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n address: string;\n proxyApiUrl: string;\n}): Promise<WrappedTransaction[]> => {\n const provider = getProvider({ isTestnet, proxyApiUrl });\n\n const signaturesResponse = await provider.getSignaturesForAddress(solAddress(address), { limit: 25 }).send(); // Same as we do for Bitcoin\n const signatures = signaturesResponse.map((sig) => sig.signature);\n const txsRequests = await Promise.allSettled(\n signatures.map(async (sig) => ({\n txHash: sig.toString(),\n tx: await provider.getTransaction(sig, { encoding: 'json', maxSupportedTransactionVersion: 0 }).send(),\n })),\n );\n\n return txsRequests\n .filter(isFulfilled)\n .map((tx) => tx.value)\n .filter(hasPropertyDefined('tx'));\n};\n","export function hasPropertyDefined<T, K extends keyof T>(key: K) {\n return (thing: T): thing is T & Record<K, NonNullable<unknown>> => Boolean(thing[key]);\n}\n","export const getExplorerLink = (txHash: string, baseUrl?: string) => {\n const explorerLink = baseUrl ? new URL(baseUrl) : null;\n\n // Keep the query params in-tact: the Solana explorers like SolScan.io or explorer.solana.com\n // switch between clusters based on the `cluster` query param, not the domain.\n if (explorerLink) {\n explorerLink.pathname = `/tx/${txHash}`;\n }\n\n return explorerLink?.toString() ?? '';\n};\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { type Base64EncodedWireTransaction } from '@solana/kit';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { getNetworkName } from '@src/utils/get-network-name';\nimport { explainTransaction } from '@src/utils/explain/explain-transaction';\n\nimport { parseRequestParams, type SendOptions } from './schema';\n\nexport const signAndSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedTx, sendOptions }] = data;\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { details, isSimulationSuccessful, alert, balanceChange } = await explainTransaction({\n simulationParams: {\n dAppUrl: request.dappInfo.url,\n params: {\n account,\n chain: getNetworkName(network),\n transactionBase64: serializedTx,\n },\n proxyApiUrl,\n },\n network,\n provider,\n });\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details,\n alert,\n balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION,\n account,\n data: serializedTx,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response, sendOptions);\n } catch (error) {\n console.error(error);\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (\n provider: ReturnType<typeof getProvider>,\n response: SigningResult,\n sendOptions?: SendOptions,\n) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n // broadcast the signed transaction\n const txHash = await provider\n .sendTransaction(response.signedData as Base64EncodedWireTransaction, {\n ...sendOptions,\n encoding: 'base64',\n })\n .send();\n return txHash;\n};\n","import {\n AlertType,\n type Alert,\n type BalanceChange,\n type DetailSection,\n type Network,\n type TransactionSimulationResult,\n} from '@avalabs/vm-module-types';\n\nimport type { getProvider } from '../get-provider';\nimport { transactionAlerts } from '../transaction-alerts';\n\nimport type { ExplainTxParams } from './types';\nimport { parseTransaction } from './parse-transaction';\nimport { processBalanceChange } from './blockaid/process-balance-change';\nimport { scanSolanaTransaction } from './blockaid/scan-solana-transaction';\nimport { addressItem, dataItem } from '@internal/utils';\nimport { addressListItem } from '@internal/utils/src/utils/detail-item';\n\nexport const explainTransaction = async ({\n simulationParams,\n network,\n provider,\n}: {\n simulationParams: ExplainTxParams;\n network: Network;\n provider: ReturnType<typeof getProvider>;\n}): Promise<TransactionSimulationResult & { details: DetailSection[] }> => {\n const { params } = simulationParams;\n const scanResponse = await scanSolanaTransaction(simulationParams);\n const { simulation, validation } = scanResponse?.result ?? {};\n const genericDetails: DetailSection = {\n title: 'Transaction Details',\n items: [dataItem('Raw Data', simulationParams.params.transactionBase64)],\n };\n const details: DetailSection[] = [genericDetails];\n\n let isSimulationSuccessful = false;\n let balanceChange: BalanceChange | undefined;\n let alert: Alert | undefined;\n\n if (!validation || validation.result_type === 'Warning') {\n alert = transactionAlerts[AlertType.WARNING];\n } else if (validation.result_type === 'Malicious') {\n alert = transactionAlerts[AlertType.DANGER];\n }\n\n if (simulation) {\n const { balanceChange: processedBalanceChange, otherAffectedAddresses } = processBalanceChange(\n params.account,\n simulation,\n network,\n );\n balanceChange = processedBalanceChange;\n if (otherAffectedAddresses.length > 0) {\n // If there is one other affected address, we label the user's address as \"From\" and the other address as \"To\".\n // If there are more than 1 affected addresses, we label the user's address as \"Account\" and the others as \"Interacting with\".\n genericDetails.items.push(addressItem(otherAffectedAddresses.length === 1 ? 'From' : 'Account', params.account));\n genericDetails.items.push(\n otherAffectedAddresses.length === 1\n ? addressItem('To', otherAffectedAddresses[0]!)\n : addressListItem('Interacting with', otherAffectedAddresses),\n );\n } else {\n // Make sure to always show the user's address in the details.\n genericDetails.items.push(addressItem('Account', params.account));\n }\n isSimulationSuccessful = true;\n } else {\n // If Blockaid simulation fails, we fall back to parsing the transaction manually.\n const { balanceChange: parsedBalanceChange, details: parsedDetails } = await parseTransaction(\n params.transactionBase64,\n params.account,\n network,\n provider,\n );\n balanceChange = parsedBalanceChange;\n details.push(...parsedDetails);\n }\n\n return {\n isSimulationSuccessful,\n details,\n alert,\n balanceChange,\n };\n};\n","import { AlertType } from '@avalabs/vm-module-types';\n\nexport const transactionAlerts = {\n [AlertType.WARNING]: {\n type: AlertType.WARNING,\n details: {\n title: 'Suspicious Transaction',\n description: 'Use caution, this transaction may be malicious.',\n },\n },\n [AlertType.DANGER]: {\n type: AlertType.DANGER,\n details: {\n title: 'Scam Transaction',\n description: 'This transaction is malicious, do not proceed.',\n actionTitles: {\n reject: 'Reject Transaction',\n proceed: 'Proceed Anyway',\n },\n },\n },\n};\n","import type { BalanceChange, Network, SPLToken } from '@avalabs/vm-module-types';\nimport { deserializeTransactionMessage } from '@avalabs/core-wallets-sdk';\n\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { isNotNullish } from '../functional';\nimport type { getProvider } from '../get-provider';\nimport { tryToParseSolTransfer } from './instruction-parsers/sol-transfer';\nimport { tryToParseSPLTransfer } from './instruction-parsers/spl-transfer';\n\nexport const parseTransaction = async (\n serializedTx: string,\n account: string,\n network: Network,\n provider: ReturnType<typeof getProvider>,\n) => {\n const transaction = await deserializeTransactionMessage(serializedTx, provider);\n const balanceChange: BalanceChange = {\n ins: [],\n outs: [],\n };\n\n const details = await Promise.allSettled(\n transaction.instructions.map(async (instruction) => {\n return (\n tryToParseSolTransfer(instruction, balanceChange, account, network.networkToken) ??\n (await tryToParseSPLTransfer(provider, instruction, balanceChange, account, network.tokens as SPLToken[])) ??\n null\n );\n }),\n ).then((results) =>\n results\n .filter(isFulfilled)\n .map((result) => result.value)\n .filter(isNotNullish),\n );\n\n return {\n balanceChange,\n details,\n };\n};\n","import type { BalanceChange } from '@avalabs/vm-module-types';\n\nexport function isBalanceChangeEmpty(input: BalanceChange): boolean {\n return input.ins.length === 0 && input.outs.length === 0;\n}\n\nexport function isNotNullish<I>(input: I): input is NonNullable<I> {\n return input !== null && input !== undefined;\n}\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { BalanceChange, DetailSection, NetworkToken } from '@avalabs/vm-module-types';\nimport {\n identifySystemInstruction,\n parseTransferSolInstruction,\n SYSTEM_PROGRAM_ADDRESS,\n SystemInstruction,\n} from '@solana-program/system';\nimport {\n isInstructionForProgram,\n isInstructionWithAccounts,\n isInstructionWithData,\n type IInstruction,\n} from '@solana/kit';\n\nimport { addressItem } from '@internal/utils';\n\nexport const tryToParseSolTransfer = (\n instruction: IInstruction,\n balanceChange: BalanceChange,\n account: string,\n networkToken: NetworkToken,\n): DetailSection | null => {\n if (\n !isInstructionForProgram(instruction, SYSTEM_PROGRAM_ADDRESS) ||\n !isInstructionWithAccounts(instruction) ||\n !isInstructionWithData(instruction)\n ) {\n return null;\n }\n\n try {\n const systemInstruction = identifySystemInstruction(instruction);\n\n if (systemInstruction !== SystemInstruction.TransferSol) {\n return null;\n }\n\n const { accounts, data } = parseTransferSolInstruction({\n ...instruction,\n data: Uint8Array.from(instruction.data), // Fixing the typings here to satisfy parseTransferSolInstruction()\n });\n\n const isOutgoing = accounts.source.address === account;\n const balanceChangeKey = isOutgoing === true ? 'outs' : 'ins';\n\n balanceChange[balanceChangeKey].push({\n token: {\n ...networkToken,\n address: '',\n },\n items: [\n {\n displayValue: new TokenUnit(data.amount, networkToken.decimals, '').toString(),\n usdPrice: undefined,\n },\n ],\n });\n\n return {\n title: 'Transfer SOL',\n items: [addressItem('From', accounts.source.address), addressItem('To', accounts.destination.address)],\n };\n } catch {\n return null;\n }\n};\n","import { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { SolanaProvider } from '@avalabs/core-wallets-sdk';\nimport type { BalanceChange, DetailSection, SPLToken } from '@avalabs/vm-module-types';\nimport { parseTransferInstruction, identifyTokenInstruction, TokenInstruction } from '@solana-program/token';\nimport { isInstructionWithAccounts, isInstructionWithData, type Address, type IInstruction } from '@solana/kit';\n\nimport { addressItem } from '@internal/utils';\n\nconst getTokenMintFromAccountInfo = async (provider: SolanaProvider, account: Address): Promise<string | null> => {\n try {\n const tokenAccountDetails = await provider.getAccountInfo(account, { encoding: 'jsonParsed' }).send();\n\n if (Array.isArray(tokenAccountDetails.value?.data)) {\n return null;\n }\n\n const info = tokenAccountDetails.value?.data.parsed.info as Record<string, unknown>;\n return typeof info?.mint === 'string' ? info.mint : null;\n } catch {\n return null;\n }\n};\n\nexport const tryToParseSPLTransfer = async (\n provider: SolanaProvider,\n instruction: IInstruction,\n balanceChange: BalanceChange,\n account: string,\n tokens?: SPLToken[],\n): Promise<DetailSection | null> => {\n if (!tokens?.length || !isInstructionWithAccounts(instruction) || !isInstructionWithData(instruction)) {\n return null;\n }\n\n try {\n const tokenInstruction = identifyTokenInstruction(instruction);\n\n if (tokenInstruction !== TokenInstruction.Transfer) {\n return null;\n }\n\n const { accounts, data } = parseTransferInstruction({\n ...instruction,\n data: Uint8Array.from(instruction.data), // Fixing the typings here to satisfy parseTransferInstruction()\n });\n const tokenMint = await getTokenMintFromAccountInfo(provider, accounts.source.address);\n\n if (!tokenMint) {\n return null;\n }\n\n const token = tokens.find((t) => t.address.toLowerCase() === tokenMint.toLowerCase());\n\n if (!token) {\n return null;\n }\n\n const isOutgoing = accounts.source.address === account || accounts.authority.address === account;\n const balanceChangeKey = isOutgoing === true ? 'outs' : 'ins';\n\n balanceChange[balanceChangeKey].push({\n token,\n items: [\n {\n displayValue: new TokenUnit(data.amount, token.decimals, '').toString(),\n usdPrice: undefined,\n },\n ],\n });\n\n return {\n title: `Transfer ${token.symbol}`,\n items: [addressItem('From', accounts.source.address), addressItem('To', accounts.destination.address)],\n };\n } catch {\n return null;\n }\n};\n","import type Blockaid from '@blockaid/client';\nimport {\n TokenType,\n type BalanceChange,\n type Network,\n type NetworkToken,\n type SPLToken,\n type TokenDiff,\n} from '@avalabs/vm-module-types';\n\n// Simplify access to Blockaid's typings\ntype SolanaSimulation = Blockaid.Solana.MessageScanResponse.Result.Simulation;\ntype AccountSummaryAssetDiff = SolanaSimulation['account_summary']['account_assets_diff'];\ntype SolanaSimulationAsset = Exclude<AccountSummaryAssetDiff, undefined>[number]['asset'];\n\nexport const processBalanceChange = (\n account: string,\n simulationResult: Blockaid.Solana.Message.MessageScanResponse.Result.Simulation,\n network: Network,\n): { balanceChange: BalanceChange; otherAffectedAddresses: string[] } => {\n const transferedAssets = simulationResult.account_summary.account_assets_diff ?? [];\n\n const inTokenDiffDict: Record<string, TokenDiff> = {};\n const outTokenDiffDict: Record<string, TokenDiff> = {};\n\n const otherAffectedAddresses: string[] = Object.keys(simulationResult.assets_diff ?? {}).filter(\n (key) => key !== account,\n );\n\n transferedAssets.forEach(({ asset, in: assetIn, out: assetOut }) => {\n const token = convertDiffAssetToToken(asset, network);\n\n if (!token) {\n return;\n }\n\n const identifier = 'address' in token ? token.address : token.symbol;\n\n if (assetIn) {\n if (!inTokenDiffDict[identifier]) {\n inTokenDiffDict[identifier] = {\n token,\n items: [],\n };\n }\n\n inTokenDiffDict[identifier].items.push({\n displayValue: String(assetIn.value),\n usdPrice: typeof assetIn.usd_price === 'number' ? String(assetIn.usd_price) : undefined,\n });\n }\n\n if (assetOut) {\n if (!outTokenDiffDict[identifier]) {\n outTokenDiffDict[identifier] = {\n token,\n items: [],\n };\n }\n outTokenDiffDict[identifier].items.push({\n displayValue: String(assetOut.value),\n usdPrice: typeof assetOut.usd_price === 'number' ? String(assetOut.usd_price) : undefined,\n });\n }\n });\n\n return {\n balanceChange: {\n ins: Object.values(inTokenDiffDict),\n outs: Object.values(outTokenDiffDict),\n },\n otherAffectedAddresses,\n };\n};\n\nconst convertNativeAssetToToken = (\n asset: Blockaid.Solana.MessageScanResponse.Result.Simulation.SolanaNativeAssetDiff.Asset,\n): NetworkToken => {\n return {\n name: asset.type,\n symbol: asset.type, // It's either SOL or ETH according to types\n decimals: asset.decimals,\n description: '',\n logoUri: asset.logo ?? undefined,\n };\n};\n\nconst convertTokenAssetToToken = (\n asset: Blockaid.Solana.MessageScanResponse.Result.Simulation.SolanaSplFungibleAssetDiff.Asset,\n network: Network,\n): SPLToken => ({\n type: TokenType.SPL,\n address: asset.address,\n caip2Id: network.caipId ?? '',\n contractType: TokenType.SPL,\n decimals: asset.decimals,\n name: asset.name,\n symbol: asset.symbol,\n logoUri: asset.logo || undefined,\n});\n\nconst convertDiffAssetToToken = (asset: SolanaSimulationAsset, network: Network): SPLToken | NetworkToken | null => {\n if (asset.type === 'TOKEN') {\n return convertTokenAssetToToken(asset, network);\n }\n\n if (asset.type === 'SOL' || asset.type === 'ETH') {\n return convertNativeAssetToToken(asset);\n }\n\n return null;\n};\n","import Blockaid from '@blockaid/client';\nimport { base58, base64 } from '@scure/base';\n\nimport type { ExplainTxParams } from '../types';\n\nconst DUMMY_API_KEY = 'DUMMY_API_KEY'; // since we're using our own proxy and api key is handled there, we can use a dummy key here\n\nexport const scanSolanaTransaction = async ({\n proxyApiUrl,\n params,\n dAppUrl,\n}: ExplainTxParams): Promise<Blockaid.Solana.Message.MessageScanResponse | null> => {\n const blockaid = new Blockaid({\n baseURL: proxyApiUrl + '/proxy/blockaid/',\n apiKey: DUMMY_API_KEY,\n });\n\n try {\n return await blockaid.solana.message.scan({\n chain: params.chain,\n options: ['simulation', 'validation'],\n encoding: 'base64',\n metadata: {\n url: dAppUrl,\n },\n transactions: [params.transactionBase64],\n // We need to encode the account address to base64 as well\n account_address: base64.encode(base58.decode(params.account)),\n });\n } catch (err) {\n console.error('solana.message.scan() error', err);\n return null;\n }\n};\n","import { z } from 'zod';\n\nconst transactionSchema = z.object({\n account: z.string(),\n serializedTx: z.string().base64(),\n sendOptions: z\n .object({\n preflightCommitment: z.enum(['processed', 'confirmed', 'finalized']).optional(),\n maxRetries: z.bigint().optional(),\n minContextSlot: z.bigint().optional(),\n skipPreflight: z.boolean().optional(),\n })\n .optional(),\n});\n\nconst paramsSchema = z.tuple([transactionSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type TransactionParams = z.infer<typeof transactionSchema>;\nexport type SendOptions = z.infer<typeof transactionSchema>['sendOptions'];\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n} from '@avalabs/vm-module-types';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { isBalanceChangeEmpty } from '@src/utils/functional';\nimport { getNetworkName } from '@src/utils/get-network-name';\nimport { explainTransaction } from '@src/utils/explain/explain-transaction';\n\nimport { parseRequestParams } from './schema';\n\nexport const signTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedTx }] = data;\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { details, isSimulationSuccessful, alert, balanceChange } = await explainTransaction({\n simulationParams: {\n dAppUrl: request.dappInfo.url,\n params: {\n account,\n chain: getNetworkName(network),\n transactionBase64: serializedTx,\n },\n proxyApiUrl,\n },\n network,\n provider,\n });\n\n const displayData: DisplayData = {\n title: 'Sign Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details,\n alert,\n balanceChange: balanceChange && isBalanceChangeEmpty(balanceChange) ? undefined : balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_TRANSACTION,\n account,\n data: serializedTx,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n if (!('signedData' in response)) {\n return {\n error: rpcErrors.invalidRequest('No signed data returned'),\n };\n }\n\n return { result: response.signedData };\n};\n","import { z } from 'zod';\n\nconst transactionSchema = z.object({\n account: z.string(),\n serializedTx: z.string().base64(),\n});\n\nconst paramsSchema = z.tuple([transactionSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type TransactionParams = z.infer<typeof transactionSchema>;\n","import { rpcErrors } from '@metamask/rpc-errors';\nimport {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n} from '@avalabs/vm-module-types';\nimport { base64 } from '@scure/base';\n\nimport { addressItem, dataItem, textItem } from '@internal/utils';\n\nimport { parseRequestParams } from './schema';\n\nexport const signMessage = async ({\n request,\n network,\n approvalController,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n}) => {\n const { params } = request;\n const { data, success, error } = parseRequestParams(params);\n\n if (!success) {\n console.error('invalid params', error);\n return {\n error: rpcErrors.invalidParams({ message: 'Message signing params are invalid', data: { cause: error } }),\n };\n }\n\n const [{ account, serializedMessage }] = data;\n\n const utf8Decoder = new TextDecoder();\n const displayData: DisplayData = {\n title: 'Sign Message',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n dAppInfo: {\n name: request.dappInfo.name,\n action: `${request.dappInfo.name} wants you to sign the following message`,\n logoUri: request.dappInfo.icon,\n },\n disclaimer: 'Only confirm if you trust this website',\n details: [\n {\n title: 'Message Details',\n items: [\n addressItem('Account', account),\n textItem('Message', utf8Decoder.decode(base64.decode(serializedMessage))),\n dataItem('Raw Message (Base-64)', serializedMessage),\n ],\n },\n ],\n networkFeeSelector: false,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.SOLANA_SIGN_MESSAGE,\n account,\n data: serializedMessage,\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n if (!('signedData' in response)) {\n return {\n error: rpcErrors.invalidRequest('No signed data returned'),\n };\n }\n\n return { result: response.signedData };\n};\n","import { base64 } from '@scure/base';\nimport { getCompiledTransactionMessageDecoder } from '@solana/kit';\n\nexport const isTransactionBytes = (base64Payload: string): boolean => {\n try {\n const bytes = base64.decode(base64Payload);\n const decoder = getCompiledTransactionMessageDecoder();\n decoder.decode(bytes);\n return true;\n } catch {\n return false;\n }\n};\n","import { isTransactionBytes } from '@src/utils/is-transaction-bytes';\nimport { z } from 'zod';\n\nconst signMessageSchema = z\n .object({\n account: z.string(),\n serializedMessage: z.string().base64(),\n })\n .refine(({ serializedMessage }) => !isTransactionBytes(serializedMessage), {\n message: 'Cannot use signMessage() calls for signing transactions',\n });\n\nconst paramsSchema = z.tuple([signMessageSchema]);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type SignMessageParams = z.infer<typeof signMessageSchema>;\n"]}
|