@circle-fin/adapter-ethers-v6 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,89 @@
1
+ # @circle-fin/adapter-ethers-v6
2
+
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Improves static gas estimate values for contract calls. Updates adapters' `prepare()` method so that transaction simulation is now performed only during `execute()`, not during `estimate()`. Adds an optional fallback parameter to `estimate()` for cases where gas estimation fails.
8
+
9
+ ### Patch Changes
10
+
11
+ - Fix CommonJS compatibility by correcting file extensions and package exports. This resolves a "ReferenceError: require is not defined" error that occurred when using packages in CommonJS projects with ts-node.
12
+
13
+ ## 1.0.1
14
+
15
+ ### Patch Changes
16
+
17
+ - Add support for Arc Testnet chain definition. Arc is Circle's EVM-compatible Layer-1 blockchain designed for stablecoin finance and asset
18
+ tokenization, featuring USDC as the native gas token and sub-second finality via the Malachite BFT consensus engine.
19
+ - Improve error messages for developer-controlled address contexts. Calling `getAddress()` on an adapter configured with `addressContext: 'developer-controlled'` now throws a clear error explaining that addresses must be provided explicitly in the operation context.
20
+ - Update Sonic Testnet chain definition to canonical network. The `SonicTestnet` chain definition now points to the official Sonic Testnet (chainId: 14601) instead of the deprecated Sonic Blaze Testnet (chainId: 57054). The RPC endpoint has been updated to `https://rpc.testnet.soniclabs.com`, the display name simplified to "Sonic Testnet", and the USDC contract address updated to the new deployment.
21
+
22
+ **Breaking Changes:**
23
+ - **Chain ID:** 57054 → 14601
24
+ - **RPC Endpoint:** `https://rpc.blaze.soniclabs.com` → `https://rpc.testnet.soniclabs.com`
25
+ - **USDC Address:** `0xA4879Fed32Ecbef99399e5cbC247E533421C4eC6` → `0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51`
26
+
27
+ **Migration:** If you were using `SonicTestnet`, your application will automatically connect to the new network upon upgrading. Any accounts, contracts, or transactions on the old Blaze testnet (chainId: 57054) will need to be recreated on the new testnet.
28
+
29
+ ## 1.0.0
30
+
31
+ ### Major Changes
32
+
33
+ - # Ethers v6 Adapter 1.0.0 Release 🎉
34
+
35
+ Full-featured EVM blockchain adapter built on ethers.js v6 - providing comprehensive support for Ethereum and EVM-compatible chains with familiar ethers.js APIs.
36
+
37
+ ## 🚀 Core EVM Features
38
+ - **Complete EVM Support**: Full compatibility with Ethereum and EVM-compatible chains
39
+ - **Ethers.js v6 Integration**: Built on the latest ethers.js with improved performance
40
+ - **Multi-chain Support**: Seamless switching between different EVM networks
41
+ - **Wallet Integration**: Support for various wallet types and signing methods
42
+
43
+ ## 🔗 Supported Networks
44
+ - **Ethereum Mainnet & Testnets**: Full support for Ethereum ecosystem
45
+ - **Layer 2 Solutions**: Optimism, Arbitrum, Polygon, and other L2s
46
+ - **EVM Sidechains**: Base, Avalanche, and other EVM-compatible networks
47
+ - **Custom Networks**: Easy configuration for private or custom EVM chains
48
+
49
+ ## 💼 Address Management
50
+
51
+ **User-Controlled Adapters**
52
+ - Automatic address resolution from connected wallets
53
+ - Support for MetaMask, WalletConnect, and other wallet providers
54
+ - Real-time account switching and network detection
55
+
56
+ **Developer-Controlled Adapters**
57
+ - Private key-based signing for server-side applications
58
+ - Deterministic address management for automated systems
59
+ - Secure key handling with ethers.js security practices
60
+
61
+ ```typescript
62
+ // User-controlled adapter (wallet-based)
63
+ const adapter = createAdapterFromWallet(wallet)
64
+
65
+ // Developer-controlled adapter (private key)
66
+ const adapter = createAdapterFromPrivateKey({
67
+ privateKey: '0x...',
68
+ })
69
+ ```
70
+
71
+ ## ⛽ Gas Management
72
+ - **Intelligent Gas Estimation**: Automatic gas limit calculation with safety buffers
73
+ - **Dynamic Fee Calculation**: Real-time gas price fetching with configurable buffers
74
+ - **EIP-1559 Support**: Type 2 transaction support for modern fee markets
75
+ - **Gas Optimization**: Efficient transaction batching and optimization
76
+
77
+ ## 🔐 Security Features
78
+ - **Type Safety**: Full TypeScript support with strict type checking
79
+ - **Parameter Validation**: Runtime validation of all transaction parameters
80
+ - **Secure Signing**: Leverages ethers.js battle-tested signing infrastructure
81
+ - **Error Handling**: Comprehensive error handling with detailed error messages
82
+
83
+ ## 🛠️ Developer Experience
84
+ - **Rich JSDoc Documentation**: Complete API documentation with examples
85
+ - **TypeScript First**: Built with TypeScript for superior developer experience
86
+ - **Familiar APIs**: Consistent with ethers.js patterns and conventions
87
+ - **Comprehensive Testing**: Extensive test coverage for reliability
88
+
89
+ This adapter provides a robust foundation for EVM-based cross-chain USDC transfers, leveraging the mature ethers.js ecosystem while providing the specialized functionality needed for bridge operations.
@@ -20,10 +20,10 @@
20
20
 
