{"version":3,"file":"blockscout.mjs","names":["createChain"],"sources":["../../src/providers/blockscout.ts"],"sourcesContent":["/**\n * Blockscout provider — open-source block explorer\n *\n * No API key needed. Deployed on many chains. REST API v2.\n *\n * Public instances: - eth.blockscout.com - base.blockscout.com - optimism.blockscout.com -\n * arbitrum.blockscout.com - gnosis.blockscout.com - polygon.blockscout.com - linea.blockscout.com -\n * scroll.blockscout.com - zksync.blockscout.com\n */\n\nimport type {\n  ProviderCapabilities,\n  ProviderConfig,\n  ChainKey,\n  Balance,\n  Transaction,\n  TxHistoryOptions,\n  ContractInfo,\n  TokenBalance,\n  TokenBalanceOptions,\n  TokenTransferOptions,\n  GasData,\n  BlockInfo,\n  TxStatus,\n  TokenTransfer,\n} from \"../core/types.js\";\nimport { Provider } from \"../core/provider.js\";\nimport { buildQuery, normalizeBaseUrl } from \"../core/client.js\";\nimport { NotFoundError, UnsupportedChainError } from \"../core/errors.js\";\nimport { assertSafePathSegment } from \"../core/path-safety.js\";\nimport { create as createChain } from \"@agntn/chains\";\nimport { clampMaxResults, formatWei, multiplyIntegerStrings } from \"../core/types.js\";\n\nconst DEFAULT_BASE = \"https://eth.blockscout.com\";\nconst TOKEN_BALANCE_DEFAULT_TIMEOUT = 60_000;\n\nconst CHAIN_BASES: Partial<Record<ChainKey, string>> = {\n  ethereum: DEFAULT_BASE,\n  base: \"https://base.blockscout.com\",\n  arbitrum: \"https://arbitrum.blockscout.com\",\n  optimism: \"https://optimism.blockscout.com\",\n  polygon: \"https://polygon.blockscout.com\",\n  gnosis: \"https://gnosis.blockscout.com\",\n  linea: \"https://linea.blockscout.com\",\n  scroll: \"https://scroll.blockscout.com\",\n  zksync: \"https://zksync.blockscout.com\",\n  avalanche: \"https://avalanche.blockscout.com\",\n};\n\ninterface BlockscoutAddress {\n  readonly hash: string;\n  readonly coin_balance: string | null;\n  readonly implementation_address?: string;\n  readonly is_contract: boolean;\n  readonly is_verified: boolean;\n  readonly name?: string;\n  readonly token?: {\n    readonly name: string;\n    readonly symbol: string;\n    readonly decimals: string;\n    readonly type: string;\n  };\n}\n\ninterface BlockscoutTx {\n  readonly hash: string;\n  /** Null until the transaction is mined. */\n  readonly block_number: number | null;\n  readonly timestamp: string | null;\n  readonly from: { readonly hash: string };\n  readonly to: { readonly hash: string } | null;\n  readonly value: string;\n  readonly gas_used: string | null;\n  readonly gas_price: string | null;\n  /** \"ok\", \"error\", or null while the transaction is still pending. */\n  readonly status: string | null;\n  readonly method?: string;\n  readonly transaction_types?: readonly string[];\n  readonly token_transfers?: readonly BlockscoutTokenTransfer[];\n}\n\ninterface BlockscoutTokenTransfer {\n  readonly token: {\n    readonly address_hash: string;\n    readonly symbol: string;\n    readonly name: string;\n    readonly decimals: string;\n    readonly type: string;\n  };\n  readonly from: { readonly hash: string };\n  readonly to: { readonly hash: string };\n  /** ERC-721/1155 transfers carry token_id here instead of value. */\n  readonly total: { readonly value?: string };\n  readonly transaction_hash: string;\n  readonly block_number: number;\n  readonly timestamp: string;\n}\n\ninterface BlockscoutTokenBalance {\n  readonly token: {\n    readonly address_hash: string;\n    readonly symbol: string | null;\n    readonly name: string | null;\n    readonly decimals: string | null;\n    readonly type: string;\n  } | null;\n  readonly value: string;\n  readonly token_id?: string;\n}\n\ninterface BlockscoutContractInfo {\n  readonly is_verified: boolean;\n  readonly is_proxy?: boolean;\n  readonly proxy_type?: string | null;\n  readonly implementation_address?: string;\n  readonly implementations?: ReadonlyArray<{ readonly address_hash: string }>;\n  readonly name?: string;\n  readonly compiler_version?: string;\n  readonly abi?: ReadonlyArray<Readonly<Record<string, unknown>>>;\n  readonly source_code?: string;\n  readonly creation_tx_hash?: string;\n  readonly deployer?: string;\n}\n\ninterface BlockscoutBlock {\n  readonly height: number;\n  readonly hash: string;\n  readonly parent_hash: string;\n  readonly timestamp: string;\n  readonly miner: { readonly hash: string };\n  readonly gas_used: string;\n  readonly gas_limit: string;\n  readonly transactions_count: number;\n  readonly base_fee_per_gas?: string;\n}\n\ninterface BlockscoutGasPrice {\n  readonly average?: string | number;\n  readonly fast?: string | number;\n  readonly slow?: string | number;\n}\n\ninterface BlockscoutTransactionPage {\n  readonly items: readonly BlockscoutTx[];\n  readonly next_page_params?: Record<string, string | number> | null;\n}\n\nfunction getBase(chain: ChainKey): string {\n  const base = CHAIN_BASES[chain];\n  if (!base) throw new UnsupportedChainError(chain, \"blockscout\");\n  return base;\n}\n\n/* Map fungible transfers to the domain shape; ERC-721/1155 items have no value and are skipped. */\nfunction mapTokenTransfers(raw: Readonly<BlockscoutTokenTransfer[] | undefined>): TokenTransfer[] {\n  const transfers: TokenTransfer[] = [];\n  for (const tt of raw ?? []) {\n    if (tt.total.value === null || tt.total.value === undefined) continue;\n    const decimals = Number(tt.token.decimals);\n    transfers.push({\n      contract: tt.token.address_hash,\n      symbol: tt.token.symbol,\n      name: tt.token.name,\n      decimals,\n      value: tt.total.value,\n      valueFormatted: formatWei(tt.total.value, decimals),\n      from: tt.from.hash,\n      to: tt.to.hash,\n      txHash: tt.transaction_hash,\n      blockNumber: tt.block_number,\n      timestamp: tt.timestamp,\n    });\n  }\n  return transfers;\n}\n\nfunction transactionFee(raw: Readonly<BlockscoutTx>): string | undefined {\n  if (raw.gas_used === null || raw.gas_used === undefined) return undefined;\n  if (raw.gas_price === null || raw.gas_price === undefined) return undefined;\n  return multiplyIntegerStrings(raw.gas_used, raw.gas_price);\n}\n\nfunction transactionStatus(status: string | null | undefined): TxStatus {\n  if (status === \"ok\") return \"success\";\n  return status === null || status === undefined ? \"pending\" : \"failed\";\n}\n\nfunction mapTx(raw: Readonly<BlockscoutTx>): Transaction {\n  const valueWei = BigInt(raw.value).toString();\n\n  return {\n    hash: raw.hash,\n    // Transaction.blockNumber is required, so pending txs get 0, the same\n    // sentinel the etherscan and mempool providers use.\n    blockNumber: raw.block_number ?? 0,\n    timestamp: raw.timestamp ?? undefined,\n    from: raw.from.hash,\n    to: raw.to?.hash ?? null,\n    value: valueWei,\n    valueFormatted: formatWei(valueWei),\n    gasUsed: raw.gas_used ?? undefined,\n    gasPrice: raw.gas_price ?? undefined,\n    fee: transactionFee(raw),\n    status: transactionStatus(raw.status),\n    methodId: undefined,\n    functionName: raw.method,\n    isContractInteraction:\n      raw.transaction_types?.some(\n        (type) => type === \"contract_call\" || type === \"contract_creation\",\n      ) ?? false,\n    tokenTransfers: mapTokenTransfers(raw.token_transfers),\n    raw: raw as unknown as Record<string, unknown>,\n  };\n}\n\nfunction isTokenAbi(abi: readonly Readonly<Record<string, unknown>>[] | undefined): boolean {\n  return (\n    abi?.some((item) => {\n      if (item.type !== \"function\") return false;\n      const name = typeof item.name === \"string\" ? item.name : undefined;\n      return name === \"transfer\" || name === \"balanceOf\" || name === \"totalSupply\";\n    }) ?? false\n  );\n}\n\nfunction isProxyContract(data: Readonly<BlockscoutContractInfo>): boolean {\n  if (data.is_proxy !== null && data.is_proxy !== undefined) return data.is_proxy;\n  const hasProxyType = data.proxy_type !== null && data.proxy_type !== undefined;\n  return hasProxyType || (data.implementations?.length ?? 0) > 0;\n}\n\nfunction mapContractInfo(address: string, data: Readonly<BlockscoutContractInfo>): ContractInfo {\n  return {\n    address,\n    isVerified: data.is_verified,\n    isProxy: isProxyContract(data),\n    implementationAddress: data.implementation_address ?? data.implementations?.[0]?.address_hash,\n    name: data.name,\n    compilerVersion: data.compiler_version,\n    abi: data.abi ? JSON.stringify(data.abi) : undefined,\n    sourceCode: data.source_code,\n    isToken: isTokenAbi(data.abi),\n    creator: data.deployer,\n    creationTxHash: data.creation_tx_hash,\n  };\n}\n\nexport class Blockscout extends Provider {\n  static readonly key = \"blockscout\";\n\n  private defaultChain: ChainKey;\n  private readonly baseUrl: string | undefined;\n  private readonly tokenBalanceTimeout: number;\n\n  constructor(config: Readonly<ProviderConfig>) {\n    super(config);\n    this.defaultChain = config.defaultChain ?? \"ethereum\";\n    this.baseUrl = config.baseUrl ? normalizeBaseUrl(config.baseUrl) : undefined;\n    this.tokenBalanceTimeout = config.timeout ?? TOKEN_BALANCE_DEFAULT_TIMEOUT;\n  }\n  get capabilities(): ProviderCapabilities {\n    return {\n      balances: true,\n      txHistory: true,\n      txDetail: true,\n      utxos: false,\n      contractInfo: true,\n      tokenBalances: true,\n      tokenTransfers: true,\n      gasData: true,\n      blockInfo: true,\n    };\n  }\n\n  private base(chain?: ChainKey): string {\n    const chainBase = getBase(chain ?? this.defaultChain);\n    return this.baseUrl ?? chainBase;\n  }\n\n  async getBalance(address: string, chain?: ChainKey): Promise<Balance> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(address, \"address\");\n    const url = `${this.base(c)}/api/v2/addresses/${encodeURIComponent(address)}`;\n    const data = await this.getJSON<BlockscoutAddress>(url);\n    const balance = data.coin_balance ?? \"0\";\n\n    return this.snapshotBalance({\n      address,\n      chain: c,\n      balance,\n      balanceFormatted: formatWei(balance),\n      symbol: createChain(c).symbol,\n    });\n  }\n\n  /**\n   * Follow Blockscout's 50-item keyset pages up to the 100-result provider limit.\n   *\n   * @param {string} address - The `address` value.\n   * @param {ChainKey} chain - The `chain` value.\n   * @param {Readonly<TxHistoryOptions>} options - The `options` value.\n   * @returns {Promise<Transaction[]>} The resulting value.\n   */\n  async getTxHistory(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TxHistoryOptions>,\n  ): Promise<Transaction[]> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(address, \"address\");\n    const limit = clampMaxResults(options?.limit);\n    const baseUrl = `${this.base(c)}/api/v2/addresses/${encodeURIComponent(address)}/transactions`;\n\n    const transactions: Transaction[] = [];\n    let cursor: Record<string, string | number> = {};\n    for (let fetches = 0; fetches < 2 && transactions.length < limit; fetches++) {\n      const data = await this.getJSON<BlockscoutTransactionPage>(`${baseUrl}${buildQuery(cursor)}`);\n      if (!data.items.length) break;\n      transactions.push(...data.items.slice(0, limit - transactions.length).map(mapTx));\n      if (!data.next_page_params) break;\n      cursor = data.next_page_params;\n    }\n    return transactions.slice(0, limit);\n  }\n\n  override async getTxDetail(hash: string, chain?: ChainKey): Promise<Transaction> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(hash, \"tx hash\");\n    const url = `${this.base(c)}/api/v2/transactions/${encodeURIComponent(hash)}`;\n    const data = await this.getJSON<BlockscoutTx>(url);\n    return mapTx(data);\n  }\n\n  override async getContractInfo(address: string, chain?: ChainKey): Promise<ContractInfo> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(address, \"address\");\n\n    // Try verified contract first\n    try {\n      const url = `${this.base(c)}/api/v2/smart-contracts/${encodeURIComponent(address)}`;\n      const data = await this.getJSON<BlockscoutContractInfo>(url);\n      return mapContractInfo(address, data);\n    } catch (error) {\n      if (!(error instanceof NotFoundError)) throw error;\n      const addrUrl = `${this.base(c)}/api/v2/addresses/${encodeURIComponent(address)}`;\n      const addr = await this.getJSON<BlockscoutAddress>(addrUrl);\n\n      return {\n        address,\n        isVerified: addr.is_verified,\n        name: addr.name,\n        isToken: addr.token !== null && addr.token !== undefined,\n      };\n    }\n  }\n\n  override async getTokenBalances(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TokenBalanceOptions>,\n  ): Promise<TokenBalance[]> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(address, \"address\");\n    const url = `${this.base(c)}/api/v2/addresses/${encodeURIComponent(address)}/token-balances`;\n    const balances = await this.getJSON<BlockscoutTokenBalance[]>(url, {\n      timeout: this.tokenBalanceTimeout,\n    });\n\n    let tokens = balances.flatMap<TokenBalance>((item) => {\n      const token = item.token;\n      if (token?.type !== \"ERC-20\") return [];\n      const decimals = Number(token.decimals ?? 0);\n      return [\n        {\n          contract: token.address_hash,\n          symbol: token.symbol ?? \"\",\n          name: token.name ?? undefined,\n          decimals,\n          balance: item.value,\n          balanceFormatted: formatWei(item.value, decimals),\n        },\n      ];\n    });\n\n    if (options?.nonZeroOnly) {\n      tokens = tokens.filter((t) => t.balance !== \"0\");\n    }\n\n    return tokens;\n  }\n\n  /**\n   * Walk the keyset-paginated ERC-20 transfer list until `limit` is reached.\n   *\n   * The endpoint accepts only a token filter and a `next_page_params` cursor. Block range, sort,\n   * and page have no server-side equivalent and are ignored, the same way `getTxHistory` ignores\n   * them.\n   *\n   * @param {string} address - The `address` value.\n   * @param {ChainKey} chain - The `chain` value.\n   * @param {Readonly<TokenTransferOptions>} options - The `options` value.\n   * @returns {Promise<TokenTransfer[]>} The resulting value.\n   */\n  override async getTokenTransfers(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TokenTransferOptions>,\n  ): Promise<TokenTransfer[]> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(address, \"address\");\n    const limit = clampMaxResults(options?.limit);\n    const baseUrl = `${this.base(c)}/api/v2/addresses/${encodeURIComponent(address)}/token-transfers`;\n\n    const transfers: TokenTransfer[] = [];\n    let cursor: Record<string, string | number> = {};\n    // Pages hold 50 items and the limit clamps at 100, so 4 fetches always cover it.\n    for (let fetches = 0; fetches < 4 && transfers.length < limit; fetches++) {\n      const query = buildQuery({ type: \"ERC-20\", token: options?.token, ...cursor });\n      const data = await this.getJSON<{\n        items?: BlockscoutTokenTransfer[];\n        next_page_params?: Record<string, string | number> | null;\n      }>(`${baseUrl}${query}`);\n      if (!data.items?.length) break;\n      transfers.push(...mapTokenTransfers(data.items));\n      if (!data.next_page_params) break;\n      cursor = data.next_page_params;\n    }\n    return transfers.slice(0, limit);\n  }\n\n  override async getGasData(chain?: ChainKey): Promise<GasData> {\n    const c = chain ?? this.defaultChain;\n    const url = `${this.base(c)}/api/v2/stats`;\n    const data = await this.getJSON<Record<string, unknown>>(url);\n\n    // Blockscout stats endpoint varies; extract gas data if available\n    const gasPrices = data.gas_prices as BlockscoutGasPrice | undefined;\n\n    return {\n      chain: c,\n      unit: \"gwei\",\n      safeGasPrice: gasPrices?.slow === undefined ? undefined : String(gasPrices.slow),\n      proposedGasPrice: gasPrices?.average === undefined ? undefined : String(gasPrices.average),\n      fastGasPrice: gasPrices?.fast === undefined ? undefined : String(gasPrices.fast),\n    };\n  }\n\n  override async getBlockInfo(blockNumber: number, chain?: ChainKey): Promise<BlockInfo> {\n    const c = chain ?? this.defaultChain;\n    assertSafePathSegment(String(blockNumber), \"block number\");\n    const url = `${this.base(c)}/api/v2/blocks/${encodeURIComponent(String(blockNumber))}`;\n    const data = await this.getJSON<BlockscoutBlock>(url);\n\n    return {\n      number: data.height,\n      hash: data.hash,\n      parentHash: data.parent_hash,\n      timestamp: data.timestamp,\n      miner: data.miner.hash,\n      gasUsed: data.gas_used,\n      gasLimit: data.gas_limit,\n      txCount: data.transactions_count,\n      baseFee: data.base_fee_per_gas,\n    };\n  }\n}\n"],"mappings":"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"}