@augustdigital/sdk 8.3.1 → 8.5.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/lib/abis/ERC20_Bytes32.d.ts +4 -0
- package/lib/abis/ERC20_Bytes32.js +4 -0
- package/lib/abis/ERC4626.d.ts +1 -0
- package/lib/abis/ERC4626.js +1 -0
- package/lib/abis/ERC721.d.ts +1 -0
- package/lib/abis/ERC721.js +1 -0
- package/lib/abis/FeeOracle.js +1 -0
- package/lib/abis/LendingPool.js +1 -0
- package/lib/abis/LendingPoolV2.js +1 -0
- package/lib/abis/Multicall3.js +3 -0
- package/lib/abis/OFT.d.ts +20 -0
- package/lib/abis/OFT.js +20 -0
- package/lib/abis/SmartAccount.d.ts +1 -0
- package/lib/abis/SmartAccount.js +3 -0
- package/lib/abis/SwapRouter.d.ts +1 -0
- package/lib/abis/SwapRouter.js +1 -0
- package/lib/abis/UniversalSignatureValidator.js +3 -0
- package/lib/abis/index.d.ts +5 -0
- package/lib/abis/index.js +5 -0
- package/lib/adapters/evm/getters.d.ts +17 -2
- package/lib/adapters/evm/getters.js +35 -3
- package/lib/adapters/evm/index.d.ts +262 -0
- package/lib/adapters/evm/index.js +268 -1
- package/lib/adapters/evm/utils.d.ts +6 -0
- package/lib/adapters/evm/utils.js +7 -0
- package/lib/adapters/solana/constants.js +4 -1
- package/lib/adapters/solana/getters.d.ts +8 -0
- package/lib/adapters/solana/getters.js +21 -0
- package/lib/adapters/solana/idl/vault-idl.js +9 -0
- package/lib/adapters/solana/index.d.ts +55 -0
- package/lib/adapters/solana/index.js +57 -0
- package/lib/adapters/solana/utils.d.ts +28 -0
- package/lib/adapters/solana/utils.js +79 -4
- package/lib/adapters/solana/vault.actions.d.ts +19 -0
- package/lib/adapters/solana/vault.actions.js +47 -3
- package/lib/adapters/stellar/actions.d.ts +25 -0
- package/lib/adapters/stellar/actions.js +33 -0
- package/lib/adapters/stellar/constants.d.ts +26 -0
- package/lib/adapters/stellar/constants.js +29 -0
- package/lib/adapters/stellar/getters.d.ts +56 -0
- package/lib/adapters/stellar/getters.js +81 -0
- package/lib/adapters/stellar/index.d.ts +48 -0
- package/lib/adapters/stellar/index.js +48 -0
- package/lib/adapters/stellar/soroban.d.ts +20 -0
- package/lib/adapters/stellar/soroban.js +46 -0
- package/lib/adapters/stellar/submit.d.ts +12 -0
- package/lib/adapters/stellar/submit.js +19 -0
- package/lib/adapters/stellar/types.d.ts +27 -0
- package/lib/adapters/stellar/types.js +3 -0
- package/lib/adapters/stellar/utils.d.ts +10 -0
- package/lib/adapters/stellar/utils.js +10 -0
- package/lib/adapters/sui/getters.d.ts +6 -0
- package/lib/adapters/sui/getters.js +6 -0
- package/lib/adapters/sui/index.d.ts +15 -0
- package/lib/adapters/sui/index.js +15 -0
- package/lib/adapters/sui/transformer.d.ts +6 -0
- package/lib/adapters/sui/transformer.js +7 -0
- package/lib/adapters/sui/utils.d.ts +6 -0
- package/lib/adapters/sui/utils.js +6 -0
- package/lib/core/analytics/chain-name.d.ts +8 -0
- package/lib/core/analytics/chain-name.js +8 -0
- package/lib/core/analytics/constants.d.ts +4 -0
- package/lib/core/analytics/constants.js +4 -0
- package/lib/core/analytics/env.d.ts +25 -0
- package/lib/core/analytics/env.js +26 -0
- package/lib/core/analytics/index.d.ts +26 -0
- package/lib/core/analytics/index.js +35 -0
- package/lib/core/analytics/instrumentation.d.ts +26 -0
- package/lib/core/analytics/instrumentation.js +66 -2
- package/lib/core/analytics/method-taxonomy.d.ts +16 -0
- package/lib/core/analytics/method-taxonomy.js +18 -0
- package/lib/core/analytics/metrics.d.ts +23 -0
- package/lib/core/analytics/metrics.js +40 -0
- package/lib/core/analytics/sanitize.d.ts +38 -0
- package/lib/core/analytics/sanitize.js +46 -0
- package/lib/core/analytics/sentry-runtime.d.ts +11 -0
- package/lib/core/analytics/sentry-runtime.js +19 -0
- package/lib/core/analytics/sentry.d.ts +45 -0
- package/lib/core/analytics/sentry.js +115 -2
- package/lib/core/analytics/types.d.ts +27 -0
- package/lib/core/analytics/user-identity.d.ts +34 -0
- package/lib/core/analytics/user-identity.js +42 -0
- package/lib/core/analytics/version.d.ts +6 -1
- package/lib/core/analytics/version.js +6 -1
- package/lib/core/auth/verify.js +5 -0
- package/lib/core/base.class.d.ts +75 -0
- package/lib/core/base.class.js +56 -0
- package/lib/core/cache.d.ts +5 -0
- package/lib/core/cache.js +6 -0
- package/lib/core/constants/adapters.d.ts +15 -0
- package/lib/core/constants/adapters.js +28 -8
- package/lib/core/constants/core.d.ts +12 -1
- package/lib/core/constants/core.js +12 -0
- package/lib/core/constants/swap-router.d.ts +46 -0
- package/lib/core/constants/swap-router.js +50 -0
- package/lib/core/constants/vaults.d.ts +56 -0
- package/lib/core/constants/vaults.js +66 -1
- package/lib/core/constants/web3.d.ts +3 -0
- package/lib/core/constants/web3.js +18 -5
- package/lib/core/errors/index.d.ts +36 -0
- package/lib/core/errors/index.js +29 -0
- package/lib/core/fetcher.d.ts +134 -0
- package/lib/core/fetcher.js +191 -5
- package/lib/core/helpers/adapters.d.ts +9 -0
- package/lib/core/helpers/adapters.js +11 -0
- package/lib/core/helpers/chain-address.d.ts +10 -0
- package/lib/core/helpers/chain-address.js +11 -0
- package/lib/core/helpers/core.d.ts +42 -0
- package/lib/core/helpers/core.js +66 -1
- package/lib/core/helpers/explorer-link.d.ts +14 -0
- package/lib/core/helpers/explorer-link.js +14 -0
- package/lib/core/helpers/signer.d.ts +26 -0
- package/lib/core/helpers/signer.js +39 -0
- package/lib/core/helpers/swap-router.d.ts +32 -0
- package/lib/core/helpers/swap-router.js +32 -0
- package/lib/core/helpers/vault-version.d.ts +1 -0
- package/lib/core/helpers/vault-version.js +2 -0
- package/lib/core/helpers/vaults.d.ts +8 -0
- package/lib/core/helpers/vaults.js +22 -8
- package/lib/core/helpers/web3.d.ts +152 -0
- package/lib/core/helpers/web3.js +183 -6
- package/lib/core/logger/index.d.ts +55 -0
- package/lib/core/logger/index.js +19 -0
- package/lib/core/logger/slack.d.ts +3 -0
- package/lib/core/logger/slack.js +3 -0
- package/lib/core/vault-metadata.d.ts +6 -0
- package/lib/core/vault-metadata.js +6 -0
- package/lib/core/version-check.d.ts +52 -0
- package/lib/core/version-check.js +81 -0
- package/lib/evm/methods/crossChainVault.d.ts +90 -0
- package/lib/evm/methods/crossChainVault.js +186 -1
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +93 -0
- package/lib/evm/methods/crossChainVaultRegistry.js +240 -0
- package/lib/evm/methods/index.d.ts +1 -0
- package/lib/evm/methods/index.js +1 -0
- package/lib/evm/types/crossChain.d.ts +202 -0
- package/lib/evm/types/crossChain.js +11 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +19 -0
- package/lib/main.d.ts +288 -5
- package/lib/main.js +305 -0
- package/lib/modules/api/index.d.ts +1 -0
- package/lib/modules/api/index.js +6 -0
- package/lib/modules/api/main.d.ts +52 -0
- package/lib/modules/api/main.js +130 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +15 -0
- package/lib/modules/sub-accounts/fetcher.js +15 -0
- package/lib/modules/sub-accounts/main.d.ts +33 -0
- package/lib/modules/sub-accounts/main.js +38 -0
- package/lib/modules/sub-accounts/utils.d.ts +3 -0
- package/lib/modules/sub-accounts/utils.js +3 -0
- package/lib/modules/vaults/adapter.helpers.d.ts +18 -0
- package/lib/modules/vaults/adapter.helpers.js +34 -0
- package/lib/modules/vaults/fetcher.d.ts +20 -0
- package/lib/modules/vaults/fetcher.js +40 -3
- package/lib/modules/vaults/getters.d.ts +295 -0
- package/lib/modules/vaults/getters.js +552 -12
- package/lib/modules/vaults/index.d.ts +12 -0
- package/lib/modules/vaults/index.js +12 -0
- package/lib/modules/vaults/main.d.ts +292 -4
- package/lib/modules/vaults/main.js +379 -7
- package/lib/modules/vaults/read.actions.d.ts +168 -0
- package/lib/modules/vaults/read.actions.js +143 -0
- package/lib/modules/vaults/types.d.ts +34 -0
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +47 -0
- package/lib/modules/vaults/utils/call-data-decoder.js +56 -0
- package/lib/modules/vaults/utils/date-utils.d.ts +39 -0
- package/lib/modules/vaults/utils/date-utils.js +47 -1
- package/lib/modules/vaults/utils.d.ts +70 -0
- package/lib/modules/vaults/utils.js +108 -5
- package/lib/modules/vaults/write.actions.d.ts +363 -3
- package/lib/modules/vaults/write.actions.js +364 -2
- package/lib/polyfills.js +2 -0
- package/lib/sdk.d.ts +23705 -0
- package/lib/services/coingecko/fetcher.d.ts +13 -0
- package/lib/services/coingecko/fetcher.js +17 -0
- package/lib/services/debank/fetcher.d.ts +14 -0
- package/lib/services/debank/fetcher.js +12 -0
- package/lib/services/debank/utils.js +17 -0
- package/lib/services/layerzero/deposits.d.ts +11 -0
- package/lib/services/layerzero/deposits.js +34 -11
- package/lib/services/layerzero/redeems.d.ts +10 -0
- package/lib/services/layerzero/redeems.js +13 -0
- package/lib/services/layerzero/utils.d.ts +8 -0
- package/lib/services/layerzero/utils.js +11 -0
- package/lib/services/octavfi/fetcher.d.ts +7 -0
- package/lib/services/octavfi/fetcher.js +25 -0
- package/lib/services/octavfi/utils.d.ts +12 -0
- package/lib/services/octavfi/utils.js +44 -10
- package/lib/services/subgraph/fetcher.js +4 -2
- package/lib/services/subgraph/vaults.d.ts +12 -0
- package/lib/services/subgraph/vaults.js +43 -2
- package/lib/services/swap-quotes/index.d.ts +71 -0
- package/lib/services/swap-quotes/index.js +25 -0
- package/lib/services/swap-quotes/paraswap.d.ts +17 -0
- package/lib/services/swap-quotes/paraswap.js +14 -0
- package/lib/types/pools.d.ts +3 -0
- package/lib/types/typed-contract.d.ts +64 -0
- package/lib/types/vaults.d.ts +139 -2
- package/lib/types/vaults.js +10 -0
- package/lib/types/web3.d.ts +8 -0
- package/lib/types/web3.js +1 -0
- package/lib/types/webserver.d.ts +45 -0
- package/package.json +6 -5
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cross-Chain Vault Methods
|
|
4
|
+
*
|
|
5
|
+
* Implements LayerZero OVault cross-chain deposit and redemption operations.
|
|
6
|
+
* These functions are generic — callers provide their own ICrossChainVaultConfig
|
|
7
|
+
* rather than relying on hardcoded vault addresses.
|
|
8
|
+
*
|
|
9
|
+
* @module evm/methods/crossChainVault
|
|
10
|
+
*/
|
|
2
11
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
12
|
if (k2 === undefined) k2 = k;
|
|
4
13
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -52,16 +61,46 @@ exports.getLayerZeroScanUrl = getLayerZeroScanUrl;
|
|
|
52
61
|
const core_1 = require("../../core");
|
|
53
62
|
const crossChain_1 = require("../types/crossChain");
|
|
54
63
|
const OFT_1 = require("../../abis/OFT");
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Constants
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* lzReceive option hex for 500,000 gas.
|
|
69
|
+
* The Agora OFT has no enforced options for SEND_AND_CALL, so we must provide
|
|
70
|
+
* lzReceive gas explicitly or the executor reverts with Executor_ZeroLzReceiveGasProvided.
|
|
71
|
+
*/
|
|
55
72
|
const LZ_RECEIVE_OPTION_HEX = '010011010000000000000000000000000007a120';
|
|
73
|
+
/** Default fee buffer percentage applied to LayerZero native fees */
|
|
56
74
|
const DEFAULT_FEE_BUFFER_PERCENT = 50;
|
|
75
|
+
/** Default slippage in basis points (1%) */
|
|
57
76
|
const DEFAULT_SLIPPAGE_BPS = 100;
|
|
77
|
+
/** Default gas buffer for deposits (1.5x) */
|
|
58
78
|
const DEFAULT_DEPOSIT_GAS_BUFFER_PERCENT = 150;
|
|
79
|
+
/** Default gas buffer for redeems (2x) */
|
|
59
80
|
const DEFAULT_REDEEM_GAS_BUFFER_PERCENT = 200;
|
|
81
|
+
/** Default minimum gas limit for redeem operations */
|
|
60
82
|
const DEFAULT_MIN_REDEEM_GAS = 5000000n;
|
|
83
|
+
/** Default hub lzCompose gas limit */
|
|
61
84
|
const DEFAULT_HUB_LZ_COMPOSE_GAS_LIMIT = 2000000n;
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Mutex for SDK monkey-patches
|
|
87
|
+
//
|
|
88
|
+
// Multi-asset and hub-redeem flows mutate the shared `OVaultSyncMessageBuilder`
|
|
89
|
+
// — module-level bindings inside the SDK mean a shallow clone is unsafe, so we
|
|
90
|
+
// serialize patched calls. The timeout THROWS rather than silently racing
|
|
91
|
+
// concurrent callers' patches.
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
62
93
|
const PATCH_LOCK_TIMEOUT_MS = 30000;
|
|
63
94
|
let patchLock = Promise.resolve();
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Internal helpers
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
/**
|
|
99
|
+
* Try available previewRedeem signatures, falling back to 1:1 if the vault
|
|
100
|
+
* does not expose a working preview function.
|
|
101
|
+
*/
|
|
64
102
|
async function redeemPreview(publicClient, vaultAddress, shares) {
|
|
103
|
+
// 1. previewRedemption(uint256, bool) — multi-asset vault
|
|
65
104
|
try {
|
|
66
105
|
const result = await publicClient.readContract({
|
|
67
106
|
address: vaultAddress,
|
|
@@ -73,7 +112,9 @@ async function redeemPreview(publicClient, vaultAddress, shares) {
|
|
|
73
112
|
return assetsAfterFee;
|
|
74
113
|
}
|
|
75
114
|
catch {
|
|
115
|
+
/* try next */
|
|
76
116
|
}
|
|
117
|
+
// 2. Standard ERC4626: previewRedeem(uint256)
|
|
77
118
|
try {
|
|
78
119
|
return (await publicClient.readContract({
|
|
79
120
|
address: vaultAddress,
|
|
@@ -83,18 +124,30 @@ async function redeemPreview(publicClient, vaultAddress, shares) {
|
|
|
83
124
|
}));
|
|
84
125
|
}
|
|
85
126
|
catch {
|
|
127
|
+
/* try next */
|
|
86
128
|
}
|
|
129
|
+
// 3. Fallback: 1:1 ratio. Slippage protects against discrepancy.
|
|
87
130
|
return shares;
|
|
88
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Wraps generateOVaultInputs with monkey-patches for:
|
|
134
|
+
* 1. REDEEM from hub — skip quoteOFT (reverts for same-chain)
|
|
135
|
+
* 2. Multi-asset DEPOSIT — previewDeposit(address, uint256)
|
|
136
|
+
* 3. Multi-asset REDEEM — try previewRedeem variants, fallback to 1:1
|
|
137
|
+
* 4. Multi-asset composed messages — add lzReceive gas to SEND_AND_CALL
|
|
138
|
+
*/
|
|
89
139
|
async function generateOVaultInputsWithOverride(input, config, hubPublicClient, ovaultSdk) {
|
|
90
140
|
const OVaultSyncMessageBuilder = ovaultSdk.OVaultSyncMessageBuilder;
|
|
91
141
|
const OVaultSyncOperations = ovaultSdk.OVaultSyncOperations;
|
|
92
142
|
const isRedeemFromHub = input.operation === OVaultSyncOperations.REDEEM &&
|
|
93
143
|
input.srcEid === input.hubEid;
|
|
94
144
|
const isMultiAsset = !!config.multiAsset;
|
|
145
|
+
// Fast path — no patches needed
|
|
95
146
|
if (!isMultiAsset && !isRedeemFromHub) {
|
|
96
147
|
return OVaultSyncMessageBuilder.generateOVaultInputs(input);
|
|
97
148
|
}
|
|
149
|
+
// Serialize: wait for the prior holder or REJECT on timeout (silent races
|
|
150
|
+
// produced wrong cross-chain quotes).
|
|
98
151
|
const prev = patchLock;
|
|
99
152
|
let unlock;
|
|
100
153
|
patchLock = new Promise((r) => {
|
|
@@ -124,11 +177,15 @@ async function generateOVaultInputsWithOverride(input, config, hubPublicClient,
|
|
|
124
177
|
const origBuildApproval = Builder.buildApproval;
|
|
125
178
|
try {
|
|
126
179
|
if (isRedeemFromHub) {
|
|
180
|
+
// Patch 1a: skip quoteOFT (reverts for same-chain calls).
|
|
127
181
|
Builder.getOutputAmount = async () => input.amount;
|
|
182
|
+
// Patch 1b: skip SDK's allowance check — multi-asset vault contracts
|
|
183
|
+
// may not implement ERC20. Caller handles approval directly.
|
|
128
184
|
Builder.buildApproval = async () => undefined;
|
|
129
185
|
}
|
|
130
186
|
if (isMultiAsset) {
|
|
131
187
|
const { hubAssetAddress } = config.multiAsset;
|
|
188
|
+
// Patch 2/3: Multi-asset quoteOVaultOutput
|
|
132
189
|
Builder.quoteOVaultOutput = async (quoteInput) => {
|
|
133
190
|
const getOutputAmount = Builder.getOutputAmount;
|
|
134
191
|
const sourceAmount = await getOutputAmount({
|
|
@@ -158,6 +215,7 @@ async function generateOVaultInputsWithOverride(input, config, hubPublicClient,
|
|
|
158
215
|
minDstAmount: outputAmount - slippageAmount,
|
|
159
216
|
};
|
|
160
217
|
};
|
|
218
|
+
// Patch 4: Ensure lzReceive gas in extraOptions for composed messages
|
|
161
219
|
Builder.buildSendParams = async (spInput) => {
|
|
162
220
|
const origFn = origBuildSendParams;
|
|
163
221
|
const result = await origFn.call(Builder, spInput);
|
|
@@ -184,9 +242,23 @@ async function generateOVaultInputsWithOverride(input, config, hubPublicClient,
|
|
|
184
242
|
unlock();
|
|
185
243
|
}
|
|
186
244
|
}
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
// Public API: Build
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
/**
|
|
249
|
+
* Build LayerZero OVault transaction inputs for cross-chain deposits and
|
|
250
|
+
* redemptions. Does NOT execute the transaction.
|
|
251
|
+
*
|
|
252
|
+
* Overridable defaults on `props`: `slippageBps` = 100 (range 1–10000),
|
|
253
|
+
* `feeBufferPercent` = 50% (added to LZ `nativeFee`),
|
|
254
|
+
* `hubLzComposeGasLimit` = 2_000_000n (multi-asset composed messages).
|
|
255
|
+
*
|
|
256
|
+
* @returns Transaction inputs or `{ success: false, error }`.
|
|
257
|
+
*/
|
|
187
258
|
async function buildCrossChainVaultTx(props) {
|
|
188
259
|
try {
|
|
189
260
|
const { config } = props;
|
|
261
|
+
// Validate slippage at the public boundary (BPS, not decimal)
|
|
190
262
|
const slippageBps = props.slippageBps ?? DEFAULT_SLIPPAGE_BPS;
|
|
191
263
|
if (slippageBps < 1 || slippageBps > 10000) {
|
|
192
264
|
return {
|
|
@@ -194,6 +266,7 @@ async function buildCrossChainVaultTx(props) {
|
|
|
194
266
|
error: `Slippage must be between 1 and 10000 basis points (got ${slippageBps})`,
|
|
195
267
|
};
|
|
196
268
|
}
|
|
269
|
+
// Validate chains
|
|
197
270
|
const hubChain = props.hubChain;
|
|
198
271
|
const sourceChain = props.sourceChain;
|
|
199
272
|
if (!hubChain || !sourceChain) {
|
|
@@ -202,6 +275,8 @@ async function buildCrossChainVaultTx(props) {
|
|
|
202
275
|
error: 'Hub chain and source chain are required',
|
|
203
276
|
};
|
|
204
277
|
}
|
|
278
|
+
// Reject unknown chain IDs up front so a typo can't fall through to
|
|
279
|
+
// `|| hub` and route shares to a chain the user didn't pick.
|
|
205
280
|
const supportedChains = [
|
|
206
281
|
config.hubChainId,
|
|
207
282
|
...Object.keys(config.layerZeroEids.spokes).map((k) => Number(k)),
|
|
@@ -230,6 +305,7 @@ async function buildCrossChainVaultTx(props) {
|
|
|
230
305
|
return config.layerZeroEids.hub;
|
|
231
306
|
return config.layerZeroEids.spokes[chainId];
|
|
232
307
|
};
|
|
308
|
+
// Determine source and destination EIDs based on operation
|
|
233
309
|
let srcEid;
|
|
234
310
|
let dstEid;
|
|
235
311
|
let tokenAddress;
|
|
@@ -266,7 +342,9 @@ async function buildCrossChainVaultTx(props) {
|
|
|
266
342
|
error: `Invalid operation: ${props.operation}`,
|
|
267
343
|
};
|
|
268
344
|
}
|
|
345
|
+
// Normalize amount
|
|
269
346
|
const normalizedAmount = (0, core_1.toNormalizedBn)(props.amount, props.decimals);
|
|
347
|
+
// Build LayerZero OVault inputs
|
|
270
348
|
const input = {
|
|
271
349
|
srcEid,
|
|
272
350
|
hubEid: config.layerZeroEids.hub,
|
|
@@ -286,10 +364,12 @@ async function buildCrossChainVaultTx(props) {
|
|
|
286
364
|
oftAddress,
|
|
287
365
|
hubLzComposeGasLimit: props.hubLzComposeGasLimit ?? DEFAULT_HUB_LZ_COMPOSE_GAS_LIMIT,
|
|
288
366
|
};
|
|
367
|
+
// Create a minimal public client for hub chain reads (multi-asset patches)
|
|
289
368
|
const hubRpc = hubChain?.rpcUrls;
|
|
290
369
|
const hubRpcUrl = hubRpc?.default?.http?.[0];
|
|
291
370
|
let hubPublicClient;
|
|
292
371
|
try {
|
|
372
|
+
// Dynamic import to keep viem optional at the module level
|
|
293
373
|
const viem = await Promise.resolve().then(() => __importStar(require('viem')));
|
|
294
374
|
hubPublicClient = viem.createPublicClient({
|
|
295
375
|
chain: hubChain,
|
|
@@ -297,19 +377,25 @@ async function buildCrossChainVaultTx(props) {
|
|
|
297
377
|
});
|
|
298
378
|
}
|
|
299
379
|
catch {
|
|
380
|
+
// If viem is not available, provide a stub that will fail on multi-asset only
|
|
300
381
|
hubPublicClient = {
|
|
301
382
|
readContract: async () => {
|
|
302
383
|
throw new Error('viem is required for multi-asset vault operations. Install viem as a peer dependency.');
|
|
303
384
|
},
|
|
304
385
|
};
|
|
305
386
|
}
|
|
387
|
+
// Generate OVault transaction inputs (with monkey-patches for multi-asset)
|
|
306
388
|
const inputs = await generateOVaultInputsWithOverride(input, config, hubPublicClient, props.ovaultSdk);
|
|
389
|
+
// Apply fee buffer to LZ fees (post-hoc to avoid SDK double-compounding)
|
|
307
390
|
const feeBufferPercent = props.feeBufferPercent ?? DEFAULT_FEE_BUFFER_PERCENT;
|
|
308
391
|
const rawNativeFee = inputs.messageFee.nativeFee;
|
|
309
392
|
const rawMessageValue = inputs.messageValue;
|
|
310
393
|
const feeBuffer = (rawNativeFee * BigInt(feeBufferPercent)) / 100n;
|
|
311
394
|
inputs.messageFee.nativeFee = rawNativeFee + feeBuffer;
|
|
312
395
|
inputs.messageValue = rawMessageValue + feeBuffer;
|
|
396
|
+
// Patch fee into txArgs in place for OFT.send(); warn if the LayerZero
|
|
397
|
+
// SDK ever returns a different entry-point name (silent no-op would
|
|
398
|
+
// underpay the LZ fee).
|
|
313
399
|
if (inputs.contractFunctionName === 'send') {
|
|
314
400
|
const sendFee = inputs.txArgs[1];
|
|
315
401
|
sendFee.nativeFee = inputs.messageFee.nativeFee;
|
|
@@ -348,6 +434,14 @@ async function buildCrossChainVaultTx(props) {
|
|
|
348
434
|
};
|
|
349
435
|
}
|
|
350
436
|
}
|
|
437
|
+
// ---------------------------------------------------------------------------
|
|
438
|
+
// Public API: Quote
|
|
439
|
+
// ---------------------------------------------------------------------------
|
|
440
|
+
/**
|
|
441
|
+
* Estimate fees and expected shares for a cross-chain deposit. The returned
|
|
442
|
+
* quote carries `quotedAt`/`expiresAt`; re-quote via {@link isQuoteStale}
|
|
443
|
+
* before submitting.
|
|
444
|
+
*/
|
|
351
445
|
async function quoteCrossChainDeposit(props) {
|
|
352
446
|
const result = await buildCrossChainVaultTx({
|
|
353
447
|
ovaultSdk: props.ovaultSdk,
|
|
@@ -374,6 +468,11 @@ async function quoteCrossChainDeposit(props) {
|
|
|
374
468
|
expiresAt: quotedAt + crossChain_1.CROSS_CHAIN_QUOTE_TTL_MS,
|
|
375
469
|
};
|
|
376
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Estimate fees and expected assets for a cross-chain redeem. The returned
|
|
473
|
+
* quote carries `quotedAt`/`expiresAt`; re-quote via {@link isQuoteStale}
|
|
474
|
+
* before submitting.
|
|
475
|
+
*/
|
|
377
476
|
async function quoteCrossChainRedeem(props) {
|
|
378
477
|
const result = await buildCrossChainVaultTx({
|
|
379
478
|
ovaultSdk: props.ovaultSdk,
|
|
@@ -400,6 +499,14 @@ async function quoteCrossChainRedeem(props) {
|
|
|
400
499
|
expiresAt: quotedAt + crossChain_1.CROSS_CHAIN_QUOTE_TTL_MS,
|
|
401
500
|
};
|
|
402
501
|
}
|
|
502
|
+
// ---------------------------------------------------------------------------
|
|
503
|
+
// Public API: Approval
|
|
504
|
+
// ---------------------------------------------------------------------------
|
|
505
|
+
/**
|
|
506
|
+
* Returns `true` when the wallet's ERC-20 allowance is insufficient for the
|
|
507
|
+
* cross-chain operation. On RPC failure also returns `true` (defensive
|
|
508
|
+
* default — better a redundant approval than a downstream revert).
|
|
509
|
+
*/
|
|
403
510
|
async function needsCrossChainApproval(tokenAddress, spenderAddress, walletAddress, amount, publicClient) {
|
|
404
511
|
try {
|
|
405
512
|
const allowance = (await publicClient.readContract({
|
|
@@ -411,9 +518,15 @@ async function needsCrossChainApproval(tokenAddress, spenderAddress, walletAddre
|
|
|
411
518
|
return allowance < amount;
|
|
412
519
|
}
|
|
413
520
|
catch {
|
|
521
|
+
// If we can't check allowance, assume approval is needed
|
|
414
522
|
return true;
|
|
415
523
|
}
|
|
416
524
|
}
|
|
525
|
+
/**
|
|
526
|
+
* Execute a token approval for a cross-chain operation.
|
|
527
|
+
*
|
|
528
|
+
* @returns Transaction hash of the approval
|
|
529
|
+
*/
|
|
417
530
|
async function approveCrossChain(tokenAddress, spenderAddress, amount, walletClient, publicClient) {
|
|
418
531
|
if (!walletClient.account) {
|
|
419
532
|
throw new Error('Wallet not ready — please reconnect your wallet');
|
|
@@ -433,6 +546,18 @@ async function approveCrossChain(tokenAddress, spenderAddress, amount, walletCli
|
|
|
433
546
|
}
|
|
434
547
|
return hash;
|
|
435
548
|
}
|
|
549
|
+
// ---------------------------------------------------------------------------
|
|
550
|
+
// Public API: Execute
|
|
551
|
+
// ---------------------------------------------------------------------------
|
|
552
|
+
/**
|
|
553
|
+
* Execute a cross-chain deposit via LayerZero OVault. Validates the source
|
|
554
|
+
* chain, ensures approval, estimates gas with a buffer, and waits for the
|
|
555
|
+
* on-chain receipt. Defaults: `slippageBps` 100, `feeBufferPercent` 50,
|
|
556
|
+
* `gasBufferPercent` 150 — all overridable on the request.
|
|
557
|
+
*
|
|
558
|
+
* @throws Error on unsupported chain, approval revert, gas-estimation
|
|
559
|
+
* failure, or on-chain revert.
|
|
560
|
+
*/
|
|
436
561
|
async function crossChainVaultDeposit(props) {
|
|
437
562
|
if (props.userChainId !== props.config.hubChainId &&
|
|
438
563
|
!props.config.spokeChainIds.includes(props.userChainId)) {
|
|
@@ -440,6 +565,7 @@ async function crossChainVaultDeposit(props) {
|
|
|
440
565
|
}
|
|
441
566
|
const walletClient = props.walletClient;
|
|
442
567
|
const publicClient = props.publicClient;
|
|
568
|
+
// 1. Build transaction inputs
|
|
443
569
|
const result = await buildCrossChainVaultTx({
|
|
444
570
|
ovaultSdk: props.ovaultSdk,
|
|
445
571
|
config: props.config,
|
|
@@ -458,6 +584,7 @@ async function crossChainVaultDeposit(props) {
|
|
|
458
584
|
throw new Error(result.error || 'Failed to build transaction');
|
|
459
585
|
}
|
|
460
586
|
const txInputs = result.data;
|
|
587
|
+
// 2. Check and execute approval if needed
|
|
461
588
|
if (!props.skipApprovalCheck) {
|
|
462
589
|
const tokenAddr = txInputs.approval?.tokenAddress ??
|
|
463
590
|
props.config.contracts.assetToken[props.userChainId];
|
|
@@ -469,6 +596,7 @@ async function crossChainVaultDeposit(props) {
|
|
|
469
596
|
await approveCrossChain(tokenAddr, spenderAddr, approvalAmount, walletClient, publicClient);
|
|
470
597
|
}
|
|
471
598
|
}
|
|
599
|
+
// 3. Estimate gas with buffer
|
|
472
600
|
if (!walletClient.account) {
|
|
473
601
|
throw new Error('Wallet not ready — please reconnect your wallet');
|
|
474
602
|
}
|
|
@@ -488,6 +616,7 @@ async function crossChainVaultDeposit(props) {
|
|
|
488
616
|
catch (estimateErr) {
|
|
489
617
|
throw new Error(`Gas estimation failed for cross-chain deposit. Ensure you have sufficient native tokens for the LayerZero fee (${txInputs.messageFee.nativeFee.toString()} wei). Original error: ${estimateErr instanceof Error ? estimateErr.message : String(estimateErr)}`);
|
|
490
618
|
}
|
|
619
|
+
// 4. Execute the transaction
|
|
491
620
|
const hash = await walletClient.writeContract({
|
|
492
621
|
account: walletClient.account,
|
|
493
622
|
address: txInputs.contractAddress,
|
|
@@ -497,6 +626,7 @@ async function crossChainVaultDeposit(props) {
|
|
|
497
626
|
value: txInputs.messageValue,
|
|
498
627
|
gas: gasLimit,
|
|
499
628
|
});
|
|
629
|
+
// 5. Wait for confirmation
|
|
500
630
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
501
631
|
hash: hash,
|
|
502
632
|
});
|
|
@@ -508,13 +638,21 @@ async function crossChainVaultDeposit(props) {
|
|
|
508
638
|
success: true,
|
|
509
639
|
};
|
|
510
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Execute a cross-chain redemption via LayerZero OVault. User must be on the
|
|
643
|
+
* hub chain. Defaults: `slippageBps` 100, `feeBufferPercent` 50,
|
|
644
|
+
* `gasBufferPercent` 200 (compose calls under-estimate on mainnet),
|
|
645
|
+
* `minGasLimit` 5_000_000n — all overridable on the request.
|
|
646
|
+
*/
|
|
511
647
|
async function crossChainVaultRedeem(props) {
|
|
648
|
+
// 1. Validate: redemptions must be from hub chain
|
|
512
649
|
if (props.userChainId !== props.config.hubChainId) {
|
|
513
650
|
throw new Error(`Redemptions must be executed from hub chain (${props.config.hubChainId}). ` +
|
|
514
651
|
`Please switch to the hub chain first.`);
|
|
515
652
|
}
|
|
516
653
|
const walletClient = props.walletClient;
|
|
517
654
|
const publicClient = props.publicClient;
|
|
655
|
+
// 2. Build transaction inputs
|
|
518
656
|
const result = await buildCrossChainVaultTx({
|
|
519
657
|
ovaultSdk: props.ovaultSdk,
|
|
520
658
|
config: props.config,
|
|
@@ -533,12 +671,14 @@ async function crossChainVaultRedeem(props) {
|
|
|
533
671
|
throw new Error(result.error || 'Failed to build transaction');
|
|
534
672
|
}
|
|
535
673
|
const txInputs = result.data;
|
|
674
|
+
// 3. Check and execute approval if needed
|
|
536
675
|
if (!props.skipApprovalCheck && txInputs.approval) {
|
|
537
676
|
const approvalNeeded = await needsCrossChainApproval(txInputs.approval.tokenAddress, txInputs.approval.spender, props.walletAddress, txInputs.approval.amount, publicClient);
|
|
538
677
|
if (approvalNeeded) {
|
|
539
678
|
await approveCrossChain(txInputs.approval.tokenAddress, txInputs.approval.spender, txInputs.approval.amount, walletClient, publicClient);
|
|
540
679
|
}
|
|
541
680
|
}
|
|
681
|
+
// 4. Estimate gas with buffer
|
|
542
682
|
if (!walletClient.account) {
|
|
543
683
|
throw new Error('Wallet account not available');
|
|
544
684
|
}
|
|
@@ -560,6 +700,7 @@ async function crossChainVaultRedeem(props) {
|
|
|
560
700
|
catch (estimateErr) {
|
|
561
701
|
throw new Error(`Gas estimation failed for cross-chain redeem. Ensure you have sufficient native tokens for the LayerZero fee (${txInputs.messageFee.nativeFee.toString()} wei). Original error: ${estimateErr instanceof Error ? estimateErr.message : String(estimateErr)}`);
|
|
562
702
|
}
|
|
703
|
+
// 5. Execute the transaction
|
|
563
704
|
const hash = await walletClient.writeContract({
|
|
564
705
|
account: walletClient.account,
|
|
565
706
|
address: txInputs.contractAddress,
|
|
@@ -569,6 +710,7 @@ async function crossChainVaultRedeem(props) {
|
|
|
569
710
|
value: txInputs.messageValue,
|
|
570
711
|
gas: gasLimit,
|
|
571
712
|
});
|
|
713
|
+
// 6. Wait for confirmation
|
|
572
714
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
573
715
|
hash: hash,
|
|
574
716
|
});
|
|
@@ -580,9 +722,18 @@ async function crossChainVaultRedeem(props) {
|
|
|
580
722
|
success: true,
|
|
581
723
|
};
|
|
582
724
|
}
|
|
725
|
+
// ---------------------------------------------------------------------------
|
|
726
|
+
// Public API: Error Classification
|
|
727
|
+
// ---------------------------------------------------------------------------
|
|
728
|
+
/**
|
|
729
|
+
* Check if an error indicates a missing LayerZero peer configuration.
|
|
730
|
+
*/
|
|
583
731
|
function isNoPeerError(errStr) {
|
|
584
732
|
return errStr.includes('0xf6ff4fb7') || errStr.includes('NoPeer');
|
|
585
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* Classify a cross-chain contract error into a known error type.
|
|
736
|
+
*/
|
|
586
737
|
function classifyCrossChainError(error) {
|
|
587
738
|
const err = error;
|
|
588
739
|
const msg = err?.message ?? String(error);
|
|
@@ -609,13 +760,30 @@ function classifyCrossChainError(error) {
|
|
|
609
760
|
return 'network';
|
|
610
761
|
return 'unknown';
|
|
611
762
|
}
|
|
763
|
+
// ---------------------------------------------------------------------------
|
|
764
|
+
// Public API: Utility helpers
|
|
765
|
+
// ---------------------------------------------------------------------------
|
|
766
|
+
/**
|
|
767
|
+
* Check if a user can deposit from their current chain.
|
|
768
|
+
*/
|
|
612
769
|
function canDepositFromChain(config, userChainId) {
|
|
613
770
|
return (userChainId === config.hubChainId ||
|
|
614
771
|
config.spokeChainIds.includes(userChainId));
|
|
615
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Check if a user can redeem from their current chain (must be hub).
|
|
775
|
+
*/
|
|
616
776
|
function canRedeemFromChain(config, userChainId) {
|
|
617
777
|
return userChainId === config.hubChainId;
|
|
618
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* Check if an operation is cross-chain (needs LayerZero).
|
|
781
|
+
*
|
|
782
|
+
* An operation is cross-chain when:
|
|
783
|
+
* - The user's chain differs from the hub chain, OR
|
|
784
|
+
* - The destination chain differs from the hub chain
|
|
785
|
+
* (e.g. deposit from hub but receive shares on a spoke)
|
|
786
|
+
*/
|
|
619
787
|
function isCrossChainOperation(config, userChainId, destinationChainId) {
|
|
620
788
|
if (userChainId !== config.hubChainId)
|
|
621
789
|
return true;
|
|
@@ -624,10 +792,20 @@ function isCrossChainOperation(config, userChainId, destinationChainId) {
|
|
|
624
792
|
return true;
|
|
625
793
|
return false;
|
|
626
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* Get all chain IDs that a vault supports (hub + all spokes).
|
|
797
|
+
*/
|
|
627
798
|
function getAvailableChains(config) {
|
|
628
799
|
return [config.hubChainId, ...config.spokeChainIds];
|
|
629
800
|
}
|
|
801
|
+
/**
|
|
802
|
+
* Format a cross-chain error into a user-friendly message.
|
|
803
|
+
*
|
|
804
|
+
* Mirrors the `classifyCrossChainDepositError` from upshift-app but is
|
|
805
|
+
* generic enough for any SDK consumer.
|
|
806
|
+
*/
|
|
630
807
|
function formatCrossChainError(errMsg) {
|
|
808
|
+
// If the error already contains specific gas fee info, show it directly
|
|
631
809
|
if (errMsg.includes('Cross-chain fee is') ||
|
|
632
810
|
errMsg.includes('Gas estimation failed'))
|
|
633
811
|
return errMsg;
|
|
@@ -642,17 +820,24 @@ function formatCrossChainError(errMsg) {
|
|
|
642
820
|
if (lower.includes('user rejected'))
|
|
643
821
|
return 'Transaction cancelled by user.';
|
|
644
822
|
if (lower.includes('hub chain'))
|
|
645
|
-
return errMsg;
|
|
823
|
+
return errMsg; // Already descriptive
|
|
646
824
|
if (errMsg.includes('reverted'))
|
|
647
825
|
return 'Transaction reverted on-chain. This may be due to insufficient gas or a contract error.';
|
|
648
826
|
return 'Cross-chain transaction failed. Please try again.';
|
|
649
827
|
}
|
|
828
|
+
/**
|
|
829
|
+
* Get the LayerZero Scan URL for tracking a cross-chain message.
|
|
830
|
+
*/
|
|
650
831
|
function getLayerZeroScanUrl(txHash, testnet = false) {
|
|
651
832
|
const baseUrl = testnet
|
|
652
833
|
? 'https://testnet.layerzeroscan.com'
|
|
653
834
|
: 'https://layerzeroscan.com';
|
|
654
835
|
return `${baseUrl}/tx/${txHash}`;
|
|
655
836
|
}
|
|
837
|
+
/**
|
|
838
|
+
* Well-known LayerZero Endpoint IDs for common chains.
|
|
839
|
+
* SDK consumers can use these when building their ICrossChainVaultConfig.
|
|
840
|
+
*/
|
|
656
841
|
exports.LAYERZERO_ENDPOINT_IDS = {
|
|
657
842
|
ETHEREUM: 30101,
|
|
658
843
|
ARBITRUM: 30110,
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Chain Vault Registry
|
|
3
|
+
*
|
|
4
|
+
* Address-keyed registry of August's LayerZero OVault deployments plus the
|
|
5
|
+
* resolver helpers that turn a vault address into the
|
|
6
|
+
* {@link ICrossChainVaultConfig} consumed by `buildCrossChainVaultTx`,
|
|
7
|
+
* `crossChainVaultDeposit`, and `quoteCrossChainDeposit`.
|
|
8
|
+
*
|
|
9
|
+
* This is the cross-chain analogue of the SwapRouter registry
|
|
10
|
+
* (`VAULTS_USING_SWAP_ROUTER` / `getSwapRouterAddress`): consumers resolve a
|
|
11
|
+
* full config by vault address instead of hand-assembling the per-chain
|
|
12
|
+
* contract maps and LayerZero EIDs. Without it, every consuming app would
|
|
13
|
+
* re-encode the same address book.
|
|
14
|
+
*
|
|
15
|
+
* Addresses are ported verbatim from upshift-app `src/config/ovault.ts` and
|
|
16
|
+
* cross-checked against the read-side `LAYERZERO_VAULTS` registry in
|
|
17
|
+
* `services/layerzero/deposits.ts`. Verify against the deployed contracts
|
|
18
|
+
* before adding or editing an entry — a wrong address silently routes funds
|
|
19
|
+
* to the wrong chain.
|
|
20
|
+
*
|
|
21
|
+
* Return convention (deliberate, mirrors the SwapRouter helpers): lookups that
|
|
22
|
+
* resolve a single optional value (`getCrossChainVaultConfig`,
|
|
23
|
+
* `getOVaultChains`) return `undefined` for an unregistered vault, while
|
|
24
|
+
* list-returning helpers (`getWithdrawDestinationChains`) return `[]` so
|
|
25
|
+
* callers can iterate without a null-check.
|
|
26
|
+
*
|
|
27
|
+
* @module evm/methods/crossChainVaultRegistry
|
|
28
|
+
*/
|
|
29
|
+
import type { IAddress } from '../../types';
|
|
30
|
+
import type { ICrossChainVaultConfig } from '../types/crossChain';
|
|
31
|
+
/**
|
|
32
|
+
* August's LayerZero OVault deployments, keyed by lowercase hub-chain vault
|
|
33
|
+
* address. Resolve entries with {@link getCrossChainVaultConfig} rather than
|
|
34
|
+
* indexing directly — the helper handles address-casing for you.
|
|
35
|
+
*
|
|
36
|
+
* @see {@link getCrossChainVaultConfig} for the typed, case-insensitive lookup.
|
|
37
|
+
*/
|
|
38
|
+
export declare const CROSS_CHAIN_VAULT_CONFIGS: Readonly<Record<string, ICrossChainVaultConfig>>;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the full cross-chain config for a vault. Address comparison is
|
|
41
|
+
* case-insensitive.
|
|
42
|
+
*
|
|
43
|
+
* @param vault - Hub-chain vault contract address.
|
|
44
|
+
* @returns The {@link ICrossChainVaultConfig} to pass to
|
|
45
|
+
* `crossChainVaultDeposit` / `quoteCrossChainDeposit`, or `undefined` when
|
|
46
|
+
* the vault is not a registered OVault deployment.
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const config = getCrossChainVaultConfig('0xE9B725010A9E419412ed67d0fA5f3A5f40159D32');
|
|
50
|
+
* if (config) await quoteCrossChainDeposit({ config, ...rest });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function getCrossChainVaultConfig(vault: IAddress): ICrossChainVaultConfig | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Whether a vault is a registered LayerZero OVault and should route deposits
|
|
56
|
+
* through the cross-chain flow. Address comparison is case-insensitive.
|
|
57
|
+
*
|
|
58
|
+
* @param vault - Vault contract address.
|
|
59
|
+
* @returns `true` when the vault has an entry in
|
|
60
|
+
* {@link CROSS_CHAIN_VAULT_CONFIGS}.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isCrossChainVault(vault: IAddress): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Get the hub and spoke chain IDs a vault is deployed across — the set of
|
|
65
|
+
* chains a user can deposit from.
|
|
66
|
+
*
|
|
67
|
+
* @param vault - Vault contract address.
|
|
68
|
+
* @returns `{ hub, spokes }` chain IDs, or `undefined` when the vault is not a
|
|
69
|
+
* registered OVault deployment.
|
|
70
|
+
*/
|
|
71
|
+
export declare function getOVaultChains(vault: IAddress): {
|
|
72
|
+
hub: number;
|
|
73
|
+
spokes: number[];
|
|
74
|
+
} | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Whether a vault's receipt token is hub-only (no cross-chain withdraw).
|
|
77
|
+
* The deposit UI must not offer a spoke share destination for these vaults.
|
|
78
|
+
*
|
|
79
|
+
* @param vault - Vault contract address.
|
|
80
|
+
* @returns `true` for vaults whose shares cannot leave the hub chain
|
|
81
|
+
* (AUGUST-6300).
|
|
82
|
+
*/
|
|
83
|
+
export declare function isHubOnlyReceipt(vault: IAddress): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Chains a user can receive the underlying asset on when withdrawing.
|
|
86
|
+
* Hub-only-receipt vaults redeem to the hub chain only (AUGUST-6300); all
|
|
87
|
+
* other OVault vaults can redeem to the hub or any spoke.
|
|
88
|
+
*
|
|
89
|
+
* @param vault - Vault contract address.
|
|
90
|
+
* @returns Destination chain IDs, or an empty array when the vault is not a
|
|
91
|
+
* registered OVault deployment.
|
|
92
|
+
*/
|
|
93
|
+
export declare function getWithdrawDestinationChains(vault: IAddress): number[];
|