@circle-fin/adapter-ethers-v6

中文文档
1.13.1发布于 2026/11/06TypeScriptESM + CJS近 30 天下载 8502

EVM 区块链适配器由 Ethers v6 供电

中文使用文档
文档目录41 节
  1. 目录
  2. 概览
  3. 为什么以太s v6适应器?
  4. 何时使用此适配器
  5. 安装
  6. 同伴依赖关系
  7. 解决版本冲突
  8. 快速启动
  9. Zero-Config 设置( 建议)
  10. 生产设置
  11. 浏览器钱包设置
  12. 下一个Generation API( /next (中文(简体) )
  13. 开始 /next
  14. 为什么 /next ? 吗?
  15. 套装大小注释
  16. 目前的限制 /next
  17. 已编制交易:估计、模拟、执行
  18. 日志
  19. 计量
  20. 托肯书记官处
  21. 交易调制
  22. 遥测密钥编辑出错( C)
  23. 迁移路径
  24. 操作 Context 模式
  25. 为什么是Context行动?
  26. 基本用途
  27. 多频道业务
  28. 地址背景指南
  29. 用户控制( 建议)
  30. 开发者控制( 高级)
  31. 用法实例
  32. 合同互动
  33. EIP-712 签署
  34. 跨越海峡
  35. API 参考
  36. 工厂功能
  37. 核心方法
  38. 调试操作
  39. 支持的链路( R)
  40. 发展
  41. 许可证

以太s v6 适应器

npm version TypeScript License

由 Ethers v6 供电的型式安全 EVM 区块链适配器

使用单一的强型接口与16+ EVM 网络进行无缝互动

目录

概览

Ethers v6 适配器是强烈类型的执行 Adapter 接口 与EVM兼容的区块链。在大众之上建造 以太为 v6 库中,它通过一个统一接口提供类型安全的区块链交互,该接口旨在与该区无缝地工作 桥套 用于索拉纳网络和EVM网络之间跨链的USDC转移,以及用于额外稳定币业务的任何未来工具包。 任何使用App Kits架构建造的Kit和/或任何插入这些工具包的供应商都可以使用.

为什么以太s v6适应器?

  • 带上你自己的设定: 使用您现有的以太 JsonRpcProvider 财务报告和审定财务报表 Wallet 实例
  • EVM 兼容: 与Ethereum, Base, Arbitrium 和所有 EVM 链条一起工作
  • QQ 类型安全: 以 TypeScript 严格模式用于完整类型安全
  • 简单 API: 复杂区块链操作上的清洁抽象
  • 交易生命周期 - 完成编制/估计/执行工作流程
  • * 跨链准备就绪 - EVM链与索拉纳之间无缝接通的USDC

何时使用此适配器

对于 Kit 用户

如果使用Bridge Kit或其他App Kit进行跨链操作,只需即时处理出一个适配器并传递给工具包. 同一个适配器在所有支持的链条上工作.

// Single adapter instance for multi-chain operations
// Note: Private keys can be provided with or without '0x' prefix
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`, // Both '0x...' and '...' work
})

// Both formats are automatically normalized:
const adapter1 = createEthersAdapterFromPrivateKey({
  privateKey: '0x1234...', // With prefix ✅
})

const adapter2 = createEthersAdapterFromPrivateKey({
  privateKey: '1234...', // Without prefix ✅ (automatically normalized)
})

对于 Kit 提供者开发者

若建供养者(如道俗 BridgingProvider 执行),您将使用适配器的抽象方法与不同的链条相互作用. 行动Context模式使多链操作无缝.

安装

npm install @circle-fin/adapter-ethers-v6 ethers
# or
yarn add @circle-fin/adapter-ethers-v6 ethers

同伴依赖关系

这个适配器需要 ethers (v6)作为同伴依赖. 与适配器一起安装 :

npm install @circle-fin/adapter-ethers-v6 ethers
# or
yarn add @circle-fin/adapter-ethers-v6 ethers

已支持的版本 : ^6.11.0 (6.11.x至6.x.x,不包括7.x.x.x.)

解决版本冲突

如果遇到同伴依赖警告:

  • 检查你的 ethers 版本 : npm ls ethers
  • 保证醚 v6 介于 6.1.10. 至 7.0.0 (排他性)之间
  • 使用 npm install ethers@^6.11.0 以安装兼容的版本
  • 说明: 这个适配器是 没有 兼容醚 v5 或 v7

快速启动

最简单的方式是从懒惰的初始化开始. 默认配置自动处理适配器设置.

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'

// Minimal configuration with lazy initialization
// Note: Private keys work with or without '0x' prefix
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`, // Both '0x...' and '...' work
  // Defaults applied:
  // - addressContext: 'user-controlled'
  // - supportedChains: all EVM chains (~34 networks)
  // - Lazy initialization: wallet connects to chain on first operation
})