21
21
  var ethers = require('ethers');
22
22
  var zod = require('zod');
23
+ require('@ethersproject/units');
23
24
  var bytes = require('@ethersproject/bytes');
24
25
  var address = require('@ethersproject/address');
25
26
  var bs58 = require('bs58');
26
- require('@ethersproject/units');
27
27
 
28
28
  function _interopDefault (e) { return e && e.__esModule ? e.default : e; }
29
29
 
@@ -9977,7 +9977,7 @@ class EthersAdapter extends EvmAdapter {
9977
9977
  * @param overrides - Optional estimate overrides.
9978
9978
  * @returns Promise resolving to the estimated gas, gas price, and total fee.
9979
9979
  */
9980
- async estimateGasForFunction(contract, functionName, args, chain, overrides) {
9980
+ async estimateGasForFunction(contract, functionName, args, chain, overrides, fallback) {
9981
9981
  let gas;
9982
9982
  try {
9983
9983
  const contractFunction = contract.getFunction(functionName);
@@ -9986,7 +9986,12 @@ class EthersAdapter extends EvmAdapter {
9986
9986
  : await contractFunction.estimateGas(...args);
9987
9987
  }
9988
9988
  catch (error) {
9989
- throw new Error(`Gas estimation failed: ${error.message}`);
9989
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
9990
+ if (fallback &&
9991
+ errorMessage.toLocaleLowerCase().includes('execution reverted')) {
9992
+ return fallback;
9993
+ }
9994
+ throw new Error(`Gas estimation failed: ${errorMessage}`);
9990
9995
  }
9991
9996
  let gasPrice;
9992
9997
  try {
@@ -10211,18 +10216,19 @@ class EthersAdapter extends EvmAdapter {
10211
10216
  }
10212
10217
  // For state-changing functions, use the original logic
10213
10218
  const contract = this.createContractInstance(params, signer, resolvedContext.address, provider);
10214
- await this.simulateFunctionCall(contract, functionName, args);
10215
10219
  return {
10216
10220
  type: 'evm',
10217
- estimate: async (overrides) => {
10221
+ estimate: async (overrides, fallback) => {
10218
10222
  await this.ensureChain(targetChain);
10219
10223
  // Reconnect the contract with the correct provider for the target chain to ensure
10220
10224
  // gas estimation and fee data retrieval use the correct network.
10221
10225
  const estimationProvider = await this.getProvider(targetChain);
10222
10226
  const contractForEstimation = contract.connect(estimationProvider);
10223
- return this.estimateGasForFunction(contractForEstimation, functionName, args, targetChain, overrides);
10227
+ return this.estimateGasForFunction(contractForEstimation, functionName, args, targetChain, overrides, fallback);
10224
10228
  },
10225
10229
  execute: async (overrides) => {
10230
+ // Simulate the function call to catch errors before submission
10231
+ await this.simulateFunctionCall(contract, functionName, args);
10226
10232
  await this.ensureChain(targetChain);
10227
10233
  // Reconnect the contract with the current signer, which is on the correct
10228
10234
  // chain after `ensureChain`, to ensure the transaction is populated and
@@ -10836,4 +10842,4 @@ exports.createAdapterFromPrivateKey = createAdapterFromPrivateKey;
10836
10842
  exports.createAdapterFromProvider = createAdapterFromProvider;
10837
10843
  exports.parseSignature = parseSignature;
10838
10844
  exports.validateAdapterCapabilities = validateAdapterCapabilities;
10839
- //# sourceMappingURL=index.cjs.js.map
10845
+ //# sourceMappingURL=index.cjs.map
package/index.cjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/index.d.ts CHANGED
@@ -596,10 +596,11 @@ interface EvmPreparedChainRequest {
596
596
  * Estimate the gas cost for the contract execution.
597
597
  *
598
598
  * @param overrides - Optional parameters to override the default estimation behavior
599
+ * @param fallback - Optional fallback gas information to use if the estimation fails
599
600
  * @returns A promise that resolves to the estimated gas information
600
601
  * @throws If the estimation fails
601
602
  */
602
- estimate(overrides?: EvmEstimateOverrides): Promise<EstimatedGas>;
603
+ estimate(overrides?: EvmEstimateOverrides, fallback?: EstimatedGas): Promise<EstimatedGas>;
603
604
  /**
604
605
  * Execute the prepared contract call.
605
606
  *
@@ -677,7 +678,7 @@ interface SolanaPreparedChainRequest {
677
678
  /** The type of the chain request. */
678
679
  type: 'solana';
679
680
  /** Estimate the compute units and fee for the transaction. */
680
- estimate(overrides?: SolanaEstimateOverrides): Promise<EstimatedGas>;
681
+ estimate(overrides?: SolanaEstimateOverrides, fallback?: EstimatedGas): Promise<EstimatedGas>;
681
682
  /** Execute the prepared transaction. */
682
683
  execute(overrides?: SolanaExecuteOverrides): Promise<string>;
683
684
  }
@@ -709,7 +710,7 @@ interface NoopPreparedChainRequest {
709
710
  * Placeholder for the estimate method.
710
711
  * @returns The estimated gas cost.
711
712
  */
712
- estimate: () => Promise<EstimatedGas>;
713
+ estimate: (overrides?: EvmEstimateOverrides | SolanaEstimateOverrides, fallback?: EstimatedGas) => Promise<EstimatedGas>;
713
714
  /**
714
715
  * Placeholder for the execute method.
715
716
  * @returns The transaction hash.
@@ -1967,10 +1968,23 @@ interface AdapterCapabilities {
1967
1968
  */
1968
1969
  declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
1969
1970
  /**
1970
- * The type of the chain.
1971
- * @example 'evm', 'solana'
1971
+ * The type of the chain for this adapter.
1972
+ *
1973
+ * - For concrete adapters, this should be a real chain type (e.g., `'evm'`, `'solana'`, etc.) from the ChainType union.
1974
+ * - For hybrid adapters (adapters that route to concrete adapters supporting multiple ecosystems),
1975
+ * set this property to the string literal `'hybrid'`.
1976
+ *
1977
+ * Note: `'hybrid'` is not a legal ChainType and should only be used as a marker for multi-ecosystem adapters.
1978
+ * Hybrid adapters do not interact directly with any chain, but instead route requests to a concrete underlying adapter.
1979
+ *
1980
+ * @example
1981
+ * // For an EVM-only adapter:
1982
+ * chainType = 'evm'
1983
+ *
1984
+ * // For a hybrid adapter:
1985
+ * chainType = 'hybrid'
1972
1986
  */
1973
- abstract chainType: ChainType;
1987
+ abstract chainType: ChainType | 'hybrid';
1974
1988
  /**
1975
1989
  * Capabilities of this adapter, defining address control model and supported chains.
1976
1990
  *
@@ -2052,7 +2066,7 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
2052
2066
  * })
2053
2067
  * ```
2054
2068
  */
2055
- prepareAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, ctx?: OperationContext<TAdapterCapabilities>): Promise<PreparedChainRequest>;
2069
+ prepareAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, ctx: OperationContext<TAdapterCapabilities>): Promise<PreparedChainRequest>;
2056
2070
  /**
2057
2071
  * Prepares a transaction for future gas estimation and execution.
2058
2072
  *
package/index.mjs CHANGED
@@ -19,10 +19,10 @@
19
19
  import { JsonRpcProvider, Wallet, BrowserProvider, Interface, Contract } from 'ethers';
20
20
  export { JsonRpcProvider } from 'ethers';
21
21
  import { z } from 'zod';
22
+ import '@ethersproject/units';
22
23
  import { hexlify, hexZeroPad } from '@ethersproject/bytes';
23
24
  import { getAddress } from '@ethersproject/address';
24
25
  import bs58 from 'bs58';
25
- import '@ethersproject/units';
26
26
 
27
27
  /**
28
28
  * Type-safe registry for managing and executing blockchain action handlers.
@@ -9972,7 +9972,7 @@ class EthersAdapter extends EvmAdapter {
9972
9972
  * @param overrides - Optional estimate overrides.
9973
9973
  * @returns Promise resolving to the estimated gas, gas price, and total fee.
9974
9974
  */
9975
- async estimateGasForFunction(contract, functionName, args, chain, overrides) {
9975
+ async estimateGasForFunction(contract, functionName, args, chain, overrides, fallback) {
9976
9976
  let gas;
9977
9977
  try {
9978
9978
  const contractFunction = contract.getFunction(functionName);
@@ -9981,7 +9981,12 @@ class EthersAdapter extends EvmAdapter {
9981
9981
  : await contractFunction.estimateGas(...args);
9982
9982
  }
9983
9983
  catch (error) {
9984
- throw new Error(`Gas estimation failed: ${error.message}`);
9984
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
9985
+ if (fallback &&
9986
+ errorMessage.toLocaleLowerCase().includes('execution reverted')) {
9987
+ return fallback;
9988
+ }
9989
+ throw new Error(`Gas estimation failed: ${errorMessage}`);
9985
9990
  }
9986
9991
  let gasPrice;
9987
9992
  try {
@@ -10206,18 +10211,19 @@ class EthersAdapter extends EvmAdapter {
10206
10211
  }
10207
10212
  // For state-changing functions, use the original logic
10208
10213
  const contract = this.createContractInstance(params, signer, resolvedContext.address, provider);
10209
- await this.simulateFunctionCall(contract, functionName, args);
10210
10214
  return {
10211
10215
  type: 'evm',
10212
- estimate: async (overrides) => {
10216
+ estimate: async (overrides, fallback) => {
10213
10217
  await this.ensureChain(targetChain);
10214
10218
  // Reconnect the contract with the correct provider for the target chain to ensure
10215
10219
  // gas estimation and fee data retrieval use the correct network.
10216
10220
  const estimationProvider = await this.getProvider(targetChain);
10217
10221
  const contractForEstimation = contract.connect(estimationProvider);
10218
- return this.estimateGasForFunction(contractForEstimation, functionName, args, targetChain, overrides);
10222
+ return this.estimateGasForFunction(contractForEstimation, functionName, args, targetChain, overrides, fallback);
10219
10223
  },
10220
10224
  execute: async (overrides) => {
10225
+ // Simulate the function call to catch errors before submission
10226
+ await this.simulateFunctionCall(contract, functionName, args);
10221
10227
  await this.ensureChain(targetChain);
10222
10228
  // Reconnect the contract with the current signer, which is on the correct
10223
10229
  // chain after `ensureChain`, to ensure the transaction is populated and
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@circle-fin/adapter-ethers-v6",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "EVM blockchain adapter powered by Ethers v6",
5
- "main": "./index.cjs.js",
5
+ "main": "./index.cjs",
6
6
  "module": "./index.mjs",
7
7
  "types": "./index.d.ts",
8
8
  "dependencies": {
@@ -22,13 +22,15 @@
22
22
  ".": {
23
23
  "types": "./index.d.ts",
24
24
  "import": "./index.mjs",
25
- "default": "./index.cjs.js"
25
+ "require": "./index.cjs",
26
+ "default": "./index.cjs"
26
27
  }
27
28
  },
28
29
  "files": [
29
30
  "index.*",
30
31
  "README.md",
31
32
  "LICENSE",
33
+ "CHANGELOG.md",
32
34
  "package.json"
33
35
  ],
34
36
  "publishConfig": {
package/index.cjs.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}