@circle-fin/provider-cctp-v2 1.8.1 → 1.8.3
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 +12 -0
- package/index.cjs +61 -90
- package/index.d.ts +85 -4
- package/index.mjs +61 -90
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @circle-fin/provider-cctp-v2
|
|
2
2
|
|
|
3
|
+
## 1.8.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `bridge` no longer rejects Gas Station-enabled smart-contract accounts (SCAs) with zero native balance on the source or destination chain. EOA wallets without native funds will still fail at simulation with the underlying RPC error.
|
|
8
|
+
|
|
9
|
+
## 1.8.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Internal dependency updates. No user-facing changes.
|
|
14
|
+
|
|
3
15
|
## 1.8.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/index.cjs
CHANGED
|
@@ -400,23 +400,21 @@ var UnifiedBalanceChain;
|
|
|
400
400
|
* Enumeration of blockchains that support earn (vault deposit/withdraw)
|
|
401
401
|
* operations through the Earn Kit.
|
|
402
402
|
*
|
|
403
|
-
* Currently only Ethereum mainnet is supported. Additional chains
|
|
404
|
-
* will be added as vault protocol support expands.
|
|
405
|
-
*
|
|
406
403
|
* @example
|
|
407
404
|
* ```typescript
|
|
408
405
|
* import { EarnChain } from '@core/chains'
|
|
409
406
|
*
|
|
410
407
|
* const result = await earnKit.deposit({
|
|
411
|
-
* from: { adapter, chain: EarnChain.
|
|
408
|
+
* from: { adapter, chain: EarnChain.Arc_Testnet },
|
|
412
409
|
* vaultAddress: '0x...',
|
|
413
410
|
* amount: '100',
|
|
414
411
|
* })
|
|
415
412
|
* ```
|
|
416
413
|
*/
|
|
414
|
+
// Values must match Blockchain enum members exactly.
|
|
417
415
|
var EarnChain;
|
|
418
416
|
(function (EarnChain) {
|
|
419
|
-
EarnChain["
|
|
417
|
+
EarnChain["Arc_Testnet"] = "Arc_Testnet";
|
|
420
418
|
})(EarnChain || (EarnChain = {}));
|
|
421
419
|
|
|
422
420
|
/**
|
|
@@ -4094,7 +4092,7 @@ zod.z.union([
|
|
|
4094
4092
|
* Zod schema for validating earn-specific chain identifiers.
|
|
4095
4093
|
*
|
|
4096
4094
|
* Validate that the provided chain is supported for earn (vault
|
|
4097
|
-
* deposit/withdraw) operations. Currently only
|
|
4095
|
+
* deposit/withdraw) operations. Currently only Arc Testnet is
|
|
4098
4096
|
* supported.
|
|
4099
4097
|
*
|
|
4100
4098
|
* Accept an EarnChain enum value, a matching string literal, or
|
|
@@ -4103,12 +4101,12 @@ zod.z.union([
|
|
|
4103
4101
|
* @example
|
|
4104
4102
|
* ```typescript
|
|
4105
4103
|
* import { earnChainIdentifierSchema } from '@core/chains'
|
|
4106
|
-
* import {
|
|
4104
|
+
* import { ArcTestnet, EarnChain } from '@core/chains'
|
|
4107
4105
|
*
|
|
4108
4106
|
* // Valid
|
|
4109
|
-
* earnChainIdentifierSchema.parse(EarnChain.
|
|
4110
|
-
* earnChainIdentifierSchema.parse('
|
|
4111
|
-
* earnChainIdentifierSchema.parse(
|
|
4107
|
+
* earnChainIdentifierSchema.parse(EarnChain.Arc_Testnet)
|
|
4108
|
+
* earnChainIdentifierSchema.parse('Arc_Testnet')
|
|
4109
|
+
* earnChainIdentifierSchema.parse(ArcTestnet)
|
|
4112
4110
|
*
|
|
4113
4111
|
* // Invalid (throws ZodError)
|
|
4114
4112
|
* earnChainIdentifierSchema.parse('Solana')
|
|
@@ -6393,7 +6391,8 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6393
6391
|
*
|
|
6394
6392
|
* @remarks
|
|
6395
6393
|
* Check order for KitError instances:
|
|
6396
|
-
* 1. If `recoverability === 'RETRYABLE'
|
|
6394
|
+
* 1. If `recoverability === 'RETRYABLE'` or `recoverability === 'RESUMABLE'`,
|
|
6395
|
+
* return `true` immediately (priority check).
|
|
6397
6396
|
* 2. Otherwise, check if `error.code` is in `DEFAULT_RETRYABLE_ERROR_CODES` (fallback check).
|
|
6398
6397
|
* 3. Non-KitError instances always return `false`.
|
|
6399
6398
|
*
|
|
@@ -6404,6 +6403,12 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6404
6403
|
* subsequent attempts, such as network timeouts or temporary service
|
|
6405
6404
|
* unavailability. These errors are safe to retry after a delay.
|
|
6406
6405
|
*
|
|
6406
|
+
* RESUMABLE errors indicate a multi-phase operation that completed some phases
|
|
6407
|
+
* before failing (for example, a token approval landed but the execution
|
|
6408
|
+
* transaction failed). They are also retryable — re-running the operation is
|
|
6409
|
+
* safe — but callers that have a kit-level `retry()` should prefer it so that
|
|
6410
|
+
* already-completed phases are skipped.
|
|
6411
|
+
*
|
|
6407
6412
|
* @param error - Unknown error to check
|
|
6408
6413
|
* @returns True if error is retryable
|
|
6409
6414
|
*
|
|
@@ -6449,16 +6454,29 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6449
6454
|
* })
|
|
6450
6455
|
* isRetryableError(error3) // false
|
|
6451
6456
|
*
|
|
6457
|
+
* // KitError with RESUMABLE recoverability (partially-completed operation)
|
|
6458
|
+
* const error4 = new KitError({
|
|
6459
|
+
* code: 8101,
|
|
6460
|
+
* name: 'EARN_EXECUTION_FAILED',
|
|
6461
|
+
* type: 'SERVICE',
|
|
6462
|
+
* recoverability: 'RESUMABLE',
|
|
6463
|
+
* message: 'Execution failed after approval',
|
|
6464
|
+
* })
|
|
6465
|
+
* isRetryableError(error4) // true
|
|
6466
|
+
*
|
|
6452
6467
|
* // Non-KitError
|
|
6453
|
-
* const
|
|
6454
|
-
* isRetryableError(
|
|
6468
|
+
* const error5 = new Error('Standard error')
|
|
6469
|
+
* isRetryableError(error5) // false
|
|
6455
6470
|
* ```
|
|
6456
6471
|
*/
|
|
6457
6472
|
function isRetryableError$1(error) {
|
|
6458
6473
|
// Use proper type guard to check if it's a KitError
|
|
6459
6474
|
if (isKitError(error)) {
|
|
6460
|
-
// Priority check: explicit recoverability
|
|
6461
|
-
|
|
6475
|
+
// Priority check: explicit recoverability. RESUMABLE errors are a subset of
|
|
6476
|
+
// retryable errors — re-running the operation is safe, but a kit-level
|
|
6477
|
+
// retry() can resume from the failed phase instead.
|
|
6478
|
+
if (error.recoverability === 'RETRYABLE' ||
|
|
6479
|
+
error.recoverability === 'RESUMABLE') {
|
|
6462
6480
|
return true;
|
|
6463
6481
|
}
|
|
6464
6482
|
// Fallback check: error code against default retryable codes
|
|
@@ -12248,7 +12266,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCo
|
|
|
12248
12266
|
return step;
|
|
12249
12267
|
}
|
|
12250
12268
|
|
|
12251
|
-
var version = "1.8.
|
|
12269
|
+
var version = "1.8.3";
|
|
12252
12270
|
var pkg = {
|
|
12253
12271
|
version: version};
|
|
12254
12272
|
|
|
@@ -12662,7 +12680,9 @@ const hexStringSchema = zod.z
|
|
|
12662
12680
|
* console.log(result.success) // true
|
|
12663
12681
|
* ```
|
|
12664
12682
|
*/
|
|
12665
|
-
hexStringSchema
|
|
12683
|
+
hexStringSchema
|
|
12684
|
+
.refine((value) => value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)')
|
|
12685
|
+
.transform((value) => value);
|
|
12666
12686
|
/**
|
|
12667
12687
|
* Schema for validating transaction hashes.
|
|
12668
12688
|
*
|
|
@@ -12683,6 +12703,29 @@ hexStringSchema.refine((value) => value.length === 42, 'EVM address must be exac
|
|
|
12683
12703
|
* ```
|
|
12684
12704
|
*/
|
|
12685
12705
|
hexStringSchema.refine((value) => value.length === 66, 'Transaction hash must be exactly 66 characters long (0x + 64 hex characters)');
|
|
12706
|
+
/**
|
|
12707
|
+
* Schema for validating EVM signatures.
|
|
12708
|
+
*
|
|
12709
|
+
* This schema validates that a string is a properly formatted 65-byte EVM
|
|
12710
|
+
* signature:
|
|
12711
|
+
* - Must be a valid hex string with '0x' prefix
|
|
12712
|
+
* - Must be exactly 132 characters long (0x + 130 hex characters)
|
|
12713
|
+
*
|
|
12714
|
+
* @throws {KitError} If validation fails with INPUT_VALIDATION_FAILED code (1098), with details about which properties failed
|
|
12715
|
+
*
|
|
12716
|
+
* @example
|
|
12717
|
+
* ```typescript
|
|
12718
|
+
* import { evmSignatureSchema } from '@core/adapter'
|
|
12719
|
+
*
|
|
12720
|
+
* const validSignature = `0x${'ab'.repeat(65)}`
|
|
12721
|
+
*
|
|
12722
|
+
* const result = evmSignatureSchema.safeParse(validSignature)
|
|
12723
|
+
* console.log(result.success) // true
|
|
12724
|
+
* ```
|
|
12725
|
+
*/
|
|
12726
|
+
hexStringSchema
|
|
12727
|
+
.refine((value) => value.length === 132, 'EVM signature must be exactly 132 characters long (0x + 130 hex characters)')
|
|
12728
|
+
.transform((value) => value);
|
|
12686
12729
|
/**
|
|
12687
12730
|
* Schema for validating base58-encoded strings.
|
|
12688
12731
|
*
|
|
@@ -12829,60 +12872,6 @@ const validateBalanceForTransaction = async (params) => {
|
|
|
12829
12872
|
}
|
|
12830
12873
|
};
|
|
12831
12874
|
|
|
12832
|
-
/**
|
|
12833
|
-
* Validate that the adapter has sufficient native token balance for transaction fees.
|
|
12834
|
-
*
|
|
12835
|
-
* This function checks if the adapter's current native token balance (ETH, SOL, etc.)
|
|
12836
|
-
* is greater than zero. It throws a KitError with code 9002 (BALANCE_INSUFFICIENT_GAS)
|
|
12837
|
-
* if the balance is zero, indicating the wallet cannot pay for transaction fees.
|
|
12838
|
-
*
|
|
12839
|
-
* @param params - The validation parameters containing adapter and operation context.
|
|
12840
|
-
* @returns A promise that resolves to void if validation passes.
|
|
12841
|
-
* @throws {KitError} When the adapter's native balance is zero (code: 9002).
|
|
12842
|
-
*
|
|
12843
|
-
* @example
|
|
12844
|
-
* ```typescript
|
|
12845
|
-
* import { validateNativeBalanceForTransaction } from '@core/adapter'
|
|
12846
|
-
* import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
|
|
12847
|
-
* import { isKitError, ERROR_TYPES } from '@core/errors'
|
|
12848
|
-
*
|
|
12849
|
-
* const adapter = createViemAdapterFromPrivateKey({
|
|
12850
|
-
* privateKey: '0x...',
|
|
12851
|
-
* chain: 'Ethereum',
|
|
12852
|
-
* })
|
|
12853
|
-
*
|
|
12854
|
-
* try {
|
|
12855
|
-
* await validateNativeBalanceForTransaction({
|
|
12856
|
-
* adapter,
|
|
12857
|
-
* operationContext: { chain: 'Ethereum' },
|
|
12858
|
-
* })
|
|
12859
|
-
* console.log('Native balance validation passed')
|
|
12860
|
-
* } catch (error) {
|
|
12861
|
-
* if (isKitError(error) && error.type === ERROR_TYPES.BALANCE) {
|
|
12862
|
-
* console.error('Insufficient gas funds:', error.message)
|
|
12863
|
-
* }
|
|
12864
|
-
* }
|
|
12865
|
-
* ```
|
|
12866
|
-
*/
|
|
12867
|
-
const validateNativeBalanceForTransaction = async (params) => {
|
|
12868
|
-
const { adapter, operationContext } = params;
|
|
12869
|
-
const balancePrepared = await adapter.prepareAction('native.balanceOf', {
|
|
12870
|
-
walletAddress: operationContext.address,
|
|
12871
|
-
}, operationContext);
|
|
12872
|
-
const balance = await balancePrepared.execute();
|
|
12873
|
-
if (BigInt(balance) === 0n) {
|
|
12874
|
-
const { chain } = operationContext;
|
|
12875
|
-
const chainName = extractChainInfo(chain).name;
|
|
12876
|
-
const nativeSymbol = typeof chain === 'object' && chain !== null && 'nativeCurrency' in chain
|
|
12877
|
-
? chain.nativeCurrency.symbol
|
|
12878
|
-
: undefined;
|
|
12879
|
-
throw createInsufficientGasError(chainName, nativeSymbol, {
|
|
12880
|
-
balance: '0',
|
|
12881
|
-
walletAddress: operationContext.address,
|
|
12882
|
-
});
|
|
12883
|
-
}
|
|
12884
|
-
};
|
|
12885
|
-
|
|
12886
12875
|
/**
|
|
12887
12876
|
* Permit signature standards for gasless token approvals.
|
|
12888
12877
|
*
|
|
@@ -13443,7 +13432,7 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
13443
13432
|
async bridge(params) {
|
|
13444
13433
|
// CCTP-specific bridge params validation (includes base validation)
|
|
13445
13434
|
assertCCTPv2BridgeParams(params);
|
|
13446
|
-
const { source,
|
|
13435
|
+
const { source, amount, token } = params;
|
|
13447
13436
|
// Extract operation context from source wallet context for balance validation
|
|
13448
13437
|
const sourceOperationContext = this.extractOperationContext(source);
|
|
13449
13438
|
// Validate USDC balance for transaction on source chain
|
|
@@ -13454,24 +13443,6 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
13454
13443
|
tokenAddress: source.chain.usdcAddress,
|
|
13455
13444
|
operationContext: sourceOperationContext,
|
|
13456
13445
|
});
|
|
13457
|
-
// Validate native balance > 0 for gas fees on source chain
|
|
13458
|
-
await validateNativeBalanceForTransaction({
|
|
13459
|
-
adapter: source.adapter,
|
|
13460
|
-
operationContext: sourceOperationContext,
|
|
13461
|
-
});
|
|
13462
|
-
// Only validate destination native balance if there's an adapter
|
|
13463
|
-
// and forwarder is not being used (forwarder handles mint, no gas needed)
|
|
13464
|
-
if ('adapter' in destination &&
|
|
13465
|
-
destination.adapter &&
|
|
13466
|
-
!destination.useForwarder) {
|
|
13467
|
-
// Extract operation context from destination wallet context
|
|
13468
|
-
const destinationOperationContext = this.extractOperationContext(destination);
|
|
13469
|
-
// Validate native balance > 0 for gas fees on destination chain
|
|
13470
|
-
await validateNativeBalanceForTransaction({
|
|
13471
|
-
adapter: destination.adapter,
|
|
13472
|
-
operationContext: destinationOperationContext,
|
|
13473
|
-
});
|
|
13474
|
-
}
|
|
13475
13446
|
return bridge(params, this);
|
|
13476
13447
|
}
|
|
13477
13448
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1810,12 +1810,14 @@ declare enum PermitType {
|
|
|
1810
1810
|
* The Adapter Contract uses this to pull tokens from the user's wallet
|
|
1811
1811
|
* using permit signatures instead of requiring separate approval transactions.
|
|
1812
1812
|
*
|
|
1813
|
+
* Shared by the `swap.*` and `earn.*` action namespaces because both forward
|
|
1814
|
+
* `tokenInputs` unchanged to the adapter contract's `execute` call.
|
|
1815
|
+
*
|
|
1813
1816
|
* @example
|
|
1814
1817
|
* ```typescript
|
|
1815
1818
|
* const tokenInput: TokenInput = {
|
|
1816
1819
|
* permitType: PermitType.EIP2612,
|
|
1817
1820
|
* token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1818
|
-
* from: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
|
|
1819
1821
|
* amount: 1000000n, // 1 USDC
|
|
1820
1822
|
* permitCalldata: '0x...' // Encoded permit(value, deadline, v, r, s)
|
|
1821
1823
|
* }
|
|
@@ -1838,12 +1840,91 @@ interface TokenInput {
|
|
|
1838
1840
|
* ABI-encoded permit calldata.
|
|
1839
1841
|
*
|
|
1840
1842
|
* For EIP-2612: encode(value, deadline, v, r, s)
|
|
1841
|
-
* For Permit2: encode(permit, signature)
|
|
1842
1843
|
*
|
|
1843
1844
|
* @example '0x0000000000000000000000000000000000000000000000000000000000989680...'
|
|
1844
1845
|
*/
|
|
1845
1846
|
permitCalldata: `0x${string}`;
|
|
1846
1847
|
}
|
|
1848
|
+
|
|
1849
|
+
/**
|
|
1850
|
+
* Parameters for executing a service-signed earn operation via the Adapter
|
|
1851
|
+
* smart contract on EVM chains.
|
|
1852
|
+
*
|
|
1853
|
+
* Shared across earn action keys: `earn.deposit`, `earn.withdraw`, and
|
|
1854
|
+
* `earn.claimRewards`. Each operation forwards the same `executeParams`,
|
|
1855
|
+
* `tokenInputs`, and `signature` triple to the adapter contract's `execute`
|
|
1856
|
+
* function. The service signs `executeParams` off-chain; the contract verifies
|
|
1857
|
+
* the signature on-chain.
|
|
1858
|
+
*
|
|
1859
|
+
* @example
|
|
1860
|
+
* ```typescript
|
|
1861
|
+
* import type { ActionPayload } from '@core/adapter'
|
|
1862
|
+
*
|
|
1863
|
+
* const params: ActionPayload<'earn.deposit'> = {
|
|
1864
|
+
* executeParams: { instructions: [], tokens: [], execId: 1n, deadline: 0n, metadata: '0x' },
|
|
1865
|
+
* tokenInputs: [],
|
|
1866
|
+
* signature: '0x...',
|
|
1867
|
+
* }
|
|
1868
|
+
*
|
|
1869
|
+
* const prepared = await adapter.prepareAction('earn.deposit', params, { chain, address })
|
|
1870
|
+
* const txHash = await prepared.execute()
|
|
1871
|
+
* ```
|
|
1872
|
+
*/
|
|
1873
|
+
interface ExecuteEarnEVMParams extends ActionParameters {
|
|
1874
|
+
/**
|
|
1875
|
+
* Execution parameters returned by the earn service.
|
|
1876
|
+
*
|
|
1877
|
+
* Kept as an opaque record so the adapter forwards the service-signed struct
|
|
1878
|
+
* unchanged. The adapter contract ABI decodes it on-chain.
|
|
1879
|
+
*/
|
|
1880
|
+
executeParams: Record<string, unknown>;
|
|
1881
|
+
/**
|
|
1882
|
+
* Token inputs with permit signatures for gasless approvals.
|
|
1883
|
+
*
|
|
1884
|
+
* Populated by the earn provider after it decides how token spending is
|
|
1885
|
+
* authorised. Today deposit uses a separate `token.approve` transaction and
|
|
1886
|
+
* passes `PermitType.NONE`; a future permit-enabled path can populate this
|
|
1887
|
+
* field without a breaking change.
|
|
1888
|
+
*/
|
|
1889
|
+
tokenInputs: TokenInput[];
|
|
1890
|
+
/**
|
|
1891
|
+
* EIP-712 signature from the earn service proxy.
|
|
1892
|
+
*
|
|
1893
|
+
* The adapter contract verifies this signature on-chain. Passed through
|
|
1894
|
+
* unchanged.
|
|
1895
|
+
*/
|
|
1896
|
+
signature: `0x${string}`;
|
|
1897
|
+
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Parameters for earn execute actions across supported ecosystems.
|
|
1900
|
+
*
|
|
1901
|
+
* EVM-only today; becomes a union when a non-EVM adapter implementation
|
|
1902
|
+
* lands. Action handlers narrow via a property-based type guard, same
|
|
1903
|
+
* pattern as {@link ExecuteSwapParams}.
|
|
1904
|
+
*/
|
|
1905
|
+
type ExecuteEarnParams = ExecuteEarnEVMParams;
|
|
1906
|
+
/**
|
|
1907
|
+
* Action map for earn operations.
|
|
1908
|
+
*
|
|
1909
|
+
* Each action key forwards the same `(executeParams, tokenInputs, signature)`
|
|
1910
|
+
* triple to the adapter contract. Provider-side orchestration performs any
|
|
1911
|
+
* required token approval; this action only prepares the adapter execute call.
|
|
1912
|
+
*/
|
|
1913
|
+
interface EarnActionMap {
|
|
1914
|
+
/**
|
|
1915
|
+
* Execute a service-signed deposit against the adapter contract.
|
|
1916
|
+
*/
|
|
1917
|
+
readonly deposit: ExecuteEarnParams;
|
|
1918
|
+
/**
|
|
1919
|
+
* Execute a service-signed withdraw against the adapter contract.
|
|
1920
|
+
*/
|
|
1921
|
+
readonly withdraw: ExecuteEarnParams;
|
|
1922
|
+
/**
|
|
1923
|
+
* Execute a service-signed claim rewards against the adapter contract.
|
|
1924
|
+
*/
|
|
1925
|
+
readonly claimRewards: ExecuteEarnParams;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1847
1928
|
/**
|
|
1848
1929
|
* Single instruction to execute within the Adapter Contract.
|
|
1849
1930
|
*
|
|
@@ -2025,7 +2106,6 @@ interface ExecuteParams {
|
|
|
2025
2106
|
* const tokenInputs: TokenInput[] = [{
|
|
2026
2107
|
* permitType: PermitType.EIP2612,
|
|
2027
2108
|
* token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
2028
|
-
* from: userAddress,
|
|
2029
2109
|
* amount: 1000000n,
|
|
2030
2110
|
* permitCalldata: '0x...' // Encoded permit signature
|
|
2031
2111
|
* }]
|
|
@@ -2068,7 +2148,6 @@ interface ExecuteSwapEVMParams extends ActionParameters {
|
|
|
2068
2148
|
* [{
|
|
2069
2149
|
* permitType: PermitType.EIP2612,
|
|
2070
2150
|
* token: '0xUSDC',
|
|
2071
|
-
* from: userAddress,
|
|
2072
2151
|
* amount: 1000000n,
|
|
2073
2152
|
* permitCalldata: '0x...'
|
|
2074
2153
|
* }]
|
|
@@ -2804,6 +2883,8 @@ interface ActionMap {
|
|
|
2804
2883
|
readonly usdt: USDTActionMap;
|
|
2805
2884
|
/** Swap operations for DEX aggregator integrations. */
|
|
2806
2885
|
readonly swap: SwapActionMap;
|
|
2886
|
+
/** Earn operations that execute service-signed payloads via the adapter contract. */
|
|
2887
|
+
readonly earn: EarnActionMap;
|
|
2807
2888
|
}
|
|
2808
2889
|
/**
|
|
2809
2890
|
* Determine if a type represents an action parameter object (leaf node).
|
package/index.mjs
CHANGED
|
@@ -393,23 +393,21 @@ var UnifiedBalanceChain;
|
|
|
393
393
|
* Enumeration of blockchains that support earn (vault deposit/withdraw)
|
|
394
394
|
* operations through the Earn Kit.
|
|
395
395
|
*
|
|
396
|
-
* Currently only Ethereum mainnet is supported. Additional chains
|
|
397
|
-
* will be added as vault protocol support expands.
|
|
398
|
-
*
|
|
399
396
|
* @example
|
|
400
397
|
* ```typescript
|
|
401
398
|
* import { EarnChain } from '@core/chains'
|
|
402
399
|
*
|
|
403
400
|
* const result = await earnKit.deposit({
|
|
404
|
-
* from: { adapter, chain: EarnChain.
|
|
401
|
+
* from: { adapter, chain: EarnChain.Arc_Testnet },
|
|
405
402
|
* vaultAddress: '0x...',
|
|
406
403
|
* amount: '100',
|
|
407
404
|
* })
|
|
408
405
|
* ```
|
|
409
406
|
*/
|
|
407
|
+
// Values must match Blockchain enum members exactly.
|
|
410
408
|
var EarnChain;
|
|
411
409
|
(function (EarnChain) {
|
|
412
|
-
EarnChain["
|
|
410
|
+
EarnChain["Arc_Testnet"] = "Arc_Testnet";
|
|
413
411
|
})(EarnChain || (EarnChain = {}));
|
|
414
412
|
|
|
415
413
|
/**
|
|
@@ -4087,7 +4085,7 @@ z.union([
|
|
|
4087
4085
|
* Zod schema for validating earn-specific chain identifiers.
|
|
4088
4086
|
*
|
|
4089
4087
|
* Validate that the provided chain is supported for earn (vault
|
|
4090
|
-
* deposit/withdraw) operations. Currently only
|
|
4088
|
+
* deposit/withdraw) operations. Currently only Arc Testnet is
|
|
4091
4089
|
* supported.
|
|
4092
4090
|
*
|
|
4093
4091
|
* Accept an EarnChain enum value, a matching string literal, or
|
|
@@ -4096,12 +4094,12 @@ z.union([
|
|
|
4096
4094
|
* @example
|
|
4097
4095
|
* ```typescript
|
|
4098
4096
|
* import { earnChainIdentifierSchema } from '@core/chains'
|
|
4099
|
-
* import {
|
|
4097
|
+
* import { ArcTestnet, EarnChain } from '@core/chains'
|
|
4100
4098
|
*
|
|
4101
4099
|
* // Valid
|
|
4102
|
-
* earnChainIdentifierSchema.parse(EarnChain.
|
|
4103
|
-
* earnChainIdentifierSchema.parse('
|
|
4104
|
-
* earnChainIdentifierSchema.parse(
|
|
4100
|
+
* earnChainIdentifierSchema.parse(EarnChain.Arc_Testnet)
|
|
4101
|
+
* earnChainIdentifierSchema.parse('Arc_Testnet')
|
|
4102
|
+
* earnChainIdentifierSchema.parse(ArcTestnet)
|
|
4105
4103
|
*
|
|
4106
4104
|
* // Invalid (throws ZodError)
|
|
4107
4105
|
* earnChainIdentifierSchema.parse('Solana')
|
|
@@ -6386,7 +6384,8 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6386
6384
|
*
|
|
6387
6385
|
* @remarks
|
|
6388
6386
|
* Check order for KitError instances:
|
|
6389
|
-
* 1. If `recoverability === 'RETRYABLE'
|
|
6387
|
+
* 1. If `recoverability === 'RETRYABLE'` or `recoverability === 'RESUMABLE'`,
|
|
6388
|
+
* return `true` immediately (priority check).
|
|
6390
6389
|
* 2. Otherwise, check if `error.code` is in `DEFAULT_RETRYABLE_ERROR_CODES` (fallback check).
|
|
6391
6390
|
* 3. Non-KitError instances always return `false`.
|
|
6392
6391
|
*
|
|
@@ -6397,6 +6396,12 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6397
6396
|
* subsequent attempts, such as network timeouts or temporary service
|
|
6398
6397
|
* unavailability. These errors are safe to retry after a delay.
|
|
6399
6398
|
*
|
|
6399
|
+
* RESUMABLE errors indicate a multi-phase operation that completed some phases
|
|
6400
|
+
* before failing (for example, a token approval landed but the execution
|
|
6401
|
+
* transaction failed). They are also retryable — re-running the operation is
|
|
6402
|
+
* safe — but callers that have a kit-level `retry()` should prefer it so that
|
|
6403
|
+
* already-completed phases are skipped.
|
|
6404
|
+
*
|
|
6400
6405
|
* @param error - Unknown error to check
|
|
6401
6406
|
* @returns True if error is retryable
|
|
6402
6407
|
*
|
|
@@ -6442,16 +6447,29 @@ const DEFAULT_RETRYABLE_ERROR_CODES = [
|
|
|
6442
6447
|
* })
|
|
6443
6448
|
* isRetryableError(error3) // false
|
|
6444
6449
|
*
|
|
6450
|
+
* // KitError with RESUMABLE recoverability (partially-completed operation)
|
|
6451
|
+
* const error4 = new KitError({
|
|
6452
|
+
* code: 8101,
|
|
6453
|
+
* name: 'EARN_EXECUTION_FAILED',
|
|
6454
|
+
* type: 'SERVICE',
|
|
6455
|
+
* recoverability: 'RESUMABLE',
|
|
6456
|
+
* message: 'Execution failed after approval',
|
|
6457
|
+
* })
|
|
6458
|
+
* isRetryableError(error4) // true
|
|
6459
|
+
*
|
|
6445
6460
|
* // Non-KitError
|
|
6446
|
-
* const
|
|
6447
|
-
* isRetryableError(
|
|
6461
|
+
* const error5 = new Error('Standard error')
|
|
6462
|
+
* isRetryableError(error5) // false
|
|
6448
6463
|
* ```
|
|
6449
6464
|
*/
|
|
6450
6465
|
function isRetryableError$1(error) {
|
|
6451
6466
|
// Use proper type guard to check if it's a KitError
|
|
6452
6467
|
if (isKitError(error)) {
|
|
6453
|
-
// Priority check: explicit recoverability
|
|
6454
|
-
|
|
6468
|
+
// Priority check: explicit recoverability. RESUMABLE errors are a subset of
|
|
6469
|
+
// retryable errors — re-running the operation is safe, but a kit-level
|
|
6470
|
+
// retry() can resume from the failed phase instead.
|
|
6471
|
+
if (error.recoverability === 'RETRYABLE' ||
|
|
6472
|
+
error.recoverability === 'RESUMABLE') {
|
|
6455
6473
|
return true;
|
|
6456
6474
|
}
|
|
6457
6475
|
// Fallback check: error code against default retryable codes
|
|
@@ -12241,7 +12259,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCo
|
|
|
12241
12259
|
return step;
|
|
12242
12260
|
}
|
|
12243
12261
|
|
|
12244
|
-
var version = "1.8.
|
|
12262
|
+
var version = "1.8.3";
|
|
12245
12263
|
var pkg = {
|
|
12246
12264
|
version: version};
|
|
12247
12265
|
|
|
@@ -12655,7 +12673,9 @@ const hexStringSchema = z
|
|
|
12655
12673
|
* console.log(result.success) // true
|
|
12656
12674
|
* ```
|
|
12657
12675
|
*/
|
|
12658
|
-
hexStringSchema
|
|
12676
|
+
hexStringSchema
|
|
12677
|
+
.refine((value) => value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)')
|
|
12678
|
+
.transform((value) => value);
|
|
12659
12679
|
/**
|
|
12660
12680
|
* Schema for validating transaction hashes.
|
|
12661
12681
|
*
|
|
@@ -12676,6 +12696,29 @@ hexStringSchema.refine((value) => value.length === 42, 'EVM address must be exac
|
|
|
12676
12696
|
* ```
|
|
12677
12697
|
*/
|
|
12678
12698
|
hexStringSchema.refine((value) => value.length === 66, 'Transaction hash must be exactly 66 characters long (0x + 64 hex characters)');
|
|
12699
|
+
/**
|
|
12700
|
+
* Schema for validating EVM signatures.
|
|
12701
|
+
*
|
|
12702
|
+
* This schema validates that a string is a properly formatted 65-byte EVM
|
|
12703
|
+
* signature:
|
|
12704
|
+
* - Must be a valid hex string with '0x' prefix
|
|
12705
|
+
* - Must be exactly 132 characters long (0x + 130 hex characters)
|
|
12706
|
+
*
|
|
12707
|
+
* @throws {KitError} If validation fails with INPUT_VALIDATION_FAILED code (1098), with details about which properties failed
|
|
12708
|
+
*
|
|
12709
|
+
* @example
|
|
12710
|
+
* ```typescript
|
|
12711
|
+
* import { evmSignatureSchema } from '@core/adapter'
|
|
12712
|
+
*
|
|
12713
|
+
* const validSignature = `0x${'ab'.repeat(65)}`
|
|
12714
|
+
*
|
|
12715
|
+
* const result = evmSignatureSchema.safeParse(validSignature)
|
|
12716
|
+
* console.log(result.success) // true
|
|
12717
|
+
* ```
|
|
12718
|
+
*/
|
|
12719
|
+
hexStringSchema
|
|
12720
|
+
.refine((value) => value.length === 132, 'EVM signature must be exactly 132 characters long (0x + 130 hex characters)')
|
|
12721
|
+
.transform((value) => value);
|
|
12679
12722
|
/**
|
|
12680
12723
|
* Schema for validating base58-encoded strings.
|
|
12681
12724
|
*
|
|
@@ -12822,60 +12865,6 @@ const validateBalanceForTransaction = async (params) => {
|
|
|
12822
12865
|
}
|
|
12823
12866
|
};
|
|
12824
12867
|
|
|
12825
|
-
/**
|
|
12826
|
-
* Validate that the adapter has sufficient native token balance for transaction fees.
|
|
12827
|
-
*
|
|
12828
|
-
* This function checks if the adapter's current native token balance (ETH, SOL, etc.)
|
|
12829
|
-
* is greater than zero. It throws a KitError with code 9002 (BALANCE_INSUFFICIENT_GAS)
|
|
12830
|
-
* if the balance is zero, indicating the wallet cannot pay for transaction fees.
|
|
12831
|
-
*
|
|
12832
|
-
* @param params - The validation parameters containing adapter and operation context.
|
|
12833
|
-
* @returns A promise that resolves to void if validation passes.
|
|
12834
|
-
* @throws {KitError} When the adapter's native balance is zero (code: 9002).
|
|
12835
|
-
*
|
|
12836
|
-
* @example
|
|
12837
|
-
* ```typescript
|
|
12838
|
-
* import { validateNativeBalanceForTransaction } from '@core/adapter'
|
|
12839
|
-
* import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
|
|
12840
|
-
* import { isKitError, ERROR_TYPES } from '@core/errors'
|
|
12841
|
-
*
|
|
12842
|
-
* const adapter = createViemAdapterFromPrivateKey({
|
|
12843
|
-
* privateKey: '0x...',
|
|
12844
|
-
* chain: 'Ethereum',
|
|
12845
|
-
* })
|
|
12846
|
-
*
|
|
12847
|
-
* try {
|
|
12848
|
-
* await validateNativeBalanceForTransaction({
|
|
12849
|
-
* adapter,
|
|
12850
|
-
* operationContext: { chain: 'Ethereum' },
|
|
12851
|
-
* })
|
|
12852
|
-
* console.log('Native balance validation passed')
|
|
12853
|
-
* } catch (error) {
|
|
12854
|
-
* if (isKitError(error) && error.type === ERROR_TYPES.BALANCE) {
|
|
12855
|
-
* console.error('Insufficient gas funds:', error.message)
|
|
12856
|
-
* }
|
|
12857
|
-
* }
|
|
12858
|
-
* ```
|
|
12859
|
-
*/
|
|
12860
|
-
const validateNativeBalanceForTransaction = async (params) => {
|
|
12861
|
-
const { adapter, operationContext } = params;
|
|
12862
|
-
const balancePrepared = await adapter.prepareAction('native.balanceOf', {
|
|
12863
|
-
walletAddress: operationContext.address,
|
|
12864
|
-
}, operationContext);
|
|
12865
|
-
const balance = await balancePrepared.execute();
|
|
12866
|
-
if (BigInt(balance) === 0n) {
|
|
12867
|
-
const { chain } = operationContext;
|
|
12868
|
-
const chainName = extractChainInfo(chain).name;
|
|
12869
|
-
const nativeSymbol = typeof chain === 'object' && chain !== null && 'nativeCurrency' in chain
|
|
12870
|
-
? chain.nativeCurrency.symbol
|
|
12871
|
-
: undefined;
|
|
12872
|
-
throw createInsufficientGasError(chainName, nativeSymbol, {
|
|
12873
|
-
balance: '0',
|
|
12874
|
-
walletAddress: operationContext.address,
|
|
12875
|
-
});
|
|
12876
|
-
}
|
|
12877
|
-
};
|
|
12878
|
-
|
|
12879
12868
|
/**
|
|
12880
12869
|
* Permit signature standards for gasless token approvals.
|
|
12881
12870
|
*
|
|
@@ -13436,7 +13425,7 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
13436
13425
|
async bridge(params) {
|
|
13437
13426
|
// CCTP-specific bridge params validation (includes base validation)
|
|
13438
13427
|
assertCCTPv2BridgeParams(params);
|
|
13439
|
-
const { source,
|
|
13428
|
+
const { source, amount, token } = params;
|
|
13440
13429
|
// Extract operation context from source wallet context for balance validation
|
|
13441
13430
|
const sourceOperationContext = this.extractOperationContext(source);
|
|
13442
13431
|
// Validate USDC balance for transaction on source chain
|
|
@@ -13447,24 +13436,6 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
13447
13436
|
tokenAddress: source.chain.usdcAddress,
|
|
13448
13437
|
operationContext: sourceOperationContext,
|
|
13449
13438
|
});
|
|
13450
|
-
// Validate native balance > 0 for gas fees on source chain
|
|
13451
|
-
await validateNativeBalanceForTransaction({
|
|
13452
|
-
adapter: source.adapter,
|
|
13453
|
-
operationContext: sourceOperationContext,
|
|
13454
|
-
});
|
|
13455
|
-
// Only validate destination native balance if there's an adapter
|
|
13456
|
-
// and forwarder is not being used (forwarder handles mint, no gas needed)
|
|
13457
|
-
if ('adapter' in destination &&
|
|
13458
|
-
destination.adapter &&
|
|
13459
|
-
!destination.useForwarder) {
|
|
13460
|
-
// Extract operation context from destination wallet context
|
|
13461
|
-
const destinationOperationContext = this.extractOperationContext(destination);
|
|
13462
|
-
// Validate native balance > 0 for gas fees on destination chain
|
|
13463
|
-
await validateNativeBalanceForTransaction({
|
|
13464
|
-
adapter: destination.adapter,
|
|
13465
|
-
operationContext: destinationOperationContext,
|
|
13466
|
-
});
|
|
13467
|
-
}
|
|
13468
13439
|
return bridge(params, this);
|
|
13469
13440
|
}
|
|
13470
13441
|
/**
|