// Chain specified per operation via OperationContext
const prepared = await adapter.prepare(
  {
    address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
    abi: usdcAbi,
    functionName: 'transfer',
    args: ['0xrecipient', '1000000'],
  },
  { chain: 'Ethereum' }, // Chain specified in context
)

const txHash = await prepared.execute()

生产设置

对于生产用途,提供定制RPC终点,以提高可靠性和性能:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'
import { JsonRpcProvider } from 'ethers'
import { Ethereum, Base, Polygon } from '@circle-fin/bridge-kit/chains'

// Production-ready with custom RPC endpoints and lazy initialization
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
  // Custom RPC provider with explicit chain mapping
  getProvider: ({ chain }) => {
    // Map chain names to RPC endpoints
    // Customize this mapping based on your RPC provider
    const rpcEndpoints: Record<string, string> = {
      Ethereum: `https://eth-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`,
      Base: `https://base-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`,
      Polygon: `https://polygon-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`,
    }

    const endpoint = rpcEndpoints[chain.name]
    if (!endpoint) {
      throw new Error(`RPC endpoint not configured for chain: ${chain.name}`)
    }

    return new JsonRpcProvider(endpoint, chain.chainId)
  },
  // Optionally restrict to specific chains
  capabilities: {
    supportedChains: [Ethereum, Base, Polygon],
  },
})

生产说明: 默认工厂方法使用公共RPC端点,这些端点可能具有速率限制. 用于生产,使用Alchemy,Infura,或QuickNode等专用供应商.

浏览器钱包设置

对于带有MetaMask或钱包连接的浏览器环境:

import { createEthersAdapterFromProvider } from '@circle-fin/adapter-ethers-v6'

// Minimal browser wallet configuration
const adapter = await createEthersAdapterFromProvider({
  provider: window.ethereum,
  // Default capabilities applied automatically
})

// User will be prompted to connect wallet
// Address is automatically resolved from connected wallet
const prepared = await adapter.prepare(
  {
    address: '0xcontract',
    abi: contractAbi,
    functionName: 'approve',
    args: ['0xspender', '1000000'],
  },
  { chain: 'Polygon' },
)

下一个Generation API(/next(中文(简体) )

预览 - 电话 /next 入口是即将到来的默认适配器架构. 它与目前所支持的桥梁流量的切入点相当,并且与所有现有工具包(Bridge Kit等)完全兼容。 在下一个主要发布, /next 将会成为默认的导入,当前切入点将会被退出。 见 目前的限制 /next 在通过之前.

开始 /next

通过改变单一导入路径来切换到新架构. 其他一切不变:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6/next'

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
})

// Pass it to the Bridge Kit exactly as before — no changes needed downstream

提示 : 这个 /next 工厂接受 privateKey 作为一个平地 string - 那个 0x 前缀为可选并自动正常化。 不需要模板字面类型的断言 .

浏览器钱包工作相同 :

import { createEthersAdapterFromProvider } from '@circle-fin/adapter-ethers-v6/next'
import { Ethereum, Base, Polygon } from '@circle-fin/bridge-kit/chains'

const adapter = createEthersAdapterFromProvider({
  provider: window.ethereum,
  capabilities: {
    addressContext: 'user-controlled',
    supportedChains: [Ethereum, Base, Polygon],
  },
})

createEthersAdapterFromProvider 也接受一种醚 Provider 直接 – 在您已经使用过的服务器侧工作流程中有用 维持a JsonRpcProvider 并且希望适配器能重用它 将输入包入每个链 BrowserProvider数字 :

