@circle-fin/app-kit 1.17.0 → 1.18.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 +41 -0
- package/borrow.cjs +6 -6
- package/borrow.d.cts +3 -3
- package/borrow.d.mts +3 -3
- package/borrow.d.ts +3 -3
- package/borrow.mjs +6 -6
- package/bridge.cjs +272 -18
- package/bridge.d.cts +3 -3
- package/bridge.d.mts +3 -3
- package/bridge.d.ts +3 -3
- package/bridge.mjs +272 -18
- package/chains.cjs +2 -2
- package/chains.d.cts +1 -1
- package/chains.d.mts +1 -1
- package/chains.d.ts +1 -1
- package/chains.mjs +2 -2
- package/context.d.cts +3 -3
- package/context.d.mts +3 -3
- package/context.d.ts +3 -3
- package/earn.cjs +365 -14
- package/earn.d.cts +3 -3
- package/earn.d.mts +3 -3
- package/earn.d.ts +3 -3
- package/earn.mjs +365 -14
- package/estimateBridge.cjs +272 -18
- package/estimateBridge.d.cts +3 -3
- package/estimateBridge.d.mts +3 -3
- package/estimateBridge.d.ts +3 -3
- package/estimateBridge.mjs +272 -18
- package/estimateSwap.cjs +6 -6
- package/estimateSwap.d.cts +3 -3
- package/estimateSwap.d.mts +3 -3
- package/estimateSwap.d.ts +3 -3
- package/estimateSwap.mjs +6 -6
- package/index.cjs +558 -27
- package/index.d.cts +42 -8
- package/index.d.mts +42 -8
- package/index.d.ts +42 -8
- package/index.mjs +558 -27
- package/package.json +8 -8
- package/server.cjs +3 -3
- package/server.mjs +3 -3
- package/swap.cjs +6 -6
- package/swap.d.cts +3 -3
- package/swap.d.mts +3 -3
- package/swap.d.ts +3 -3
- package/swap.mjs +6 -6
- package/unifiedBalance.cjs +68 -10
- package/unifiedBalance.mjs +68 -10
package/earn.cjs
CHANGED
|
@@ -2445,6 +2445,15 @@ class KitError extends Error {
|
|
|
2445
2445
|
recoverability: 'RETRYABLE'
|
|
2446
2446
|
}
|
|
2447
2447
|
],
|
|
2448
|
+
// DEPOSIT_INTENT_INVALID: the Veda deposit intent is missing, expired, or
|
|
2449
|
+
// not signed by the depositing wallet.
|
|
2450
|
+
[
|
|
2451
|
+
380418,
|
|
2452
|
+
{
|
|
2453
|
+
errorDef: EarnError.SIGNATURE_REJECTED,
|
|
2454
|
+
recoverability: 'FATAL'
|
|
2455
|
+
}
|
|
2456
|
+
],
|
|
2448
2457
|
// Bridge (380_5XX)
|
|
2449
2458
|
[
|
|
2450
2459
|
380500,
|
|
@@ -3358,14 +3367,14 @@ var BorrowChain;
|
|
|
3358
3367
|
symbol: 'USDC',
|
|
3359
3368
|
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
3360
3369
|
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
3361
|
-
// See: https://docs.arc.
|
|
3370
|
+
// See: https://docs.arc.io/arc/references/contract-addresses
|
|
3362
3371
|
decimals: 18
|
|
3363
3372
|
},
|
|
3364
3373
|
chainId: 5042002,
|
|
3365
3374
|
isTestnet: true,
|
|
3366
3375
|
explorerUrl: 'https://testnet.arcscan.app/tx/{hash}',
|
|
3367
3376
|
rpcEndpoints: [
|
|
3368
|
-
'https://rpc.testnet.arc.
|
|
3377
|
+
'https://rpc.testnet.arc.io'
|
|
3369
3378
|
],
|
|
3370
3379
|
eurcAddress: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
3371
3380
|
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
@@ -9560,7 +9569,7 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
9560
9569
|
}
|
|
9561
9570
|
|
|
9562
9571
|
var name$4 = "@circle-fin/bridge-kit";
|
|
9563
|
-
var version$4 = "1.
|
|
9572
|
+
var version$4 = "1.16.0";
|
|
9564
9573
|
var pkg$4 = {
|
|
9565
9574
|
name: name$4,
|
|
9566
9575
|
version: version$4};
|
|
@@ -11356,7 +11365,7 @@ const validateQuoteItemSchema = zod.z.object({
|
|
|
11356
11365
|
registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
11357
11366
|
|
|
11358
11367
|
var name$3 = "@circle-fin/swap-kit";
|
|
11359
|
-
var version$3 = "1.8.
|
|
11368
|
+
var version$3 = "1.8.1";
|
|
11360
11369
|
var pkg$3 = {
|
|
11361
11370
|
name: name$3,
|
|
11362
11371
|
version: version$3};
|
|
@@ -14617,6 +14626,47 @@ const abiParameterSchema = zod.z.object({
|
|
|
14617
14626
|
*/ function hasSignTypedData(adapter) {
|
|
14618
14627
|
return typeof adapter === 'object' && adapter !== null && 'signTypedData' in adapter && typeof adapter.signTypedData === 'function';
|
|
14619
14628
|
}
|
|
14629
|
+
/**
|
|
14630
|
+
* Type guard to check if an adapter can actually produce an EIP-712
|
|
14631
|
+
* typed-data signature.
|
|
14632
|
+
*
|
|
14633
|
+
* @remarks
|
|
14634
|
+
* Strengthens {@link hasSignTypedData}: having a `signTypedData` method
|
|
14635
|
+
* does not guarantee it can succeed. Adapters whose signer is delegated
|
|
14636
|
+
* (e.g. through a signing strategy backed by a smart contract account)
|
|
14637
|
+
* expose the method but reject typed-data payloads at runtime. Such
|
|
14638
|
+
* adapters report their real capability through an optional
|
|
14639
|
+
* `supportsSignTypedData()` method, which this guard consults when
|
|
14640
|
+
* present. Adapters without the capability method are assumed able to
|
|
14641
|
+
* sign, preserving the previous duck-typing behavior.
|
|
14642
|
+
*
|
|
14643
|
+
* @param adapter - The adapter to check
|
|
14644
|
+
* @returns True if calling `signTypedData` can be expected to succeed
|
|
14645
|
+
*
|
|
14646
|
+
* @example
|
|
14647
|
+
* ```typescript
|
|
14648
|
+
* import { canSignTypedData } from '@core/adapter-evm'
|
|
14649
|
+
*
|
|
14650
|
+
* if (canSignTypedData(adapter)) {
|
|
14651
|
+
* const signature = await adapter.signTypedData(typedData, context)
|
|
14652
|
+
* } else {
|
|
14653
|
+
* // take an on-chain approval path instead of a permit signature
|
|
14654
|
+
* }
|
|
14655
|
+
* ```
|
|
14656
|
+
*/ function canSignTypedData(adapter) {
|
|
14657
|
+
if (!hasSignTypedData(adapter)) {
|
|
14658
|
+
return false;
|
|
14659
|
+
}
|
|
14660
|
+
if (typeof adapter.supportsSignTypedData === 'function') {
|
|
14661
|
+
// The value is `boolean` per the interface, but a plain-JS adapter may
|
|
14662
|
+
// return anything; treat it as untrusted and coerce to a strict
|
|
14663
|
+
// boolean. Comparing an `unknown` (not a `boolean`) also keeps the
|
|
14664
|
+
// lint autofix from stripping this as a redundant `=== true`.
|
|
14665
|
+
const supported = adapter.supportsSignTypedData();
|
|
14666
|
+
return supported === true;
|
|
14667
|
+
}
|
|
14668
|
+
return true;
|
|
14669
|
+
}
|
|
14620
14670
|
|
|
14621
14671
|
/** Inputs for {@link checkErc3009ValidityWindow}. */ /**
|
|
14622
14672
|
* Check an ERC-3009 authorization validity window.
|
|
@@ -15463,7 +15513,7 @@ new Set(Object.values(Blockchain));
|
|
|
15463
15513
|
registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
15464
15514
|
|
|
15465
15515
|
var name$2 = "@circle-fin/earn-kit";
|
|
15466
|
-
var version$2 = "1.
|
|
15516
|
+
var version$2 = "1.10.0";
|
|
15467
15517
|
var pkg$2 = {
|
|
15468
15518
|
name: name$2,
|
|
15469
15519
|
version: version$2};
|
|
@@ -15570,6 +15620,61 @@ const EARN_BRIDGE_USDC_ERC3009_DOMAINS = {
|
|
|
15570
15620
|
*
|
|
15571
15621
|
* @internal
|
|
15572
15622
|
*/ const EARN_BRIDGE_MAX_VALIDITY_SECONDS = 86_400n;
|
|
15623
|
+
/**
|
|
15624
|
+
* Static fields of the EIP-712 domain for the `DepositIntent` typed-data
|
|
15625
|
+
* intent. `chainId` is excluded here — it must come from the deposit's
|
|
15626
|
+
* actual chain (see {@link buildDepositIntentTypedData}), since a mismatched
|
|
15627
|
+
* `chainId` in the domain separator would make every intent signature
|
|
15628
|
+
* invalid.
|
|
15629
|
+
*
|
|
15630
|
+
* `verifyingContract` is intentionally omitted — the intent is verified
|
|
15631
|
+
* off-chain by the Earn Service, not by a deployed contract.
|
|
15632
|
+
*
|
|
15633
|
+
* @internal
|
|
15634
|
+
*/ const DEPOSIT_INTENT_DOMAIN = {
|
|
15635
|
+
name: 'Circle EarnKit',
|
|
15636
|
+
version: '1'
|
|
15637
|
+
};
|
|
15638
|
+
/**
|
|
15639
|
+
* EIP-712 type definition for the `DepositIntent` struct.
|
|
15640
|
+
*
|
|
15641
|
+
* @internal
|
|
15642
|
+
*/ const DEPOSIT_INTENT_TYPES = {
|
|
15643
|
+
DepositIntent: [
|
|
15644
|
+
{
|
|
15645
|
+
name: 'wallet',
|
|
15646
|
+
type: 'address'
|
|
15647
|
+
},
|
|
15648
|
+
{
|
|
15649
|
+
name: 'vault',
|
|
15650
|
+
type: 'address'
|
|
15651
|
+
},
|
|
15652
|
+
{
|
|
15653
|
+
name: 'amount',
|
|
15654
|
+
type: 'uint256'
|
|
15655
|
+
},
|
|
15656
|
+
{
|
|
15657
|
+
name: 'deadline',
|
|
15658
|
+
type: 'uint256'
|
|
15659
|
+
}
|
|
15660
|
+
]
|
|
15661
|
+
};
|
|
15662
|
+
/**
|
|
15663
|
+
* Lifetime of a `DepositIntent` signature, in seconds.
|
|
15664
|
+
*
|
|
15665
|
+
* The Earn Service rejects a deadline more than 300 seconds ahead of its own
|
|
15666
|
+
* clock. 240 seconds leaves room for clock skew between the client and the
|
|
15667
|
+
* service while still covering the deposit request that follows the
|
|
15668
|
+
* signature.
|
|
15669
|
+
*
|
|
15670
|
+
* @internal
|
|
15671
|
+
*/ const DEPOSIT_INTENT_TTL_SECONDS = 240;
|
|
15672
|
+
/**
|
|
15673
|
+
* Protocol value the Earn Service reports for Veda vaults. A deposit into a
|
|
15674
|
+
* Veda vault needs a signed `DepositIntent`.
|
|
15675
|
+
*
|
|
15676
|
+
* @internal
|
|
15677
|
+
*/ const VEDA_PROTOCOL = 'veda';
|
|
15573
15678
|
/**
|
|
15574
15679
|
* Display symbol for vault share tokens.
|
|
15575
15680
|
*
|
|
@@ -18407,7 +18512,7 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
18407
18512
|
}
|
|
18408
18513
|
|
|
18409
18514
|
var name$1 = "@circle-fin/provider-earn-service";
|
|
18410
|
-
var version$1 = "1.
|
|
18515
|
+
var version$1 = "1.8.0";
|
|
18411
18516
|
var pkg$1 = {
|
|
18412
18517
|
name: name$1,
|
|
18413
18518
|
version: version$1};
|
|
@@ -18759,8 +18864,9 @@ function toPositionInfo(data) {
|
|
|
18759
18864
|
* Build signed deposit instructions via the Earn Service API.
|
|
18760
18865
|
*
|
|
18761
18866
|
* Call `POST /v1/earnKit/deposit` with the vault address, amount,
|
|
18762
|
-
* wallet address, and chain
|
|
18763
|
-
* parameters for on-chain
|
|
18867
|
+
* wallet address, and chain, plus the signed `DepositIntent` when one is
|
|
18868
|
+
* given. Return EIP-712 signed execution parameters for on-chain
|
|
18869
|
+
* submission.
|
|
18764
18870
|
*
|
|
18765
18871
|
* @param params - Deposit parameters
|
|
18766
18872
|
* @returns Signed execution parameters for the deposit
|
|
@@ -18774,7 +18880,8 @@ function toPositionInfo(data) {
|
|
|
18774
18880
|
vaultAddress: params.vaultAddress,
|
|
18775
18881
|
amount: params.amount,
|
|
18776
18882
|
address: params.address,
|
|
18777
|
-
chain: params.chain
|
|
18883
|
+
chain: params.chain,
|
|
18884
|
+
...params.intent
|
|
18778
18885
|
};
|
|
18779
18886
|
try {
|
|
18780
18887
|
const response = await pollApiPost(url.toString(), requestBody, isDepositResponse, pollingConfig);
|
|
@@ -18786,6 +18893,232 @@ function toPositionInfo(data) {
|
|
|
18786
18893
|
}
|
|
18787
18894
|
}
|
|
18788
18895
|
|
|
18896
|
+
/**
|
|
18897
|
+
* Build the version-1 EarnKit `DepositIntent` EIP-712 typed data.
|
|
18898
|
+
*
|
|
18899
|
+
* The signed struct binds the depositing `wallet`, the target `vault`, the
|
|
18900
|
+
* deposit `amount` in the asset's smallest unit, and a signature `deadline`.
|
|
18901
|
+
* The Earn Service rebuilds the same struct from the deposit request and
|
|
18902
|
+
* rejects the deposit unless `wallet` signed it. The domain intentionally
|
|
18903
|
+
* omits `verifyingContract` because the service verifies the signature
|
|
18904
|
+
* off-chain.
|
|
18905
|
+
*
|
|
18906
|
+
* `domain.chainId` comes from the deposit's chain rather than a constant: the
|
|
18907
|
+
* domain separator must match what the service rebuilds, and a wrong
|
|
18908
|
+
* `chainId` would make every intent signature invalid.
|
|
18909
|
+
*
|
|
18910
|
+
* This function returns the fully-typed {@link DepositIntentTypedData} with
|
|
18911
|
+
* no assertion. {@link resolveDepositIntent} casts it to the adapter's
|
|
18912
|
+
* generic `EIP712Domain` shape only where it calls `adapter.signTypedData`,
|
|
18913
|
+
* since that shared interface always requires `verifyingContract`. The
|
|
18914
|
+
* adapter's runtime `eip712DomainSchema` treats `verifyingContract` as
|
|
18915
|
+
* optional, so the cast is safe at runtime. BorrowKit's
|
|
18916
|
+
* `buildWebhookRegistrationTypedData` works around the same gap.
|
|
18917
|
+
*
|
|
18918
|
+
* @param params - Wallet, vault, base-unit amount, deadline, and chain id.
|
|
18919
|
+
* @returns EIP-712 typed data ready to be cast for `adapter.signTypedData`.
|
|
18920
|
+
*
|
|
18921
|
+
* @example
|
|
18922
|
+
* ```typescript
|
|
18923
|
+
* const typedData = buildDepositIntentTypedData({
|
|
18924
|
+
* wallet: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
18925
|
+
* vault: '0x00000000000000000000000000000000000000a1',
|
|
18926
|
+
* amount: 100_000_000n,
|
|
18927
|
+
* deadline: 1_700_000_000n,
|
|
18928
|
+
* chainId: 5_042_002,
|
|
18929
|
+
* })
|
|
18930
|
+
* ```
|
|
18931
|
+
*
|
|
18932
|
+
* @internal
|
|
18933
|
+
*/ function buildDepositIntentTypedData(params) {
|
|
18934
|
+
return {
|
|
18935
|
+
domain: {
|
|
18936
|
+
...DEPOSIT_INTENT_DOMAIN,
|
|
18937
|
+
chainId: params.chainId
|
|
18938
|
+
},
|
|
18939
|
+
types: DEPOSIT_INTENT_TYPES,
|
|
18940
|
+
primaryType: 'DepositIntent',
|
|
18941
|
+
message: {
|
|
18942
|
+
wallet: params.wallet,
|
|
18943
|
+
vault: params.vault,
|
|
18944
|
+
amount: params.amount,
|
|
18945
|
+
deadline: params.deadline
|
|
18946
|
+
}
|
|
18947
|
+
};
|
|
18948
|
+
}
|
|
18949
|
+
/**
|
|
18950
|
+
* Earn Service error code for a missing, expired, or wrongly signed
|
|
18951
|
+
* `DepositIntent` (`DEPOSIT_INTENT_INVALID`).
|
|
18952
|
+
*/ const DEPOSIT_INTENT_INVALID_CODE = 380418;
|
|
18953
|
+
/**
|
|
18954
|
+
* Sign a `DepositIntent` when the target vault needs one.
|
|
18955
|
+
*
|
|
18956
|
+
* A Veda vault mints shares straight to the depositing wallet, so the Earn
|
|
18957
|
+
* Service only builds a Veda deposit for a wallet that signed a
|
|
18958
|
+
* `DepositIntent` for the same vault and amount. The vault lookup exists only
|
|
18959
|
+
* to find out whether the vault is a Veda vault (and its asset decimals, to
|
|
18960
|
+
* sign the amount). Other vaults ignore the intent, so this returns no intent
|
|
18961
|
+
* for them and the wallet sees no extra signature prompt. A vault the service
|
|
18962
|
+
* does not return is also treated as not needing an intent; the deposit call
|
|
18963
|
+
* then reports why.
|
|
18964
|
+
*
|
|
18965
|
+
* A failed vault lookup does not stop the deposit: this returns the lookup
|
|
18966
|
+
* error with no intent, so a non-Veda deposit works as before. A Veda deposit
|
|
18967
|
+
* then gets `DEPOSIT_INTENT_INVALID` from the service, and
|
|
18968
|
+
* {@link resolveDepositError} reports the lookup error instead. The lookup
|
|
18969
|
+
* fails either by throwing or by returning the vault in its `errors` list (for
|
|
18970
|
+
* example `VAULT_REFRESH_BUSY`); both are kept the same way.
|
|
18971
|
+
*
|
|
18972
|
+
* @param params - Adapter, resolved chain, wallet, vault, human-readable
|
|
18973
|
+
* amount, and service config.
|
|
18974
|
+
* @returns The signed intent when the vault needs one, and the lookup error
|
|
18975
|
+
* when the vault lookup failed.
|
|
18976
|
+
* @throws {@link KitError} `InputError.VALIDATION_FAILED` when the vault needs
|
|
18977
|
+
* an intent but the chain is not EVM, the adapter cannot sign typed data, or
|
|
18978
|
+
* the amount has more decimal places than the vault asset.
|
|
18979
|
+
*
|
|
18980
|
+
* @example
|
|
18981
|
+
* ```typescript
|
|
18982
|
+
* const { intent } = await resolveDepositIntent({
|
|
18983
|
+
* adapter,
|
|
18984
|
+
* chain: ArcTestnet,
|
|
18985
|
+
* address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
18986
|
+
* vaultAddress: '0x00000000000000000000000000000000000000a1',
|
|
18987
|
+
* amount: '100',
|
|
18988
|
+
* config,
|
|
18989
|
+
* })
|
|
18990
|
+
* // intent -> { intentSignature: '0x…', intentDeadline: 1700000240 }
|
|
18991
|
+
* ```
|
|
18992
|
+
*
|
|
18993
|
+
* @internal
|
|
18994
|
+
*/ async function resolveDepositIntent(params) {
|
|
18995
|
+
let lookup;
|
|
18996
|
+
try {
|
|
18997
|
+
lookup = await fetchVaults({
|
|
18998
|
+
// `resolveAdapterContext` already rejected chains the Earn Service does
|
|
18999
|
+
// not support, so the chain is an Earn chain here.
|
|
19000
|
+
vaults: [
|
|
19001
|
+
{
|
|
19002
|
+
chain: params.chain,
|
|
19003
|
+
vaultAddress: params.vaultAddress
|
|
19004
|
+
}
|
|
19005
|
+
],
|
|
19006
|
+
config: params.config
|
|
19007
|
+
});
|
|
19008
|
+
} catch (lookupError) {
|
|
19009
|
+
return {
|
|
19010
|
+
lookupError
|
|
19011
|
+
};
|
|
19012
|
+
}
|
|
19013
|
+
const vaultError = lookup.errors.find((candidate)=>isSameAddress(candidate.vaultAddress, params.vaultAddress));
|
|
19014
|
+
if (vaultError !== undefined) {
|
|
19015
|
+
// Same handling as a thrown lookup error, mapped with the Earn Service
|
|
19016
|
+
// error table so it keeps its recoverability (VAULT_REFRESH_BUSY retries).
|
|
19017
|
+
return {
|
|
19018
|
+
lookupError: parseEarnApiError({
|
|
19019
|
+
responseBody: {
|
|
19020
|
+
code: vaultError.code,
|
|
19021
|
+
message: vaultError.message
|
|
19022
|
+
}
|
|
19023
|
+
}, {
|
|
19024
|
+
operation: 'getVaults'
|
|
19025
|
+
})
|
|
19026
|
+
};
|
|
19027
|
+
}
|
|
19028
|
+
const vault = lookup.vaults.find((candidate)=>isSameAddress(candidate.address, params.vaultAddress));
|
|
19029
|
+
if (vault?.protocol.toLowerCase() !== VEDA_PROTOCOL) {
|
|
19030
|
+
return {};
|
|
19031
|
+
}
|
|
19032
|
+
if (params.chain.type !== 'evm') {
|
|
19033
|
+
throw createValidationFailedError('from.chain', params.chain.chain, 'Veda vault deposits need an EVM chain to sign the deposit intent');
|
|
19034
|
+
}
|
|
19035
|
+
if (!canSignTypedData(params.adapter)) {
|
|
19036
|
+
throw createValidationFailedError('from.adapter', params.adapter, 'adapter must support signTypedData for Veda vault deposits');
|
|
19037
|
+
}
|
|
19038
|
+
const wallet = assertHexAddress('from.address', params.address, 'Depositor address must be a 0x-prefixed 20-byte hex address.');
|
|
19039
|
+
const assetDecimals = vault.liquidityProfile.totalDeposits.decimals;
|
|
19040
|
+
// Amount.parse truncates extra digits, but the service rejects them. Fail
|
|
19041
|
+
// before the wallet prompt instead of asking to sign a deposit that cannot
|
|
19042
|
+
// go through.
|
|
19043
|
+
assertDecimalPlaces('amount', params.amount, assetDecimals, `amount must have at most ${String(assetDecimals)} decimal places for the vault asset`);
|
|
19044
|
+
const deadline = Math.floor(Date.now() / 1000) + DEPOSIT_INTENT_TTL_SECONDS;
|
|
19045
|
+
const typedData = buildDepositIntentTypedData({
|
|
19046
|
+
wallet,
|
|
19047
|
+
vault: params.vaultAddress,
|
|
19048
|
+
amount: Amount.parse(params.amount, {
|
|
19049
|
+
decimals: assetDecimals
|
|
19050
|
+
}).raw,
|
|
19051
|
+
deadline: BigInt(deadline),
|
|
19052
|
+
chainId: params.chain.chainId
|
|
19053
|
+
});
|
|
19054
|
+
// `typedData.domain` intentionally omits `verifyingContract` (the Earn
|
|
19055
|
+
// Service verifies off-chain), but the shared `signTypedData` signature
|
|
19056
|
+
// requires the standard `EIP712Domain` shape. The adapter's runtime
|
|
19057
|
+
// `eip712DomainSchema` treats `verifyingContract` as optional, so this cast
|
|
19058
|
+
// is safe at runtime.
|
|
19059
|
+
const intentSignature = await params.adapter.signTypedData(typedData, {
|
|
19060
|
+
chain: params.chain,
|
|
19061
|
+
address: wallet
|
|
19062
|
+
});
|
|
19063
|
+
return {
|
|
19064
|
+
intent: {
|
|
19065
|
+
intentSignature,
|
|
19066
|
+
intentDeadline: deadline
|
|
19067
|
+
}
|
|
19068
|
+
};
|
|
19069
|
+
}
|
|
19070
|
+
/**
|
|
19071
|
+
* Pick the error to report for a failed deposit request.
|
|
19072
|
+
*
|
|
19073
|
+
* When the vault lookup failed, the SDK sent the deposit without an intent.
|
|
19074
|
+
* If the service then answers `DEPOSIT_INTENT_INVALID`, the vault is a Veda
|
|
19075
|
+
* vault and the real cause is the failed lookup, not a bad signature. Report
|
|
19076
|
+
* the lookup error, which keeps its own recoverability (often retryable),
|
|
19077
|
+
* instead of a fatal signature rejection.
|
|
19078
|
+
*
|
|
19079
|
+
* When the SDK did send an intent and the service still answers
|
|
19080
|
+
* `DEPOSIT_INTENT_INVALID`, the error stays a fatal signature rejection, but
|
|
19081
|
+
* its message adds that the intent may have expired: the deadline starts
|
|
19082
|
+
* before the wallet prompt, so a slow signer can submit an expired intent.
|
|
19083
|
+
* Calling `deposit()` again signs a new one. Every other error is reported as
|
|
19084
|
+
* is.
|
|
19085
|
+
*
|
|
19086
|
+
* @param resolution - The result of {@link resolveDepositIntent}.
|
|
19087
|
+
* @param error - The error from the deposit request.
|
|
19088
|
+
* @returns The error to throw.
|
|
19089
|
+
*
|
|
19090
|
+
* @example
|
|
19091
|
+
* ```typescript
|
|
19092
|
+
* try {
|
|
19093
|
+
* return await fetchDeposit({ ...params, intent: resolution.intent })
|
|
19094
|
+
* } catch (error) {
|
|
19095
|
+
* throw resolveDepositError(resolution, error)
|
|
19096
|
+
* }
|
|
19097
|
+
* ```
|
|
19098
|
+
*
|
|
19099
|
+
* @internal
|
|
19100
|
+
*/ function resolveDepositError(resolution, error) {
|
|
19101
|
+
if (resolution.lookupError !== undefined && isKitError(error) && isEarnServiceCode(error.cause?.trace, DEPOSIT_INTENT_INVALID_CODE)) {
|
|
19102
|
+
return resolution.lookupError;
|
|
19103
|
+
}
|
|
19104
|
+
if (resolution.intent !== undefined && isKitError(error) && isEarnServiceCode(error.cause?.trace, DEPOSIT_INTENT_INVALID_CODE)) {
|
|
19105
|
+
return new KitError({
|
|
19106
|
+
code: error.code,
|
|
19107
|
+
name: error.name,
|
|
19108
|
+
type: error.type,
|
|
19109
|
+
recoverability: error.recoverability,
|
|
19110
|
+
message: `${error.message} The deposit intent may have expired before the deposit was submitted (it is valid for ${String(DEPOSIT_INTENT_TTL_SECONDS)} seconds from when the SDK asks the wallet to sign). Call deposit() again to sign a new intent.`,
|
|
19111
|
+
...error.cause !== undefined && {
|
|
19112
|
+
cause: error.cause
|
|
19113
|
+
}
|
|
19114
|
+
});
|
|
19115
|
+
}
|
|
19116
|
+
return error;
|
|
19117
|
+
}
|
|
19118
|
+
function isEarnServiceCode(trace, code) {
|
|
19119
|
+
return typeof trace === 'object' && trace !== null && 'earnServiceCode' in trace && trace.earnServiceCode === code;
|
|
19120
|
+
}
|
|
19121
|
+
|
|
18789
19122
|
/**
|
|
18790
19123
|
* Build cross-chain deposit instructions via the bridge API.
|
|
18791
19124
|
*
|
|
@@ -20014,13 +20347,31 @@ function finishElapsedWait(lastStatus, lastError) {
|
|
|
20014
20347
|
const adapterContractAddress = requireAdapterContract(chain);
|
|
20015
20348
|
const { adapter } = params.from;
|
|
20016
20349
|
const vaultAddress = assertHexAddress('vaultAddress', params.vaultAddress, 'Vault address must be a 0x-prefixed 20-byte hex address.');
|
|
20017
|
-
const { execId, executionParams, signature } = await this.runPhase(ctx, 'deposit', 'fetchParams', async ()=>
|
|
20350
|
+
const { execId, executionParams, signature } = await this.runPhase(ctx, 'deposit', 'fetchParams', async ()=>{
|
|
20351
|
+
// Veda vaults mint shares straight to `address`, so the service
|
|
20352
|
+
// needs proof that `address` asked for this deposit. Sign it here,
|
|
20353
|
+
// inside fetchParams, so a rejected prompt fails this phase.
|
|
20354
|
+
const resolution = await resolveDepositIntent({
|
|
20355
|
+
adapter,
|
|
20356
|
+
chain,
|
|
20357
|
+
address,
|
|
20018
20358
|
vaultAddress,
|
|
20019
20359
|
amount: params.amount,
|
|
20020
|
-
address,
|
|
20021
|
-
chain: apiChain,
|
|
20022
20360
|
config
|
|
20023
|
-
})
|
|
20361
|
+
});
|
|
20362
|
+
try {
|
|
20363
|
+
return await fetchDeposit({
|
|
20364
|
+
vaultAddress,
|
|
20365
|
+
amount: params.amount,
|
|
20366
|
+
address,
|
|
20367
|
+
chain: apiChain,
|
|
20368
|
+
intent: resolution.intent,
|
|
20369
|
+
config
|
|
20370
|
+
});
|
|
20371
|
+
} catch (error) {
|
|
20372
|
+
throw resolveDepositError(resolution, error);
|
|
20373
|
+
}
|
|
20374
|
+
}, ()=>undefined);
|
|
20024
20375
|
validateExecutionDeadline(executionParams);
|
|
20025
20376
|
const transactionReportContext = {
|
|
20026
20377
|
execId,
|
|
@@ -23027,7 +23378,7 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
23027
23378
|
};
|
|
23028
23379
|
|
|
23029
23380
|
var name = "@circle-fin/borrow-kit";
|
|
23030
|
-
var version = "1.1.
|
|
23381
|
+
var version = "1.1.1";
|
|
23031
23382
|
var pkg = {
|
|
23032
23383
|
name: name,
|
|
23033
23384
|
version: version};
|
package/earn.d.cts
CHANGED
|
@@ -10147,11 +10147,11 @@ interface AppKitContext {
|
|
|
10147
10147
|
*/
|
|
10148
10148
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
10149
10149
|
/**
|
|
10150
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
10150
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
10151
10151
|
* BorrowKit, and UnifiedBalanceKit.
|
|
10152
10152
|
*
|
|
10153
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
10154
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
10153
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
10154
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
10155
10155
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
10156
10156
|
*
|
|
10157
10157
|
* @defaultValue false
|
package/earn.d.mts
CHANGED
|
@@ -10147,11 +10147,11 @@ interface AppKitContext {
|
|
|
10147
10147
|
*/
|
|
10148
10148
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
10149
10149
|
/**
|
|
10150
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
10150
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
10151
10151
|
* BorrowKit, and UnifiedBalanceKit.
|
|
10152
10152
|
*
|
|
10153
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
10154
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
10153
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
10154
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
10155
10155
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
10156
10156
|
*
|
|
10157
10157
|
* @defaultValue false
|
package/earn.d.ts
CHANGED
|
@@ -10147,11 +10147,11 @@ interface AppKitContext {
|
|
|
10147
10147
|
*/
|
|
10148
10148
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
10149
10149
|
/**
|
|
10150
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
10150
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
10151
10151
|
* BorrowKit, and UnifiedBalanceKit.
|
|
10152
10152
|
*
|
|
10153
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
10154
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
10153
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
10154
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
10155
10155
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
10156
10156
|
*
|
|
10157
10157
|
* @defaultValue false
|