fuels-ts Provider 链上查询指南:从 getCoins 到 getMessageProof 的 9 个核心方法
发布时间:2026/9/10 9:06:02来源:尧图网络
fuels-ts Provider 链上查询指南从 getCoins 到 getMessageProof 的 9 个核心方法【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts配置好 Provider燃料主网、测试网或本地节点的 JSON-RPC 连接之后你便可以通过 fuels-ts SDK 只读地查询 Fuel 区块链上的各类链上数据账户资产、UTXO 代币、消息Message、区块、交易与消息包含性证明。本文以 querying-the-chain.md 为主线完整讲解Provider上 9 个核心查询方法并结合 packages/account/src/providers/provider.ts 的源码实现说明它们的参数、默认值与底层调用逻辑让你能直接把这些片段落到自己的 DApp 或脚本里。若还没有完成节点连接建议先阅读 Connecting to the Network 了解网络 URL 配置本文片段中的LOCAL_NETWORK_URL、WALLET_ADDRESS、WALLET_PVT_KEY均来自文档站的环境配置。查询方法总览Provider类是 SDK 与 Fuel 节点交互的统一入口。以下方法用于读取链上状态其中多数是只读的 GraphQL 查询部分如produceBlocks仅适用于本地测试节点方法作用是否支持分页getBaseAssetId返回链的基础资产 ID否getCoins返回账户地址的 UTXO 代币可按资产 ID 过滤是getResourcesToSpend返回一笔交易可花费的资源代币或消息否getBalances返回所有资产的总额UTXO 未花费消息视节点能力而定getBlocks返回链上区块是getMessageByNonce按 nonce 查询单条消息否getMessages返回地址收到的消息列表是getMessageProof返回消息被区块包含的密码学证明否getTransactions返回链上交易列表是每页上限 30本文出现的示例片段原文位于 apps/docs/src/guide/provider/snippets/functionality。getBaseAssetId获取基础资产 ID基础资产base asset是链上执行任何交易都需要使用的底层资产Fuel 链上即 ETH。在构建交易前应先通过 Provider 取回该 ID再把它传给交易的收款输出等结构。import { Address, Provider, ScriptTransactionRequest } from fuels; import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from ../../../../env; // 通过 provider 获取基础资产 ID const provider new Provider(LOCAL_NETWORK_URL); const baseAssetId await provider.getBaseAssetId(); // 0x... // 实例化收款方地址 const recipientAddress new Address(WALLET_ADDRESS); // 创建一笔脚本交易请求 const transactionRequest new ScriptTransactionRequest(); // 使用基础资产执行一次转账输出 transactionRequest.addCoinOutput(recipientAddress, 100, baseAssetId);完整代码见 get-base-asset-id.ts。注意其注释返回值是形如0x...的地址格式字符串。从源码看该方法的实现非常简单——直接读取链的共识参数async getBaseAssetId() { const all await this.getChain(); const { consensusParameters: { baseAssetId }, } all; return baseAssetId; }参见 provider.ts L1047-L1053。也就是说基础资产 ID 是由节点返回的链共识参数决定的同一个 Provider 连接的链不同getBaseAssetId()的结果就可能不同因此不建议硬编码资产 ID而是每次从 Provider 动态获取。getCoins查询账户的 UTXO 代币getCoins返回某个账户地址名下的 UTXO 代币列表可按资产 ID 过滤并支持 GraphQL 游标分页paginationArgs参数。从 Provider 调用时需要显式传入地址import { Provider, Wallet } from fuels; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from ../../../../env; const provider new Provider(LOCAL_NETWORK_URL); const wallet Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const assetIdA 0x0101010101010101010101010101010101010101010101010101010101010101; const baseAssetId await provider.getBaseAssetId(); // 取最多 100 个、资产 ID 等于 baseAssetId 的代币 const { coins: coinsOnlyBaseAsset } await provider.getCoins( wallet.address, baseAssetId ); // [ // { amount: bn(100), assetId: baseAssetId }, // ... // ] // 取最多 100 个、不限资产 ID 的代币 const { coins: coinsAnyAsset } await provider.getCoins(wallet.address); // [ // { amount: bn(100), assetId: baseAssetId } // { amount: bn(100), assetId: assetIdA } // ... // ]分别见 get-coins-from-provider.ts 与 get-coins-from-account.ts。getCoins在Account钱包是它的子类上也有同名实现可以省去address参数直接读取钱包自己的地址const { coins } await wallet.getCoins(baseAssetId);从签名看Provider 版本完整参数为getCoins(owner, assetId?, paginationArgs?)见 provider.ts L1890-L1919返回结构为{ coins, pageInfo }其中每个coin被映射为{ id, assetId, amount, owner, blockCreated, txCreatedIdx }。分页的详细用法after/first前向分页、before/last反向分页、pageInfo中的startCursor/endCursor/hasNextPage/hasPreviousPage请参见 pagination.md按该文档说明当不传assetId与paginationArgs时getCoins默认按基础资产 ID 返回前 100 条。getResourcesToSpend挑选一笔交易的可花费资源Fuel 是 UTXO 模型交易需要预先选定燃料可花费的代币与消息。getResourcesToSpend根据若干CoinQuantityLike数量需求返回满足条件的可花费资源代币或消息供后续addResources组装进交易。它接受可选的第三参resourcesIdsToIgnore用来排除特定的 UTXO ID 或消息 nonceimport type { CoinQuantityLike, ResourcesIdsToIgnore } from fuels; import { Provider, ScriptTransactionRequest, Wallet } from fuels; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from ../../../../env; const provider new Provider(LOCAL_NETWORK_URL); const wallet Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const assetIdA 0x0101010101010101010101010101010101010101010101010101010101010101; const baseAssetId await provider.getBaseAssetId(); // 需要 32 个 baseAsset最多接受 42 个以及 50 个 assetIdA const quantities: CoinQuantityLike[] [ { amount: 32, assetId: baseAssetId, max: 42 }, { amount: 50, assetId: assetIdA }, ]; const utxoId 0x00000000000000000000000000000000000000000000000000000000000000010001; const messageNonce 0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0; const excludedIds: ResourcesIdsToIgnore { utxos: [utxoId], messages: [messageNonce], }; const spendableResources await provider.getResourcesToSpend( wallet.address, quantities, excludedIds ); const tx new ScriptTransactionRequest(); tx.addResources(spendableResources);Account类同样实现了此方法省去address见 get-resources-to-spend-from-account.tsconst spendableResources await wallet.getResourcesToSpend( quantities, excludedIds );两个版本完整代码分别在 get-resources-to-spend-from-provider.ts 和 get-resources-to-spend-from-account.ts。在 provider.ts L1929-L1984 的实现中可以看到两个值得注意的细节CoinQuantityLike中amount为 0 时会被提升为 1amount.eqn(0) ? bn(1) : amount确保 GraphQL 查询语义正确节点返回的coinsToSpend会被扁平化并按类型Coin或MessageCoin还原成结构化的Resource对象——这就是可花费资源既可能来自 UTXO 代币、也可能来自桥上消息这一设计在代码层面的体现。getBalances按资产汇总余额getBalances返回某个地址下所有资产的金额汇总即所有 UTXO 代币与未花费消息代币message coin数量之和。与getCoins的区别是它只给出每种资产的总额而不展开单个代币const { balances } await provider.getBalances(wallet.address); // [ // { amount: bn(42), assetId: baseAssetId } // baseAssetId 总额 // { amount: bn(100), assetId: assetIdA } // assetIdA 总额 // ]Account上同样可以直接调用get-balances.tsawait wallet.getBalances();源码实现provider.ts L2279-L2313比文档描述更精细它会先通过getNodeFeatures()探测节点是否支持余额分页只有节点支持时才使用调用方传入的paginationArgs否则回退到{ first: NON_PAGINATED_BALANCES_SIZE }保证在不支持分页的旧节点上也能拿全数据。因此返回对象只有在节点支持分页时才附带pageInfo。getBlocks按分页参数取区块getBlocks接收paginationArgs返回链上区块同样支持游标分页。下面的例子展示了如何获取最近 10 个区块——先用produceBlocks在本地节点上强制出块确保区块存在再读取import { Provider } from fuels; import { LOCAL_NETWORK_URL } from ../../../../env; const provider new Provider(LOCAL_NETWORK_URL); const blockToProduce 3; // 强制产生一些区块保证链上有区块可查 await provider.produceBlocks(blockToProduce); const { blocks } await provider.getBlocks({ last: blockToProduce, });见 get-blocks.ts。注意这里使用的是反向分页组合last: blockToProduce表示取游标之前即最新的 N 个区块。produceBlocks属于本地开发专用 API仅应在测试节点上使用。getMessageByNonce按 nonce 查消息每条 Fuel 消息都有唯一的nonce。getMessageByNonce可根据 nonce 直接取回单条消息。由于在常规网络上不一定能方便地制造消息示例用fuels/test-utils的launchTestNode启动本地测试节点并在快照配置里用TestMessage预置一条消息import { launchTestNode, TestMessage } from fuels/test-utils; const { provider } await launchTestNode({ nodeOptions: { snapshotConfig: { stateConfig: { messages: [ new TestMessage({ nonce: 0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0, }).toChainMessage(), ], }, }, }, }); const nonce 0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0; const message await provider.getMessageByNonce(nonce);完整代码见 get-messages-by-nonce.ts。片段中的using launched await launchTestNode(...)是 TS 显式资源管理语法SDK 测试工具包中的标准用法会自动在作用域结束时关闭测试节点。getMessages查询消息列表getMessages用于获取某地址收到的消息列表同样支持分页。因为它被定义在Account上所以可以从钱包实例直接查询import { Provider, Wallet } from fuels; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from ../../../../env; const provider new Provider(LOCAL_NETWORK_URL); const wallet Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); // 从钱包查询收到的消息 const { messages } await wallet.getMessages();见 get-messages.ts。底层实现provider.ts L2322-L2356使用与getCoins相同的分页校验RESOURCES_PAGE_SIZE_LIMIT并将每条消息映射为{ messageId, sender, recipient, nonce, amount, data, daHeight }——其中messageId由InputMessageCoder.getMessageId依据发送方、接收方、nonce、金额与数据计算得到data则会被decodeData解码而不是直接返回原始字节。getMessageProof获取消息包含性证明消息证明message proof是一份密码学证明用于证实某条消息确实被包含进了某个区块。这在桥bridge等需要向其他链出示提款证据的场景中很关键。getMessageProof需要交易 ID 与从 MessageOut receipt 中取得的 nonce并可用区块 ID或区块高度二选一定位提交区块。按区块 ID 查询import type { TransactionResultMessageOutReceipt } from fuels; import { sleep } from fuels; import { launchTestNode } from fuels/test-utils; using launched await launchTestNode({ nodeOptions: { args: [--poa-instant, false, --poa-interval-period, 1s], }, }); const { provider, wallets: [sender, recipient] } launched; // 从 sender 向 L1 发起一笔提款交易从而产生一条消息 const withdrawTx await sender.withdrawToBaseLayer( recipient.address.toB256(), 100 ); const result await withdrawTx.waitForResult(); // 等待新区块提交1 个确认块取最新区块 await sleep(1500); const latestBlock await provider.getBlock(latest); // 从初始交易的 receipt 中取 nonce const { nonce } result.receipts[0] as TransactionResultMessageOutReceipt; // 用最新区块 ID 查询该消息的证明 const messageProofFromBlockId await provider.getMessageProof( result.id, nonce, latestBlock?.id );按区块高度查询第四参传高度const messageProofFromBlockHeight await provider.getMessageProof( result.id, nonce, undefined, latestBlock?.height );两个版本分别见 get-message-proof-block-id.ts 与 get-message-proof-block-height.ts。示例末尾会校验messageProofFromBlockId?.amount.toNumber() 100即证明中的金额应与提款金额一致。源码 provider.ts L2367-L2408 中有两个实现细节值得注意commitBlockId与commitBlockHeight不能同时传否则会抛出FuelError错误码INVALID_INPUT_PARAMETERS内部会把区块高度从BN转为十进制数字字符串再发给节点 GraphQL 查询代码注释也指出这是对 fuel client 侧的兼容处理。getTransactions查询交易列表getTransactions返回链上交易列表每页最多 30 条适合做区块浏览器式的时间线展示import { Provider } from fuels; import { LOCAL_NETWORK_URL } from ../../../../env; const provider new Provider(LOCAL_NETWORK_URL); const { transactions } await provider.getTransactions();见 get-transactions.ts。文档明确标注这是单页上限 30 条的接口需要更多历史交易时应按返回结构中的分页信息逐页拉取。汇总与下一步围绕 Provider 的链上查询能力本指南覆盖了资产getBaseAssetId、getCoins、getBalances、getResourcesToSpend、消息getMessageByNonce、getMessages、getMessageProof以及区块/交易浏览getBlocks、getTransactions三大类共 9 个方法并展示了它们在Provider与Account钱包两个层面的等价调用方式。想进一步深入可在当前仓库中阅读查询类代码示例目录apps/docs/src/guide/provider/snippets/functionality分页参数与默认行为pagination.md 及配套片段 pagination.tsProvider 完整方法实现packages/account/src/providers/provider.tsProvider 的集成级测试如getCoins、getResourcesToSpend的实际链上行为provider.test.ts。掌握了只读查询之后下一步通常是结合ScriptTransactionRequest/Contract构建并发送交易完成从读链到写链的完整闭环。【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网