@avalabs/svm-module 1.4.6 → 1.6.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/chunk-7VP42LRT.js +5 -0
- package/dist/chunk-7VP42LRT.js.map +1 -0
- package/dist/chunk-TKL4UUHE.cjs +11 -0
- package/dist/chunk-TKL4UUHE.cjs.map +1 -0
- package/dist/index.cjs +11 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -12
- package/dist/index.d.ts +29 -12
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/provider/index.cjs +22 -0
- package/dist/provider/index.cjs.map +1 -0
- package/dist/provider/index.d.cts +110 -0
- package/dist/provider/index.d.ts +110 -0
- package/dist/provider/index.js +15 -0
- package/dist/provider/index.js.map +1 -0
- package/manifest.json +12 -2
- package/package.json +17 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/module.ts","../manifest.json","../src/env.ts"],"names":["parseManifest","rpcErrors","manifest_default","Environment","prodEnv","devEnv","getEnv","environment","_proxyApiUrl","_approvalController","_appInfo","SvmModule","approvalController","appInfo","__privateAdd","proxyApiUrl","__privateSet","__privateGet","result","request"],"mappings":"mVAAA,OACE,iBAAAA,MAOK,2BACP,MAAkD,cAClD,OAAS,aAAAC,MAAiB,uBCV1B,IAAAC,EAAA,CACE,KAAQ,MACR,YAAe,GACf,QAAW,QACX,QAAW,CACT,OAAU,CACR,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,gBACZ,YAAe,sBACf,SAAY,4BACd,CACF,CACF,CACF,EACA,QAAW,CACT,SAAY,CACV,0CACA,0CACA,yCACF,EACA,WAAc,CAAC,QAAQ,CACzB,EACA,SAAY,MACZ,YAAe,CACb,IAAO,CACL,MAAS,GACT,QAAW,CAAC,gBAAgB,EAC5B,qBAAwB,CAAC,gBAAgB,CAC3C,CACF,EACA,gBAAmB,KACrB,ECjCA,OAAS,eAAAC,MAAmB,2BAMrB,IAAMC,EAAe,CAC1B,YAAa,gCACf,EAEaC,EAAc,CACzB,YAAa,oCACf,EAEaC,EAAUC,GAAkC,CACvD,OAAQA,EAAa,CACnB,KAAKJ,EAAY,WACf,OAAOC,EACT,KAAKD,EAAY,IACf,OAAOE,CACX,CACF,EFrBA,IAAAG,EAAAC,EAAAC,EAeaC,EAAN,KAAkC,CAKvC,YAAY,CAAE,mBAAAC,EAAoB,YAAAL,EAAa,QAAAM,CAAQ,EAAsB,CAJ7EC,EAAA,KAAAN,EAAA,QACAM,EAAA,KAAAL,EAAA,QACAK,EAAA,KAAAJ,EAAA,QAGE,GAAM,CAAE,YAAAK,CAAY,EAAIT,EAAOC,CAAW,EAE1CS,EAAA,KAAKN,EAAWG,GAChBG,EAAA,KAAKR,EAAeO,GACpBC,EAAA,KAAKP,EAAsBG,GAI3BK,EAAA,KAAKT,GACLS,EAAA,KAAKR,GACLQ,EAAA,KAAKP,EACP,CAGA,aAAc,CACZ,OAAO,QAAQ,QAAQ,CAAC,CAA4B,CACtD,CAGA,YAAa,CACX,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAGA,aAAc,CACZ,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAEA,aAAc,CACZ,IAAMQ,EAASlB,EAAcE,CAAY,EACzC,OAAOgB,EAAO,QAAUA,EAAO,KAAO,MACxC,CAGA,eAAgB,CACd,OAAO,QAAQ,QAAQ,CAAC,CAAgB,CAC1C,CAGA,uBAAwB,CACtB,OAAO,QAAQ,QAAQ,CACrB,aAAc,CAAC,CACjB,CAAC,CACH,CAGA,WAAY,CACV,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAGA,MAAM,aAAaC,EAAqB,CACtC,MAAO,CAAE,MAAOlB,EAAU,mBAAmB,UAAUkB,EAAQ,MAAM,gBAAgB,CAAE,CACzF,CACF,EA3DEX,EAAA,YACAC,EAAA,YACAC,EAAA","sourcesContent":["import {\n parseManifest,\n type AppInfo,\n type ApprovalController,\n type ConstructorParams,\n type Module,\n type NetworkFees,\n type RpcRequest,\n} from '@avalabs/vm-module-types';\nimport { type Rpc, type SolanaRpcApiDevnet } from '@solana/rpc';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport ManifestJson from '../manifest.json';\nimport { getEnv } from './env';\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 // TODO\n getProvider() {\n return Promise.resolve({} as Rpc<SolanaRpcApiDevnet>);\n }\n\n // TODO\n getAddress() {\n return Promise.resolve({});\n }\n\n // TODO\n getBalances() {\n return Promise.resolve({});\n }\n\n getManifest() {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n // TODO\n getNetworkFee() {\n return Promise.resolve({} as NetworkFees);\n }\n\n // TODO\n getTransactionHistory() {\n return Promise.resolve({\n transactions: [],\n });\n }\n\n // TODO\n getTokens() {\n return Promise.resolve([]);\n }\n\n // TODO\n async onRpcRequest(request: RpcRequest) {\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\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 },\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\": [\"getGenesisHash\"],\n \"nonRestrictedMethods\": [\"getGenesisHash\"]\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"]}
|
|
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/functional.ts","../src/utils/instruction-parsers/sol-transfer.ts","../src/utils/instruction-parsers/spl-transfer.ts","../src/handlers/sign-and-send-transaction/schema.ts","../src/handlers/sign-transaction/sign-transaction.ts","../src/handlers/sign-transaction/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","addressItem","label","value","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","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","transactionSchema","paramsSchema","parseRequestParams","signAndSendTransaction","request","success","serializedTx","sendOptions","transaction","details","results","displayData","signingData","getTxHash","signTransaction","_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';\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 }\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} 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 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\"],\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),\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 BalanceChange,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n type SPLToken,\n} from '@avalabs/vm-module-types';\nimport { deserializeTransactionMessage } from '@avalabs/core-wallets-sdk';\nimport { type Base64EncodedWireTransaction } from '@solana/kit';\n\nimport { dataItem } from '@internal/utils/src/utils/detail-item';\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { isBalanceChangeEmpty, isNotNullish } from '@src/utils/functional';\nimport { tryToParseSolTransfer } from '@src/utils/instruction-parsers/sol-transfer';\nimport { tryToParseSPLTransfer } from '@src/utils/instruction-parsers/spl-transfer';\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 transaction = await deserializeTransactionMessage(serializedTx, provider);\n const balanceChange: BalanceChange = {\n ins: [],\n outs: [],\n };\n\n // TODO: simulate transaction with Blockaid. Parsing like below can be used as a fallback.\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 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 {\n title: 'Transaction Details',\n items: [dataItem('Raw Data', serializedTx)],\n },\n ...details,\n ],\n balanceChange: isBalanceChangeEmpty(balanceChange) ? undefined : balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful: false,\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 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, 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) => {\n if (\n !isInstructionForProgram(instruction, SYSTEM_PROGRAM_ADDRESS) ||\n !isInstructionWithAccounts(instruction) ||\n !isInstructionWithData(instruction)\n ) {\n return;\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: 'Native Transfer',\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, 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) => {\n if (!tokens?.length || !isInstructionWithAccounts(instruction) || !isInstructionWithData(instruction)) {\n return;\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 { 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 BalanceChange,\n type DisplayData,\n type Network,\n type RpcRequest,\n type SigningData,\n type SPLToken,\n} from '@avalabs/vm-module-types';\nimport { deserializeTransactionMessage } from '@avalabs/core-wallets-sdk';\n\nimport { dataItem } from '@internal/utils/src/utils/detail-item';\nimport { isFulfilled } from '@internal/utils/src/utils/is-promise-fulfilled';\n\nimport { getProvider } from '@src/utils/get-provider';\nimport { isBalanceChangeEmpty, isNotNullish } from '@src/utils/functional';\nimport { tryToParseSolTransfer } from '@src/utils/instruction-parsers/sol-transfer';\nimport { tryToParseSPLTransfer } from '@src/utils/instruction-parsers/spl-transfer';\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 transaction = await deserializeTransactionMessage(serializedTx, provider);\n const balanceChange: BalanceChange = {\n ins: [],\n outs: [],\n };\n\n // TODO: simulate transaction with Blockaid. Parsing like below can be used as a fallback.\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 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 {\n title: 'Transaction Details',\n items: [dataItem('Raw Data', serializedTx)],\n },\n ...details,\n ],\n balanceChange: isBalanceChangeEmpty(balanceChange) ? undefined : balanceChange,\n networkFeeSelector: false,\n isSimulationSuccessful: false,\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"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkTKL4UUHE_cjs = require('../chunk-TKL4UUHE.cjs');
|
|
4
|
+
var un = require('events');
|
|
5
|
+
var vmModuleTypes = require('@avalabs/vm-module-types');
|
|
6
|
+
var base = require('@scure/base');
|
|
7
|
+
var walletStandardFeatures = require('@solana/wallet-standard-features');
|
|
8
|
+
var features = require('@wallet-standard/features');
|
|
9
|
+
var coreChainsSdk = require('@avalabs/core-chains-sdk');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var un__default = /*#__PURE__*/_interopDefault(un);
|
|
14
|
+
|
|
15
|
+
var x=o=>{let e=Buffer.from(base.base58.decode(o));return {get[Symbol.toStringTag](){return `PublicKey(${this.toString()})`},toBase58:()=>o,toBuffer:()=>e,toBytes:()=>e,toJSON:()=>o,toString:()=>o,equals:a=>o===a.toBase58(),encode:()=>e}};var u,m,K,O,M,Z=class extends un__default.default{constructor(t,{icon:a,version:r,name:c}){super();chunkTKL4UUHE_cjs.a(this,"publicKey",null);chunkTKL4UUHE_cjs.c(this,u,void 0);chunkTKL4UUHE_cjs.c(this,m,void 0);chunkTKL4UUHE_cjs.c(this,K,t=>{let a=t.find(({vm:r})=>r===vmModuleTypes.NetworkVMType.SVM)?.address;a?this.publicKey?(this.publicKey=x(a),this.emit("accountChanged")):(this.publicKey=x(a),this.emit("connect")):this.disconnect();});chunkTKL4UUHE_cjs.c(this,O,t=>({connect:this.connect,disconnect:this.disconnect,accountsChangedCA:chunkTKL4UUHE_cjs.b(this,K)})[t]??(()=>{}));chunkTKL4UUHE_cjs.c(this,M,({method:t,params:a})=>{let r=chunkTKL4UUHE_cjs.b(this,O).call(this,t);if(r)return r(a);this.emit(t,a);});chunkTKL4UUHE_cjs.d(this,m,{icon:a,name:c,version:r}),chunkTKL4UUHE_cjs.d(this,u,t),chunkTKL4UUHE_cjs.b(this,u).subscribeToMessage(chunkTKL4UUHE_cjs.b(this,M));}get info(){return chunkTKL4UUHE_cjs.b(this,m)}async connect({onlyIfTrusted:t}={}){if(this.publicKey)return {publicKey:this.publicKey};let[a]=await chunkTKL4UUHE_cjs.b(this,u).request({data:{method:"wallet_requestAccountPermission",params:{addressVM:vmModuleTypes.NetworkVMType.SVM,onlyIfTrusted:t}}});return this.publicKey=x(a),{publicKey:this.publicKey}}async disconnect(){this.publicKey=null,this.emit("disconnect");}async signAndSendTransaction(t,a,r,c){return await chunkTKL4UUHE_cjs.b(this,u).request({scope:a,data:{method:vmModuleTypes.RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION,params:[{account:t,serializedTx:r,sendOptions:c}]}})}async signTransaction(t,a,r){return await chunkTKL4UUHE_cjs.b(this,u).request({scope:a,data:{method:vmModuleTypes.RpcMethod.SOLANA_SIGN_TRANSACTION,params:[{account:t,serializedTx:r}]}})}async signAllTransactions(t,a,r){let c=[];for(let l of r){let j=await this.signTransaction(t,a,l);c.push(j);}return c}signMessage(){throw new Error("signMessage() not implemented.")}signIn(){throw new Error("signIn() not implemented.")}};u=new WeakMap,m=new WeakMap,K=new WeakMap,O=new WeakMap,M=new WeakMap;function nn(o){let e=({register:t})=>t(o);try{window.dispatchEvent(new z(e));}catch(t){console.error(`wallet-standard:register-wallet event could not be dispatched
|
|
16
|
+
`,t);}try{window.addEventListener("wallet-standard:app-ready",({detail:t})=>e(t));}catch(t){console.error(`wallet-standard:app-ready event listener could not be added
|
|
17
|
+
`,t);}}var S,z=class extends Event{constructor(t){super("wallet-standard:register-wallet",{bubbles:!1,cancelable:!1,composed:!1});chunkTKL4UUHE_cjs.c(this,S,void 0);chunkTKL4UUHE_cjs.d(this,S,t);}get detail(){return chunkTKL4UUHE_cjs.b(this,S)}get type(){return "wallet-standard:register-wallet"}preventDefault(){throw new Error("preventDefault cannot be called")}stopImmediatePropagation(){throw new Error("stopImmediatePropagation cannot be called")}stopPropagation(){throw new Error("stopPropagation cannot be called")}};S=new WeakMap;var tn="solana:mainnet",en="solana:devnet",an="solana:testnet",g=[tn,en,an],pn={[tn]:coreChainsSdk.SolanaCaip2ChainId.MAINNET,[en]:coreChainsSdk.SolanaCaip2ChainId.DEVNET,[an]:coreChainsSdk.SolanaCaip2ChainId.TESTNET};function P(o){return g.includes(o)}function _(o){return pn[o]}var mn=g,Sn=[walletStandardFeatures.SolanaSignAndSendTransaction,walletStandardFeatures.SolanaSignTransaction],y,w,E,T,A,b,U=class U{constructor({address:e,publicKey:t,label:a,icon:r}){chunkTKL4UUHE_cjs.c(this,y,void 0);chunkTKL4UUHE_cjs.c(this,w,void 0);chunkTKL4UUHE_cjs.c(this,E,void 0);chunkTKL4UUHE_cjs.c(this,T,void 0);chunkTKL4UUHE_cjs.c(this,A,void 0);chunkTKL4UUHE_cjs.c(this,b,void 0);new.target===U&&Object.freeze(this),chunkTKL4UUHE_cjs.d(this,y,e),chunkTKL4UUHE_cjs.d(this,w,t),chunkTKL4UUHE_cjs.d(this,E,mn),chunkTKL4UUHE_cjs.d(this,T,Sn),chunkTKL4UUHE_cjs.d(this,A,a),chunkTKL4UUHE_cjs.d(this,b,r);}get address(){return chunkTKL4UUHE_cjs.b(this,y)}get publicKey(){return chunkTKL4UUHE_cjs.b(this,w).slice()}get chains(){return chunkTKL4UUHE_cjs.b(this,E).slice()}get features(){return chunkTKL4UUHE_cjs.b(this,T).slice()}get label(){return chunkTKL4UUHE_cjs.b(this,A)}get icon(){return chunkTKL4UUHE_cjs.b(this,b)}};y=new WeakMap,w=new WeakMap,E=new WeakMap,T=new WeakMap,A=new WeakMap,b=new WeakMap;var L=U;function on(o,e){return yn(o,e)}function yn(o,e){if(o===e)return !0;let t=o.length;if(t!==e.length)return !1;for(let a=0;a<t;a++)if(o[a]!==e[a])return !1;return !0}var vn="connection:",p,V,h,s,k,v,J,F,rn,f,N,R,H,q,W,B,$=class ${constructor(e){chunkTKL4UUHE_cjs.c(this,v);chunkTKL4UUHE_cjs.c(this,F);chunkTKL4UUHE_cjs.c(this,p,{});chunkTKL4UUHE_cjs.c(this,V,"1.0.0");chunkTKL4UUHE_cjs.c(this,h,void 0);chunkTKL4UUHE_cjs.c(this,s,null);chunkTKL4UUHE_cjs.c(this,k,(e,t)=>(chunkTKL4UUHE_cjs.b(this,p)[e]??=[],chunkTKL4UUHE_cjs.b(this,p)[e]?.push(t),()=>chunkTKL4UUHE_cjs.e(this,F,rn).call(this,e,t)));chunkTKL4UUHE_cjs.c(this,f,()=>{let e=chunkTKL4UUHE_cjs.b(this,h).publicKey?.toBase58();if(e){let t=chunkTKL4UUHE_cjs.b(this,h).publicKey.toBytes(),a=chunkTKL4UUHE_cjs.b(this,s);(!a||a.address!==e||!on(a.publicKey,t))&&(chunkTKL4UUHE_cjs.d(this,s,new L({address:e,publicKey:t})),chunkTKL4UUHE_cjs.e(this,v,J).call(this,"change",{accounts:this.accounts}));}});chunkTKL4UUHE_cjs.c(this,N,()=>{chunkTKL4UUHE_cjs.b(this,s)&&(chunkTKL4UUHE_cjs.d(this,s,null),chunkTKL4UUHE_cjs.e(this,v,J).call(this,"change",{accounts:this.accounts}));});chunkTKL4UUHE_cjs.c(this,R,()=>{chunkTKL4UUHE_cjs.b(this,h).publicKey?chunkTKL4UUHE_cjs.b(this,f).call(this):chunkTKL4UUHE_cjs.b(this,N).call(this);});chunkTKL4UUHE_cjs.c(this,H,async({silent:e}={})=>(chunkTKL4UUHE_cjs.b(this,s)||await chunkTKL4UUHE_cjs.b(this,h).connect(e?{onlyIfTrusted:!0}:void 0),chunkTKL4UUHE_cjs.b(this,f).call(this),{accounts:this.accounts}));chunkTKL4UUHE_cjs.c(this,q,async()=>{await chunkTKL4UUHE_cjs.b(this,h).disconnect();});chunkTKL4UUHE_cjs.c(this,W,async(...e)=>{if(!chunkTKL4UUHE_cjs.b(this,s))throw new Error("not connected");let t=[];if(e.length===1){let{transaction:a,account:r,chain:c,options:l}=e[0],{minContextSlot:j,preflightCommitment:sn,skipPreflight:cn,maxRetries:ln}=l||{};if(r!==chunkTKL4UUHE_cjs.b(this,s))throw new Error("invalid account");if(!P(c))throw new Error("invalid chain");let dn=await chunkTKL4UUHE_cjs.b(this,h).signAndSendTransaction(chunkTKL4UUHE_cjs.b(this,s).address,_(c),base.base64.encode(a),{preflightCommitment:sn,minContextSlot:j,maxRetries:ln,skipPreflight:cn});t.push({signature:base.base58.decode(dn)});}else if(e.length>1)for(let a of e)t.push(...await chunkTKL4UUHE_cjs.b(this,W).call(this,a));return t});chunkTKL4UUHE_cjs.c(this,B,async(...e)=>{if(!chunkTKL4UUHE_cjs.b(this,s))throw new Error("not connected");let t=[];if(e.length===1){let{transaction:a,account:r,chain:c}=e[0];if(r!==chunkTKL4UUHE_cjs.b(this,s))throw new Error("invalid account");if(c&&!P(c))throw new Error("invalid chain");let l=await chunkTKL4UUHE_cjs.b(this,h).signTransaction(chunkTKL4UUHE_cjs.b(this,s).address,_(c||g[0]),base.base64.encode(a));t.push({signedTransaction:base.base64.decode(l)});}else if(e.length>1){let a;for(let l of e){if(l.account!==chunkTKL4UUHE_cjs.b(this,s))throw new Error("invalid account");if(l.chain){if(!P(l.chain))throw new Error("invalid chain");if(a){if(l.chain!==a)throw new Error("conflicting chain")}else a=l.chain;}}let r=e.map(({transaction:l})=>base.base64.encode(l)),c=await chunkTKL4UUHE_cjs.b(this,h).signAllTransactions(chunkTKL4UUHE_cjs.b(this,s).address,_(a||g[0]),r);t.push(...c.map(l=>({signedTransaction:base.base64.decode(l)})));}return t});new.target===$&&Object.freeze(this),chunkTKL4UUHE_cjs.d(this,h,e),e.on("connect",chunkTKL4UUHE_cjs.b(this,f),this),e.on("disconnect",chunkTKL4UUHE_cjs.b(this,N),this),e.on("accountChanged",chunkTKL4UUHE_cjs.b(this,R),this),chunkTKL4UUHE_cjs.b(this,f).call(this);}get version(){return chunkTKL4UUHE_cjs.b(this,V)}get walletVersion(){return chunkTKL4UUHE_cjs.b(this,h).info.version}get name(){return chunkTKL4UUHE_cjs.b(this,h).info.name}get icon(){return chunkTKL4UUHE_cjs.b(this,h).info.icon}get chains(){return g.slice()}get features(){return {[features.StandardConnect]:{version:"1.0.0",connect:chunkTKL4UUHE_cjs.b(this,H)},[features.StandardDisconnect]:{version:"1.0.0",disconnect:chunkTKL4UUHE_cjs.b(this,q)},[features.StandardEvents]:{version:"1.0.0",on:chunkTKL4UUHE_cjs.b(this,k)},[walletStandardFeatures.SolanaSignAndSendTransaction]:{version:"1.0.0",supportedTransactionVersions:["legacy",0],signAndSendTransaction:chunkTKL4UUHE_cjs.b(this,W)},[walletStandardFeatures.SolanaSignTransaction]:{version:"1.0.0",supportedTransactionVersions:["legacy",0],signTransaction:chunkTKL4UUHE_cjs.b(this,B)},[vn]:{connection:chunkTKL4UUHE_cjs.b(this,h)}}}get accounts(){return chunkTKL4UUHE_cjs.b(this,s)?[chunkTKL4UUHE_cjs.b(this,s)]:[]}};p=new WeakMap,V=new WeakMap,h=new WeakMap,s=new WeakMap,k=new WeakMap,v=new WeakSet,J=function(e,...t){chunkTKL4UUHE_cjs.b(this,p)[e]?.forEach(a=>a.apply(null,t));},F=new WeakSet,rn=function(e,t){chunkTKL4UUHE_cjs.b(this,p)[e]=chunkTKL4UUHE_cjs.b(this,p)[e]?.filter(a=>t!==a);},f=new WeakMap,N=new WeakMap,R=new WeakMap,H=new WeakMap,q=new WeakMap,W=new WeakMap,B=new WeakMap;var D=$;function Yn(o){nn(new D(o));}
|
|
18
|
+
|
|
19
|
+
exports.SolanaWalletProvider = Z;
|
|
20
|
+
exports.initialize = Yn;
|
|
21
|
+
//# sourceMappingURL=out.js.map
|
|
22
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/provider/provider.ts","../../src/provider/public-key.ts","../../src/provider/register.ts","../../src/provider/wallet.ts","../../src/provider/account.ts","../../src/provider/solana.ts","../../src/provider/util.ts","../../src/provider/initialize.ts"],"names":["EventEmitter","NetworkVMType","RpcMethod","base58","legacyPublicKey","address","byteArray","otherPubKey","_chainAgnosticProvider","_info","_accountsChanged","_getEventHandler","_handleBackgroundMessage","SolanaWalletProvider","chainAgnosticProvider","icon","version","name","__publicField","__privateAdd","accounts","vm","method","__privateGet","params","eventHandler","__privateSet","onlyIfTrusted","account","caipId","serializedTx","sendOptions","serializedTxs","results","tx","signedTx","registerWallet","wallet","callback","register","RegisterWalletEvent","error","api","_detail","SolanaSignAndSendTransaction","SolanaSignTransaction","StandardConnect","StandardDisconnect","StandardEvents","base64","SolanaCaip2ChainId","SOLANA_MAINNET_CHAIN","SOLANA_DEVNET_CHAIN","SOLANA_TESTNET_CHAIN","SOLANA_CHAINS","SOLANA_CHAIN_TO_CAIP2_ID","isSolanaChain","chain","getSolanaCaip2Id","chains","features","_address","_publicKey","_chains","_features","_label","_icon","_ConnectedWalletAccount","publicKey","label","ConnectedWalletAccount","bytesEqual","a","b","arraysEqual","length","i","ConnectionNamespace","_listeners","_version","_connection","_account","_on","_emit","emit_fn","_off","off_fn","_connected","_disconnected","_reconnected","_connect","_disconnect","_signAndSendTransaction","_signTransaction","_StandardWallet","connection","event","listener","__privateMethod","silent","inputs","outputs","transaction","options","minContextSlot","preflightCommitment","skipPreflight","maxRetries","signature","input","signedTransaction","transactions","signedTransactions","args","existingListener","StandardWallet","initialize"],"mappings":"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","sourcesContent":["import EventEmitter from 'events';\nimport { NetworkVMType, RpcMethod, type ChainAgnosticProvider } from '@avalabs/vm-module-types';\nimport type { PublicKey, SendOptions } from '@solana/web3.js';\nimport type { SolanaCaip2ChainId } from '@avalabs/core-chains-sdk';\n\nimport type { Connection } from './window';\nimport { legacyPublicKey } from './public-key';\nimport type { WalletIcon } from '@wallet-standard/base';\n\nenum DAppProviderRequest {\n WALLET_CONNECT = 'wallet_requestAccountPermission',\n}\n\n/**\n * Represents a Solana Wallet Provider that interacts with a chain-agnostic provider\n * to manage wallet connections, transactions, and events.\n *\n * @extends EventEmitter\n * @implements Connection\n */\nexport class SolanaWalletProvider extends EventEmitter implements Connection {\n public publicKey: PublicKey | null = null;\n\n readonly #chainAgnosticProvider: ChainAgnosticProvider;\n readonly #info: { icon: WalletIcon; version: string; name: string };\n\n /**\n * Creates an instance of SolanaWalletProvider.\n *\n * @param chainAgnosticProvider - The chain-agnostic provider used for communication.\n * @param options - Wallet information including icon, version, and name.\n */\n constructor(\n chainAgnosticProvider: ChainAgnosticProvider,\n { icon, version, name }: { icon: WalletIcon; version: string; name: string },\n ) {\n super();\n this.#info = {\n icon,\n name,\n version,\n };\n this.#chainAgnosticProvider = chainAgnosticProvider;\n this.#chainAgnosticProvider.subscribeToMessage(this.#handleBackgroundMessage);\n }\n\n /**\n * Retrieves wallet metadata such as icon, version, and name.\n */\n get info() {\n return this.#info;\n }\n\n /**\n * Connects to the wallet. If already connected, returns the public key.\n *\n * @param options - Connection options.\n * @param options.onlyIfTrusted - If true, connects without approval if previously approved.\n * @returns An object containing the public key.\n */\n async connect({ onlyIfTrusted }: { onlyIfTrusted?: boolean } = {}) {\n if (this.publicKey) {\n return { publicKey: this.publicKey };\n }\n\n const [address] = await this.#chainAgnosticProvider.request<[string]>({\n data: {\n method: DAppProviderRequest.WALLET_CONNECT,\n params: { addressVM: NetworkVMType.SVM, onlyIfTrusted },\n },\n });\n\n this.publicKey = legacyPublicKey(address);\n return { publicKey: this.publicKey };\n }\n\n async disconnect() {\n this.publicKey = null;\n this.emit('disconnect');\n }\n\n /**\n * Signs and sends a transaction.\n *\n * @param account - The account to use for signing.\n * @param caipId - The Solana CAIP-2 chain ID.\n * @param serializedTx - The serialized transaction to sign and send.\n * @param sendOptions - Options for sending the transaction. See the docs here: https://solana.com/pl/docs/rpc/http/sendtransaction.\n * @returns The transaction signature.\n */\n async signAndSendTransaction(\n account: string,\n caipId: SolanaCaip2ChainId,\n serializedTx: string,\n sendOptions: SendOptions,\n ) {\n const signature = await this.#chainAgnosticProvider.request<string>({\n scope: caipId,\n data: {\n method: RpcMethod.SOLANA_SIGN_AND_SEND_TRANSACTION,\n params: [\n {\n account,\n serializedTx,\n sendOptions,\n },\n ],\n },\n });\n\n return signature;\n }\n\n /**\n * Signs a transaction without sending it.\n *\n * @param account - The account to use for signing.\n * @param caipId - The Solana CAIP-2 chain ID.\n * @param serializedTx - The serialized transaction to sign.\n * @returns The signed transaction.\n */\n async signTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string) {\n const signedTx = await this.#chainAgnosticProvider.request<string>({\n scope: caipId,\n data: {\n method: RpcMethod.SOLANA_SIGN_TRANSACTION,\n params: [\n {\n account,\n serializedTx,\n },\n ],\n },\n });\n\n return signedTx;\n }\n\n /**\n * Handles account changes by updating the public key and emitting appropriate events.\n * The incoming {accounts} array may include non-Solana accounts, so we filter for the\n * address described with the Solana VM type.\n */\n #accountsChanged = (accounts: { address: string; vm: NetworkVMType }[]) => {\n const address = accounts.find(({ vm }) => vm === NetworkVMType.SVM)?.address;\n\n if (!address) {\n // Account switched to an unknown account\n this.disconnect();\n } else if (this.publicKey) {\n // Account switched to a known account while we're already connected to a different one\n this.publicKey = legacyPublicKey(address);\n this.emit('accountChanged');\n } else {\n // Account switched to a known account while we're not connected\n this.publicKey = legacyPublicKey(address);\n this.emit('connect');\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #getEventHandler = (method: string): ((...params: any[]) => void) => {\n const handlerMap = {\n connect: this.connect,\n disconnect: this.disconnect,\n accountsChangedCA: this.#accountsChanged,\n };\n\n return handlerMap[method as keyof typeof handlerMap] ?? (() => {});\n };\n\n #handleBackgroundMessage = ({ method, params }: { method: string; params: unknown }) => {\n const eventHandler = this.#getEventHandler(method);\n if (eventHandler) {\n return eventHandler(params);\n }\n\n this.emit(method, params);\n };\n\n /**\n * Signs multiple transactions without sending them.\n *\n * @param address - The address to use for signing.\n * @param caipId - The Solana CAIP-2 chain ID.\n * @param serializedTxs - An array of serialized transactions to sign.\n * @returns An array of signed transactions.\n */\n async signAllTransactions(address: string, caipId: SolanaCaip2ChainId, serializedTxs: string[]): Promise<string[]> {\n const results: string[] = [];\n\n for (const tx of serializedTxs) {\n const signedTx = await this.signTransaction(address, caipId, tx);\n results.push(signedTx);\n }\n\n return results;\n }\n\n signMessage() {\n throw new Error('signMessage() not implemented.');\n }\n\n signIn() {\n throw new Error('signIn() not implemented.');\n }\n}\n","import { base58 } from '@scure/base';\nimport type { PublicKey } from '@solana/web3.js';\n\n// The wallet adapters expect a PublicKey instance (from @solana/web3.js < 2.0.0),\n// but we're already on v2.1.0.\n// To just straight up satisfy this requirement, we'd have to either use the legacy\n// @solana/web3.js package, which is already deprecated and has its own issues.\n// So here, I'm importing only the PublicKey type from @solana/web3.js < 2.0.0\n// and satisfying its interface with a custom implementation (minus the static\n// methods, which we do not use anyway).\nexport const legacyPublicKey = (address: string): PublicKey => {\n const byteArray = Buffer.from(base58.decode(address));\n\n const publicKey = {\n get [Symbol.toStringTag]() {\n return `PublicKey(${this.toString()})`;\n },\n toBase58: () => address,\n toBuffer: () => byteArray,\n toBytes: () => byteArray,\n toJSON: () => address,\n toString: () => address,\n equals: (otherPubKey: PublicKey) => address === otherPubKey.toBase58(),\n encode: () => byteArray,\n } as const;\n\n return publicKey satisfies PublicKey;\n};\n","// This is based on @wallet-standard/wallet\n\nimport type {\n DEPRECATED_WalletsWindow,\n Wallet,\n WalletEventsWindow,\n WindowRegisterWalletEvent,\n WindowRegisterWalletEventCallback,\n} from '@wallet-standard/base';\n\nexport function registerWallet(wallet: Wallet): void {\n const callback: WindowRegisterWalletEventCallback = ({ register }) => register(wallet);\n try {\n (window as WalletEventsWindow).dispatchEvent(new RegisterWalletEvent(callback));\n } catch (error) {\n console.error('wallet-standard:register-wallet event could not be dispatched\\n', error);\n }\n try {\n (window as WalletEventsWindow).addEventListener('wallet-standard:app-ready', ({ detail: api }) => callback(api));\n } catch (error) {\n console.error('wallet-standard:app-ready event listener could not be added\\n', error);\n }\n}\n\nclass RegisterWalletEvent extends Event implements WindowRegisterWalletEvent {\n readonly #detail: WindowRegisterWalletEventCallback;\n\n get detail() {\n return this.#detail;\n }\n\n override get type() {\n return 'wallet-standard:register-wallet' as const;\n }\n\n constructor(callback: WindowRegisterWalletEventCallback) {\n super('wallet-standard:register-wallet', {\n bubbles: false,\n cancelable: false,\n composed: false,\n });\n this.#detail = callback;\n }\n\n /** @deprecated */\n override preventDefault(): never {\n throw new Error('preventDefault cannot be called');\n }\n\n /** @deprecated */\n override stopImmediatePropagation(): never {\n throw new Error('stopImmediatePropagation cannot be called');\n }\n\n /** @deprecated */\n override stopPropagation(): never {\n throw new Error('stopPropagation cannot be called');\n }\n}\n\n/** @deprecated */\nexport function DEPRECATED_registerWallet(wallet: Wallet): void {\n registerWallet(wallet);\n try {\n ((window as DEPRECATED_WalletsWindow).navigator.wallets ||= []).push(({ register }) => register(wallet));\n } catch (error) {\n console.error('window.navigator.wallets could not be pushed\\n', error);\n }\n}\n","import {\n SolanaSignAndSendTransaction,\n type SolanaSignAndSendTransactionFeature,\n type SolanaSignAndSendTransactionMethod,\n type SolanaSignAndSendTransactionOutput,\n // type SolanaSignInMethod,\n // type SolanaSignInOutput,\n // type SolanaSignMessageMethod,\n // type SolanaSignMessageOutput,\n SolanaSignTransaction,\n type SolanaSignTransactionFeature,\n type SolanaSignTransactionMethod,\n type SolanaSignTransactionOutput,\n} from '@solana/wallet-standard-features';\nimport type { Wallet } from '@wallet-standard/base';\nimport {\n StandardConnect,\n type StandardConnectFeature,\n type StandardConnectMethod,\n StandardDisconnect,\n type StandardDisconnectFeature,\n type StandardDisconnectMethod,\n StandardEvents,\n type StandardEventsFeature,\n type StandardEventsListeners,\n type StandardEventsNames,\n type StandardEventsOnMethod,\n} from '@wallet-standard/features';\nimport { base58, base64 } from '@scure/base';\nimport { ConnectedWalletAccount } from './account';\nimport type { SolanaChain } from './solana';\nimport { getSolanaCaip2Id, isSolanaChain, SOLANA_CHAINS } from './solana';\nimport { bytesEqual } from './util';\nimport type { Connection } from './window';\n\nexport const ConnectionNamespace = 'connection:';\n\nexport type ConnectorFeature = {\n [ConnectionNamespace]: {\n connection: Connection;\n };\n};\n\nexport class StandardWallet implements Wallet {\n readonly #listeners: {\n [E in StandardEventsNames]?: StandardEventsListeners[E][];\n } = {};\n // Version of the Wallet Standard this wallet implements\n readonly #version = '1.0.0' as const;\n\n // Wallet connection\n readonly #connection: Connection;\n\n // Current account the wallet is connected with\n #account: ConnectedWalletAccount | null = null;\n\n /** Wallet Standard version this wallet implements */\n get version() {\n return this.#version;\n }\n\n /** Wallet version (i.e. Core Extension's version) */\n get walletVersion() {\n return this.#connection.info.version;\n }\n\n /** Name of the connected wallet app */\n get name() {\n return this.#connection.info.name;\n }\n\n /** Icon of the connected wallet app */\n get icon() {\n return this.#connection.info.icon;\n }\n\n get chains() {\n return SOLANA_CHAINS.slice();\n }\n\n get features(): StandardConnectFeature &\n StandardDisconnectFeature &\n StandardEventsFeature &\n SolanaSignAndSendTransactionFeature &\n SolanaSignTransactionFeature &\n // SolanaSignMessageFeature &\n // SolanaSignInFeature &\n ConnectorFeature {\n return {\n [StandardConnect]: {\n version: '1.0.0',\n connect: this.#connect,\n },\n [StandardDisconnect]: {\n version: '1.0.0',\n disconnect: this.#disconnect,\n },\n [StandardEvents]: {\n version: '1.0.0',\n on: this.#on,\n },\n [SolanaSignAndSendTransaction]: {\n version: '1.0.0',\n supportedTransactionVersions: ['legacy', 0],\n signAndSendTransaction: this.#signAndSendTransaction,\n },\n [SolanaSignTransaction]: {\n version: '1.0.0',\n supportedTransactionVersions: ['legacy', 0],\n signTransaction: this.#signTransaction,\n },\n // [SolanaSignMessage]: {\n // version: '1.0.0',\n // signMessage: this.#signMessage,\n // },\n // [SolanaSignIn]: {\n // version: '1.0.0',\n // signIn: this.#signIn,\n // },\n [ConnectionNamespace]: {\n connection: this.#connection,\n },\n };\n }\n\n get accounts() {\n return this.#account ? [this.#account] : [];\n }\n\n constructor(connection: Connection) {\n if (new.target === StandardWallet) {\n Object.freeze(this);\n }\n\n this.#connection = connection;\n\n connection.on('connect', this.#connected, this);\n connection.on('disconnect', this.#disconnected, this);\n connection.on('accountChanged', this.#reconnected, this);\n\n this.#connected();\n }\n\n #on: StandardEventsOnMethod = (event, listener) => {\n this.#listeners[event] ??= [];\n this.#listeners[event]?.push(listener);\n\n return (): void => this.#off(event, listener);\n };\n\n #emit<E extends StandardEventsNames>(event: E, ...args: Parameters<StandardEventsListeners[E]>): void {\n // eslint-disable-next-line prefer-spread\n this.#listeners[event]?.forEach((listener) => listener.apply(null, args));\n }\n\n #off<E extends StandardEventsNames>(event: E, listener: StandardEventsListeners[E]): void {\n this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);\n }\n\n #connected = () => {\n const address = this.#connection.publicKey?.toBase58();\n if (address) {\n const publicKey = this.#connection.publicKey!.toBytes();\n\n const account = this.#account;\n if (!account || account.address !== address || !bytesEqual(account.publicKey, publicKey)) {\n this.#account = new ConnectedWalletAccount({ address, publicKey });\n this.#emit('change', { accounts: this.accounts });\n }\n }\n };\n\n #disconnected = () => {\n if (this.#account) {\n this.#account = null;\n this.#emit('change', { accounts: this.accounts });\n }\n };\n\n #reconnected = () => {\n if (this.#connection.publicKey) {\n this.#connected();\n } else {\n this.#disconnected();\n }\n };\n\n #connect: StandardConnectMethod = async ({ silent } = {}) => {\n if (!this.#account) {\n await this.#connection.connect(silent ? { onlyIfTrusted: true } : undefined);\n }\n\n this.#connected();\n\n return { accounts: this.accounts };\n };\n\n #disconnect: StandardDisconnectMethod = async () => {\n await this.#connection.disconnect();\n };\n\n #signAndSendTransaction: SolanaSignAndSendTransactionMethod = async (...inputs) => {\n if (!this.#account) throw new Error('not connected');\n\n const outputs: SolanaSignAndSendTransactionOutput[] = [];\n\n if (inputs.length === 1) {\n const { transaction, account, chain, options } = inputs[0]!;\n const { minContextSlot, preflightCommitment, skipPreflight, maxRetries } = options || {};\n if (account !== this.#account) throw new Error('invalid account');\n if (!isSolanaChain(chain)) throw new Error('invalid chain');\n\n const signature = await this.#connection.signAndSendTransaction(\n this.#account.address,\n getSolanaCaip2Id(chain),\n base64.encode(transaction),\n {\n preflightCommitment,\n minContextSlot,\n maxRetries,\n skipPreflight,\n },\n );\n\n outputs.push({ signature: base58.decode(signature) });\n } else if (inputs.length > 1) {\n for (const input of inputs) {\n outputs.push(...(await this.#signAndSendTransaction(input)));\n }\n }\n\n return outputs;\n };\n\n #signTransaction: SolanaSignTransactionMethod = async (...inputs) => {\n if (!this.#account) throw new Error('not connected');\n\n const outputs: SolanaSignTransactionOutput[] = [];\n\n if (inputs.length === 1) {\n const { transaction, account, chain } = inputs[0]!;\n if (account !== this.#account) throw new Error('invalid account');\n if (chain && !isSolanaChain(chain)) throw new Error('invalid chain');\n\n const signedTransaction = await this.#connection.signTransaction(\n this.#account.address,\n getSolanaCaip2Id(chain || SOLANA_CHAINS[0]),\n base64.encode(transaction),\n );\n\n outputs.push({ signedTransaction: base64.decode(signedTransaction) });\n } else if (inputs.length > 1) {\n let chain: SolanaChain | undefined = undefined;\n for (const input of inputs) {\n if (input.account !== this.#account) throw new Error('invalid account');\n if (input.chain) {\n if (!isSolanaChain(input.chain)) throw new Error('invalid chain');\n if (chain) {\n if (input.chain !== chain) throw new Error('conflicting chain');\n } else {\n chain = input.chain;\n }\n }\n }\n\n const transactions = inputs.map(({ transaction }) => base64.encode(transaction));\n\n const signedTransactions = await this.#connection.signAllTransactions(\n this.#account.address,\n getSolanaCaip2Id(chain || SOLANA_CHAINS[0]),\n transactions,\n );\n\n outputs.push(\n ...signedTransactions.map((signedTransaction) => ({\n signedTransaction: base64.decode(signedTransaction),\n })),\n );\n }\n\n return outputs;\n };\n\n // #signMessage: SolanaSignMessageMethod = async (...inputs) => {\n // if (!this.#account) throw new Error('not connected');\n\n // const outputs: SolanaSignMessageOutput[] = [];\n\n // if (inputs.length === 1) {\n // const { message, account } = inputs[0]!;\n // if (account !== this.#account) throw new Error('invalid account');\n\n // const { signature } = await this.#connection.signMessage(message);\n\n // outputs.push({ signedMessage: message, signature });\n // } else if (inputs.length > 1) {\n // for (const input of inputs) {\n // outputs.push(...(await this.#signMessage(input)));\n // }\n // }\n\n // return outputs;\n // };\n\n // #signIn: SolanaSignInMethod = async (...inputs) => {\n // const outputs: SolanaSignInOutput[] = [];\n\n // if (inputs.length > 1) {\n // for (const input of inputs) {\n // outputs.push(await this.#connection.signIn(input));\n // }\n // } else {\n // return [await this.#connection.signIn(inputs[0])];\n // }\n\n // return outputs;\n // };\n}\n","// This is based on from @wallet-standard/wallet\n\nimport {\n SolanaSignAndSendTransaction,\n // SolanaSignMessage,\n SolanaSignTransaction,\n} from '@solana/wallet-standard-features';\nimport type { WalletAccount } from '@wallet-standard/base';\nimport { SOLANA_CHAINS } from './solana';\n\nconst chains = SOLANA_CHAINS;\nconst features = [\n SolanaSignAndSendTransaction,\n SolanaSignTransaction,\n // SolanaSignMessage,\n] as const;\n\nexport class ConnectedWalletAccount implements WalletAccount {\n readonly #address: WalletAccount['address'];\n readonly #publicKey: WalletAccount['publicKey'];\n readonly #chains: WalletAccount['chains'];\n readonly #features: WalletAccount['features'];\n readonly #label: WalletAccount['label'];\n readonly #icon: WalletAccount['icon'];\n\n get address() {\n return this.#address;\n }\n\n get publicKey() {\n return this.#publicKey.slice();\n }\n\n get chains() {\n return this.#chains.slice();\n }\n\n get features() {\n return this.#features.slice();\n }\n\n get label() {\n return this.#label;\n }\n\n get icon() {\n return this.#icon;\n }\n\n constructor({ address, publicKey, label, icon }: Omit<WalletAccount, 'chains' | 'features'>) {\n if (new.target === ConnectedWalletAccount) {\n Object.freeze(this);\n }\n\n this.#address = address;\n this.#publicKey = publicKey;\n this.#chains = chains;\n this.#features = features;\n this.#label = label;\n this.#icon = icon;\n }\n}\n","// This is based on @solana/wallet-standard-chains\n\nimport type { IdentifierString } from '@wallet-standard/base';\nimport type { Transaction, VersionedTransaction } from '@solana/web3.js';\nimport { SolanaCaip2ChainId } from '@avalabs/core-chains-sdk';\n\n/** Solana Mainnet (beta) cluster, e.g. https://api.mainnet-beta.solana.com */\nexport const SOLANA_MAINNET_CHAIN = 'solana:mainnet';\n\n/** Solana Devnet cluster, e.g. https://api.devnet.solana.com */\nexport const SOLANA_DEVNET_CHAIN = 'solana:devnet';\n\n/** Solana Testnet cluster, e.g. https://api.testnet.solana.com */\nexport const SOLANA_TESTNET_CHAIN = 'solana:testnet';\n\n/** Solana Localnet cluster, e.g. http://localhost:8899 */\n// export const SOLANA_LOCALNET_CHAIN = 'solana:localnet';\n\n/** Array of all Solana clusters */\nexport const SOLANA_CHAINS = [\n SOLANA_MAINNET_CHAIN,\n SOLANA_DEVNET_CHAIN,\n SOLANA_TESTNET_CHAIN,\n // SOLANA_LOCALNET_CHAIN,\n] as const;\n\n/** Type of all Solana clusters */\nexport type SolanaChain = (typeof SOLANA_CHAINS)[number];\n\nexport const SOLANA_CHAIN_TO_CAIP2_ID = {\n [SOLANA_MAINNET_CHAIN]: SolanaCaip2ChainId.MAINNET,\n [SOLANA_DEVNET_CHAIN]: SolanaCaip2ChainId.DEVNET,\n [SOLANA_TESTNET_CHAIN]: SolanaCaip2ChainId.TESTNET,\n};\n\n/**\n * Check if a chain corresponds with one of the Solana clusters.\n */\nexport function isSolanaChain(chain: IdentifierString): chain is SolanaChain {\n return SOLANA_CHAINS.includes(chain as SolanaChain);\n}\n\nexport function getSolanaCaip2Id(chain: SolanaChain): SolanaCaip2ChainId {\n return SOLANA_CHAIN_TO_CAIP2_ID[chain];\n}\n\nexport function isVersionedTransaction(\n transaction: Transaction | VersionedTransaction,\n): transaction is VersionedTransaction {\n return 'version' in transaction;\n}\n","// This is copied from @wallet-standard/wallet\n\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n return arraysEqual(a, b);\n}\n\ninterface Indexed<T> {\n length: number;\n [index: number]: T;\n}\n\nexport function arraysEqual<T>(a: Indexed<T>, b: Indexed<T>): boolean {\n if (a === b) return true;\n\n const length = a.length;\n if (length !== b.length) return false;\n\n for (let i = 0; i < length; i++) {\n if (a[i] !== b[i]) return false;\n }\n\n return true;\n}\n","import { registerWallet } from './register';\nimport { StandardWallet } from './wallet';\nimport type { Connection } from './window';\n\nexport function initialize(connection: Connection): void {\n registerWallet(new StandardWallet(connection));\n}\n"]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { ChainAgnosticProvider } from '@avalabs/vm-module-types';
|
|
3
|
+
import { PublicKey, SendOptions } from '@solana/web3.js';
|
|
4
|
+
import { SolanaCaip2ChainId } from '@avalabs/core-chains-sdk';
|
|
5
|
+
import { WalletIcon } from '@wallet-standard/base';
|
|
6
|
+
|
|
7
|
+
interface ConnectionEvent {
|
|
8
|
+
connect(...args: unknown[]): unknown;
|
|
9
|
+
disconnect(...args: unknown[]): unknown;
|
|
10
|
+
accountChanged(...args: unknown[]): unknown;
|
|
11
|
+
}
|
|
12
|
+
interface ConnectionEventEmitter {
|
|
13
|
+
on<E extends keyof ConnectionEvent>(event: E, listener: ConnectionEvent[E], context?: any): void;
|
|
14
|
+
off<E extends keyof ConnectionEvent>(event: E, listener: ConnectionEvent[E], context?: any): void;
|
|
15
|
+
}
|
|
16
|
+
interface Connection extends ConnectionEventEmitter {
|
|
17
|
+
publicKey: PublicKey | null;
|
|
18
|
+
info: {
|
|
19
|
+
icon: WalletIcon;
|
|
20
|
+
version: string;
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
connect(options?: {
|
|
24
|
+
onlyIfTrusted?: boolean;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
publicKey: PublicKey;
|
|
27
|
+
}>;
|
|
28
|
+
disconnect(): Promise<void>;
|
|
29
|
+
signAndSendTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string, options?: SendOptions): Promise<string>;
|
|
30
|
+
signTransaction(account: string, caip2Id: SolanaCaip2ChainId, base64EncodedTx: string): Promise<string>;
|
|
31
|
+
signAllTransactions(account: string, caip2Id: SolanaCaip2ChainId, base64EncodedTxs: string[]): Promise<string[]>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Represents a Solana Wallet Provider that interacts with a chain-agnostic provider
|
|
36
|
+
* to manage wallet connections, transactions, and events.
|
|
37
|
+
*
|
|
38
|
+
* @extends EventEmitter
|
|
39
|
+
* @implements Connection
|
|
40
|
+
*/
|
|
41
|
+
declare class SolanaWalletProvider extends EventEmitter implements Connection {
|
|
42
|
+
#private;
|
|
43
|
+
publicKey: PublicKey | null;
|
|
44
|
+
/**
|
|
45
|
+
* Creates an instance of SolanaWalletProvider.
|
|
46
|
+
*
|
|
47
|
+
* @param chainAgnosticProvider - The chain-agnostic provider used for communication.
|
|
48
|
+
* @param options - Wallet information including icon, version, and name.
|
|
49
|
+
*/
|
|
50
|
+
constructor(chainAgnosticProvider: ChainAgnosticProvider, { icon, version, name }: {
|
|
51
|
+
icon: WalletIcon;
|
|
52
|
+
version: string;
|
|
53
|
+
name: string;
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Retrieves wallet metadata such as icon, version, and name.
|
|
57
|
+
*/
|
|
58
|
+
get info(): {
|
|
59
|
+
icon: `data:image/svg+xml;base64,${string}` | `data:image/webp;base64,${string}` | `data:image/png;base64,${string}` | `data:image/gif;base64,${string}`;
|
|
60
|
+
version: string;
|
|
61
|
+
name: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Connects to the wallet. If already connected, returns the public key.
|
|
65
|
+
*
|
|
66
|
+
* @param options - Connection options.
|
|
67
|
+
* @param options.onlyIfTrusted - If true, connects without approval if previously approved.
|
|
68
|
+
* @returns An object containing the public key.
|
|
69
|
+
*/
|
|
70
|
+
connect({ onlyIfTrusted }?: {
|
|
71
|
+
onlyIfTrusted?: boolean;
|
|
72
|
+
}): Promise<{
|
|
73
|
+
publicKey: PublicKey;
|
|
74
|
+
}>;
|
|
75
|
+
disconnect(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Signs and sends a transaction.
|
|
78
|
+
*
|
|
79
|
+
* @param account - The account to use for signing.
|
|
80
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
81
|
+
* @param serializedTx - The serialized transaction to sign and send.
|
|
82
|
+
* @param sendOptions - Options for sending the transaction. See the docs here: https://solana.com/pl/docs/rpc/http/sendtransaction.
|
|
83
|
+
* @returns The transaction signature.
|
|
84
|
+
*/
|
|
85
|
+
signAndSendTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string, sendOptions: SendOptions): Promise<string>;
|
|
86
|
+
/**
|
|
87
|
+
* Signs a transaction without sending it.
|
|
88
|
+
*
|
|
89
|
+
* @param account - The account to use for signing.
|
|
90
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
91
|
+
* @param serializedTx - The serialized transaction to sign.
|
|
92
|
+
* @returns The signed transaction.
|
|
93
|
+
*/
|
|
94
|
+
signTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string): Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Signs multiple transactions without sending them.
|
|
97
|
+
*
|
|
98
|
+
* @param address - The address to use for signing.
|
|
99
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
100
|
+
* @param serializedTxs - An array of serialized transactions to sign.
|
|
101
|
+
* @returns An array of signed transactions.
|
|
102
|
+
*/
|
|
103
|
+
signAllTransactions(address: string, caipId: SolanaCaip2ChainId, serializedTxs: string[]): Promise<string[]>;
|
|
104
|
+
signMessage(): void;
|
|
105
|
+
signIn(): void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
declare function initialize(connection: Connection): void;
|
|
109
|
+
|
|
110
|
+
export { SolanaWalletProvider, initialize };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { ChainAgnosticProvider } from '@avalabs/vm-module-types';
|
|
3
|
+
import { PublicKey, SendOptions } from '@solana/web3.js';
|
|
4
|
+
import { SolanaCaip2ChainId } from '@avalabs/core-chains-sdk';
|
|
5
|
+
import { WalletIcon } from '@wallet-standard/base';
|
|
6
|
+
|
|
7
|
+
interface ConnectionEvent {
|
|
8
|
+
connect(...args: unknown[]): unknown;
|
|
9
|
+
disconnect(...args: unknown[]): unknown;
|
|
10
|
+
accountChanged(...args: unknown[]): unknown;
|
|
11
|
+
}
|
|
12
|
+
interface ConnectionEventEmitter {
|
|
13
|
+
on<E extends keyof ConnectionEvent>(event: E, listener: ConnectionEvent[E], context?: any): void;
|
|
14
|
+
off<E extends keyof ConnectionEvent>(event: E, listener: ConnectionEvent[E], context?: any): void;
|
|
15
|
+
}
|
|
16
|
+
interface Connection extends ConnectionEventEmitter {
|
|
17
|
+
publicKey: PublicKey | null;
|
|
18
|
+
info: {
|
|
19
|
+
icon: WalletIcon;
|
|
20
|
+
version: string;
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
connect(options?: {
|
|
24
|
+
onlyIfTrusted?: boolean;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
publicKey: PublicKey;
|
|
27
|
+
}>;
|
|
28
|
+
disconnect(): Promise<void>;
|
|
29
|
+
signAndSendTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string, options?: SendOptions): Promise<string>;
|
|
30
|
+
signTransaction(account: string, caip2Id: SolanaCaip2ChainId, base64EncodedTx: string): Promise<string>;
|
|
31
|
+
signAllTransactions(account: string, caip2Id: SolanaCaip2ChainId, base64EncodedTxs: string[]): Promise<string[]>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Represents a Solana Wallet Provider that interacts with a chain-agnostic provider
|
|
36
|
+
* to manage wallet connections, transactions, and events.
|
|
37
|
+
*
|
|
38
|
+
* @extends EventEmitter
|
|
39
|
+
* @implements Connection
|
|
40
|
+
*/
|
|
41
|
+
declare class SolanaWalletProvider extends EventEmitter implements Connection {
|
|
42
|
+
#private;
|
|
43
|
+
publicKey: PublicKey | null;
|
|
44
|
+
/**
|
|
45
|
+
* Creates an instance of SolanaWalletProvider.
|
|
46
|
+
*
|
|
47
|
+
* @param chainAgnosticProvider - The chain-agnostic provider used for communication.
|
|
48
|
+
* @param options - Wallet information including icon, version, and name.
|
|
49
|
+
*/
|
|
50
|
+
constructor(chainAgnosticProvider: ChainAgnosticProvider, { icon, version, name }: {
|
|
51
|
+
icon: WalletIcon;
|
|
52
|
+
version: string;
|
|
53
|
+
name: string;
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Retrieves wallet metadata such as icon, version, and name.
|
|
57
|
+
*/
|
|
58
|
+
get info(): {
|
|
59
|
+
icon: `data:image/svg+xml;base64,${string}` | `data:image/webp;base64,${string}` | `data:image/png;base64,${string}` | `data:image/gif;base64,${string}`;
|
|
60
|
+
version: string;
|
|
61
|
+
name: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Connects to the wallet. If already connected, returns the public key.
|
|
65
|
+
*
|
|
66
|
+
* @param options - Connection options.
|
|
67
|
+
* @param options.onlyIfTrusted - If true, connects without approval if previously approved.
|
|
68
|
+
* @returns An object containing the public key.
|
|
69
|
+
*/
|
|
70
|
+
connect({ onlyIfTrusted }?: {
|
|
71
|
+
onlyIfTrusted?: boolean;
|
|
72
|
+
}): Promise<{
|
|
73
|
+
publicKey: PublicKey;
|
|
74
|
+
}>;
|
|
75
|
+
disconnect(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Signs and sends a transaction.
|
|
78
|
+
*
|
|
79
|
+
* @param account - The account to use for signing.
|
|
80
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
81
|
+
* @param serializedTx - The serialized transaction to sign and send.
|
|
82
|
+
* @param sendOptions - Options for sending the transaction. See the docs here: https://solana.com/pl/docs/rpc/http/sendtransaction.
|
|
83
|
+
* @returns The transaction signature.
|
|
84
|
+
*/
|
|
85
|
+
signAndSendTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string, sendOptions: SendOptions): Promise<string>;
|
|
86
|
+
/**
|
|
87
|
+
* Signs a transaction without sending it.
|
|
88
|
+
*
|
|
89
|
+
* @param account - The account to use for signing.
|
|
90
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
91
|
+
* @param serializedTx - The serialized transaction to sign.
|
|
92
|
+
* @returns The signed transaction.
|
|
93
|
+
*/
|
|
94
|
+
signTransaction(account: string, caipId: SolanaCaip2ChainId, serializedTx: string): Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Signs multiple transactions without sending them.
|
|
97
|
+
*
|
|
98
|
+
* @param address - The address to use for signing.
|
|
99
|
+
* @param caipId - The Solana CAIP-2 chain ID.
|
|
100
|
+
* @param serializedTxs - An array of serialized transactions to sign.
|
|
101
|
+
* @returns An array of signed transactions.
|
|
102
|
+
*/
|
|
103
|
+
signAllTransactions(address: string, caipId: SolanaCaip2ChainId, serializedTxs: string[]): Promise<string[]>;
|
|
104
|
+
signMessage(): void;
|
|
105
|
+
signIn(): void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
declare function initialize(connection: Connection): void;
|
|
109
|
+
|
|
110
|
+
export { SolanaWalletProvider, initialize };
|