import { createEthersAdapterFromProvider } from '@circle-fin/adapter-ethers-v6/next'
import { JsonRpcProvider } from 'ethers'

const provider = new JsonRpcProvider(process.env.RPC_URL)

const adapter = createEthersAdapterFromProvider({ provider })

工厂在运行时检测输入形状: EIP-1193 提供商 (单位:千美元){ request }每条链被包裹,而乙醚 Provider (单位:千美元){ getNetwork }直接使用并返回自己的 getSigner() 结果.

为什么 /next? 吗?

当前切入点/next 切入点
套装大小包含全部适配器私人进口 解锁树摇; 默认工厂仍然拉 compat shim — 看 捆绑大小
准备结果estimate() 财务报告和审定财务报表 execute()estimate(), (中文(简体) ), simulate(),以及 execute(overrides?)
收费模式{ gas, gasPrice, fee }{ fee, units, unitPrice } ——所有生态系统保持一致
观察性不详内建伐木、计量和事件仪器
重试恢复能力( R)不详可配置重试, 以指数倒置表示短暂的失败
调制解析硬码地址累加式符号登记——用符号解决任何符号跨链
交易调试固定气体默认值可配置的费用缓冲、优先收费下限和确认超时

套装大小注释

这个 /next 入口的清洁建筑设计 按原产地计算可动摇树:进口 createPrepare 无 createBatchExecute 只能运送准备路径。 单位 当前预览释放默认 createAdapter 工厂仍然 牵扯在遗产 compat shim (withLegacyCompat → @core/adapter-compat消费者可以通过 生成的适配器与现有工具包和提供者不作改动. 那闪电是默认的 /next 捆绑量度~11% 大于我们内部基准中遗留的切入点.

如果捆绑大小对您至关重要,则直接通过 assembleAdapter 从 @core/adapter-base 跳过 withLegacyCompat。未来微小的释放将分裂共通 在单独的入口后面,所以默认的工厂 仅新建 API.

目前的限制 /next

这个 /next 以太适配器与当前切入点对等 支持的桥流,但一些能力仍在 进展。 在项目问题跟踪器中跟踪这些结果,以采取后续行动 释放:

  • 没有原子批量批准+活化. EIP-5792 信息技术 wallet_sendCalls 只能用Viem 进行批量 /next 适配器; 以太 适配器(以及 CCTP) /next 桥由它驱动时的桥流)提交 核准和烧为两个单独的交易.
  • 圆形钱包适配器尚未迁移到 /next。 。 。 . 仅 eVM (viem/ethers) 和索拉纳适配器显示 /next 入场点; 圆形钱包留在目前的出入口上.
  • 中止语义只停止本地等待 . 通过中止(或 可中止) signal 取消数 waitForTransaction 并预防 未经同意 execute 从广播,但 一经交易 播放, 中止不会在链上取消 交易 并且应该通过散列进行调和.

已编制交易:估计、模拟、执行

当您准备通过 /next 适配器,你用三种生命周期方法返回更丰富的对象:

const prepared = await adapter.prepare(
  {
    address: '0xContractAddress',
    abi: contractAbi,
    functionName: 'transfer',
    args: ['0xRecipient', 1_000_000n],
  },
  { chain: 'Base' },
)

// 1. Estimate gas and fees before committing
const { fee, units, unitPrice } = await prepared.estimate()

// 2. Simulate the transaction to catch reverts without spending gas
const simulation = await prepared.simulate()

// 3. Execute when ready (with optional gas overrides)
const result = await prepared.execute()

// `result` is a `{ txId, wait }` envelope:
// - `txId` is the transaction hash on EVM (the field is named `txId`
//   rather than `hash` so the same shape works across ecosystems).
// - `wait()` resolves once the transaction is confirmed on-chain.
console.log('submitted tx:', result.txId)
const confirmation = await result.wait()
console.log('confirmed in block:', confirmation.blockNumber)

这个 simulate() 步骤是新建的 /next ——它根据当前链状状态对交易进行干燥,表面在耗用气体前还原原因.

日志

传出 a runtime 选项以获取每个适配器操作的结构化日志,包括 RPC 调用、重试和出错。 最快的方法是使用内置 createRuntime 帮助者 :

