@ember-finance/sdk 2.11.0-pre.7 → 2.12.0-ccip.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/dist/src/abis/CcipRouter.json +58 -0
- package/dist/src/abis/EmberDepositParkingLot.json +175 -43
- package/dist/src/abis/index.d.ts +3 -1
- package/dist/src/abis/index.js +4 -1
- package/dist/src/api/v2/models/evm-ccip-lane.d.ts +73 -0
- package/dist/src/api/v2/models/evm-ccip-lane.js +14 -0
- package/dist/src/api/v2/models/evm-ccip-rate-limits.d.ts +36 -0
- package/dist/src/api/v2/models/evm-ccip-rate-limits.js +14 -0
- package/dist/src/api/v2/models/evm-ccip-token-pool.d.ts +122 -0
- package/dist/src/api/v2/models/evm-ccip-token-pool.js +17 -0
- package/dist/src/api/v2/models/evm-contracts.d.ts +9 -0
- package/dist/src/api/v2/models/evm-oftadapter.d.ts +11 -0
- package/dist/src/api/v2/models/evm-oftadapter.js +4 -1
- package/dist/src/api/v2/models/evm-oftpeer.d.ts +12 -0
- package/dist/src/api/v2/models/index.d.ts +3 -0
- package/dist/src/api/v2/models/index.js +3 -0
- package/dist/src/evm-vaults/interfaces/index.d.ts +44 -0
- package/dist/src/evm-vaults/on-chain-calls/operator.d.ts +16 -0
- package/dist/src/evm-vaults/on-chain-calls/operator.js +20 -0
- package/dist/src/evm-vaults/on-chain-calls/tx-builder.d.ts +36 -1
- package/dist/src/evm-vaults/on-chain-calls/tx-builder.js +75 -0
- package/dist/src/evm-vaults/on-chain-calls/user.d.ts +33 -1
- package/dist/src/evm-vaults/on-chain-calls/user.js +61 -0
- package/dist/src/evm-vaults/on-chain-calls/vault-admin.d.ts +16 -0
- package/dist/src/evm-vaults/on-chain-calls/vault-admin.js +20 -0
- package/dist/src/evm-vaults/on-chain-calls/vault-reader.d.ts +14 -1
- package/dist/src/evm-vaults/on-chain-calls/vault-reader.js +33 -1
- package/dist/src/evm-vaults/utils/ccip.d.ts +23 -0
- package/dist/src/evm-vaults/utils/ccip.js +32 -0
- package/dist/src/evm-vaults/utils/deployment-parser.d.ts +27 -1
- package/dist/src/evm-vaults/utils/deployment-parser.js +37 -0
- package/dist/src/evm-vaults/utils/index.d.ts +1 -0
- package/dist/src/evm-vaults/utils/index.js +1 -0
- package/package.json +1 -6
- package/dist/src/placements/adapters/alphalend.d.ts +0 -1
- package/dist/src/placements/adapters/alphalend.js +0 -58
- package/dist/src/placements/adapters/bluefin-spot.d.ts +0 -1
- package/dist/src/placements/adapters/bluefin-spot.js +0 -78
- package/dist/src/placements/adapters/current.d.ts +0 -1
- package/dist/src/placements/adapters/current.js +0 -70
- package/dist/src/placements/adapters/evm-protocols.d.ts +0 -1
- package/dist/src/placements/adapters/evm-protocols.js +0 -8
- package/dist/src/placements/adapters/factory.d.ts +0 -15
- package/dist/src/placements/adapters/factory.js +0 -62
- package/dist/src/placements/adapters/index.d.ts +0 -14
- package/dist/src/placements/adapters/index.js +0 -25
- package/dist/src/placements/adapters/navi.d.ts +0 -1
- package/dist/src/placements/adapters/navi.js +0 -53
- package/dist/src/placements/adapters/pendle.d.ts +0 -9
- package/dist/src/placements/adapters/pendle.js +0 -108
- package/dist/src/placements/adapters/royco.d.ts +0 -2
- package/dist/src/placements/adapters/royco.js +0 -49
- package/dist/src/placements/adapters/suilend.d.ts +0 -1
- package/dist/src/placements/adapters/suilend.js +0 -57
- package/dist/src/placements/batch.d.ts +0 -70
- package/dist/src/placements/batch.js +0 -197
- package/dist/src/placements/client.d.ts +0 -17
- package/dist/src/placements/client.js +0 -194
- package/dist/src/placements/evm.d.ts +0 -29
- package/dist/src/placements/evm.js +0 -280
- package/dist/src/placements/index.d.ts +0 -9
- package/dist/src/placements/index.js +0 -9
- package/dist/src/placements/pointers.d.ts +0 -24
- package/dist/src/placements/pointers.js +0 -126
- package/dist/src/placements/registry.d.ts +0 -11
- package/dist/src/placements/registry.js +0 -19
- package/dist/src/placements/sui.d.ts +0 -47
- package/dist/src/placements/sui.js +0 -302
- package/dist/src/placements/types.d.ts +0 -147
- package/dist/src/placements/types.js +0 -1
- package/dist/src/placements/vaults.d.ts +0 -15
- package/dist/src/placements/vaults.js +0 -97
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Ember Protocol Vaults API
|
|
5
|
+
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
6
|
+
*
|
|
7
|
+
* The version of the OpenAPI document: 2.0.0
|
|
8
|
+
*
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
11
|
+
* https://openapi-generator.tech
|
|
12
|
+
* Do not edit the class manually.
|
|
13
|
+
*/
|
|
14
|
+
export const EvmCcipTokenPoolBridgeTransportEnum = {
|
|
15
|
+
LayerZero: "LayerZero",
|
|
16
|
+
Ccip: "CCIP"
|
|
17
|
+
};
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { EvmAtomicLiquidityLib } from "./evm-atomic-liquidity-lib.js";
|
|
13
13
|
import type { EvmAtomicVault } from "./evm-atomic-vault.js";
|
|
14
|
+
import type { EvmCcipTokenPool } from "./evm-ccip-token-pool.js";
|
|
14
15
|
import type { EvmDepositParkingLot } from "./evm-deposit-parking-lot.js";
|
|
15
16
|
import type { EvmDepositToken } from "./evm-deposit-token.js";
|
|
16
17
|
import type { EvmOFTAdapter } from "./evm-oftadapter.js";
|
|
@@ -80,6 +81,14 @@ export interface EvmContracts {
|
|
|
80
81
|
oftAdapters?: {
|
|
81
82
|
[key: string]: EvmOFTAdapter;
|
|
82
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Map of CCIP token pools by name
|
|
86
|
+
* @type {{ [key: string]: EvmCcipTokenPool; }}
|
|
87
|
+
* @memberof EvmContracts
|
|
88
|
+
*/
|
|
89
|
+
ccipTokenPools?: {
|
|
90
|
+
[key: string]: EvmCcipTokenPool;
|
|
91
|
+
};
|
|
83
92
|
/**
|
|
84
93
|
*
|
|
85
94
|
* @type {EvmVaultValidator}
|
|
@@ -82,6 +82,12 @@ export interface EvmOFTAdapter {
|
|
|
82
82
|
* @memberof EvmOFTAdapter
|
|
83
83
|
*/
|
|
84
84
|
deploymentBlockNumber?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Which bridge this entry describes. Read this rather than inferring the transport from which map the entry was found in.
|
|
87
|
+
* @type {string}
|
|
88
|
+
* @memberof EvmOFTAdapter
|
|
89
|
+
*/
|
|
90
|
+
bridgeTransport?: EvmOFTAdapterBridgeTransportEnum;
|
|
85
91
|
/**
|
|
86
92
|
* Map of peers by LayerZero endpoint ID
|
|
87
93
|
* @type {{ [key: string]: EvmOFTPeer; }}
|
|
@@ -91,3 +97,8 @@ export interface EvmOFTAdapter {
|
|
|
91
97
|
[key: string]: EvmOFTPeer;
|
|
92
98
|
};
|
|
93
99
|
}
|
|
100
|
+
export declare const EvmOFTAdapterBridgeTransportEnum: {
|
|
101
|
+
readonly LayerZero: "LayerZero";
|
|
102
|
+
readonly Ccip: "CCIP";
|
|
103
|
+
};
|
|
104
|
+
export type EvmOFTAdapterBridgeTransportEnum = (typeof EvmOFTAdapterBridgeTransportEnum)[keyof typeof EvmOFTAdapterBridgeTransportEnum];
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
* @interface EvmOFTPeer
|
|
16
16
|
*/
|
|
17
17
|
export interface EvmOFTPeer {
|
|
18
|
+
/**
|
|
19
|
+
* The remote chain\'s network name, e.g. atlantic. The map key is a LayerZero endpoint ID, which names nothing outside LayerZero, so read this instead.
|
|
20
|
+
* @type {string}
|
|
21
|
+
* @memberof EvmOFTPeer
|
|
22
|
+
*/
|
|
23
|
+
remoteNetwork?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The bridge contract at the far end, as a plain address. Same meaning as remoteAddress on a CCIP lane.
|
|
26
|
+
* @type {string}
|
|
27
|
+
* @memberof EvmOFTPeer
|
|
28
|
+
*/
|
|
29
|
+
remoteAddress?: string;
|
|
18
30
|
/**
|
|
19
31
|
* The peer address in bytes32 format
|
|
20
32
|
* @type {string}
|
|
@@ -24,6 +24,9 @@ export * from "./ember-position.js";
|
|
|
24
24
|
export * from "./escrow-claim-transaction.js";
|
|
25
25
|
export * from "./evm-atomic-liquidity-lib.js";
|
|
26
26
|
export * from "./evm-atomic-vault.js";
|
|
27
|
+
export * from "./evm-ccip-lane.js";
|
|
28
|
+
export * from "./evm-ccip-rate-limits.js";
|
|
29
|
+
export * from "./evm-ccip-token-pool.js";
|
|
27
30
|
export * from "./evm-contracts.js";
|
|
28
31
|
export * from "./evm-deposit-parking-lot.js";
|
|
29
32
|
export * from "./evm-deposit-token.js";
|
|
@@ -24,6 +24,9 @@ export * from "./ember-position.js";
|
|
|
24
24
|
export * from "./escrow-claim-transaction.js";
|
|
25
25
|
export * from "./evm-atomic-liquidity-lib.js";
|
|
26
26
|
export * from "./evm-atomic-vault.js";
|
|
27
|
+
export * from "./evm-ccip-lane.js";
|
|
28
|
+
export * from "./evm-ccip-rate-limits.js";
|
|
29
|
+
export * from "./evm-ccip-token-pool.js";
|
|
27
30
|
export * from "./evm-contracts.js";
|
|
28
31
|
export * from "./evm-deposit-parking-lot.js";
|
|
29
32
|
export * from "./evm-deposit-token.js";
|
|
@@ -184,6 +184,11 @@ export interface IParkingLotInfo {
|
|
|
184
184
|
operator: string;
|
|
185
185
|
/** Whether new deposit requests are currently paused */
|
|
186
186
|
depositsPaused: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Whether cancellation of pending requests is currently paused. While true the
|
|
189
|
+
* queue can grow and be processed but depositors cannot withdraw from it.
|
|
190
|
+
*/
|
|
191
|
+
cancellationsPaused: boolean;
|
|
187
192
|
/** Total collateral currently escrowed across pending requests */
|
|
188
193
|
totalPendingAssets: bigint;
|
|
189
194
|
/** Number of live (unprocessed, uncancelled) pending requests */
|
|
@@ -237,6 +242,45 @@ export interface ICoverVaultCallOptions extends IUserCallOptions {
|
|
|
237
242
|
/**
|
|
238
243
|
* Optional parameters for high-level OFT bridge send calls.
|
|
239
244
|
*/
|
|
245
|
+
/**
|
|
246
|
+
* Parameters for a CCIP bridge send.
|
|
247
|
+
*
|
|
248
|
+
* Deliberately shaped like IOFTSendParam so the two transports read the same
|
|
249
|
+
* way, but CCIP names a destination by chain selector rather than endpoint id,
|
|
250
|
+
* and takes the receiver as a plain address — the SDK encodes it.
|
|
251
|
+
*/
|
|
252
|
+
export interface ICcipSendParam {
|
|
253
|
+
/** CCIP chain selector of the destination. A 64-bit value, so a string. */
|
|
254
|
+
destinationChainSelector: string;
|
|
255
|
+
/** Recipient address on the destination chain */
|
|
256
|
+
receiver: string;
|
|
257
|
+
/** Amount to send in local token decimals */
|
|
258
|
+
amount: bigint;
|
|
259
|
+
/** Fee token; omit to pay in the chain's native currency */
|
|
260
|
+
feeToken?: string;
|
|
261
|
+
/** Destination execution gas. 0 for a plain token transfer. */
|
|
262
|
+
destinationGasLimit?: bigint;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* A CCIP fee quote.
|
|
266
|
+
*
|
|
267
|
+
* CCIP charges one fee, unlike LayerZero's native/LZ token split, and does not
|
|
268
|
+
* quote the received amount separately: a burn-and-mint pool mints exactly what
|
|
269
|
+
* was burned, so the amount received is the amount sent.
|
|
270
|
+
*/
|
|
271
|
+
export interface ICcipFeeQuote {
|
|
272
|
+
/** Fee required to send, in feeToken units (wei when paying natively) */
|
|
273
|
+
fee: bigint;
|
|
274
|
+
/** Token the fee is charged in; the zero address means native currency */
|
|
275
|
+
feeToken: string;
|
|
276
|
+
}
|
|
277
|
+
/** Overrides for a CCIP bridge send. */
|
|
278
|
+
export interface ICcipBridgeSendOptions extends IEvmCallOptions {
|
|
279
|
+
/** Fee token; omit to pay in the chain's native currency */
|
|
280
|
+
feeToken?: string;
|
|
281
|
+
/** Destination execution gas. 0 for a plain token transfer. */
|
|
282
|
+
destinationGasLimit?: bigint;
|
|
283
|
+
}
|
|
240
284
|
export interface IBridgeSendOptions extends IEvmCallOptions {
|
|
241
285
|
/** Minimum amount to receive on destination; defaults to amount */
|
|
242
286
|
minAmount?: bigint;
|
|
@@ -61,6 +61,22 @@ export declare class EVMOperatorCalls extends EVMOnChainCalls {
|
|
|
61
61
|
* @returns EvmOnChainCallResponse
|
|
62
62
|
*/
|
|
63
63
|
processParkingLotDeposits(vaultAddress: string, numRequests: NumStr, options?: IEvmCallOptions): Promise<EvmOnChainCallResponse>;
|
|
64
|
+
/**
|
|
65
|
+
* Process every queued deposit request in a vault's parking lot up to and
|
|
66
|
+
* including `upToSequenceNumber`, forwarding escrowed collateral into the vault.
|
|
67
|
+
* Operator-only.
|
|
68
|
+
*
|
|
69
|
+
* Prefer this over {@link processParkingLotDeposits} when settling through a
|
|
70
|
+
* known request: `numRequests` counts queue SLOTS walked and cancelled slots
|
|
71
|
+
* count towards it, so the count has to be derived from the live head and is
|
|
72
|
+
* easy to get wrong. Reverts if the sequence number is past the queue tail
|
|
73
|
+
* (IndexOutOfBounds) or at/below the head (InvalidRequest) rather than clamping.
|
|
74
|
+
* @param vaultAddress The vault the parking lot serves
|
|
75
|
+
* @param upToSequenceNumber Last request sequence number to settle (inclusive)
|
|
76
|
+
* @param options Optional tx execution params (incl. optional parkingLotAddress override)
|
|
77
|
+
* @returns EvmOnChainCallResponse
|
|
78
|
+
*/
|
|
79
|
+
processParkingLotDepositsUpTo(vaultAddress: string, upToSequenceNumber: NumStr, options?: IEvmCallOptions): Promise<EvmOnChainCallResponse>;
|
|
64
80
|
/**
|
|
65
81
|
* Set an account's status on a vault's parking-lot deposit allow-list.
|
|
66
82
|
* Operator-gated (EmberDepositParkingLot.setDepositAllowListStatus); emits
|
|
@@ -76,6 +76,26 @@ export class EVMOperatorCalls extends EVMOnChainCalls {
|
|
|
76
76
|
const txCall = this.txBuilder.processParkingLotDeposits(parkingLotAddress, numRequests);
|
|
77
77
|
return this.execCall(txCall, options);
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Process every queued deposit request in a vault's parking lot up to and
|
|
81
|
+
* including `upToSequenceNumber`, forwarding escrowed collateral into the vault.
|
|
82
|
+
* Operator-only.
|
|
83
|
+
*
|
|
84
|
+
* Prefer this over {@link processParkingLotDeposits} when settling through a
|
|
85
|
+
* known request: `numRequests` counts queue SLOTS walked and cancelled slots
|
|
86
|
+
* count towards it, so the count has to be derived from the live head and is
|
|
87
|
+
* easy to get wrong. Reverts if the sequence number is past the queue tail
|
|
88
|
+
* (IndexOutOfBounds) or at/below the head (InvalidRequest) rather than clamping.
|
|
89
|
+
* @param vaultAddress The vault the parking lot serves
|
|
90
|
+
* @param upToSequenceNumber Last request sequence number to settle (inclusive)
|
|
91
|
+
* @param options Optional tx execution params (incl. optional parkingLotAddress override)
|
|
92
|
+
* @returns EvmOnChainCallResponse
|
|
93
|
+
*/
|
|
94
|
+
async processParkingLotDepositsUpTo(vaultAddress, upToSequenceNumber, options) {
|
|
95
|
+
const parkingLotAddress = this.parser.resolveParkingLotAddress(vaultAddress, options?.parkingLotAddress);
|
|
96
|
+
const txCall = this.txBuilder.processParkingLotDepositsUpTo(parkingLotAddress, upToSequenceNumber);
|
|
97
|
+
return this.execCall(txCall, options);
|
|
98
|
+
}
|
|
79
99
|
/**
|
|
80
100
|
* Set an account's status on a vault's parking-lot deposit allow-list.
|
|
81
101
|
* Operator-gated (EmberDepositParkingLot.setDepositAllowListStatus); emits
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EVMDeploymentParser } from "../utils/index.js";
|
|
2
|
-
import { EvmProtocolInfo, VaultPauseOperation, ITransactionCall, IPermitSignature, IOFTSendParam, IOFTMessagingFee } from "../interfaces/index.js";
|
|
2
|
+
import { EvmProtocolInfo, VaultPauseOperation, ITransactionCall, IPermitSignature, IOFTSendParam, IOFTMessagingFee, ICcipSendParam } from "../interfaces/index.js";
|
|
3
3
|
import { NumStr } from "../../common/types.js";
|
|
4
4
|
/**
|
|
5
5
|
* EVM Transaction Builder for Ember Protocol (ERC-4626 Compatible)
|
|
@@ -167,6 +167,18 @@ export declare class EVMTxBuilder {
|
|
|
167
167
|
* @returns Transaction call object
|
|
168
168
|
*/
|
|
169
169
|
processParkingLotDeposits(parkingLotAddress: string, numRequests: NumStr): ITransactionCall;
|
|
170
|
+
/**
|
|
171
|
+
* Processes every queued deposit request up to and including
|
|
172
|
+
* `upToSequenceNumber` (operator-only). Prefer this over
|
|
173
|
+
* {@link processParkingLotDeposits} when settling through a known request:
|
|
174
|
+
* `numRequests` counts queue SLOTS walked and cancelled slots count towards it,
|
|
175
|
+
* so a count has to be derived from the live head and is easy to get wrong.
|
|
176
|
+
* Reverts if the sequence number is past the queue tail or at/below the head.
|
|
177
|
+
* @param parkingLotAddress Address of the EmberDepositParkingLot
|
|
178
|
+
* @param upToSequenceNumber Last request sequence number to settle (inclusive)
|
|
179
|
+
* @returns Transaction call object
|
|
180
|
+
*/
|
|
181
|
+
processParkingLotDepositsUpTo(parkingLotAddress: string, upToSequenceNumber: NumStr): ITransactionCall;
|
|
170
182
|
/**
|
|
171
183
|
* Rotates the operator authorised to process a parking lot's queue
|
|
172
184
|
* (vault-admin only).
|
|
@@ -183,6 +195,15 @@ export declare class EVMTxBuilder {
|
|
|
183
195
|
* @returns Transaction call object
|
|
184
196
|
*/
|
|
185
197
|
setParkingLotDepositsPaused(parkingLotAddress: string, paused: boolean): ITransactionCall;
|
|
198
|
+
/**
|
|
199
|
+
* Pauses or resumes cancellation of pending deposit requests in a parking lot
|
|
200
|
+
* (vault admin or protocol guardian). While paused the queue can still grow and
|
|
201
|
+
* the operator can still process it, but depositors cannot withdraw from it.
|
|
202
|
+
* @param parkingLotAddress Address of the EmberDepositParkingLot
|
|
203
|
+
* @param paused True to block cancellation, false to resume
|
|
204
|
+
* @returns Transaction call object
|
|
205
|
+
*/
|
|
206
|
+
setParkingLotCancellationsPaused(parkingLotAddress: string, paused: boolean): ITransactionCall;
|
|
186
207
|
setParkingLotDepositAllowList(parkingLotAddress: string, account: string, status: boolean): ITransactionCall;
|
|
187
208
|
/**
|
|
188
209
|
* Updates the paused status of a vault operation (called via ProtocolConfig)
|
|
@@ -522,6 +543,20 @@ export declare class EVMTxBuilder {
|
|
|
522
543
|
* @returns Transaction call object
|
|
523
544
|
*/
|
|
524
545
|
bridgeSend(adapterAddress: string, sendParam: IOFTSendParam, fee: IOFTMessagingFee, refundAddress: string): ITransactionCall;
|
|
546
|
+
/**
|
|
547
|
+
* Builds the CCIP send call.
|
|
548
|
+
*
|
|
549
|
+
* The counterpart to bridgeSend, but the call goes to Chainlink's Router
|
|
550
|
+
* rather than to our own pool: the Router pulls the tokens, charges the fee
|
|
551
|
+
* and hands off to the pool. That is also why the approval for a CCIP bridge
|
|
552
|
+
* goes to the Router and not to the pool.
|
|
553
|
+
*
|
|
554
|
+
* @param routerAddress The CCIP Router on the source chain
|
|
555
|
+
* @param sendParam Destination, receiver and amount
|
|
556
|
+
* @param tokenAddress The receipt token being bridged
|
|
557
|
+
* @param fee Fee from getCcipFeeQuote, sent as value when paying natively
|
|
558
|
+
*/
|
|
559
|
+
ccipSend(routerAddress: string, sendParam: ICcipSendParam, tokenAddress: string, fee: bigint): ITransactionCall;
|
|
525
560
|
private atomicCall;
|
|
526
561
|
/** Claim the caller's own escrowed (deferred) holdback collateral. */
|
|
527
562
|
atomicClaimHoldback(vaultAddress: string): ITransactionCall;
|
|
@@ -4,6 +4,8 @@ import EmberETHVaultABI from "../../abis/EmberETHVault.json" with { type: "json"
|
|
|
4
4
|
import EmberProtocolConfigABI from "../../abis/EmberProtocolConfig.json" with { type: "json" };
|
|
5
5
|
import ERC20TokenABI from "../../abis/ERC20Token.json" with { type: "json" };
|
|
6
6
|
import EmberVaultOFTAdapterABI from "../../abis/EmberVaultMintBurnOFTAdapter.json" with { type: "json" };
|
|
7
|
+
import CcipRouterABI from "../../abis/CcipRouter.json" with { type: "json" };
|
|
8
|
+
import { ZERO_ADDRESS, encodeCcipReceiver, encodeCcipExtraArgs } from "../utils/ccip.js";
|
|
7
9
|
import AtomicLiquidityABI from "../../abis/AtomicLiquidity.json" with { type: "json" };
|
|
8
10
|
import EmberDepositParkingLotABI from "../../abis/EmberDepositParkingLot.json" with { type: "json" };
|
|
9
11
|
import OpenCoverVaultABI from "../../abis/OpenCoverVault.json" with { type: "json" };
|
|
@@ -314,6 +316,27 @@ export class EVMTxBuilder {
|
|
|
314
316
|
chainId: this.getChainId()
|
|
315
317
|
};
|
|
316
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Processes every queued deposit request up to and including
|
|
321
|
+
* `upToSequenceNumber` (operator-only). Prefer this over
|
|
322
|
+
* {@link processParkingLotDeposits} when settling through a known request:
|
|
323
|
+
* `numRequests` counts queue SLOTS walked and cancelled slots count towards it,
|
|
324
|
+
* so a count has to be derived from the live head and is easy to get wrong.
|
|
325
|
+
* Reverts if the sequence number is past the queue tail or at/below the head.
|
|
326
|
+
* @param parkingLotAddress Address of the EmberDepositParkingLot
|
|
327
|
+
* @param upToSequenceNumber Last request sequence number to settle (inclusive)
|
|
328
|
+
* @returns Transaction call object
|
|
329
|
+
*/
|
|
330
|
+
processParkingLotDepositsUpTo(parkingLotAddress, upToSequenceNumber) {
|
|
331
|
+
return {
|
|
332
|
+
to: parkingLotAddress,
|
|
333
|
+
functionName: "processDepositsUpTo",
|
|
334
|
+
args: [BigInt(upToSequenceNumber)],
|
|
335
|
+
abi: EmberDepositParkingLotABI.abi,
|
|
336
|
+
value: 0n,
|
|
337
|
+
chainId: this.getChainId()
|
|
338
|
+
};
|
|
339
|
+
}
|
|
317
340
|
/**
|
|
318
341
|
* Rotates the operator authorised to process a parking lot's queue
|
|
319
342
|
* (vault-admin only).
|
|
@@ -348,6 +371,24 @@ export class EVMTxBuilder {
|
|
|
348
371
|
chainId: this.getChainId()
|
|
349
372
|
};
|
|
350
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Pauses or resumes cancellation of pending deposit requests in a parking lot
|
|
376
|
+
* (vault admin or protocol guardian). While paused the queue can still grow and
|
|
377
|
+
* the operator can still process it, but depositors cannot withdraw from it.
|
|
378
|
+
* @param parkingLotAddress Address of the EmberDepositParkingLot
|
|
379
|
+
* @param paused True to block cancellation, false to resume
|
|
380
|
+
* @returns Transaction call object
|
|
381
|
+
*/
|
|
382
|
+
setParkingLotCancellationsPaused(parkingLotAddress, paused) {
|
|
383
|
+
return {
|
|
384
|
+
to: parkingLotAddress,
|
|
385
|
+
functionName: "setCancellationsPaused",
|
|
386
|
+
args: [paused],
|
|
387
|
+
abi: EmberDepositParkingLotABI.abi,
|
|
388
|
+
value: 0n,
|
|
389
|
+
chainId: this.getChainId()
|
|
390
|
+
};
|
|
391
|
+
}
|
|
351
392
|
setParkingLotDepositAllowList(parkingLotAddress, account, status) {
|
|
352
393
|
return {
|
|
353
394
|
to: parkingLotAddress,
|
|
@@ -1108,6 +1149,40 @@ export class EVMTxBuilder {
|
|
|
1108
1149
|
chainId: this.getChainId()
|
|
1109
1150
|
};
|
|
1110
1151
|
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Builds the CCIP send call.
|
|
1154
|
+
*
|
|
1155
|
+
* The counterpart to bridgeSend, but the call goes to Chainlink's Router
|
|
1156
|
+
* rather than to our own pool: the Router pulls the tokens, charges the fee
|
|
1157
|
+
* and hands off to the pool. That is also why the approval for a CCIP bridge
|
|
1158
|
+
* goes to the Router and not to the pool.
|
|
1159
|
+
*
|
|
1160
|
+
* @param routerAddress The CCIP Router on the source chain
|
|
1161
|
+
* @param sendParam Destination, receiver and amount
|
|
1162
|
+
* @param tokenAddress The receipt token being bridged
|
|
1163
|
+
* @param fee Fee from getCcipFeeQuote, sent as value when paying natively
|
|
1164
|
+
*/
|
|
1165
|
+
ccipSend(routerAddress, sendParam, tokenAddress, fee) {
|
|
1166
|
+
const feeToken = sendParam.feeToken ?? ZERO_ADDRESS;
|
|
1167
|
+
return {
|
|
1168
|
+
to: routerAddress,
|
|
1169
|
+
functionName: "ccipSend",
|
|
1170
|
+
args: [
|
|
1171
|
+
sendParam.destinationChainSelector,
|
|
1172
|
+
{
|
|
1173
|
+
receiver: encodeCcipReceiver(sendParam.receiver),
|
|
1174
|
+
data: "0x",
|
|
1175
|
+
tokenAmounts: [{ token: tokenAddress, amount: sendParam.amount }],
|
|
1176
|
+
feeToken,
|
|
1177
|
+
extraArgs: encodeCcipExtraArgs(sendParam.destinationGasLimit)
|
|
1178
|
+
}
|
|
1179
|
+
],
|
|
1180
|
+
abi: CcipRouterABI.abi,
|
|
1181
|
+
// Paying in a token means the Router pulls it instead, so no value.
|
|
1182
|
+
value: feeToken === ZERO_ADDRESS ? fee : 0n,
|
|
1183
|
+
chainId: this.getChainId()
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1111
1186
|
// ============================================
|
|
1112
1187
|
// Atomic Liquidity Vault methods (BFE-817/818)
|
|
1113
1188
|
//
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Signer, Provider } from "ethers";
|
|
2
2
|
import { EVMOnChainCalls } from "./onchain-calls.js";
|
|
3
|
-
import { EvmProtocolInfo, IUserCallOptions, IEvmCallOptions, ICoverVaultCallOptions, EvmOnChainCallResponse, IPermitSignature, IETHDepositOptions, IBridgeSendOptions, IOFTFeeQuote } from "../interfaces/index.js";
|
|
3
|
+
import { EvmProtocolInfo, IUserCallOptions, IEvmCallOptions, ICoverVaultCallOptions, EvmOnChainCallResponse, IPermitSignature, IETHDepositOptions, IBridgeSendOptions, IOFTFeeQuote, ICcipFeeQuote, ICcipBridgeSendOptions } from "../interfaces/index.js";
|
|
4
4
|
import { NumStr } from "../../common/types.js";
|
|
5
5
|
import { Chain } from "../../api/v2/index.js";
|
|
6
6
|
/**
|
|
@@ -423,6 +423,38 @@ export declare class EVMUserCalls extends EVMOnChainCalls {
|
|
|
423
423
|
* @returns Transaction execution response
|
|
424
424
|
*/
|
|
425
425
|
bridgeSendToken(destinationChain: Chain, tokenAddress: string, amount: NumStr, receiver: string, feeQuote: IOFTFeeQuote, options?: IBridgeSendOptions): Promise<EvmOnChainCallResponse>;
|
|
426
|
+
/**
|
|
427
|
+
* Bridges a receipt token to a destination chain using the vault's CCIP pool.
|
|
428
|
+
*
|
|
429
|
+
* The counterpart to bridgeSendToken. Call getBridgeTransportForVault first
|
|
430
|
+
* and pick the matching method — a vault has exactly one active bridge, and
|
|
431
|
+
* calling the wrong one throws rather than silently doing nothing.
|
|
432
|
+
*
|
|
433
|
+
* Two differences from the LayerZero path worth knowing:
|
|
434
|
+
* - the allowance goes to the CCIP Router, not to the pool, because the
|
|
435
|
+
* Router is what pulls the tokens;
|
|
436
|
+
* - the destination is named by network, and the chain selector is read
|
|
437
|
+
* from the configured lane. An unconfigured route throws here rather
|
|
438
|
+
* than reverting on chain.
|
|
439
|
+
*
|
|
440
|
+
* @param destinationNetwork Destination network name, e.g. "atlantic"
|
|
441
|
+
* @param tokenAddress Receipt token address (also the vault identifier in EVM deployment data)
|
|
442
|
+
* @param amount Amount to bridge in local token decimals
|
|
443
|
+
* @param receiver Recipient wallet address on the destination chain
|
|
444
|
+
* @param feeQuote Fee quote returned by reader.getCcipFeeQuote
|
|
445
|
+
* @param options Optional bridge/send overrides
|
|
446
|
+
* @returns Transaction execution response
|
|
447
|
+
*/
|
|
448
|
+
bridgeSendTokenViaCcip(destinationNetwork: string, tokenAddress: string, amount: NumStr, receiver: string, feeQuote: ICcipFeeQuote, options?: ICcipBridgeSendOptions): Promise<EvmOnChainCallResponse>;
|
|
449
|
+
/**
|
|
450
|
+
* Reports which bridge a vault uses, or undefined if it has none.
|
|
451
|
+
*
|
|
452
|
+
* A vault has exactly one active bridge, but different vaults use different
|
|
453
|
+
* ones, so branch on this rather than assuming either transport.
|
|
454
|
+
*
|
|
455
|
+
* @param tokenAddress Receipt token address (also the vault identifier in EVM deployment data)
|
|
456
|
+
*/
|
|
457
|
+
getBridgeTransportForVault(tokenAddress: string): "LayerZero" | "CCIP" | undefined;
|
|
426
458
|
/**
|
|
427
459
|
* Gets the vault contract instance for read operations
|
|
428
460
|
* @param vaultAddress The address of the vault
|
|
@@ -637,6 +637,67 @@ export class EVMUserCalls extends EVMOnChainCalls {
|
|
|
637
637
|
}, refundAddress);
|
|
638
638
|
return this.execCall(txCall, options);
|
|
639
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* Bridges a receipt token to a destination chain using the vault's CCIP pool.
|
|
642
|
+
*
|
|
643
|
+
* The counterpart to bridgeSendToken. Call getBridgeTransportForVault first
|
|
644
|
+
* and pick the matching method — a vault has exactly one active bridge, and
|
|
645
|
+
* calling the wrong one throws rather than silently doing nothing.
|
|
646
|
+
*
|
|
647
|
+
* Two differences from the LayerZero path worth knowing:
|
|
648
|
+
* - the allowance goes to the CCIP Router, not to the pool, because the
|
|
649
|
+
* Router is what pulls the tokens;
|
|
650
|
+
* - the destination is named by network, and the chain selector is read
|
|
651
|
+
* from the configured lane. An unconfigured route throws here rather
|
|
652
|
+
* than reverting on chain.
|
|
653
|
+
*
|
|
654
|
+
* @param destinationNetwork Destination network name, e.g. "atlantic"
|
|
655
|
+
* @param tokenAddress Receipt token address (also the vault identifier in EVM deployment data)
|
|
656
|
+
* @param amount Amount to bridge in local token decimals
|
|
657
|
+
* @param receiver Recipient wallet address on the destination chain
|
|
658
|
+
* @param feeQuote Fee quote returned by reader.getCcipFeeQuote
|
|
659
|
+
* @param options Optional bridge/send overrides
|
|
660
|
+
* @returns Transaction execution response
|
|
661
|
+
*/
|
|
662
|
+
async bridgeSendTokenViaCcip(destinationNetwork, tokenAddress, amount, receiver, feeQuote, options) {
|
|
663
|
+
if (!this.provider) {
|
|
664
|
+
throw new Error("Provider required for bridge send read operations and allowance checks");
|
|
665
|
+
}
|
|
666
|
+
const pool = this.parser.getCcipTokenPoolByVaultAddress(tokenAddress);
|
|
667
|
+
if (!pool?.router) {
|
|
668
|
+
throw new Error(`CCIP token pool not found for token address: ${tokenAddress}`);
|
|
669
|
+
}
|
|
670
|
+
const lane = this.parser.getCcipLaneByVaultAndNetwork(tokenAddress, destinationNetwork);
|
|
671
|
+
if (!lane?.remoteChainSelector) {
|
|
672
|
+
throw new Error(`No CCIP lane configured from this chain to "${destinationNetwork}" for token ${tokenAddress}`);
|
|
673
|
+
}
|
|
674
|
+
const amountBigInt = BigInt(amount);
|
|
675
|
+
// The Router moves the tokens, so it is the Router that needs approval.
|
|
676
|
+
const token = new ethers.Contract(tokenAddress, ["function allowance(address,address) view returns (uint256)"], this.provider);
|
|
677
|
+
const currentAllowance = await token.allowance(await this.getWalletAddress(), pool.router);
|
|
678
|
+
if (currentAllowance < amountBigInt) {
|
|
679
|
+
throw new Error(`Insufficient allowance for bridge transfer. Current allowance: ${currentAllowance}, required: ${amountBigInt}`);
|
|
680
|
+
}
|
|
681
|
+
const txCall = this.txBuilder.ccipSend(pool.router, {
|
|
682
|
+
destinationChainSelector: lane.remoteChainSelector,
|
|
683
|
+
receiver,
|
|
684
|
+
amount: amountBigInt,
|
|
685
|
+
feeToken: options?.feeToken,
|
|
686
|
+
destinationGasLimit: options?.destinationGasLimit
|
|
687
|
+
}, tokenAddress, feeQuote.fee);
|
|
688
|
+
return this.execCall(txCall, options);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Reports which bridge a vault uses, or undefined if it has none.
|
|
692
|
+
*
|
|
693
|
+
* A vault has exactly one active bridge, but different vaults use different
|
|
694
|
+
* ones, so branch on this rather than assuming either transport.
|
|
695
|
+
*
|
|
696
|
+
* @param tokenAddress Receipt token address (also the vault identifier in EVM deployment data)
|
|
697
|
+
*/
|
|
698
|
+
getBridgeTransportForVault(tokenAddress) {
|
|
699
|
+
return this.parser.getBridgeTransportByVaultAddress(tokenAddress);
|
|
700
|
+
}
|
|
640
701
|
// ============================================
|
|
641
702
|
// Read-Only Methods
|
|
642
703
|
// ============================================
|
|
@@ -72,6 +72,22 @@ export declare class EVMVaultAdminCalls extends EVMOnChainCalls {
|
|
|
72
72
|
* @returns EvmOnChainCallResponse
|
|
73
73
|
*/
|
|
74
74
|
setParkingLotDepositsPaused(vaultAddress: string, paused: boolean, options?: IEvmCallOptions): Promise<EvmOnChainCallResponse>;
|
|
75
|
+
/**
|
|
76
|
+
* Pause or resume cancellation of pending deposit requests in a vault's parking
|
|
77
|
+
* lot (EmberDepositParkingLot.setCancellationsPaused); emits
|
|
78
|
+
* CancellationsPausedUpdated. Callable by the vault admin or the protocol
|
|
79
|
+
* guardian.
|
|
80
|
+
*
|
|
81
|
+
* While paused, depositors cannot withdraw from the queue — new deposits still
|
|
82
|
+
* join it and the operator can still process it — so the pending total can grow
|
|
83
|
+
* but not shrink. Note a depositor who parks while it is set cannot cancel until
|
|
84
|
+
* it is cleared.
|
|
85
|
+
* @param vaultAddress The address of the vault
|
|
86
|
+
* @param paused True to block cancellation, false to resume
|
|
87
|
+
* @param options Optional tx execution params (incl. optional parkingLotAddress override)
|
|
88
|
+
* @returns EvmOnChainCallResponse
|
|
89
|
+
*/
|
|
90
|
+
setParkingLotCancellationsPaused(vaultAddress: string, paused: boolean, options?: IEvmCallOptions): Promise<EvmOnChainCallResponse>;
|
|
75
91
|
/**
|
|
76
92
|
* Update the rate manager of a vault
|
|
77
93
|
* @param vaultAddress The address of the vault
|
|
@@ -91,6 +91,26 @@ export class EVMVaultAdminCalls extends EVMOnChainCalls {
|
|
|
91
91
|
const txCall = this.txBuilder.setParkingLotDepositsPaused(parkingLotAddress, paused);
|
|
92
92
|
return this.execCall(txCall, options);
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Pause or resume cancellation of pending deposit requests in a vault's parking
|
|
96
|
+
* lot (EmberDepositParkingLot.setCancellationsPaused); emits
|
|
97
|
+
* CancellationsPausedUpdated. Callable by the vault admin or the protocol
|
|
98
|
+
* guardian.
|
|
99
|
+
*
|
|
100
|
+
* While paused, depositors cannot withdraw from the queue — new deposits still
|
|
101
|
+
* join it and the operator can still process it — so the pending total can grow
|
|
102
|
+
* but not shrink. Note a depositor who parks while it is set cannot cancel until
|
|
103
|
+
* it is cleared.
|
|
104
|
+
* @param vaultAddress The address of the vault
|
|
105
|
+
* @param paused True to block cancellation, false to resume
|
|
106
|
+
* @param options Optional tx execution params (incl. optional parkingLotAddress override)
|
|
107
|
+
* @returns EvmOnChainCallResponse
|
|
108
|
+
*/
|
|
109
|
+
async setParkingLotCancellationsPaused(vaultAddress, paused, options) {
|
|
110
|
+
const parkingLotAddress = this.parser.resolveParkingLotAddress(vaultAddress, options?.parkingLotAddress);
|
|
111
|
+
const txCall = this.txBuilder.setParkingLotCancellationsPaused(parkingLotAddress, paused);
|
|
112
|
+
return this.execCall(txCall, options);
|
|
113
|
+
}
|
|
94
114
|
/**
|
|
95
115
|
* Update the rate manager of a vault
|
|
96
116
|
* @param vaultAddress The address of the vault
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Provider } from "ethers";
|
|
2
2
|
import { EVMDeploymentParser } from "../utils/deployment-parser.js";
|
|
3
|
-
import { EvmProtocolInfo, IOFTSendParam, IOFTFeeQuote, IOFTVaultSupportedChain, IParkingLotInfo } from "../interfaces/index.js";
|
|
3
|
+
import { EvmProtocolInfo, IOFTSendParam, IOFTFeeQuote, IOFTVaultSupportedChain, IParkingLotInfo, ICcipSendParam, ICcipFeeQuote } from "../interfaces/index.js";
|
|
4
4
|
import { NumStr } from "../../common/types.js";
|
|
5
5
|
import { Chain, VaultsApi } from "../../api/v2/index.js";
|
|
6
6
|
/**
|
|
@@ -524,4 +524,17 @@ export declare class EVMVaultReader {
|
|
|
524
524
|
* @returns Combined fee quote including native fee and expected amounts
|
|
525
525
|
*/
|
|
526
526
|
getOFTFeeQuote(vaultId: string, sendParam: IOFTSendParam, payInLzToken?: boolean): Promise<IOFTFeeQuote>;
|
|
527
|
+
/**
|
|
528
|
+
* Quotes what a CCIP bridge send will cost.
|
|
529
|
+
*
|
|
530
|
+
* The counterpart to getOFTFeeQuote. CCIP charges one fee rather than
|
|
531
|
+
* LayerZero's native/LZ-token pair, and quotes no received amount: a
|
|
532
|
+
* burn-and-mint pool mints exactly what it burned, so the amount received is
|
|
533
|
+
* the amount sent.
|
|
534
|
+
*
|
|
535
|
+
* @param vaultId The vault (receipt token) address on the source chain
|
|
536
|
+
* @param sendParam Destination, receiver and amount
|
|
537
|
+
* @returns The fee and the token it is charged in
|
|
538
|
+
*/
|
|
539
|
+
getCcipFeeQuote(vaultId: string, sendParam: ICcipSendParam): Promise<ICcipFeeQuote>;
|
|
527
540
|
}
|
|
@@ -4,6 +4,8 @@ import EmberVaultABI from "../../abis/EmberVault.json" with { type: "json" };
|
|
|
4
4
|
import EmberETHVaultABI from "../../abis/EmberETHVault.json" with { type: "json" };
|
|
5
5
|
import EmberProtocolConfigABI from "../../abis/EmberProtocolConfig.json" with { type: "json" };
|
|
6
6
|
import ERC20TokenABI from "../../abis/ERC20Token.json" with { type: "json" };
|
|
7
|
+
import CcipRouterABI from "../../abis/CcipRouter.json" with { type: "json" };
|
|
8
|
+
import { ZERO_ADDRESS, encodeCcipReceiver, encodeCcipExtraArgs } from "../utils/ccip.js";
|
|
7
9
|
import EmberVaultOFTAdapterABI from "../../abis/EmberVaultMintBurnOFTAdapter.json" with { type: "json" };
|
|
8
10
|
import EmberDepositParkingLotABI from "../../abis/EmberDepositParkingLot.json" with { type: "json" };
|
|
9
11
|
import { Configuration, VaultsApi } from "../../api/v2/index.js";
|
|
@@ -227,9 +229,10 @@ export class EVMVaultReader {
|
|
|
227
229
|
*/
|
|
228
230
|
async getParkingLotInfo(parkingLotAddress) {
|
|
229
231
|
const parkingLot = this.getParkingLotContract(parkingLotAddress);
|
|
230
|
-
const [operator, depositsPaused, totalPendingAssets, livePendingCount, sequenceNumber, queueStartIndex] = await Promise.all([
|
|
232
|
+
const [operator, depositsPaused, cancellationsPaused, totalPendingAssets, livePendingCount, sequenceNumber, queueStartIndex] = await Promise.all([
|
|
231
233
|
parkingLot.operator(),
|
|
232
234
|
parkingLot.depositsPaused(),
|
|
235
|
+
parkingLot.cancellationsPaused(),
|
|
233
236
|
parkingLot.totalPendingAssets(),
|
|
234
237
|
parkingLot.getLivePendingDepositsCount(),
|
|
235
238
|
parkingLot.sequenceNumber(),
|
|
@@ -239,6 +242,7 @@ export class EVMVaultReader {
|
|
|
239
242
|
address: parkingLotAddress,
|
|
240
243
|
operator,
|
|
241
244
|
depositsPaused,
|
|
245
|
+
cancellationsPaused,
|
|
242
246
|
totalPendingAssets,
|
|
243
247
|
livePendingCount,
|
|
244
248
|
sequenceNumber,
|
|
@@ -734,4 +738,32 @@ export class EVMVaultReader {
|
|
|
734
738
|
maxAmountLD: oftQuote.oftLimit.maxAmountLD
|
|
735
739
|
};
|
|
736
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* Quotes what a CCIP bridge send will cost.
|
|
743
|
+
*
|
|
744
|
+
* The counterpart to getOFTFeeQuote. CCIP charges one fee rather than
|
|
745
|
+
* LayerZero's native/LZ-token pair, and quotes no received amount: a
|
|
746
|
+
* burn-and-mint pool mints exactly what it burned, so the amount received is
|
|
747
|
+
* the amount sent.
|
|
748
|
+
*
|
|
749
|
+
* @param vaultId The vault (receipt token) address on the source chain
|
|
750
|
+
* @param sendParam Destination, receiver and amount
|
|
751
|
+
* @returns The fee and the token it is charged in
|
|
752
|
+
*/
|
|
753
|
+
async getCcipFeeQuote(vaultId, sendParam) {
|
|
754
|
+
const pool = this.parser.getCcipTokenPoolByVaultAddress(vaultId);
|
|
755
|
+
if (!pool?.router) {
|
|
756
|
+
throw new Error(`CCIP token pool not found for vault: ${vaultId}`);
|
|
757
|
+
}
|
|
758
|
+
const feeToken = sendParam.feeToken ?? ZERO_ADDRESS;
|
|
759
|
+
const router = new Contract(pool.router, CcipRouterABI.abi, this.provider);
|
|
760
|
+
const fee = await router.getFee(sendParam.destinationChainSelector, {
|
|
761
|
+
receiver: encodeCcipReceiver(sendParam.receiver),
|
|
762
|
+
data: "0x",
|
|
763
|
+
tokenAmounts: [{ token: vaultId, amount: sendParam.amount }],
|
|
764
|
+
feeToken,
|
|
765
|
+
extraArgs: encodeCcipExtraArgs(sendParam.destinationGasLimit)
|
|
766
|
+
});
|
|
767
|
+
return { fee, feeToken };
|
|
768
|
+
}
|
|
737
769
|
}
|