{"version":3,"sources":["../src/module.ts","../src/env.ts","../manifest.json","../src/utils/get-provider.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.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/token-service/watchlist-proxy-client.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","../../../packages-internal/utils/src/consts.ts","../../../packages-internal/utils/src/utils/get-glacier-api-key.ts","../../../packages-internal/utils/src/utils/glacier-fetch-http-request.ts","../../../packages-internal/utils/src/utils/rpc-error-opts.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/convert-btc-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-balances/get-balances.ts","../src/handlers/get-address/get-address.ts","../src/handlers/bitcoin-send-transaction/bitcoin-send-transaction.ts","../src/handlers/bitcoin-send-transaction/schema.ts","../src/utils/is-btc-balance.ts","../src/utils/calculate-gas-limit.ts","../src/utils/bitcoin-tx-updater.ts","../src/utils/wait-for-tx-receipt.ts","../src/utils/get-tx-hash.ts","../src/handlers/bitcoin-sign-transaction/bitcoin-sign-transaction.ts","../src/handlers/bitcoin-sign-transaction/schema.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/derive-addresses/derive-addresses.ts"],"names":["RpcMethod","parseManifest","rpcErrors","Environment","prodEnv","devEnv","getEnv","__name","environment","manifest_default","BitcoinProvider","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","charsum","s","i","sum","arrayHash","array","cs","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","_RetryBackoffPolicy","retryIndex","secondsToDelay","_","msToDelay","linearCount","linearStepMs","n","base","incSum","ms","r","coingeckoRetry","response","RawSimplePriceResponseSchema","fetchAndVerify","fetchOptions","schema","fetchFn","responseJson","_CoingeckoProxyClient","proxyApiUrl","params","queryParams","id","rawQueryParams","CoingeckoProxyClient","z","WatchlistTokenResponseSchema","_WatchlistProxyClient","WatchlistProxyClient","_storage","_proxyApiUrl","_fetchFn","_coingeckoBasicClient","_TokenService","storage","fetch","__privateAdd","__publicField","data","currencies","formattedData","tokenData","currency","__privateSet","__privateGet","tokenDetails","token","tokenInfo","coinIds","cacheId","useCoingeckoProxy","tokenAddresses","assetPlatformId","rawData","marketCap","vol24","change24","lastUpdated","shouldThrow","TokenService","number","object","record","string","ExchangeRateSchema","DetailItemType","fundsRecipientItem","address","amount","maxDecimals","symbol","currencyItem","label","value","linkItem","addressItem","AppName","GLACIER_API_KEY","getGlacierApiKey","GLOBAL_QUERY_PARAMS","rpcErrorOpts","message","cause","getProvider","isTestnet","glacierApiKey","getNetworkFee","provider","high","low","medium","TokenType","TransactionType","convertBtcTransaction","tx","network","explorerUrl","networkToken","txAddress","getTransactionHistory","TokenUnit","getBalances","addresses","withScripts","tokenService","coingeckoTokenId","marketData","balanceInSatoshis","utxos","unconfirmedBalanceInSatoshis","utxosUnconfirmed","balance","balanceInCurrency","balanceDisplayValue","unconfirmedBalance","unconfirmedBalanceInCurrency","acc","accountBalance","getBech32AddressFromXPub","getBtcAddressFromPubKey","networks","NetworkVMType","WalletType","getAddress","accountIndex","xpub","walletType","pubKeyBuffer","paramsSchema","parseRequestParams","isBtcBalance","hasUtxos","hasLocked","hasUnlockedUnstaked","createTransferTx","calculateGasLimit","fee","feeRate","requests","getTxUpdater","requestId","signingData","displayData","request","account","to","inputs","outputs","newData","updatedRequest","waitForTransactionReceipt","txHash","onTransactionPending","onTransactionConfirmed","onTransactionReverted","explorerLink","getTxHash","bitcoinSendTransaction","approvalController","dappInfo","rawParams","success","parseError","btcBalance","from","updateTx","cleanup","error","inputUtxo","outputUtxo","bitcoinSignTransaction","details","detailsError","parseTxDetails","fromAddress","transferTotal","decimals","getScript","scripts","script","inputsTotal","outputsTotal","assertNonEmpty","hasDerivationDetails","buildDerivationPath","derivationPathType","deriveAddress","secretId","derivationPath","publicKeyHex","publicKey","deriveAddressesForBtc","init","deriveAddresses","accountIndices","publicKeys","_approvalController","_runtime","_BitcoinModule","runtime","BitcoinModule"],"mappings":"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","sourcesContent":["import type {\n  Module,\n  Manifest,\n  NetworkFees,\n  GetTransactionHistory,\n  RpcRequest,\n  Network,\n  GetBalancesParams,\n  GetAddressParams,\n  GetAddressResponse,\n  ApprovalController,\n  ConstructorParams,\n  DeriveAddressParams,\n  DeriveAddressesParams,\n  BuildDerivationPathParams,\n  RuntimeParams,\n} from '@avalabs/vm-module-types';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getEnv } from './env';\n\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getBalances } from './handlers/get-balances/get-balances';\nimport { getAddress } from './handlers/get-address/get-address';\nimport { bitcoinSendTransaction } from './handlers/bitcoin-send-transaction/bitcoin-send-transaction';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getProvider } from './utils/get-provider';\nimport { bitcoinSignTransaction } from './handlers/bitcoin-sign-transaction/bitcoin-sign-transaction';\nimport { deriveAddress } from './handlers/derive-address/derive-address';\nimport { deriveAddresses } from './handlers/derive-addresses/derive-addresses';\nimport { buildDerivationPath } from './handlers/build-derivation-path/build-derivation-path';\n\nexport class BitcoinModule implements Module {\n  #proxyApiUrl: string;\n  #approvalController: ApprovalController;\n  #runtime?: RuntimeParams;\n\n  constructor({ environment, approvalController, runtime }: ConstructorParams) {\n    const { proxyApiUrl } = getEnv(environment);\n\n    this.#approvalController = approvalController;\n    this.#proxyApiUrl = proxyApiUrl;\n    this.#runtime = runtime;\n  }\n\n  getProvider(network: Network): Promise<BitcoinProvider> {\n    return getProvider({\n      isTestnet: Boolean(network.isTestnet),\n      proxyApiUrl: this.#proxyApiUrl,\n    });\n  }\n\n  getAddress({ accountIndex, xpub, walletType, network }: GetAddressParams): Promise<GetAddressResponse> {\n    return getAddress({ accountIndex, xpub, network, walletType });\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  deriveAddresses(params: DeriveAddressesParams) {\n    return deriveAddresses({\n      ...params,\n      approvalController: this.#approvalController,\n    });\n  }\n\n  getBalances({ addresses, currency, network, storage }: GetBalancesParams) {\n    return getBalances({\n      addresses,\n      currency,\n      network,\n      proxyApiUrl: this.#proxyApiUrl,\n      storage,\n      fetch: this.#runtime?.fetch,\n    });\n  }\n\n  getManifest(): Manifest | undefined {\n    const result = parseManifest(ManifestJson);\n    return result.success ? result.data : undefined;\n  }\n\n  getNetworkFee(network: Network): Promise<NetworkFees> {\n    return getNetworkFee({\n      isTestnet: Boolean(network.isTestnet),\n      proxyApiUrl: this.#proxyApiUrl,\n    });\n  }\n\n  async getTransactionHistory({ address, network }: GetTransactionHistory) {\n    return {\n      transactions: await getTransactionHistory({\n        address,\n        network,\n        proxyApiUrl: this.#proxyApiUrl,\n      }),\n    };\n  }\n\n  getTokens(_: Network) {\n    return Promise.resolve([]);\n  }\n\n  async onRpcRequest(request: RpcRequest, network: Network) {\n    switch (request.method) {\n      case RpcMethod.BITCOIN_SEND_TRANSACTION:\n        return bitcoinSendTransaction({\n          request,\n          network,\n          approvalController: this.#approvalController,\n          proxyApiUrl: this.#proxyApiUrl,\n        });\n      case RpcMethod.BITCOIN_SIGN_TRANSACTION:\n        return bitcoinSignTransaction({\n          request,\n          network,\n          approvalController: this.#approvalController,\n          proxyApiUrl: this.#proxyApiUrl,\n        });\n      default:\n        return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n    }\n  }\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","{\n  \"name\": \"Bitcoin\",\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/bitcoin-module\",\n          \"registry\": \"https://registry.npmjs.org\"\n        }\n      }\n    }\n  },\n  \"network\": {\n    \"chainIds\": [\"bip122:000000000019d6689c085ae165831e93\", \"bip122:000000000933ea01ad0ee984209779ba\"],\n    \"namespaces\": [\"bip122\"]\n  },\n  \"cointype\": \"0\",\n  \"permissions\": {\n    \"rpc\": {\n      \"dapps\": true,\n      \"methods\": [\"bitcoin_sendTransaction\", \"bitcoin_signTransaction\"],\n      \"nonRestrictedMethods\": []\n    }\n  },\n  \"manifestVersion\": \"0.1\"\n}\n","import { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getGlacierApiKey } from '@internal/utils';\n\ntype ProviderParams = {\n  isTestnet: boolean;\n  proxyApiUrl: string;\n};\n\nexport const getProvider = async ({ isTestnet, proxyApiUrl }: ProviderParams): Promise<BitcoinProvider> => {\n  const glacierApiKey = getGlacierApiKey();\n\n  return new BitcoinProvider(\n    !isTestnet,\n    undefined,\n    `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btcbook-testnet' : 'btcbook'}`,\n    `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btc-testnet' : 'btc'}`,\n    glacierApiKey ? { token: glacierApiKey } : {},\n  );\n};\n","import {\n  VsCurrencyType,\n  getBasicCoingeckoHttp,\n  simplePrice,\n  simpleTokenPrice,\n  type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { RawSimplePriceResponse, SimplePriceResponse, Storage } from '@avalabs/vm-module-types';\nimport { arrayHash } from '../../utils/array-hash';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { CoingeckoProxyClient } from './coingecko-proxy-client';\nimport { WatchlistProxyClient } from './watchlist-proxy-client';\n\ntype FetchFn = typeof globalThis.fetch;\n\ntype ConstructorParams = {\n  storage?: Storage;\n  proxyApiUrl: string;\n  fetch?: FetchFn;\n};\n\nexport class TokenService {\n  #storage?: Storage;\n  #proxyApiUrl: string;\n  #fetchFn: FetchFn;\n  #coingeckoBasicClient: ReturnType<typeof getBasicCoingeckoHttp>;\n\n  constructor({ storage, proxyApiUrl, fetch }: ConstructorParams) {\n    this.#storage = storage;\n    this.#proxyApiUrl = proxyApiUrl;\n    this.#fetchFn = fetch ?? globalThis.fetch;\n    this.#coingeckoBasicClient = getBasicCoingeckoHttp(undefined, this.#fetchFn);\n  }\n\n  async getWatchlistDataForToken({\n    tokenDetails,\n    currency = VsCurrencyType.USD,\n  }: {\n    tokenDetails: {\n      symbol: string;\n      isNative: boolean;\n      caip2Id: string;\n      address?: string;\n    };\n    currency: VsCurrencyType;\n  }): Promise<{\n    priceInCurrency: number;\n    change24: number;\n    marketCap: number;\n    vol24: number;\n  }> {\n    const data = (\n      await new WatchlistProxyClient(this.#proxyApiUrl).watchlistToken({\n        tokens: tokenDetails.symbol,\n        currency: currency,\n      })\n    ).filter((token) => {\n      return tokenDetails.isNative\n        ? token.internalId === `NATIVE-${tokenDetails.symbol.toLowerCase()}`\n        : token.platforms[tokenDetails.caip2Id] === tokenDetails.address;\n    });\n\n    const [tokenInfo] = data;\n\n    if (!tokenInfo) {\n      return {\n        priceInCurrency: 0,\n        change24: 0,\n        marketCap: 0,\n        vol24: 0,\n      };\n    }\n\n    return {\n      priceInCurrency: tokenInfo.current_price ?? 0,\n      change24: tokenInfo.price_change_percentage_24h ?? 0,\n      marketCap: tokenInfo.market_cap ?? 0,\n      vol24: tokenInfo.total_volume ?? 0,\n    };\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, this.#fetchFn).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(this.#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, this.#fetchFn).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(this.#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","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","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  /**\n   * linearThenExponential backoff:\n   * - First `linearCount` retries: linear increase by `linearStepMs`\n   * - After that: increment grows exponentially based on `linearStepMs`\n   *   Example (linearCount=4, linearStepMs=1000):\n   *     1s, 2s, 3s, 4s, 6s, 10s, 18s, 34s...\n   */\n  static linearThenExponential(linearCount: number, linearStepMs: number): RetryBackoffPolicyInterface {\n    return (retryIndex: number): number => {\n      if (retryIndex < linearCount) {\n        // Linear phase: (i+1) * step\n        return (retryIndex + 1) * linearStepMs;\n      }\n      // Exponential-increment phase (closed form):\n      // n = number of exponential increments applied\n      // base = linearCount * step\n      // increment sum = 2*step * (2^n - 1)\n      const n = retryIndex - linearCount + 1;\n      const base = linearCount * linearStepMs;\n      const incSum = 2 * linearStepMs * (Math.pow(2, n) - 1);\n      return base + incSum;\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","import { RawSimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nexport class CoingeckoProxyClient {\n  constructor(\n    private proxyApiUrl: string,\n    private fetchFn?: typeof fetch,\n  ) {}\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      this.fetchFn,\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      this.fetchFn,\n    );\n  }\n}\n","import type { ZodSchema } from 'zod';\nimport z from 'zod';\n\nexport async function fetchAndVerify<T extends ZodSchema>(\n  fetchOptions: Parameters<typeof fetch>,\n  schema: T,\n  fetchFn: typeof fetch = fetch,\n): Promise<z.infer<T>> {\n  const response = await fetchFn(...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 { fetchAndVerify } from '../../utils/fetch-and-verify';\nimport { z } from 'zod';\n\nconst WatchlistTokenResponseSchema = z.array(\n  z.object({\n    // the object has more properties than the ones listed here, but we only need these at the moment\n    internalId: z.string(),\n    id: z.string(),\n    symbol: z.string(),\n    name: z.string(),\n    image: z.string().optional().nullable(),\n    current_price: z.number().optional().nullable(),\n    price_change_percentage_24h: z.number().optional().nullable(),\n    market_cap: z.number().optional().nullable(),\n    total_volume: z.number().optional().nullable(),\n    platforms: z.record(z.string(), z.string()),\n  }),\n);\n\nexport class WatchlistProxyClient {\n  constructor(private proxyApiUrl: string) {}\n\n  watchlistToken(params: { tokens: string; currency: string }) {\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}/watchlist/tokens?${queryParams}`,\n        {\n          method: 'GET',\n          headers: {\n            'Content-Type': 'application/json',\n          },\n        },\n      ],\n      WatchlistTokenResponseSchema,\n    );\n  }\n}\n","import z, { number, object, record, string } from 'zod';\nimport { fetchAndVerify } from '../../utils/fetch-and-verify';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n  'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n  date: string(),\n  usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n  try {\n    return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_URL], ExchangeRateSchema);\n  } catch {\n    return await fetchAndVerify([CURRENCY_EXCHANGE_RATES_FALLBACK_URL], ExchangeRateSchema);\n  }\n};\n","import {\n  type AddressItem,\n  type CurrencyItem,\n  type NodeIDItem,\n  type TextItem,\n  type DataItem,\n  type DateItem,\n  type LinkItemValue,\n  DetailItemType,\n  type LinkItem,\n  type FundsRecipientItem,\n  type AddressListItem,\n  type NetworkItemValue,\n  type NetworkItem,\n} from '@avalabs/vm-module-types';\n\nexport const fundsRecipientItem = (\n  address: string,\n  amount: bigint,\n  maxDecimals: number,\n  symbol: string,\n): FundsRecipientItem => ({\n  type: DetailItemType.FUNDS_RECIPIENT,\n  label: address,\n  amount,\n  maxDecimals,\n  symbol,\n});\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n  label,\n  type: DetailItemType.CURRENCY,\n  value,\n  maxDecimals,\n  symbol,\n});\n\nexport const textItem = (\n  label: string,\n  value: string,\n  alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n  label,\n  alignment,\n  type: DetailItemType.TEXT,\n  value,\n});\n\nexport const linkItem = (label: string, value: LinkItemValue): LinkItem => ({\n  label,\n  value,\n  type: DetailItemType.LINK,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n  label,\n  type: DetailItemType.ADDRESS,\n  value,\n});\n\nexport const addressListItem = (label: string, value: string[]): AddressListItem => ({\n  label,\n  type: DetailItemType.ADDRESS_LIST,\n  value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n  label,\n  type: DetailItemType.NODE_ID,\n  value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n  label,\n  type: DetailItemType.DATA,\n  value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n  label,\n  type: DetailItemType.DATE,\n  value,\n});\n\nexport const networkItem = (label: string, value: NetworkItemValue): NetworkItem => ({\n  label,\n  type: DetailItemType.NETWORK,\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","export const GLACIER_API_KEY = process.env.GLACIER_API_KEY;\n","import { GLACIER_API_KEY } from '../consts';\n\n// this key is only needed in development to bypass rate limit\n// it should never be used in production\nexport const getGlacierApiKey = (): string | undefined => {\n  return GLACIER_API_KEY;\n};\n","import {\n  ApiError,\n  type ApiRequestOptions,\n  CancelablePromise,\n  FetchHttpRequest,\n  type OpenAPIConfig,\n} from '@avalabs/glacier-sdk';\nimport { getGlacierApiKey } from './get-glacier-api-key';\nimport { RetryBackoffPolicy } from './retry';\n\nconst GLOBAL_QUERY_PARAMS: Record<string, string | undefined> = {\n  rltoken: getGlacierApiKey(),\n};\n\n/**\n * Custom HTTP request handler that automatically appends the Glacier API key (if present)\n * to bypass rate limits in development environments.\n */\nexport class GlacierFetchHttpRequest extends FetchHttpRequest {\n  #failedRequests = 0;\n  #getDelay = RetryBackoffPolicy.exponential();\n\n  constructor(config: OpenAPIConfig) {\n    super(config);\n  }\n\n  public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {\n    // Merge global query parameters with request-specific ones\n    const mergedQuery = {\n      ...GLOBAL_QUERY_PARAMS,\n      ...(options.query || {}), // Request-specific params (override globals if same key)\n    };\n\n    // Create modified options with merged query\n    const modifiedOptions: ApiRequestOptions = {\n      ...options,\n      query: Object.keys(mergedQuery).length > 0 ? mergedQuery : undefined,\n    };\n\n    const getRequest = () => super.request<T>(modifiedOptions);\n    return this.#failedRequests > 0 ? this.#postponeRequest<T>(getRequest) : this.#request<T>(getRequest);\n  }\n\n  #request<T>(getRequest: () => CancelablePromise<T>): CancelablePromise<T> {\n    const inner = getRequest();\n    return new CancelablePromise((resolve, reject, onCancel) => {\n      onCancel(() => inner.cancel());\n      inner\n        .then((response) => {\n          this.#failedRequests = 0;\n          resolve(response);\n        })\n        .catch((err) => {\n          if (err instanceof ApiError) {\n            const isHttpTooManyRequests = err.status === 429;\n            const isHttpInternalServerError = err.status >= 500 && err.status < 600;\n            this.#failedRequests += Number(isHttpTooManyRequests || isHttpInternalServerError);\n          }\n          reject(err);\n        });\n    });\n  }\n\n  #postponeRequest<T>(getRequest: () => CancelablePromise<T>): CancelablePromise<T> {\n    const delay = this.#getDelay(this.#failedRequests);\n    return new CancelablePromise<T>((resolve, reject, onCancel) => {\n      const timeout = setTimeout(() => {\n        const inner = getRequest();\n        onCancel(() => {\n          inner.cancel();\n          clearTimeout(timeout);\n        });\n        inner.then(resolve).catch(reject);\n      }, delay);\n    });\n  }\n}\n","/**\n * Builds the options object for `rpcErrors.internal()` / `rpcErrors.invalidParams()` etc.\n * Ensures the actual error message appears in the top-level `message` field,\n * which is what viem exposes as `error.details` to dapps.\n */\nexport const rpcErrorOpts = (message: string, cause: unknown) => ({\n  message: `${message}${cause instanceof Error ? `: ${cause.message}` : ''}`,\n  data: { cause },\n});\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\n/**\n * Returns {@link NetworkFees} based on `estimatesmartfee` RPC call\n */\nexport async function getNetworkFee({\n  isTestnet,\n  proxyApiUrl,\n}: {\n  isTestnet: boolean;\n  proxyApiUrl: string;\n}): Promise<NetworkFees> {\n  const provider = await getProvider({\n    isTestnet,\n    proxyApiUrl,\n  });\n\n  const { high, low, medium } = await provider.getFeeRates();\n\n  return {\n    low: {\n      maxFeePerGas: BigInt(low),\n    },\n    medium: {\n      maxFeePerGas: BigInt(medium),\n    },\n    high: {\n      maxFeePerGas: BigInt(high),\n    },\n    isFixedFee: false,\n  };\n}\n","import { TokenType, TransactionType, type Network, type Transaction } from '@avalabs/vm-module-types';\nimport type { BitcoinHistoryTx } from '@avalabs/core-wallets-sdk';\n\ntype ConverterOptions = {\n  address: string;\n  network: Network;\n};\n\nexport const convertBtcTransaction = (tx: BitcoinHistoryTx, { address, network }: ConverterOptions): Transaction => {\n  const { explorerUrl, networkToken } = network;\n  const txAddress = tx.addresses[0] ?? '';\n\n  return {\n    chainId: network.chainId.toString(),\n    explorerLink: `${explorerUrl}/tx/${tx.hash}`,\n    from: tx.isSender ? address : txAddress,\n    gasUsed: tx.fee.toString(),\n    hash: tx.hash,\n    isContractCall: false,\n    isIncoming: !tx.isSender,\n    isOutgoing: tx.isSender,\n    isSender: tx.isSender,\n    timestamp: tx.receivedTime * 1000,\n    to: tx.isSender ? txAddress : address,\n    tokens: [\n      {\n        amount: (Math.abs(tx.amount) / 10 ** networkToken.decimals).toString(),\n        decimal: networkToken.decimals.toString(),\n        name: networkToken.name,\n        symbol: networkToken.symbol,\n        type: TokenType.NATIVE,\n      },\n    ],\n    txType: tx.isSender ? TransactionType.SEND : TransactionType.RECEIVE,\n  };\n};\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\nimport { convertBtcTransaction } from './convert-btc-transaction';\n\ntype GetBtcTransactionHistoryOptions = {\n  network: Network;\n  address: string;\n  proxyApiUrl: string;\n};\n\nexport const getTransactionHistory = async ({ address, network, proxyApiUrl }: GetBtcTransactionHistoryOptions) => {\n  const provider = await getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n  const rawHistory = await provider.getTxHistory(address);\n\n  return rawHistory.map((tx) =>\n    convertBtcTransaction(tx, {\n      address,\n      network,\n    }),\n  );\n};\n","import type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport { type GetBalancesParams, TokenType, type TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nimport { TokenService } from '@internal/utils';\n\nimport { getProvider } from '../../utils/get-provider';\n\ntype GetBtcBalancesResponse = Record<string, Record<string, TokenWithBalanceBTC>>;\n\ntype GetBTCBalancesParams = Omit<GetBalancesParams, 'currency'> & {\n  proxyApiUrl: string;\n  withScripts?: boolean;\n  currency?: string;\n  fetch?: typeof globalThis.fetch;\n};\n\nexport const getBalances = async ({\n  addresses,\n  currency,\n  network,\n  withScripts = false,\n  proxyApiUrl,\n  storage,\n  fetch,\n}: GetBTCBalancesParams): Promise<GetBtcBalancesResponse> => {\n  const provider = await getProvider({\n    isTestnet: Boolean(network.isTestnet),\n    proxyApiUrl,\n  });\n\n  const tokenService = new TokenService({ proxyApiUrl, storage, fetch });\n  const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;\n  const withPrices = typeof currency === 'string' && typeof coingeckoTokenId === 'string';\n  const marketData = withPrices\n    ? await tokenService.getWatchlistDataForToken({\n        tokenDetails: {\n          symbol: network.networkToken.symbol,\n          isNative: true,\n          caip2Id: network.caipId ?? '',\n        },\n        currency: currency as VsCurrencyType,\n      })\n    : undefined;\n\n  const balances = await Promise.allSettled(\n    addresses.map(async (address) => {\n      const {\n        balance: balanceInSatoshis,\n        utxos,\n        balanceUnconfirmed: unconfirmedBalanceInSatoshis,\n        utxosUnconfirmed,\n      } = await provider.getUtxoBalance(address, withScripts);\n\n      const balance = new TokenUnit(balanceInSatoshis, network.networkToken.decimals, network.networkToken.symbol);\n      const balanceInCurrency =\n        marketData?.priceInCurrency !== undefined ? balance.mul(marketData.priceInCurrency) : undefined;\n      const balanceDisplayValue = balance.toDisplay();\n\n      const unconfirmedBalance = new TokenUnit(\n        unconfirmedBalanceInSatoshis,\n        network.networkToken.decimals,\n        network.networkToken.symbol,\n      );\n      const unconfirmedBalanceInCurrency =\n        marketData?.priceInCurrency !== undefined ? unconfirmedBalance.mul(marketData.priceInCurrency) : undefined;\n\n      const symbol = network.networkToken.symbol;\n\n      return {\n        [address]: {\n          [symbol]: {\n            ...network.networkToken,\n            utxos,\n            utxosUnconfirmed,\n            coingeckoId: coingeckoTokenId ?? '',\n            type: TokenType.NATIVE,\n            balance: balance.toSubUnit(),\n            balanceDisplayValue,\n            balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n            balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n            priceInCurrency: marketData?.priceInCurrency,\n            marketCap: marketData?.marketCap,\n            vol24: marketData?.vol24,\n            change24: marketData?.change24,\n            unconfirmedBalance: unconfirmedBalance.toSubUnit(),\n            unconfirmedBalanceDisplayValue: unconfirmedBalance.toDisplay(),\n            unconfirmedBalanceInCurrency: unconfirmedBalanceInCurrency?.toDisplay({\n              fixedDp: 2,\n              asNumber: true,\n            }),\n            unconfirmedBalanceCurrencyDisplayValue: unconfirmedBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n          },\n        },\n      };\n    }),\n  );\n\n  return balances.reduce((acc, accountBalance) => {\n    if (accountBalance.status === 'rejected') {\n      return acc;\n    }\n\n    return {\n      ...acc,\n      ...accountBalance.value,\n    };\n  }, {});\n};\n","import type { GetAddressParams, GetAddressResponse } from '@avalabs/vm-module-types';\nimport { getBech32AddressFromXPub, getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\nimport { NetworkVMType, WalletType } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\ntype GetAddress = Omit<GetAddressParams, 'xpubXP'>;\n\nexport const getAddress = async ({\n  accountIndex,\n  xpub,\n  network,\n  walletType,\n}: GetAddress): Promise<GetAddressResponse> => {\n  const isTestnet = Boolean(network?.isTestnet);\n  switch (walletType) {\n    case WalletType.Mnemonic:\n    case WalletType.Ledger:\n    case WalletType.Keystone: {\n      return {\n        [NetworkVMType.BITCOIN]: getBech32AddressFromXPub(\n          xpub,\n          accountIndex,\n          isTestnet ? networks.testnet : networks.bitcoin,\n        ),\n      };\n    }\n    case WalletType.LedgerLive:\n    case WalletType.Seedless: {\n      const pubKeyBuffer = Buffer.from(xpub, 'hex');\n      return {\n        [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(pubKeyBuffer, isTestnet ? networks.testnet : networks.bitcoin),\n      };\n    }\n    default:\n      throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);\n  }\n};\n","import {\n  RpcMethod,\n  type ApprovalController,\n  type DisplayData,\n  type Hex,\n  type Network,\n  type RpcRequest,\n  type SigningData,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport { getBalances } from '../get-balances/get-balances';\nimport { isBtcBalance } from '../../utils/is-btc-balance';\nimport { createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport { calculateGasLimit } from '../../utils/calculate-gas-limit';\nimport { addressItem, currencyItem, rpcErrorOpts } from '@internal/utils';\nimport { linkItem } from '@internal/utils/src/utils/detail-item';\nimport { getTxUpdater } from '../../utils/bitcoin-tx-updater';\nimport { waitForTransactionReceipt } from '../../utils/wait-for-tx-receipt';\nimport { getTxHash } from '../../utils/get-tx-hash';\n\ntype BitcoinSendTransactionParams = {\n  request: RpcRequest;\n  network: Network;\n  approvalController: ApprovalController;\n  proxyApiUrl: string;\n};\n\nexport const bitcoinSendTransaction = async ({\n  request,\n  network,\n  approvalController,\n  proxyApiUrl,\n}: BitcoinSendTransactionParams) => {\n  const { dappInfo, params: rawParams } = request;\n\n  const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n  if (!success) {\n    console.error('invalid params', parseError);\n    return {\n      error: rpcErrors.invalidParams(rpcErrorOpts('Transaction params are invalid', parseError)),\n    };\n  }\n\n  const balances = await getBalances({ addresses: [params.from], network, proxyApiUrl, withScripts: true });\n  const btcBalance = balances?.[params.from]?.[network.networkToken.symbol];\n\n  if (!isBtcBalance(btcBalance)) {\n    return {\n      error: rpcErrors.internal('Balance for the source account is not available'),\n    };\n  }\n\n  const provider = await getProvider({\n    isTestnet: Boolean(network.isTestnet),\n    proxyApiUrl,\n  });\n\n  const { to, from, amount, feeRate } = params;\n\n  const { inputs, outputs, fee } = createTransferTx(\n    to,\n    from,\n    amount,\n    feeRate,\n    btcBalance.utxos as BitcoinInputUTXO[], // we asked for scripts in getBalances() call\n    provider.getNetwork(),\n  );\n\n  if (!inputs || !outputs) {\n    return {\n      error: rpcErrors.internal('Unable to create transaction'),\n    };\n  }\n\n  const displayData: DisplayData = {\n    title: 'Do you approve this 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: [\n          addressItem('From', from),\n          linkItem('Website', dappInfo),\n          addressItem('To', to),\n          currencyItem('Amount', BigInt(amount), network.networkToken.decimals, network.networkToken.symbol),\n        ],\n      },\n    ],\n    networkFeeSelector: true,\n  };\n\n  const signingData: SigningData = {\n    type: RpcMethod.BITCOIN_SEND_TRANSACTION,\n    account: from,\n    data: {\n      to,\n      amount,\n      fee,\n      feeRate,\n      gasLimit: calculateGasLimit(fee, feeRate),\n      inputs,\n      outputs,\n      balance: btcBalance,\n    },\n  };\n\n  const { updateTx, cleanup } = getTxUpdater(request.requestId, signingData, displayData, provider);\n  const response = await approvalController.requestApproval({ request, displayData, signingData, updateTx });\n\n  cleanup();\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);\n  } catch (error) {\n    return {\n      error: rpcErrors.internal(rpcErrorOpts('Unable to get transaction hash', error)),\n    };\n  }\n\n  waitForTransactionReceipt({\n    explorerUrl: network.explorerUrl ?? '',\n    provider,\n    txHash: txHash as Hex,\n    onTransactionPending: approvalController.onTransactionPending,\n    onTransactionConfirmed: approvalController.onTransactionConfirmed,\n    onTransactionReverted: approvalController.onTransactionReverted,\n    // Pass the requestId so that client apps can pair the transaction\n    // status changes back to their respective requests for better tracking.\n    request: request,\n  });\n\n  return {\n    result: txHash,\n  };\n};\n","import { z } from 'zod';\n\nconst paramsSchema = z.object({\n  from: z.string(),\n  to: z.string(),\n  amount: z.number(),\n  feeRate: z.number(),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n  return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSendTransactionParams = z.infer<typeof paramsSchema>;\n","import type { TokenWithBalance, TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nexport const isBtcBalance = (balance?: TokenWithBalance): balance is TokenWithBalanceBTC => {\n  if (!balance) {\n    return false;\n  }\n\n  const hasUtxos = 'utxos' in balance; // BTC, P-Chain or X-Chain\n  const hasLocked = 'locked' in balance; // X-Chain only\n  const hasUnlockedUnstaked = 'unlockedUnstaked' in balance; // P-Chain only\n\n  return hasUtxos && !hasUnlockedUnstaked && !hasLocked;\n};\n","// The transaction's byte size is for BTC as gasLimit is for EVM.\n// Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n// Since we know the `fee` and the `feeRate`, we can get the transaction's\n// byte length by division.\n//\n// Note: We use `Math.ceil` here to ensure the gasLimit is sufficient and\n// to avoid any decimal values. Rounding up helps prevent underestimating the\n// required gas, as gasLimit must be an integer. While this may slightly increase\n// the fee, it minimizes the risk of transaction failure due to insufficient gasLimit.\n\nexport const calculateGasLimit = (fee: number, feeRate: number): number => {\n  return Math.ceil(fee / feeRate);\n};\n","import { BitcoinProvider, createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport type { BtcTxUpdateFn, DisplayData, RpcMethod, SigningData } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { calculateGasLimit } from './calculate-gas-limit';\n\ntype SigningData_BtcSendTx = Extract<SigningData, { type: RpcMethod.BITCOIN_SEND_TRANSACTION }>;\n\nconst requests = new Map<string, { signingData: SigningData_BtcSendTx; displayData: DisplayData }>();\n\nexport const getTxUpdater = (\n  requestId: string,\n  signingData: SigningData_BtcSendTx,\n  displayData: DisplayData,\n  provider: BitcoinProvider,\n): { updateTx: BtcTxUpdateFn; cleanup: () => void } => {\n  requests.set(requestId, { signingData, displayData });\n\n  return {\n    updateTx: ({ feeRate }) => {\n      const request = requests.get(requestId);\n\n      if (!request) {\n        throw rpcErrors.resourceNotFound();\n      }\n\n      const { signingData } = request;\n\n      if (typeof feeRate === 'undefined' || feeRate === signingData.data.feeRate) {\n        return request;\n      }\n\n      const {\n        account,\n        data: { to, amount, balance },\n      } = signingData;\n      const { inputs, outputs, fee } = createTransferTx(\n        to,\n        account,\n        amount,\n        feeRate,\n        balance.utxos as BitcoinInputUTXO[],\n        provider.getNetwork(),\n      );\n\n      if (!inputs || !outputs) {\n        throw rpcErrors.internal('Unable to create transaction');\n      }\n\n      const newData = {\n        ...signingData,\n        data: {\n          ...signingData.data,\n          fee,\n          feeRate,\n          gasLimit: calculateGasLimit(fee, feeRate),\n          inputs,\n          outputs,\n        },\n      };\n\n      const updatedRequest = { ...request, signingData: newData };\n      requests.set(requestId, updatedRequest);\n\n      return updatedRequest;\n    },\n    cleanup: () => requests.delete(requestId),\n  };\n};\n","import type { Hex, RpcRequest } from '@avalabs/vm-module-types';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\nexport const waitForTransactionReceipt = async ({\n  explorerUrl,\n  provider,\n  txHash,\n  onTransactionPending,\n  onTransactionConfirmed,\n  onTransactionReverted,\n  request,\n}: {\n  explorerUrl: string;\n  provider: BitcoinProvider;\n  txHash: Hex;\n  onTransactionPending: ({\n    txHash,\n    request,\n    explorerLink,\n  }: {\n    txHash: Hex;\n    request: RpcRequest;\n    explorerLink: string;\n  }) => void;\n  onTransactionConfirmed: ({\n    txHash,\n    explorerLink,\n    request,\n  }: {\n    txHash: Hex;\n    explorerLink: string;\n    request: RpcRequest;\n  }) => void;\n  onTransactionReverted: ({ txHash, request }: { txHash: Hex; request: RpcRequest }) => void;\n  request: RpcRequest;\n}) => {\n  try {\n    const explorerLink = `${explorerUrl}/tx/${txHash}`;\n    onTransactionPending({ txHash, request, explorerLink });\n    await provider.waitForTx(txHash);\n    onTransactionConfirmed({ txHash, explorerLink, request });\n  } catch (err) {\n    console.error(err);\n    onTransactionReverted({ txHash, request });\n  }\n};\n","import type { SigningResult } from '@avalabs/vm-module-types';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\nexport const getTxHash = async (provider: BitcoinProvider, response: SigningResult) => {\n  if ('txHash' in response) {\n    return response.txHash;\n  }\n\n  return provider.issueRawTx(response.signedData);\n};\n","import {\n  RpcMethod,\n  type ApprovalController,\n  type DisplayData,\n  type Hex,\n  type Network,\n  type RpcRequest,\n  type SigningData,\n} from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { BitcoinProvider, BitcoinInputUTXO, BitcoinOutputUTXO } from '@avalabs/core-wallets-sdk';\n\nimport { addressItem, currencyItem, rpcErrorOpts } from '@internal/utils';\nimport { fundsRecipientItem, linkItem } from '@internal/utils/src/utils/detail-item';\n\nimport { getProvider } from '../../utils/get-provider';\nimport { waitForTransactionReceipt } from '../../utils/wait-for-tx-receipt';\nimport { getTxHash } from '../../utils/get-tx-hash';\nimport { parseRequestParams, type BitcoinSignTransactionParams } from './schema';\n\ntype BitcoinSignTransactionRequestParams = {\n  request: RpcRequest;\n  network: Network;\n  approvalController: ApprovalController;\n  proxyApiUrl: string;\n};\n\nexport const bitcoinSignTransaction = async ({\n  request,\n  network,\n  approvalController,\n  proxyApiUrl,\n}: BitcoinSignTransactionRequestParams) => {\n  const { dappInfo, params: rawParams } = request;\n  const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n  if (!success) {\n    console.error('invalid params', parseError);\n    return {\n      error: rpcErrors.invalidParams(rpcErrorOpts('Transaction params are invalid', parseError)),\n    };\n  }\n\n  const provider = await getProvider({\n    isTestnet: Boolean(network.isTestnet),\n    proxyApiUrl,\n  });\n\n  const { details, error: detailsError } = await parseTxDetails(params, provider);\n  if (detailsError) {\n    return {\n      error: rpcErrors.internal(rpcErrorOpts('Transaction invalid or cannot be parsed', detailsError)),\n    };\n  }\n\n  const { fee, fromAddress, outputs, transferTotal } = details;\n  const { decimals, symbol } = network.networkToken;\n\n  const displayData: DisplayData = {\n    title: 'Do you approve this 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: [\n          linkItem('Website', dappInfo),\n          addressItem('From', fromAddress),\n          currencyItem('Total Transferred Amount', BigInt(transferTotal), decimals, symbol),\n        ],\n      },\n      {\n        title: 'Recipients',\n        items: outputs.map(({ address, value }) => fundsRecipientItem(address, BigInt(value), decimals, symbol)),\n      },\n      { title: 'Network Fee', items: [currencyItem('Total Fee', BigInt(fee), decimals, symbol)] },\n    ],\n    networkFeeSelector: false,\n  };\n\n  const signingData: SigningData = {\n    type: RpcMethod.BITCOIN_SIGN_TRANSACTION,\n    account: fromAddress,\n    data: {\n      inputs: params.inputs,\n      outputs: params.outputs,\n    },\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);\n  } catch (error) {\n    return {\n      error: rpcErrors.internal(rpcErrorOpts('Unable to get transaction hash', error)),\n    };\n  }\n\n  waitForTransactionReceipt({\n    explorerUrl: network.explorerUrl ?? '',\n    provider,\n    txHash: txHash as Hex,\n    onTransactionPending: approvalController.onTransactionPending,\n    onTransactionConfirmed: approvalController.onTransactionConfirmed,\n    onTransactionReverted: approvalController.onTransactionReverted,\n    // Pass the requestId so that client apps can pair the transaction\n    // status changes back to their respective requests for better tracking.\n    request: request,\n  });\n\n  return {\n    result: txHash,\n  };\n};\n\nconst getScript = (inputs: BitcoinInputUTXO[]): string => {\n  const scripts = Array.from(new Set(inputs.map(({ script }) => script)));\n\n  if (scripts.length !== 1) {\n    throw rpcErrors.invalidParams({\n      message: `All input UTXOs must belong to a single address, found ${scripts.length}`,\n    });\n  }\n\n  return scripts[0]!;\n};\n\nconst parseTxDetails = async (\n  params: BitcoinSignTransactionParams,\n  provider: BitcoinProvider,\n): Promise<\n  | {\n      details: {\n        fromAddress: string;\n        outputs: [BitcoinOutputUTXO, ...BitcoinOutputUTXO[]];\n        fee: number;\n        transferTotal: number;\n      };\n      error: null;\n    }\n  | { details: null; error: Error }\n> => {\n  try {\n    const script = getScript(params.inputs);\n    const fromAddress = await provider.getAddressFromScript(script);\n    const outputs = params.outputs.filter(({ address }) => address !== fromAddress);\n    const inputsTotal = params.inputs.reduce((sum, { value }) => sum + value, 0);\n    const outputsTotal = params.outputs.reduce((sum, { value }) => sum + value, 0); // with the change address\n    const transferTotal = outputs.reduce((sum, { value }) => sum + value, 0); // without the change address\n    const fee = inputsTotal - outputsTotal;\n\n    assertNonEmpty(outputs);\n\n    return {\n      error: null,\n      details: {\n        fromAddress,\n        outputs,\n        fee,\n        transferTotal,\n      },\n    };\n  } catch (error) {\n    console.error(error);\n    return {\n      details: null,\n      error: error instanceof Error ? error : new Error(error?.toString() ?? 'Unknown error'),\n    };\n  }\n};\n\nfunction assertNonEmpty<T>(array: T[]): asserts array is [T, ...T[]] {\n  if (array.length < 1) {\n    throw new Error('No actual output is provided, this transaction would only burn funds');\n  }\n}\n","import { z } from 'zod';\n\nconst inputUtxo = z.object({\n  txHash: z.string(),\n  txHex: z.string().optional(),\n  index: z.number(),\n  value: z.number(),\n  script: z.string().min(1), // Just make sure it's never an empty string\n  blockHeight: z.number(),\n  confirmations: z.number(),\n  confirmedTime: z.string().optional(),\n});\n\nconst outputUtxo = z.object({\n  address: z.string(),\n  value: z.number(),\n});\n\nconst paramsSchema = z.object({\n  inputs: z.array(inputUtxo).min(1),\n  outputs: z.array(outputUtxo).min(1),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n  return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSignTransactionParams = z.infer<typeof paramsSchema>;\n","import type { ApprovalController, DeriveAddressParams, DeriveAddressResponse } from '@avalabs/vm-module-types';\nimport { NetworkVMType } from '@avalabs/vm-module-types';\n\nimport { hasDerivationDetails } from '@internal/utils/src/utils/address-derivation';\n\nimport { getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\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, network, 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).BITCOIN : undefined;\n  const publicKeyHex = await approvalController.requestPublicKey({\n    curve: 'secp256k1',\n    secretId,\n    derivationPath,\n  });\n  const publicKey = Buffer.from(publicKeyHex, 'hex');\n\n  return {\n    [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(\n      publicKey,\n      network.isTestnet ? networks.testnet : networks.bitcoin,\n    ),\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 { rpcErrors } from '@metamask/rpc-errors';\nimport {\n  NetworkVMType,\n  type BuildDerivationPathParams,\n  type BuildDerivationPathResponse,\n} from '@avalabs/vm-module-types';\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  derivationPathType,\n}: BuildDerivationPathParams): Pick<BuildDerivationPathResponse, NetworkVMType.BITCOIN> => {\n  if (accountIndex < 0) {\n    throw rpcErrors.invalidParams('Account index must be a non-negative integer');\n  }\n\n  switch (derivationPathType) {\n    case 'bip44':\n      return {\n        [NetworkVMType.BITCOIN]: `m/44'/60'/0'/0/${accountIndex}`,\n      };\n\n    case 'ledger_live':\n      return {\n        [NetworkVMType.BITCOIN]: `m/44'/60'/${accountIndex}'/0/0`,\n      };\n\n    default:\n      throw rpcErrors.invalidParams(`Unsupported derivation path type: ${derivationPathType}`);\n  }\n};\n","import type { ApprovalController, DeriveAddressesParams, DeriveAddressesResponse } from '@avalabs/vm-module-types';\nimport { NetworkVMType } from '@avalabs/vm-module-types';\nimport { deriveAddressesForBtc, init } from '@avalabs/crypto-sdk';\n\nimport { buildDerivationPath } from '../build-derivation-path/build-derivation-path';\n\nexport const deriveAddresses = async (\n  params: DeriveAddressesParams & { approvalController: ApprovalController },\n): Promise<DeriveAddressesResponse> => {\n  const { approvalController, network, secretId, accountIndices, derivationPathType } = params;\n\n  if (accountIndices.length === 0) {\n    return [];\n  }\n\n  await init();\n\n  const publicKeys = await Promise.all(\n    accountIndices.map(async (accountIndex) => {\n      const derivationPath = buildDerivationPath({ accountIndex, derivationPathType }).BITCOIN;\n      const publicKeyHex = await approvalController.requestPublicKey({\n        curve: 'secp256k1',\n        secretId,\n        derivationPath,\n      });\n      return Uint8Array.from(Buffer.from(publicKeyHex, 'hex'));\n    }),\n  );\n\n  const addresses = await deriveAddressesForBtc(publicKeys, Boolean(network.isTestnet));\n\n  return addresses.map((address) => ({ [NetworkVMType.BITCOIN]: address }));\n};\n"]}