import {
  createEthersAdapterFromPrivateKey,
  createRuntime,
} from '@circle-fin/adapter-ethers-v6/next'

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
  runtime: createRuntime(), // Logs to stdout via pino at 'info' level
})

要与自己的日志集成, 请通过执行对象 debug, (中文(简体) ), info, (中文(简体) ), warn, (中文(简体) ), error,以及 child 改为 createRuntime。日志接口使用 (message, fields) 参数顺序——皮诺等库使用 (fields, message),所以需要一个薄薄的包装:

import {
  createEthersAdapterFromPrivateKey,
  createRuntime,
} from '@circle-fin/adapter-ethers-v6/next'
import pino from 'pino'

function wrapPino(p: pino.Logger) {
  return {
    debug: (msg: string, fields?: Record<string, unknown>) =>
      p.debug(fields, msg),
    info: (msg: string, fields?: Record<string, unknown>) =>
      p.info(fields, msg),
    warn: (msg: string, fields?: Record<string, unknown>) =>
      p.warn(fields, msg),
    error: (msg: string, fields?: Record<string, unknown>) =>
      p.error(fields, msg),
    child: (tags: Record<string, unknown>) => wrapPino(p.child(tags)),
  }
}

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
  runtime: createRuntime({ logger: wrapPino(pino({ level: 'debug' })) }),
})

计量

这个 runtime 选项还接受 metrics 用于计数器、直方图和计时器的执行。 插入普罗米修斯,StatsD, Datadog, OpenTeleometry, 或任何其他后端 :

import {
  createEthersAdapterFromPrivateKey,
  createRuntime,
} from '@circle-fin/adapter-ethers-v6/next'

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
  runtime: createRuntime({
    metrics: {
      counter: (name) => ({
        inc: (labels, value) => {
          /* emit counter */
        },
      }),
      histogram: (name) => ({
        observe: (labels, value) => {
          /* emit histogram */
        },
      }),
      timer: (name) => ({
        start: (labels) => {
          const t0 = Date.now()
          return () => {
            /* observe Date.now() - t0 */
          }
        },
      }),
      child: (labels) => {
        /* return scoped Metrics with base labels merged */
      },
    },
  }),
})

否时 metrics 平面电话是无声的 无声的 零起落.

托肯书记官处

默认情况下,适配器知道USDC(和其他内置符)在每个支持链上的情况. 这个 tokens 选项允许您注册额外的符号,以便它们可以通过符号而不是原始地址来引用.

import {
  createEthersAdapterFromPrivateKey,
  createTokenRegistry,
} from '@circle-fin/adapter-ethers-v6/next'

const tokens = createTokenRegistry({
  tokens: [
    {
      symbol: 'WETH',
      decimals: 18,
      locators: {
        Ethereum: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        Base: '0x4200000000000000000000000000000000000006',
      },
    },
  ],
})

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
  tokens,
})

登记册自动解决每个链条的正确合同地址和小数,因此下游代码可以指: 'WETH' 而不是每个网络的硬编码地址.

交易调制

这个 config 选项允许您调制气价、 重试行为和确认超时 :

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6/next'

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
  config: {
    transaction: {
      feePriceBufferBps: 2000n, // 20% buffer on gas pricing (default)
      minPriorityFeeWei: 1_500_000_000n, // 1.5 gwei priority-fee floor
      confirmationTimeoutMs: 120_000, // 2 minute confirmation timeout
    },
    retry: {
      maxAttempts: 3,
      baseDelayMs: 1000,
    },
  },
})
设置它控制着什么默认
feePriceBufferBps减少天然气定价,防止估算和纳入之间的价格波动(基准点;10 000=100%)2000n (20%)
minPriorityFeeWei下限 maxPriorityFeePerGas ——防止近零小费被验证者静悄悄地投出1_500_000_000n (1.5克维)
confirmationTimeoutMs多长时间 waitForTransaction 等待时间结束客户违约
retry.maxAttempts最大尝试次数( 不包括初始尝试)3
retry.baseDelayMs以毫秒为单位的重试之间的基数延迟( 每次重试时通过指数倒置)200

设定 retry: false 完全禁用自动重试.

遥测密钥编辑出错( C)

KitError.cause.trace 是SDK用于遥测管道的诊断表面. 它带有有用的死后背景—— 修饰的 rawError 形状, 提供者 code,则a shortMessage 字段。 这些字段的字符串 能够 包括配置的 RPC URL 和任何嵌入的 API 密钥, 因为 ethers v6's makeError() 格式 info 键直接输入信件串本身,例如:

missing response (requestUrl="https://mainnet.infura.io/v3/MY_KEY", code=SERVER_ERROR, ...)

同样的图案在Viem的表面 HttpRequestError.shortMessageSDK分两层处理:

  1. 对象图条( 总是在) - 那个 request, (中文(简体) ), info来源 XMLHttpRequest,以及 transport.url 属性从未嵌入 cause.trace. 这是从第一轮重排开始的合同.
  2. 信件内容擦除( 对 ~ 12 已知 RPC 提供者默认操作; 操作员可扩展) - SDK飞船 defaultMessageRedactor 在模块加载时活动,将API-key片段从信件字符串醚/viem格式的内部清除出,用于最常用的没有操作员配置的公用RPC供应商. URL 分类通过平台实现 URL 解析器加一个主机后缀列表( p)DEFAULT_RPC_HOST_SUFFIXES因此,添加一个新的提供者是一行变更,不需要正则审计.

默认会从盒子里抓出什么

提供者主机后缀
炼金术.g.alchemy.com
因福拉语Name.infura.io
快速节点.quiknode.pro
安克尔.ankr.com
链层.p2pify.com
温柔.gateway.tenderly.co
块化PI.blockpi.network
获取锁定.getblock.io
莫拉利斯语Name.moralis-nodes.com
赫利乌斯(索拉纳).helius-rpc.com, (中文(简体) ), .helius.xyz
特里通(索拉纳语).rpcpool.com
一般查询字符串?api-key=…, (中文(简体) ), ?apikey=…, (中文(简体) ), ?token=…, (中文(简体) ), ?secret=…, (中文(简体) ), ?key=…
一般认证信头Bearer <token>

任何 URL 内容 host.endsWith(suffix) 匹配表格的批发 [REDACTED]. 分类由同一人进行 URL 解析平台用途 fetch(),因此它不能不慎匹配调用数据,合同地址,交易散列,或者返回原因(其中没有一个解析为URL).

防御深度,不是保证

3件事情仍然需要你注意, 即使默认:

  1. 自定义或自托管的 RPC URL 不被默认覆盖. 扩展主机后缀列表 composeRedactor数字 :

    import {
      composeRedactor,
      setMessageRedactor,
      DEFAULT_RPC_HOST_SUFFIXES,
    } from '@core/errors'
    
    setMessageRedactor(
      composeRedactor({
        hostSuffixes: [...DEFAULT_RPC_HOST_SUFFIXES, '.rpc.my-corp.example'],
      }),
    )
    
  2. 错误消息仍然不可信输出 . 不要写到持久存储器(S3,日志文件,出票系统,支持笔录)上,没有你自己的日志寄出层洗涤. SDK保护了JSON.string的遥测管 cause.trace;它不保护临时 console.error(err) 调用您的应用程序代码.

  3. 默认可以作假-否定. 新的提供者, URL 格式的更改, 或自定义传输的奇数错误形状可能会滑过. 将每个错误信息视为可能包含一个你无法识别的秘密,并在您的日志发送层进行针擦除(Sentry's) denyUrls 编号 : beforeSend数据犬 redact-paths你自己的前卫.

其他逃生舱

目标打电话
在自定义策略后恢复默认值resetMessageRedactor()
读取活动策略( 例如 ) . /healthz(中文(简体) )getMessageRedactor()
完全禁用编辑( 本地 dev / 原始提供者测试)setMessageRedactor(undefined)
长度保留编辑( 函数表)setMessageRedactor((msg) => msg.replace(/[A-Fa-f0-9]{32,64}/g, (m) => '*'.repeat(m.length)))

设置器 替换 积极政策——使用 composeRedactor({ hostSuffixes, patterns }) (或打电话) defaultMessageRedactor(msg) 如果想要扩展而不是替换,则从函数形式重排符中选择)。 见 setMessageRedactor这是JSDoc的合同.

为何默认

跨越现代 SDKs 的主导模式( AWS SDK v3 中间软件, Stale 的请求日志器, Sentry's Default Integrations, OpenTeleometry 的 URL/ query-param 洗涤器) 是默认情况下为高自信模式进行秘密洗涤并让操作员延伸或禁用. 与此相反的姿态——“错误可能包含秘密,自己擦除这些秘密”——在历史上是一个经常导致证书漏入整个JS生态系统的日志汇总器的原因(特别是轴向器,它把全部请求的URL倒入) error.config (默认情况下). SDK有意采用保守-默认姿态.

迁移路径

这个 /next 入站点设计为零平移:

  1. 现在 - 从 @circle-fin/adapter-ethers-v6/next. 返回的适配器与所有现有的工具包和提供者完全兼容——他们方面不需要改动.
  2. 下一个主要发布 - 电话 /next 架构成为默认条目(@circle-fin/adapter-ethers-v6) (中文(简体) ). 当前基于类的适配器将被删除.

我需要改变什么? 如果您仅使用工厂功能( Q)createEthersAdapterFromPrivateKey, (中文(简体) ), createEthersAdapterFromProvider),并将适配器传递给一个工具包,没有超出导入路径的. 适配器满足了工具包所期望的相同接口.

操作 Context 模式

为什么是Context行动?

Context行动模式是多链操作的现代方法. 您不锁定单个链的适配器,而是指定每个操作的链. 这样就能够形成强大的模式,如使用单一适配器进行跨链接通.

福利:

  • ✅ 一个适配器,许多链条 - 无需为每个网络创建单独的适配器
  • ✅ 明确比较好 - 链条在代码里总是清晰的
  • ✅ 类型安全 - 完整类型脚本支持和编译时间检查
  • ✅ 消除模糊 - 不混淆使用哪个链条

基本用途

每个操作接受一个 OperationContext 指定链的参数:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'

// Create adapter without specifying a chain - true lazy initialization
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
})

// Chain specified explicitly in every operation
const prepared = await adapter.prepare(
  {
    address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    abi: usdcAbi,
    functionName: 'transfer',
    args: ['0xrecipient', '1000000'],
  },
  { chain: 'Ethereum' },
)

const gas = await prepared.estimate()
const txHash = await prepared.execute()

多频道业务

单个适配器用于跨多个链条的操作:

// Create adapter once for use across multiple chains
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
})

// Transfer USDC on Ethereum
const ethPrepared = await adapter.prepare(
  {
    address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
    abi: usdcAbi,
    functionName: 'transfer',
    args: ['0xrecipient', '1000000'],
  },
  { chain: 'Ethereum' },
)

// Transfer USDC on Base using the same adapter
const basePrepared = await adapter.prepare(
  {
    address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
    abi: usdcAbi,
    functionName: 'transfer',
    args: ['0xrecipient', '1000000'],
  },
  { chain: 'Base' },
)

// Execute both transfers
await ethPrepared.execute()
await basePrepared.execute()

地址背景指南

适配器支持两个地址控制模式. 选一个适合你的用法.

最佳服务: 私钥钱包、浏览器钱包(MetaMask)、硬件钱包

如何运作: 地址由连接的签名人/钱包自动解决。 您不需要在“ Context” 行动中指定它 .

何时使用 :

  • QQ 构建用户连接钱包的 dApp
  • 使用私人密钥进行后端自动化
  • QQ 单一钱包签名所有交易
  • QQ 具有一个身份的服务器侧脚本
// User-controlled adapter (default for factory functions)
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
  // addressContext: 'user-controlled' is the default
})

// Address automatically resolved from private key/wallet
const prepared = await adapter.prepare(
  {
    address: '0xcontract',
    abi: contractAbi,
    functionName: 'approve',
    args: ['0xspender', '1000000'],
  },
  { chain: 'Polygon' }, // No address needed in context for user-controlled
)

开发者控制( 高级)

最佳服务: 保管解决方案、多实体系统、企业应用程序

如何运作: 每项行动必须在行动内容中明确提供地址.

何时使用 :

  • QQ 构建管理多个客户端钱包的监护解决方案
  • 企业系统,不同用户有不同的签名密钥
  • 多西格或授权签字基础设施
  • 每个交易地址不同的系统
import { EthersAdapter } from '@circle-fin/adapter-ethers-v6'
import { Ethereum, Base } from '@circle-fin/bridge-kit/chains'

// Developer-controlled adapter (manual constructor)
const adapter = new EthersAdapter(
  {
    getProvider: ({ chain }) => new JsonRpcProvider('https://...'),
    signer: wallet,
  },
  {
    addressContext: 'developer-controlled', // ← Explicit address required
    supportedChains: [Ethereum, Base],
  },
)

// Address must be provided in context for developer-controlled adapters
const prepared = await adapter.prepare(
  {
    address: '0xcontract',
    abi: contractAbi,
    functionName: 'approve',
    args: ['0xspender', '1000000'],
  },
  {
    chain: 'Ethereum',
    address: '0x1234...', // Required for developer-controlled
  },
)

用法实例

合同互动

转移 USDC 使用同一适配器的跨不同链条:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'

// Create adapter with lazy initialization
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
})

const usdcAbi = ['function transfer(address to, uint256 amount) returns (bool)']

// Transfer on Ethereum - chain specified in operation
const ethPrepared = await adapter.prepare(
  {
    address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
    abi: usdcAbi,
    functionName: 'transfer',
    args: ['0xrecipient', '1000000'], // 1 USDC (6 decimals)
  },
  { chain: 'Ethereum' },
)

// Estimate and execute
const gas = await ethPrepared.estimate()
console.log('Estimated gas:', gas.gas)

const txHash = await ethPrepared.execute()
console.log('Transaction hash:', txHash)

EIP-712 签署

签字许可批准 用于批准无气证:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
})

// Sign ERC-2612 permit (gasless USDC approval)
const signature = await adapter.signTypedData(
  {
    domain: {
      name: 'USD Coin',
      version: '2',
      chainId: 1,
      verifyingContract: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    },
    types: {
      Permit: [
        { name: 'owner', type: 'address' },
        { name: 'spender', type: 'address' },
        { name: 'value', type: 'uint256' },
        { name: 'nonce', type: 'uint256' },
        { name: 'deadline', type: 'uint256' },
      ],
    },
    primaryType: 'Permit',
    message: {
      owner: '0xowner',
      spender: '0xspender',
      value: '1000000',
      nonce: '0',
      deadline: '1735689600',
    },
  },
  { chain: 'Ethereum' }, // Chain must be specified
)

console.log('Permit signature:', signature)
// Use signature for gasless approval

跨越海峡

桥梁 USDC 使用带有 Context 操作的桥套:

import { createEthersAdapterFromPrivateKey } from '@circle-fin/adapter-ethers-v6'
import { BridgeKit } from '@circle-fin/bridge-kit'

// Create adapter for multi-chain operations
const adapter = createEthersAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
})

const kit = new BridgeKit()

// Bridge from Ethereum to Base using the same adapter
const result = await kit.bridge({
  from: { adapter, chain: 'Ethereum' },
  to: { adapter, chain: 'Base' },
  amount: '100.50',
  token: 'USDC',
})

console.log('Bridge transaction:', result.transactionHash)

API 参考

工厂功能

createEthersAdapterFromPrivateKey(params)

从私钥创建适配器供服务器侧使用.

参数:

  • privateKey - 32字节十六进制字符串(有无) 0x 前缀 - 自动正常化)
  • getProvider? - 可选自定义提供者功能
  • capabilities? - 可选部分能力(默认:用户控制+所有EVM链)

回返情况: EthersAdapter 懒惰的初始化实例

说明: 创建时不需要链条 。 适配器在第一次操作时会以懒惰的方式连接链.

const adapter = createEthersAdapterFromPrivateKey({
  privateKey: '0x...',
})

createEthersAdapterFromProvider(params)

从浏览器钱包提供者(MetaMask, WaletConnect等)创建适配器.

参数:

  • provider - EIP-1193兼容供应商
  • getProvider? - 可选自定义提供者功能
  • capabilities? - 可选部分能力(默认:用户控制+所有EVM链)

回返情况: Promise<EthersAdapter> 实例

const adapter = await createEthersAdapterFromProvider({
  provider: window.ethereum,
})

核心方法

prepare(params, ctx)

拟订合同职能,要求估算和执行.

参数:

  • params - 合同呼叫参数(地址、ABI、函数) 名称, 参数)
  • ctx - 说吧 需求 有链式规格的操作Context

回返情况: Promise<PreparedChainRequest> 与 estimate() 财务报告和审定财务报表 execute() 方法

const prepared = await adapter.prepare(
  {
    address: '0xcontract',
    abi: contractAbi,
    functionName: 'transfer',
    args: ['0xto', '1000000'],
  },
  { chain: 'Ethereum' }, // Required
)

signTypedData(typedData, ctx)

签出EIP-712打入的许可证,元交易等数据.

参数:

  • typedData - EIP-712结构数据
  • ctx - 说吧 需求 有链式规格的操作Context

回返情况: Promise<string> - 签名为正弦

const signature = await adapter.signTypedData(permitData, {
  chain: 'Ethereum',
})

waitForTransaction(txHash, config?)

等待交易确认.

参数:

  • txHash - 交易散列等待
  • config? - 备选等待配置(确认、超时)

回返情况: Promise<TransactionReceipt>

const receipt = await adapter.waitForTransaction('0x...')

getAddress(chain)

获取连接的钱包地址 。 链条参数由操作Context分辨率自动提供.

回返情况: Promise<string> - 钱包地址

调试操作

使用动作系统构建的符号操作 :

// Get USDC balance
const balance = await adapter.actions.usdc.balanceOf({
  address: '0xwallet',
  chain: 'Ethereum',
})

// Get token allowance
const allowance = await adapter.actions.token.allowance({
  tokenAddress: '0xtoken',
  owner: '0xowner',
  spender: '0xspender',
  chain: 'Base',
})

支持的链路( R)

Ethers v6适配器解决了Circle的CCTP v2协议所支持的任何EVM相容链条——它在运行时验证了链条类型,而不是硬编码链条列表,因此随着链条被添加而自动保持同步. 见 主读取器 用于完整,最新的支持主网和测试网链列表.

发展

这个包是App Kits monorepo的一部分.

# Build
nx build @circle-fin/adapter-ethers-v6

# Test
nx test @circle-fin/adapter-ethers-v6

许可证

这个项目根据Apache 2.0许可证获得许可. 联系人 支助 详细情况.


准备好了吗?

加入磁盘 二. 支助 访问我们的救世主

由 Circle 创建

版本与发布记录

@circle-fin/adapter-ethers-v6 共发布 38 个版本,首次发布于 2025/08/26;过去 12 个月发布了 33 个版本。

版本发布日期距今
1.13.1latest2026/11/064 天前
1.13.02026/10/3110 天前
1.12.42026/10/2317 天前
1.12.32026/10/2119 天前
1.12.22026/10/1624 天前
1.12.12026/09/301 个月前

其他发布通道:alpha → 0.0.2-alpha.6。

关于 @circle-fin/adapter-ethers-v6 的常见问题

@circle-fin/adapter-ethers-v6 是什么?

EVM 区块链适配器由 Ethers v6 供电

如何安装 @circle-fin/adapter-ethers-v6?

在项目目录运行 npm install @circle-fin/adapter-ethers-v6,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ethers(^6.11.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@circle-fin/adapter-ethers-v6 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@circle-fin/adapter-ethers-v6 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@circle-fin/adapter-ethers-v6 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@circle-fin/adapter-ethers-v6 可以商用吗?

@circle-fin/adapter-ethers-v6 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@circle-fin/adapter-ethers-v6 的下载量有多少?

根据 npm 官方下载统计,@circle-fin/adapter-ethers-v6 在 2026/10/10 – 2026/11/08 这 30 天内被下载 8,502 次,日均约 283 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@circle-fin/adapter-ethers-v6 还在维护吗?

最新版本 1.13.1 发布于 2026/11/06(4 天前);至今共发布 38 个版本,其中过去 12 个月发布了 33 个;首次发布于 2025/08/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。