@sodax/sdk 2.0.0-rc.12 → 2.0.0-rc.13
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/index.cjs +961 -22
- package/dist/index.d.cts +479 -4
- package/dist/index.d.ts +479 -4
- package/dist/index.mjs +950 -24
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAbiItem, isAddress, toHex, hexToBytes, encodeAbiParameters, parseAbiParameters, defineChain, encodeFunctionData, erc20Abi as erc20Abi$1, createPublicClient, http, bytesToHex, keccak256, stringToBytes, fromHex, encodePacked, decodeAbiParameters, parseEventLogs, maxUint160, maxUint48 } from 'viem';
|
|
1
|
+
import { getAbiItem, parseAbi, isAddress, toHex, hexToBytes, encodeAbiParameters, parseAbiParameters, defineChain, encodeFunctionData, erc20Abi as erc20Abi$1, createPublicClient, http, bytesToHex, keccak256, stringToBytes, fromHex, encodePacked, decodeAbiParameters, parseEventLogs, maxUint160, maxUint48 } from 'viem';
|
|
2
2
|
import { bcs } from '@mysten/sui/bcs';
|
|
3
3
|
import { PublicKey, Connection, VersionedTransaction, SystemProgram, ComputeBudgetProgram, TransactionMessage, TransactionInstruction } from '@solana/web3.js';
|
|
4
4
|
import { rpc, Address, xdr, Account, Horizon, Contract, TransactionBuilder, nativeToScVal, TimeoutInfinite, scValToBigInt, Operation, Asset, FeeBumpTransaction } from '@stellar/stellar-sdk';
|
|
@@ -169,7 +169,8 @@ var SODAX_FEATURES = [
|
|
|
169
169
|
"migration",
|
|
170
170
|
"dex",
|
|
171
171
|
"partner",
|
|
172
|
-
"recovery"
|
|
172
|
+
"recovery",
|
|
173
|
+
"leverageYield"
|
|
173
174
|
];
|
|
174
175
|
|
|
175
176
|
// src/shared/utils/tiny-invariant.ts
|
|
@@ -531,6 +532,27 @@ var SodaTokens = {
|
|
|
531
532
|
vault: "0x243b0c26c8b38793908d7C64e8510f21B19B4613"
|
|
532
533
|
}
|
|
533
534
|
};
|
|
535
|
+
var LsodaSymbols = ["lsodaWEETH", "lsodaWSTETH"];
|
|
536
|
+
var LsodaTokens = {
|
|
537
|
+
lsodaWEETH: {
|
|
538
|
+
symbol: "lsodaWEETH",
|
|
539
|
+
name: "Leveraged Soda weETH",
|
|
540
|
+
decimals: 18,
|
|
541
|
+
address: "0xD09de2f5070699A909c0FD32fb5A909d3886701D",
|
|
542
|
+
chainKey: ChainKeys.SONIC_MAINNET,
|
|
543
|
+
hubAsset: "0xD09de2f5070699A909c0FD32fb5A909d3886701D",
|
|
544
|
+
vault: "0xD09de2f5070699A909c0FD32fb5A909d3886701D"
|
|
545
|
+
},
|
|
546
|
+
lsodaWSTETH: {
|
|
547
|
+
symbol: "lsodaWSTETH",
|
|
548
|
+
name: "Leveraged Soda wstETH",
|
|
549
|
+
decimals: 18,
|
|
550
|
+
address: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a",
|
|
551
|
+
chainKey: ChainKeys.SONIC_MAINNET,
|
|
552
|
+
hubAsset: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a",
|
|
553
|
+
vault: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a"
|
|
554
|
+
}
|
|
555
|
+
};
|
|
534
556
|
var sonicSupportedTokens = {
|
|
535
557
|
S: {
|
|
536
558
|
symbol: "S",
|
|
@@ -595,7 +617,8 @@ var sonicSupportedTokens = {
|
|
|
595
617
|
hubAsset: "0x7c7d53EEcda37a87ce0D5bf8E0b24512A48dC963",
|
|
596
618
|
vault: SodaTokens.sodaSODA.address
|
|
597
619
|
},
|
|
598
|
-
...SodaTokens
|
|
620
|
+
...SodaTokens,
|
|
621
|
+
...LsodaTokens
|
|
599
622
|
};
|
|
600
623
|
var redbellySupportedTokens = {
|
|
601
624
|
RBNT: {
|
|
@@ -3596,7 +3619,8 @@ var swapSupportedTokens = {
|
|
|
3596
3619
|
spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.USDT,
|
|
3597
3620
|
spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.wS,
|
|
3598
3621
|
spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.SODA,
|
|
3599
|
-
...Object.values(SodaTokens)
|
|
3622
|
+
...Object.values(SodaTokens),
|
|
3623
|
+
...Object.values(LsodaTokens)
|
|
3600
3624
|
],
|
|
3601
3625
|
[ChainKeys.AVALANCHE_MAINNET]: [
|
|
3602
3626
|
spokeChainConfig[ChainKeys.AVALANCHE_MAINNET].supportedTokens.AVAX,
|
|
@@ -3836,6 +3860,41 @@ var swapsConfig = {
|
|
|
3836
3860
|
var getSupportedSolverTokens = (chainId) => swapSupportedTokens[chainId];
|
|
3837
3861
|
var isSwapSupportedToken = (chainId, token) => swapSupportedTokens[chainId].some((t) => t.address.toLowerCase() === token.toLowerCase());
|
|
3838
3862
|
|
|
3863
|
+
// ../types/dist/leverageYield/leverageYield.js
|
|
3864
|
+
var leverageYieldVaults = [
|
|
3865
|
+
{
|
|
3866
|
+
name: LsodaTokens.lsodaWEETH.symbol,
|
|
3867
|
+
vault: LsodaTokens.lsodaWEETH.vault,
|
|
3868
|
+
asset: SodaTokens.sodaWEETH.address,
|
|
3869
|
+
// sodaWEETH on Sonic
|
|
3870
|
+
borrowToken: SodaTokens.sodaETH.address,
|
|
3871
|
+
// sodaETH on Sonic
|
|
3872
|
+
lsdSource: {
|
|
3873
|
+
// DefiLlama pool for EtherFi's weETH on Ethereum (project: 'ether.fi-stake').
|
|
3874
|
+
poolId: "46bd2bdf-6d92-4066-b482-e885ee172264",
|
|
3875
|
+
fallbackAprPct: 3,
|
|
3876
|
+
label: "EtherFi (weETH)"
|
|
3877
|
+
}
|
|
3878
|
+
},
|
|
3879
|
+
{
|
|
3880
|
+
name: LsodaTokens.lsodaWSTETH.symbol,
|
|
3881
|
+
vault: LsodaTokens.lsodaWSTETH.vault,
|
|
3882
|
+
asset: SodaTokens.sodaWSTETH.address,
|
|
3883
|
+
// sodaWSTETH on Sonic
|
|
3884
|
+
borrowToken: SodaTokens.sodaETH.address,
|
|
3885
|
+
// sodaETH on Sonic
|
|
3886
|
+
lsdSource: {
|
|
3887
|
+
// DefiLlama pool for Lido's stETH on Ethereum (wstETH inherits this rate via redeem).
|
|
3888
|
+
poolId: "747c1d2a-c668-4682-b9f9-296708a3dd90",
|
|
3889
|
+
fallbackAprPct: 2.4,
|
|
3890
|
+
label: "Lido (stETH)"
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
];
|
|
3894
|
+
var leverageYieldConfig = {
|
|
3895
|
+
vaults: leverageYieldVaults
|
|
3896
|
+
};
|
|
3897
|
+
|
|
3839
3898
|
// ../types/dist/sodax-config/sodax-config.js
|
|
3840
3899
|
var bridgeConfig = {
|
|
3841
3900
|
partnerFee: void 0
|
|
@@ -3847,6 +3906,7 @@ var sodaxConfig = {
|
|
|
3847
3906
|
moneyMarket: moneyMarketConfig,
|
|
3848
3907
|
bridge: bridgeConfig,
|
|
3849
3908
|
dex: dexConfig,
|
|
3909
|
+
leverageYield: leverageYieldConfig,
|
|
3850
3910
|
hub: hubConfig,
|
|
3851
3911
|
api: apiConfig,
|
|
3852
3912
|
solver: solverConfig,
|
|
@@ -3988,7 +4048,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
|
|
|
3988
4048
|
}
|
|
3989
4049
|
|
|
3990
4050
|
// ../types/dist/index.js
|
|
3991
|
-
var CONFIG_VERSION =
|
|
4051
|
+
var CONFIG_VERSION = 211;
|
|
3992
4052
|
function isEvmSpokeChainConfig(value) {
|
|
3993
4053
|
return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
|
|
3994
4054
|
}
|
|
@@ -22267,17 +22327,11 @@ var SuiSpokeService = class {
|
|
|
22267
22327
|
]
|
|
22268
22328
|
});
|
|
22269
22329
|
if (params.raw === true) {
|
|
22270
|
-
tx.setSender(from);
|
|
22271
|
-
const transactionRaw = await tx.build({
|
|
22272
|
-
client: this.publicClient,
|
|
22273
|
-
onlyTransactionKind: true
|
|
22274
|
-
});
|
|
22275
|
-
const transactionRawBase64String = Buffer.from(transactionRaw).toString("base64");
|
|
22276
22330
|
return {
|
|
22277
22331
|
from,
|
|
22278
22332
|
to: `${assetManager.packageId}::${assetManager.moduleId}::transfer`,
|
|
22279
22333
|
value: amount,
|
|
22280
|
-
data:
|
|
22334
|
+
data: tx.serialize()
|
|
22281
22335
|
};
|
|
22282
22336
|
}
|
|
22283
22337
|
return params.walletProvider.signAndExecuteTxn(tx);
|
|
@@ -22297,17 +22351,11 @@ var SuiSpokeService = class {
|
|
|
22297
22351
|
]
|
|
22298
22352
|
});
|
|
22299
22353
|
if (params.raw === true) {
|
|
22300
|
-
txb.setSender(from);
|
|
22301
|
-
const transactionRaw = await txb.build({
|
|
22302
|
-
client: this.publicClient,
|
|
22303
|
-
onlyTransactionKind: true
|
|
22304
|
-
});
|
|
22305
|
-
const transactionRawBase64String = Buffer.from(transactionRaw).toString("base64");
|
|
22306
22354
|
return {
|
|
22307
22355
|
from,
|
|
22308
22356
|
to: `${connection.packageId}::${connection.moduleId}::send_message_ua`,
|
|
22309
22357
|
value: 0n,
|
|
22310
|
-
data:
|
|
22358
|
+
data: txb.serialize()
|
|
22311
22359
|
};
|
|
22312
22360
|
}
|
|
22313
22361
|
return params.walletProvider.signAndExecuteTxn(txb);
|
|
@@ -22318,7 +22366,7 @@ var SuiSpokeService = class {
|
|
|
22318
22366
|
* @returns {Promise<bigint>} The estimated computation cost.
|
|
22319
22367
|
*/
|
|
22320
22368
|
async estimateGas({ tx }) {
|
|
22321
|
-
const txb = Transaction$1.
|
|
22369
|
+
const txb = Transaction$1.from(tx.data);
|
|
22322
22370
|
const result = await this.publicClient.devInspectTransactionBlock({
|
|
22323
22371
|
sender: tx.from,
|
|
22324
22372
|
transactionBlock: txb
|
|
@@ -22549,6 +22597,7 @@ var CustomStellarAccount = class {
|
|
|
22549
22597
|
decrementSequenceNumber() {
|
|
22550
22598
|
if (this.sequenceNumber > this.startingSequenceNumber) {
|
|
22551
22599
|
this.sequenceNumber--;
|
|
22600
|
+
return;
|
|
22552
22601
|
}
|
|
22553
22602
|
throw new Error(
|
|
22554
22603
|
`Sequence number cannot be decremented below the starting sequence number: ${this.startingSequenceNumber}`
|
|
@@ -22655,7 +22704,7 @@ var StellarSpokeService = class {
|
|
|
22655
22704
|
);
|
|
22656
22705
|
const assembledPriorityTx = rpc.assembleTransaction(rawPriorityTx, simulation).build();
|
|
22657
22706
|
if (params.raw) {
|
|
22658
|
-
const transactionXdr =
|
|
22707
|
+
const transactionXdr = assembledPriorityTx.toXDR();
|
|
22659
22708
|
return {
|
|
22660
22709
|
from,
|
|
22661
22710
|
to: this.config.getChainConfig(srcChainKey).addresses.assetManager,
|
|
@@ -22772,7 +22821,7 @@ var StellarSpokeService = class {
|
|
|
22772
22821
|
);
|
|
22773
22822
|
const assembledPriorityTx = rpc.assembleTransaction(rawPriorityTx, simulation).build();
|
|
22774
22823
|
if (params.raw) {
|
|
22775
|
-
const transactionXdr =
|
|
22824
|
+
const transactionXdr = assembledPriorityTx.toXDR();
|
|
22776
22825
|
return {
|
|
22777
22826
|
from,
|
|
22778
22827
|
to: this.config.getChainConfig(srcChainKey).addresses.assetManager,
|
|
@@ -36985,7 +37034,12 @@ var RecoveryService = class {
|
|
|
36985
37034
|
srcChainKey: chainKey,
|
|
36986
37035
|
field: "chainKey"
|
|
36987
37036
|
});
|
|
36988
|
-
const
|
|
37037
|
+
const leverageVaultAddresses = new Set(
|
|
37038
|
+
this.config.sodaxConfig.leverageYield.vaults.map((vault) => vault.vault.toLowerCase())
|
|
37039
|
+
);
|
|
37040
|
+
const entries = Object.values(chainConfig.supportedTokens).filter(
|
|
37041
|
+
(token) => isAddress(token.hubAsset) && !leverageVaultAddresses.has(token.hubAsset.toLowerCase())
|
|
37042
|
+
);
|
|
36989
37043
|
if (entries.length === 0) {
|
|
36990
37044
|
return { ok: true, value: [] };
|
|
36991
37045
|
}
|
|
@@ -37087,6 +37141,871 @@ var RecoveryService = class {
|
|
|
37087
37141
|
}
|
|
37088
37142
|
};
|
|
37089
37143
|
|
|
37144
|
+
// src/leverageYield/errors.ts
|
|
37145
|
+
var leverageYieldInvariant = createInvariant("leverageYield");
|
|
37146
|
+
var LEVERAGE_YIELD_CODES = /* @__PURE__ */ new Set([
|
|
37147
|
+
"VALIDATION_FAILED",
|
|
37148
|
+
"INTENT_CREATION_FAILED",
|
|
37149
|
+
"APPROVE_FAILED",
|
|
37150
|
+
"ALLOWANCE_CHECK_FAILED",
|
|
37151
|
+
"LOOKUP_FAILED",
|
|
37152
|
+
"TX_VERIFICATION_FAILED",
|
|
37153
|
+
"TX_SUBMIT_FAILED",
|
|
37154
|
+
"RELAY_TIMEOUT",
|
|
37155
|
+
"RELAY_FAILED",
|
|
37156
|
+
"EXECUTION_FAILED",
|
|
37157
|
+
"EXTERNAL_API_ERROR",
|
|
37158
|
+
"UNKNOWN"
|
|
37159
|
+
]);
|
|
37160
|
+
var LEVERAGE_YIELD_POST_EXECUTION_CODES = /* @__PURE__ */ new Set([
|
|
37161
|
+
"EXECUTION_FAILED",
|
|
37162
|
+
"EXTERNAL_API_ERROR",
|
|
37163
|
+
"UNKNOWN"
|
|
37164
|
+
]);
|
|
37165
|
+
var LEVERAGE_YIELD_SWAP_CODES = /* @__PURE__ */ new Set([
|
|
37166
|
+
"VALIDATION_FAILED",
|
|
37167
|
+
"INTENT_CREATION_FAILED",
|
|
37168
|
+
"TX_VERIFICATION_FAILED",
|
|
37169
|
+
"TX_SUBMIT_FAILED",
|
|
37170
|
+
"RELAY_TIMEOUT",
|
|
37171
|
+
"RELAY_FAILED",
|
|
37172
|
+
"EXECUTION_FAILED",
|
|
37173
|
+
"EXTERNAL_API_ERROR",
|
|
37174
|
+
"UNKNOWN"
|
|
37175
|
+
]);
|
|
37176
|
+
var isLeverageYieldCreateIntentError = isCodeMember(CREATE_INTENT_CODES);
|
|
37177
|
+
var isLeverageYieldApproveError = isCodeMember(APPROVE_CODES);
|
|
37178
|
+
var isLeverageYieldAllowanceCheckError = isCodeMember(ALLOWANCE_CHECK_CODES);
|
|
37179
|
+
var isLeverageYieldLookupError = isCodeMember(LOOKUP_CODES);
|
|
37180
|
+
var isLeverageYieldPostExecutionError = isCodeMember(
|
|
37181
|
+
LEVERAGE_YIELD_POST_EXECUTION_CODES
|
|
37182
|
+
);
|
|
37183
|
+
var isLeverageYieldSwapError = isCodeMember(LEVERAGE_YIELD_SWAP_CODES);
|
|
37184
|
+
var isLeverageYieldError = isCodeMember(LEVERAGE_YIELD_CODES);
|
|
37185
|
+
|
|
37186
|
+
// src/leverageYield/LeverageYieldService.ts
|
|
37187
|
+
var leverageYieldVaultAbi = parseAbi([
|
|
37188
|
+
"function asset() view returns (address)",
|
|
37189
|
+
"function getPositionDetails() view returns (uint256 collateral, uint256 debt, uint256 ltv, uint256 healthFactor, uint256 idleAsset)",
|
|
37190
|
+
// Used by getApr() — read-only metadata that doesn't change per pass.
|
|
37191
|
+
"function pool() view returns (address)",
|
|
37192
|
+
"function borrowToken() view returns (address)",
|
|
37193
|
+
"function targetLTV() view returns (uint256)"
|
|
37194
|
+
]);
|
|
37195
|
+
var INTENT_DEADLINE_BUFFER_SECONDS = 5 * 60;
|
|
37196
|
+
var ANY_SOLVER_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
37197
|
+
var MAX_WITHDRAW_DUST_BUFFER = 1000n;
|
|
37198
|
+
function pctToRay(aprPct) {
|
|
37199
|
+
return BigInt(Math.round(aprPct * 1e9)) * 10n ** 16n;
|
|
37200
|
+
}
|
|
37201
|
+
var DEFILLAMA_FETCH_TIMEOUT_MS = 1e4;
|
|
37202
|
+
var DEFILLAMA_FETCH_MAX_ATTEMPTS = 2;
|
|
37203
|
+
async function fetchWithTimeout(url, timeoutMs) {
|
|
37204
|
+
const controller = new AbortController();
|
|
37205
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
37206
|
+
try {
|
|
37207
|
+
return await fetch(url, { signal: controller.signal });
|
|
37208
|
+
} finally {
|
|
37209
|
+
clearTimeout(timeoutId);
|
|
37210
|
+
}
|
|
37211
|
+
}
|
|
37212
|
+
async function fetchDefillamaApr(poolId) {
|
|
37213
|
+
return retry(async () => {
|
|
37214
|
+
const response = await fetchWithTimeout(`https://yields.llama.fi/chart/${poolId}`, DEFILLAMA_FETCH_TIMEOUT_MS);
|
|
37215
|
+
if (!response.ok) throw new Error(`DefiLlama APR fetch failed: HTTP ${response.status}`);
|
|
37216
|
+
const json = await response.json();
|
|
37217
|
+
const series = json?.data;
|
|
37218
|
+
if (!Array.isArray(series) || series.length === 0) {
|
|
37219
|
+
throw new Error("DefiLlama APR response: empty time series");
|
|
37220
|
+
}
|
|
37221
|
+
const latest = series[series.length - 1]?.apy;
|
|
37222
|
+
if (typeof latest !== "number") throw new Error("DefiLlama APR: latest entry missing numeric apy");
|
|
37223
|
+
return latest;
|
|
37224
|
+
}, DEFILLAMA_FETCH_MAX_ATTEMPTS);
|
|
37225
|
+
}
|
|
37226
|
+
var LeverageYieldService = class {
|
|
37227
|
+
hubProvider;
|
|
37228
|
+
config;
|
|
37229
|
+
spoke;
|
|
37230
|
+
constructor({ hubProvider, config, spoke }) {
|
|
37231
|
+
this.hubProvider = hubProvider;
|
|
37232
|
+
this.config = config;
|
|
37233
|
+
this.spoke = spoke;
|
|
37234
|
+
}
|
|
37235
|
+
// ─── Registry ──────────────────────────────────────────────────────────
|
|
37236
|
+
/** Returns the static registry of known leverage-yield vaults. */
|
|
37237
|
+
listVaults() {
|
|
37238
|
+
return this.config.sodaxConfig.leverageYield.vaults;
|
|
37239
|
+
}
|
|
37240
|
+
/** Looks up a vault by its `name` field. Returns `undefined` when not registered. */
|
|
37241
|
+
getVault(name) {
|
|
37242
|
+
return this.listVaults().find((v) => v.name === name);
|
|
37243
|
+
}
|
|
37244
|
+
/**
|
|
37245
|
+
* Looks up a registered vault by its on-chain proxy address (case-insensitive).
|
|
37246
|
+
* Returns `undefined` when the address isn't in the registry.
|
|
37247
|
+
*/
|
|
37248
|
+
getVaultByAddress(address) {
|
|
37249
|
+
const normalized = address.toLowerCase();
|
|
37250
|
+
return this.listVaults().find((v) => v.vault.toLowerCase() === normalized);
|
|
37251
|
+
}
|
|
37252
|
+
/**
|
|
37253
|
+
* Resolves the intent `deadline`: returns the caller-supplied value verbatim, otherwise
|
|
37254
|
+
* derives a default from the hub-chain (Sonic) block timestamp plus
|
|
37255
|
+
* {@link INTENT_DEADLINE_BUFFER_SECONDS}. The deadline is enforced on-chain against the hub
|
|
37256
|
+
* block time, so the default is anchored to that block — never the client clock, which can
|
|
37257
|
+
* drift and produce an already-expired or over-extended deadline.
|
|
37258
|
+
*
|
|
37259
|
+
* Returns a {@link Result}: a `getBlock` RPC outage is a read failure, surfaced as
|
|
37260
|
+
* `LOOKUP_FAILED` (`method: 'resolveDeadline'`) rather than masquerading as an intent-build
|
|
37261
|
+
* failure. The `deposit` / `withdraw` callers forward it verbatim.
|
|
37262
|
+
*/
|
|
37263
|
+
async resolveDeadline(deadline, srcChainKey) {
|
|
37264
|
+
if (deadline !== void 0) return { ok: true, value: deadline };
|
|
37265
|
+
try {
|
|
37266
|
+
const block = await this.hubProvider.publicClient.getBlock({
|
|
37267
|
+
includeTransactions: false,
|
|
37268
|
+
blockTag: "latest"
|
|
37269
|
+
});
|
|
37270
|
+
return { ok: true, value: block.timestamp + BigInt(INTENT_DEADLINE_BUFFER_SECONDS) };
|
|
37271
|
+
} catch (error) {
|
|
37272
|
+
return { ok: false, error: lookupFailed("leverageYield", "resolveDeadline", error, { srcChainKey }) };
|
|
37273
|
+
}
|
|
37274
|
+
}
|
|
37275
|
+
/**
|
|
37276
|
+
* Builds the {@link LeverageYieldSwapPayload} for a leverage-yield deposit (any token → lsoda*).
|
|
37277
|
+
* The lsoda* output is delivered to the user's hub wallet on Sonic so a later
|
|
37278
|
+
* {@link LeverageYieldService.withdraw} can swap it back. Spread the result into
|
|
37279
|
+
* {@link LeverageYieldService.vaultSwap}: `vaultSwap({ ...payload, walletProvider })`.
|
|
37280
|
+
* An optional `partnerFee` is forwarded on the payload as the per-intent fee override.
|
|
37281
|
+
*
|
|
37282
|
+
* For `minOutputAmount`, quote via `sodax.swaps.getQuote` with the vault address as the
|
|
37283
|
+
* destination token (`token_dst`) — vault shares are solver-tradeable, so the generic swap
|
|
37284
|
+
* quote applies; then subtract your slippage tolerance.
|
|
37285
|
+
*/
|
|
37286
|
+
async deposit(params) {
|
|
37287
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "deposit" };
|
|
37288
|
+
try {
|
|
37289
|
+
leverageYieldInvariant(params.inputAmount > 0n, "inputAmount must be greater than 0", {
|
|
37290
|
+
...baseCtx,
|
|
37291
|
+
field: "inputAmount"
|
|
37292
|
+
});
|
|
37293
|
+
leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
|
|
37294
|
+
leverageYieldInvariant(params.inputToken.length > 0, "inputToken is required", {
|
|
37295
|
+
...baseCtx,
|
|
37296
|
+
field: "inputToken"
|
|
37297
|
+
});
|
|
37298
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
|
|
37299
|
+
const deadlineResult = await this.resolveDeadline(params.deadline, params.srcChainKey);
|
|
37300
|
+
if (!deadlineResult.ok) return deadlineResult;
|
|
37301
|
+
const deadline = deadlineResult.value;
|
|
37302
|
+
return {
|
|
37303
|
+
ok: true,
|
|
37304
|
+
value: {
|
|
37305
|
+
params: {
|
|
37306
|
+
inputToken: params.inputToken,
|
|
37307
|
+
outputToken: params.vault,
|
|
37308
|
+
inputAmount: params.inputAmount,
|
|
37309
|
+
minOutputAmount: params.minOutputAmount,
|
|
37310
|
+
deadline,
|
|
37311
|
+
allowPartialFill: false,
|
|
37312
|
+
srcChainKey: params.srcChainKey,
|
|
37313
|
+
dstChainKey: this.hubProvider.chainConfig.chain.key,
|
|
37314
|
+
srcAddress: params.srcAddress,
|
|
37315
|
+
dstAddress: hubWallet,
|
|
37316
|
+
solver: params.solver ?? ANY_SOLVER_ADDRESS,
|
|
37317
|
+
data: "0x"
|
|
37318
|
+
},
|
|
37319
|
+
// Per-intent fee override — only included when the caller supplies one, so the
|
|
37320
|
+
// payload stays free of undefined-valued keys.
|
|
37321
|
+
...params.partnerFee !== void 0 && { partnerFee: params.partnerFee }
|
|
37322
|
+
}
|
|
37323
|
+
};
|
|
37324
|
+
} catch (error) {
|
|
37325
|
+
if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
|
|
37326
|
+
return { ok: false, error: intentCreationFailed("leverageYield", error, baseCtx) };
|
|
37327
|
+
}
|
|
37328
|
+
}
|
|
37329
|
+
/**
|
|
37330
|
+
* Builds the {@link LeverageYieldSwapPayload} for a leverage-yield withdraw (lsoda* → any
|
|
37331
|
+
* token). The payload carries `hubWalletSwap: true` — {@link LeverageYieldService.vaultSwap}
|
|
37332
|
+
* then spends the lsoda* held in the user's hub wallet by authorising it via a
|
|
37333
|
+
* `Connection.sendMessage` the user signs on `srcChainKey`. Wrapped in a {@link Result} for
|
|
37334
|
+
* a call shape uniform with {@link LeverageYieldService.deposit}; async because the default
|
|
37335
|
+
* `deadline` is read from the hub block timestamp.
|
|
37336
|
+
*
|
|
37337
|
+
* For `minOutputAmount`, quote via `sodax.swaps.getQuote` with the vault address as the
|
|
37338
|
+
* source token (`token_src`) — vault shares are solver-tradeable, so the generic swap quote
|
|
37339
|
+
* applies; then subtract your slippage tolerance.
|
|
37340
|
+
*/
|
|
37341
|
+
async withdraw(params) {
|
|
37342
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "withdraw" };
|
|
37343
|
+
try {
|
|
37344
|
+
leverageYieldInvariant(params.inputAmount > 0n, "inputAmount must be greater than 0", {
|
|
37345
|
+
...baseCtx,
|
|
37346
|
+
field: "inputAmount"
|
|
37347
|
+
});
|
|
37348
|
+
leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
|
|
37349
|
+
leverageYieldInvariant(params.outputToken.length > 0, "outputToken is required", {
|
|
37350
|
+
...baseCtx,
|
|
37351
|
+
field: "outputToken"
|
|
37352
|
+
});
|
|
37353
|
+
const deadlineResult = await this.resolveDeadline(params.deadline, params.srcChainKey);
|
|
37354
|
+
if (!deadlineResult.ok) return deadlineResult;
|
|
37355
|
+
const deadline = deadlineResult.value;
|
|
37356
|
+
return {
|
|
37357
|
+
ok: true,
|
|
37358
|
+
value: {
|
|
37359
|
+
params: {
|
|
37360
|
+
inputToken: params.vault,
|
|
37361
|
+
outputToken: params.outputToken,
|
|
37362
|
+
inputAmount: params.inputAmount,
|
|
37363
|
+
minOutputAmount: params.minOutputAmount,
|
|
37364
|
+
deadline,
|
|
37365
|
+
allowPartialFill: false,
|
|
37366
|
+
srcChainKey: params.srcChainKey,
|
|
37367
|
+
dstChainKey: params.dstChainKey,
|
|
37368
|
+
srcAddress: params.srcAddress,
|
|
37369
|
+
dstAddress: params.recipient ?? params.srcAddress,
|
|
37370
|
+
solver: params.solver ?? ANY_SOLVER_ADDRESS,
|
|
37371
|
+
data: "0x"
|
|
37372
|
+
},
|
|
37373
|
+
hubWalletSwap: true
|
|
37374
|
+
}
|
|
37375
|
+
};
|
|
37376
|
+
} catch (error) {
|
|
37377
|
+
if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
|
|
37378
|
+
return { ok: false, error: intentCreationFailed("leverageYield", error, baseCtx) };
|
|
37379
|
+
}
|
|
37380
|
+
}
|
|
37381
|
+
/**
|
|
37382
|
+
* Creates a vault swap intent on the user's source spoke chain without submitting it to
|
|
37383
|
+
* the solver. Leverage-yield copy of the swap domain's `createIntent`, specialised for
|
|
37384
|
+
* vault flows — duplicated deliberately so the vault-specific execution modifiers
|
|
37385
|
+
* (`hubWalletSwap`, per-intent `partnerFee`) stay off the generic swap surface.
|
|
37386
|
+
*
|
|
37387
|
+
* Use {@link LeverageYieldService.vaultSwap} for the full end-to-end flow
|
|
37388
|
+
* (create → relay → notify solver); use this directly when you need the raw transaction
|
|
37389
|
+
* or drive the relay yourself (e.g. the backend submit-tx path). To complete a manual flow,
|
|
37390
|
+
* relay the returned `relayData` (the shared `relayTxAndWaitPacket` helper) and then call
|
|
37391
|
+
* {@link LeverageYieldService.notifySolver} with the hub-side intent tx hash.
|
|
37392
|
+
*
|
|
37393
|
+
* @param _params - Intent parameters, source chain key, wallet provider (when `raw: false`),
|
|
37394
|
+
* and optional `skipSimulation` / `hubWalletSwap` / `partnerFee`.
|
|
37395
|
+
* @returns A `Result<CreateVaultIntentResult<K, Raw>, LeverageYieldCreateIntentError>`.
|
|
37396
|
+
* On success contains:
|
|
37397
|
+
* - `tx` — chain-specific tx hash (executed) or raw tx data (raw mode).
|
|
37398
|
+
* - `intent` — the fully constructed `Intent` object augmented with `feeAmount`.
|
|
37399
|
+
* - `relayData` — `{ address, payload }` needed to submit the intent to the relayer.
|
|
37400
|
+
*
|
|
37401
|
+
* On failure `result.error` is a SodaxError with `VALIDATION_FAILED` (invariant
|
|
37402
|
+
* precondition), `INTENT_CREATION_FAILED` (spoke-side creation/deposit failed) or
|
|
37403
|
+
* `UNKNOWN` (defensive fallback).
|
|
37404
|
+
*/
|
|
37405
|
+
async createVaultIntent(_params) {
|
|
37406
|
+
const { params, skipSimulation, hubWalletSwap, partnerFee = this.config.swaps.partnerFee } = _params;
|
|
37407
|
+
const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
|
|
37408
|
+
try {
|
|
37409
|
+
leverageYieldInvariant(
|
|
37410
|
+
isUndefinedOrValidWalletProviderForChainKey(params.srcChainKey, _params.walletProvider),
|
|
37411
|
+
`Invalid wallet provider for chain key: ${params.srcChainKey}`,
|
|
37412
|
+
baseCtx
|
|
37413
|
+
);
|
|
37414
|
+
const hubChainKey = this.hubProvider.chainConfig.chain.key;
|
|
37415
|
+
const inputTokenChainKey = hubWalletSwap ? hubChainKey : params.srcChainKey;
|
|
37416
|
+
leverageYieldInvariant(
|
|
37417
|
+
this.config.isValidOriginalAssetAddress(inputTokenChainKey, params.inputToken),
|
|
37418
|
+
`Unsupported spoke chain token (srcChainKey: ${inputTokenChainKey}, inputToken: ${params.inputToken})`,
|
|
37419
|
+
{ ...baseCtx, field: "inputToken" }
|
|
37420
|
+
);
|
|
37421
|
+
leverageYieldInvariant(
|
|
37422
|
+
this.config.isValidOriginalAssetAddress(params.dstChainKey, params.outputToken),
|
|
37423
|
+
`Unsupported spoke chain token (params.dstChain: ${params.dstChainKey}, params.outputToken: ${params.outputToken})`,
|
|
37424
|
+
{ ...baseCtx, field: "outputToken" }
|
|
37425
|
+
);
|
|
37426
|
+
leverageYieldInvariant(
|
|
37427
|
+
this.config.isValidSpokeChainKey(params.srcChainKey),
|
|
37428
|
+
`Invalid spoke chain (srcChainKey): ${params.srcChainKey}`,
|
|
37429
|
+
{ ...baseCtx, field: "srcChainKey" }
|
|
37430
|
+
);
|
|
37431
|
+
leverageYieldInvariant(
|
|
37432
|
+
this.config.isValidSpokeChainKey(params.dstChainKey),
|
|
37433
|
+
`Invalid spoke chain (params.dstChain): ${params.dstChainKey}`,
|
|
37434
|
+
{ ...baseCtx, field: "dstChainKey" }
|
|
37435
|
+
);
|
|
37436
|
+
if (isBitcoinChainKey(params.dstChainKey) && params.outputToken === "BTC") {
|
|
37437
|
+
leverageYieldInvariant(
|
|
37438
|
+
params.minOutputAmount >= 546n,
|
|
37439
|
+
`Invalid minOutputAmount (params.minOutputAmount): ${params.minOutputAmount}`,
|
|
37440
|
+
{ ...baseCtx, field: "minOutputAmount" }
|
|
37441
|
+
);
|
|
37442
|
+
}
|
|
37443
|
+
const personalAddress = params.srcAddress;
|
|
37444
|
+
let walletAddress = personalAddress;
|
|
37445
|
+
if (isBitcoinChainKeyType(params.srcChainKey) && _params.raw === false) {
|
|
37446
|
+
leverageYieldInvariant(
|
|
37447
|
+
isBitcoinWalletProviderType(_params.walletProvider),
|
|
37448
|
+
`Invalid wallet provider for chain key: ${params.srcChainKey}`,
|
|
37449
|
+
baseCtx
|
|
37450
|
+
);
|
|
37451
|
+
walletAddress = await this.spoke.bitcoin.getEffectiveWalletAddress(personalAddress);
|
|
37452
|
+
await this.spoke.bitcoin.radfi.ensureRadfiAccessToken(_params.walletProvider);
|
|
37453
|
+
}
|
|
37454
|
+
const creatorHubWalletAddress = await this.hubProvider.getUserHubWalletAddress(walletAddress, params.srcChainKey);
|
|
37455
|
+
if (hubWalletSwap) {
|
|
37456
|
+
const [data2, intent2, feeAmount2] = EvmSolverService.constructCreateIntentData(
|
|
37457
|
+
{ ...params, srcChainKey: hubChainKey, srcAddress: creatorHubWalletAddress },
|
|
37458
|
+
creatorHubWalletAddress,
|
|
37459
|
+
this.config,
|
|
37460
|
+
partnerFee
|
|
37461
|
+
);
|
|
37462
|
+
const coreSendMessageParams = {
|
|
37463
|
+
srcChainKey: params.srcChainKey,
|
|
37464
|
+
// Personal address — NOT the resolved trading `walletAddress`. SpokeService.sendMessage
|
|
37465
|
+
// re-resolves the effective (Bitcoin trading) address itself; passing the already-resolved
|
|
37466
|
+
// trading address here would double-resolve it (getTradingWallet(tradingAddress) →
|
|
37467
|
+
// "Trading wallet not found"). The trading address is used only for the hub-wallet
|
|
37468
|
+
// derivation above (creatorHubWalletAddress). Mirrors MoneyMarketService borrow/withdraw.
|
|
37469
|
+
srcAddress: personalAddress,
|
|
37470
|
+
dstChainKey: hubChainKey,
|
|
37471
|
+
dstAddress: creatorHubWalletAddress,
|
|
37472
|
+
payload: data2,
|
|
37473
|
+
skipSimulation
|
|
37474
|
+
};
|
|
37475
|
+
const txResult2 = await this.spoke.sendMessage(
|
|
37476
|
+
_params.raw ? { ...coreSendMessageParams, raw: true } : {
|
|
37477
|
+
...coreSendMessageParams,
|
|
37478
|
+
raw: false,
|
|
37479
|
+
walletProvider: _params.walletProvider
|
|
37480
|
+
}
|
|
37481
|
+
);
|
|
37482
|
+
if (!txResult2.ok) {
|
|
37483
|
+
if (isLeverageYieldCreateIntentError(txResult2.error)) {
|
|
37484
|
+
return { ok: false, error: txResult2.error };
|
|
37485
|
+
}
|
|
37486
|
+
return { ok: false, error: intentCreationFailed("leverageYield", txResult2.error, baseCtx) };
|
|
37487
|
+
}
|
|
37488
|
+
return {
|
|
37489
|
+
ok: true,
|
|
37490
|
+
value: {
|
|
37491
|
+
tx: txResult2.value,
|
|
37492
|
+
intent: { ...intent2, feeAmount: feeAmount2 },
|
|
37493
|
+
relayData: { address: creatorHubWalletAddress, payload: data2 }
|
|
37494
|
+
}
|
|
37495
|
+
};
|
|
37496
|
+
}
|
|
37497
|
+
if (isHubChainKeyType(params.srcChainKey) && isSonicChainKeyType(params.srcChainKey)) {
|
|
37498
|
+
const coreSonicParams = {
|
|
37499
|
+
createIntentParams: params,
|
|
37500
|
+
creatorHubWalletAddress,
|
|
37501
|
+
solverConfig: this.config.solver,
|
|
37502
|
+
fee: partnerFee,
|
|
37503
|
+
hubProvider: this.hubProvider
|
|
37504
|
+
};
|
|
37505
|
+
const [txResult2, intent2, feeAmount2, data2] = await SonicSpokeService.createSwapIntent(
|
|
37506
|
+
_params.raw ? { ...coreSonicParams, raw: true } : {
|
|
37507
|
+
...coreSonicParams,
|
|
37508
|
+
raw: false,
|
|
37509
|
+
walletProvider: _params.walletProvider
|
|
37510
|
+
}
|
|
37511
|
+
);
|
|
37512
|
+
return {
|
|
37513
|
+
ok: true,
|
|
37514
|
+
value: {
|
|
37515
|
+
tx: txResult2,
|
|
37516
|
+
intent: { ...intent2, feeAmount: feeAmount2 },
|
|
37517
|
+
relayData: { address: intent2.creator, payload: data2 }
|
|
37518
|
+
}
|
|
37519
|
+
};
|
|
37520
|
+
}
|
|
37521
|
+
const [data, intent, feeAmount] = EvmSolverService.constructCreateIntentData(
|
|
37522
|
+
{
|
|
37523
|
+
...params,
|
|
37524
|
+
srcAddress: walletAddress
|
|
37525
|
+
},
|
|
37526
|
+
creatorHubWalletAddress,
|
|
37527
|
+
this.config,
|
|
37528
|
+
partnerFee
|
|
37529
|
+
);
|
|
37530
|
+
const coreDepositParams = {
|
|
37531
|
+
srcChainKey: params.srcChainKey,
|
|
37532
|
+
srcAddress: walletAddress,
|
|
37533
|
+
to: creatorHubWalletAddress,
|
|
37534
|
+
token: params.inputToken,
|
|
37535
|
+
amount: params.inputAmount,
|
|
37536
|
+
data,
|
|
37537
|
+
skipSimulation
|
|
37538
|
+
};
|
|
37539
|
+
const txResult = await this.spoke.deposit(
|
|
37540
|
+
_params.raw ? {
|
|
37541
|
+
...coreDepositParams,
|
|
37542
|
+
raw: true
|
|
37543
|
+
} : {
|
|
37544
|
+
...coreDepositParams,
|
|
37545
|
+
raw: false,
|
|
37546
|
+
walletProvider: _params.walletProvider
|
|
37547
|
+
}
|
|
37548
|
+
);
|
|
37549
|
+
if (!txResult.ok) {
|
|
37550
|
+
if (isLeverageYieldCreateIntentError(txResult.error)) {
|
|
37551
|
+
return { ok: false, error: txResult.error };
|
|
37552
|
+
}
|
|
37553
|
+
return {
|
|
37554
|
+
ok: false,
|
|
37555
|
+
error: intentCreationFailed("leverageYield", txResult.error, baseCtx)
|
|
37556
|
+
};
|
|
37557
|
+
}
|
|
37558
|
+
return {
|
|
37559
|
+
ok: true,
|
|
37560
|
+
value: {
|
|
37561
|
+
tx: txResult.value,
|
|
37562
|
+
intent: { ...intent, feeAmount },
|
|
37563
|
+
relayData: { address: intent.creator, payload: data }
|
|
37564
|
+
}
|
|
37565
|
+
};
|
|
37566
|
+
} catch (error) {
|
|
37567
|
+
if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
|
|
37568
|
+
return {
|
|
37569
|
+
ok: false,
|
|
37570
|
+
error: intentCreationFailed("leverageYield", error, baseCtx)
|
|
37571
|
+
};
|
|
37572
|
+
}
|
|
37573
|
+
}
|
|
37574
|
+
/**
|
|
37575
|
+
* Executes a full end-to-end leverage-yield vault swap (deposit or withdraw).
|
|
37576
|
+
* Leverage-yield copy of the swap domain's `swap()` orchestrator:
|
|
37577
|
+
* 1. Calls {@link LeverageYieldService.createVaultIntent} to submit the intent
|
|
37578
|
+
* transaction on the source spoke chain.
|
|
37579
|
+
* 2. Verifies the spoke transaction landed on-chain.
|
|
37580
|
+
* 3. For non-hub source chains: submits the spoke tx to the relayer and waits for the
|
|
37581
|
+
* relay packet to land on the hub (Sonic). Skipped when `srcChainKey` is the hub.
|
|
37582
|
+
* 4. Notifies the solver, triggering it to fill the intent.
|
|
37583
|
+
*
|
|
37584
|
+
* Spread a {@link LeverageYieldSwapPayload} from `deposit` / `withdraw` into this method
|
|
37585
|
+
* alongside the wallet provider: `vaultSwap({ ...payload, walletProvider })`.
|
|
37586
|
+
*
|
|
37587
|
+
* @returns A `Result<VaultSwapResponse, LeverageYieldSwapError>`. On success:
|
|
37588
|
+
* - `solverExecutionResponse` — solver acknowledgement (`{ answer: 'OK', intent_hash }`).
|
|
37589
|
+
* - `intent` — the on-chain intent object that was created.
|
|
37590
|
+
* - `intentDeliveryInfo` — source/destination chain keys, tx hashes, and user addresses.
|
|
37591
|
+
*
|
|
37592
|
+
* On failure `result.error` carries one of the create-intent codes plus
|
|
37593
|
+
* `TX_VERIFICATION_FAILED`, `TX_SUBMIT_FAILED`, `RELAY_TIMEOUT`, `RELAY_FAILED`,
|
|
37594
|
+
* `EXECUTION_FAILED`, `EXTERNAL_API_ERROR` or `UNKNOWN`.
|
|
37595
|
+
*/
|
|
37596
|
+
async vaultSwap(_params) {
|
|
37597
|
+
const { params } = _params;
|
|
37598
|
+
const srcChainKey = params.srcChainKey;
|
|
37599
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "vaultSwap" };
|
|
37600
|
+
try {
|
|
37601
|
+
const timeout = _params.timeout;
|
|
37602
|
+
const createIntentResult = await this.createVaultIntent(_params);
|
|
37603
|
+
if (!createIntentResult.ok) {
|
|
37604
|
+
return { ok: false, error: createIntentResult.error };
|
|
37605
|
+
}
|
|
37606
|
+
const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
|
|
37607
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
37608
|
+
txHash: spokeTxHash,
|
|
37609
|
+
chainKey: srcChainKey
|
|
37610
|
+
});
|
|
37611
|
+
if (!verifyTxHashResult.ok) {
|
|
37612
|
+
return {
|
|
37613
|
+
ok: false,
|
|
37614
|
+
error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
|
|
37615
|
+
};
|
|
37616
|
+
}
|
|
37617
|
+
let dstIntentTxHash;
|
|
37618
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
37619
|
+
dstIntentTxHash = spokeTxHash;
|
|
37620
|
+
} else {
|
|
37621
|
+
const packet = await relayTxAndWaitPacket({
|
|
37622
|
+
srcTxHash: spokeTxHash,
|
|
37623
|
+
data: relayData,
|
|
37624
|
+
chainKey: srcChainKey,
|
|
37625
|
+
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
37626
|
+
timeout
|
|
37627
|
+
});
|
|
37628
|
+
if (!packet.ok) {
|
|
37629
|
+
return {
|
|
37630
|
+
ok: false,
|
|
37631
|
+
error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
|
|
37632
|
+
};
|
|
37633
|
+
}
|
|
37634
|
+
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
37635
|
+
}
|
|
37636
|
+
const postExecResult = await this.notifySolver({
|
|
37637
|
+
intent_tx_hash: dstIntentTxHash
|
|
37638
|
+
});
|
|
37639
|
+
if (!postExecResult.ok) {
|
|
37640
|
+
return { ok: false, error: postExecResult.error };
|
|
37641
|
+
}
|
|
37642
|
+
return {
|
|
37643
|
+
ok: true,
|
|
37644
|
+
value: {
|
|
37645
|
+
solverExecutionResponse: postExecResult.value,
|
|
37646
|
+
intent,
|
|
37647
|
+
intentDeliveryInfo: {
|
|
37648
|
+
srcChainKey,
|
|
37649
|
+
srcTxHash: spokeTxHash,
|
|
37650
|
+
srcAddress: params.srcAddress,
|
|
37651
|
+
dstChainKey: params.dstChainKey,
|
|
37652
|
+
dstTxHash: dstIntentTxHash,
|
|
37653
|
+
dstAddress: params.dstAddress
|
|
37654
|
+
}
|
|
37655
|
+
}
|
|
37656
|
+
};
|
|
37657
|
+
} catch (error) {
|
|
37658
|
+
if (isLeverageYieldSwapError(error)) return { ok: false, error };
|
|
37659
|
+
return {
|
|
37660
|
+
ok: false,
|
|
37661
|
+
error: unknownFailed("leverageYield", error, baseCtx)
|
|
37662
|
+
};
|
|
37663
|
+
}
|
|
37664
|
+
}
|
|
37665
|
+
/**
|
|
37666
|
+
* Notifies the solver that the vault intent landed on the hub, triggering it to fill.
|
|
37667
|
+
* Leverage-yield copy of the swap domain's `postExecution` — emits only
|
|
37668
|
+
* `EXECUTION_FAILED` / `EXTERNAL_API_ERROR` / `UNKNOWN` (relay/verify codes appear only
|
|
37669
|
+
* on {@link LeverageYieldService.vaultSwap}, which owns the verify + relay steps).
|
|
37670
|
+
*
|
|
37671
|
+
* Called automatically by {@link LeverageYieldService.vaultSwap} after the relay packet
|
|
37672
|
+
* lands on the hub. Public so callers who created the intent via
|
|
37673
|
+
* {@link LeverageYieldService.createVaultIntent} and relayed it themselves can finish the
|
|
37674
|
+
* flow manually.
|
|
37675
|
+
*
|
|
37676
|
+
* @param request - `{ intent_tx_hash }` — the hub-chain (Sonic) tx hash where the intent
|
|
37677
|
+
* was registered (the relay packet's `dst_tx_hash`, or the spoke tx hash for hub-sourced
|
|
37678
|
+
* intents).
|
|
37679
|
+
*/
|
|
37680
|
+
async notifySolver(request) {
|
|
37681
|
+
try {
|
|
37682
|
+
const result = await SolverApiService.postExecution(request, this.config.solver, this.config.logger);
|
|
37683
|
+
if (result.ok) return result;
|
|
37684
|
+
const detail = result.error?.detail ?? {
|
|
37685
|
+
code: -999,
|
|
37686
|
+
// SolverIntentErrorCode.UNKNOWN
|
|
37687
|
+
message: "Solver returned malformed error response"
|
|
37688
|
+
};
|
|
37689
|
+
return {
|
|
37690
|
+
ok: false,
|
|
37691
|
+
error: new SodaxError("EXTERNAL_API_ERROR", detail.message, {
|
|
37692
|
+
feature: "leverageYield",
|
|
37693
|
+
context: {
|
|
37694
|
+
phase: "postExecution",
|
|
37695
|
+
api: "solver",
|
|
37696
|
+
solverCode: detail.code,
|
|
37697
|
+
solverDetail: detail
|
|
37698
|
+
}
|
|
37699
|
+
})
|
|
37700
|
+
};
|
|
37701
|
+
} catch (error) {
|
|
37702
|
+
if (isLeverageYieldPostExecutionError(error)) return { ok: false, error };
|
|
37703
|
+
return { ok: false, error: executionFailed("leverageYield", error, { phase: "postExecution" }) };
|
|
37704
|
+
}
|
|
37705
|
+
}
|
|
37706
|
+
/**
|
|
37707
|
+
* Approves the vault's underlying asset to the leverage vault on Sonic. For callers
|
|
37708
|
+
* interacting with the vault directly on the hub — the swap-style {@link
|
|
37709
|
+
* LeverageYieldService.deposit} flow handles its own approvals.
|
|
37710
|
+
*/
|
|
37711
|
+
async approve(params) {
|
|
37712
|
+
const baseCtx = { action: "approve" };
|
|
37713
|
+
try {
|
|
37714
|
+
leverageYieldInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
|
|
37715
|
+
leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
|
|
37716
|
+
const assetResult = await this.getAsset(params.vault);
|
|
37717
|
+
if (!assetResult.ok) {
|
|
37718
|
+
return { ok: false, error: approveFailed("leverageYield", assetResult.error, baseCtx) };
|
|
37719
|
+
}
|
|
37720
|
+
const from = await params.walletProvider.getWalletAddress();
|
|
37721
|
+
const baseApprove = {
|
|
37722
|
+
token: assetResult.value,
|
|
37723
|
+
amount: params.amount,
|
|
37724
|
+
from,
|
|
37725
|
+
spender: params.vault
|
|
37726
|
+
};
|
|
37727
|
+
if (params.raw) {
|
|
37728
|
+
const tx2 = await Erc20Service.approve({ ...baseApprove, raw: true });
|
|
37729
|
+
return { ok: true, value: tx2 };
|
|
37730
|
+
}
|
|
37731
|
+
const tx = await Erc20Service.approve({
|
|
37732
|
+
...baseApprove,
|
|
37733
|
+
raw: false,
|
|
37734
|
+
walletProvider: params.walletProvider
|
|
37735
|
+
});
|
|
37736
|
+
return { ok: true, value: tx };
|
|
37737
|
+
} catch (error) {
|
|
37738
|
+
if (isLeverageYieldApproveError(error)) return { ok: false, error };
|
|
37739
|
+
return { ok: false, error: approveFailed("leverageYield", error, baseCtx) };
|
|
37740
|
+
}
|
|
37741
|
+
}
|
|
37742
|
+
/**
|
|
37743
|
+
* Reads on-chain allowance of the vault's underlying asset for `owner → vault`. Returns
|
|
37744
|
+
* `true` when the allowance covers `amount`. Use before a direct
|
|
37745
|
+
* {@link LeverageYieldService.deposit}.
|
|
37746
|
+
*/
|
|
37747
|
+
async isAllowanceValid(params) {
|
|
37748
|
+
const baseCtx = { action: "allowanceCheck" };
|
|
37749
|
+
try {
|
|
37750
|
+
leverageYieldInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
|
|
37751
|
+
const assetResult = await this.getAsset(params.vault);
|
|
37752
|
+
if (!assetResult.ok) {
|
|
37753
|
+
return { ok: false, error: allowanceCheckFailed("leverageYield", assetResult.error, baseCtx) };
|
|
37754
|
+
}
|
|
37755
|
+
const allowance = await this.hubProvider.publicClient.readContract({
|
|
37756
|
+
address: assetResult.value,
|
|
37757
|
+
abi: erc20Abi$1,
|
|
37758
|
+
functionName: "allowance",
|
|
37759
|
+
args: [params.owner, params.vault]
|
|
37760
|
+
});
|
|
37761
|
+
return { ok: true, value: allowance >= params.amount };
|
|
37762
|
+
} catch (error) {
|
|
37763
|
+
if (isLeverageYieldAllowanceCheckError(error)) return { ok: false, error };
|
|
37764
|
+
return { ok: false, error: allowanceCheckFailed("leverageYield", error, baseCtx) };
|
|
37765
|
+
}
|
|
37766
|
+
}
|
|
37767
|
+
// ─── Reads ──────────────────────────────────────────────────────────────
|
|
37768
|
+
/** ERC-4626 `asset()` of the vault — the sodaWEETH-style underlying. */
|
|
37769
|
+
async getAsset(vault) {
|
|
37770
|
+
try {
|
|
37771
|
+
const value = await this.hubProvider.publicClient.readContract({
|
|
37772
|
+
address: vault,
|
|
37773
|
+
abi: leverageYieldVaultAbi,
|
|
37774
|
+
functionName: "asset"
|
|
37775
|
+
});
|
|
37776
|
+
return { ok: true, value };
|
|
37777
|
+
} catch (error) {
|
|
37778
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37779
|
+
return { ok: false, error: lookupFailed("leverageYield", "getAsset", error) };
|
|
37780
|
+
}
|
|
37781
|
+
}
|
|
37782
|
+
/** Reads the vault's leveraged position snapshot via the non-standard `getPositionDetails`. */
|
|
37783
|
+
async getPosition(vault) {
|
|
37784
|
+
try {
|
|
37785
|
+
const [collateral, debt, ltv, healthFactor, idleAsset] = await this.hubProvider.publicClient.readContract({
|
|
37786
|
+
address: vault,
|
|
37787
|
+
abi: leverageYieldVaultAbi,
|
|
37788
|
+
functionName: "getPositionDetails"
|
|
37789
|
+
});
|
|
37790
|
+
return { ok: true, value: { collateral, debt, ltv, healthFactor, idleAsset } };
|
|
37791
|
+
} catch (error) {
|
|
37792
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37793
|
+
return { ok: false, error: lookupFailed("leverageYield", "getPosition", error) };
|
|
37794
|
+
}
|
|
37795
|
+
}
|
|
37796
|
+
/**
|
|
37797
|
+
* Computes the steady-state APR of a leverage-yield vault from the AAVE supply/borrow
|
|
37798
|
+
* rates of its asset and borrowToken, scaled by the vault's target leverage. Matches the
|
|
37799
|
+
* convention used by leveraged-LSD vaults (Origami, Gearbox, etc.) — assumes constant
|
|
37800
|
+
* LTV at `targetLTV` and constant AAVE rates.
|
|
37801
|
+
*
|
|
37802
|
+
* Returns raw fields in RAY (1e27, AAVE's native rate scale) plus the leverage multiplier
|
|
37803
|
+
* in WAD (1e18). See {@link LeverageYieldApr} for the formula and caveats.
|
|
37804
|
+
*/
|
|
37805
|
+
async getApr(vault) {
|
|
37806
|
+
try {
|
|
37807
|
+
const [pool, asset, borrowToken, targetLtvBps] = await Promise.all([
|
|
37808
|
+
this.hubProvider.publicClient.readContract({
|
|
37809
|
+
address: vault,
|
|
37810
|
+
abi: leverageYieldVaultAbi,
|
|
37811
|
+
functionName: "pool"
|
|
37812
|
+
}),
|
|
37813
|
+
this.hubProvider.publicClient.readContract({
|
|
37814
|
+
address: vault,
|
|
37815
|
+
abi: leverageYieldVaultAbi,
|
|
37816
|
+
functionName: "asset"
|
|
37817
|
+
}),
|
|
37818
|
+
this.hubProvider.publicClient.readContract({
|
|
37819
|
+
address: vault,
|
|
37820
|
+
abi: leverageYieldVaultAbi,
|
|
37821
|
+
functionName: "borrowToken"
|
|
37822
|
+
}),
|
|
37823
|
+
this.hubProvider.publicClient.readContract({
|
|
37824
|
+
address: vault,
|
|
37825
|
+
abi: leverageYieldVaultAbi,
|
|
37826
|
+
functionName: "targetLTV"
|
|
37827
|
+
})
|
|
37828
|
+
]);
|
|
37829
|
+
const [assetReserve, borrowReserve] = await Promise.all([
|
|
37830
|
+
this.hubProvider.publicClient.readContract({
|
|
37831
|
+
address: pool,
|
|
37832
|
+
abi: poolAbi,
|
|
37833
|
+
functionName: "getReserveData",
|
|
37834
|
+
args: [asset]
|
|
37835
|
+
}),
|
|
37836
|
+
this.hubProvider.publicClient.readContract({
|
|
37837
|
+
address: pool,
|
|
37838
|
+
abi: poolAbi,
|
|
37839
|
+
functionName: "getReserveData",
|
|
37840
|
+
args: [borrowToken]
|
|
37841
|
+
})
|
|
37842
|
+
]);
|
|
37843
|
+
const supplyAprRay = assetReserve.currentLiquidityRate;
|
|
37844
|
+
const borrowAprRay = borrowReserve.currentVariableBorrowRate;
|
|
37845
|
+
const BPS = 10000n;
|
|
37846
|
+
const WAD2 = 1000000000000000000n;
|
|
37847
|
+
leverageYieldInvariant(targetLtvBps < BPS, `targetLTV (${targetLtvBps}) must be < 100% (10_000 bps)`, {
|
|
37848
|
+
method: "getApr",
|
|
37849
|
+
field: "targetLtvBps"
|
|
37850
|
+
});
|
|
37851
|
+
const leverageMultiplierWad = targetLtvBps * WAD2 / (BPS - targetLtvBps);
|
|
37852
|
+
const spreadRay = supplyAprRay - borrowAprRay;
|
|
37853
|
+
const netAprRay = supplyAprRay + spreadRay * leverageMultiplierWad / WAD2;
|
|
37854
|
+
return {
|
|
37855
|
+
ok: true,
|
|
37856
|
+
value: { supplyAprRay, borrowAprRay, targetLtvBps, leverageMultiplierWad, netAprRay }
|
|
37857
|
+
};
|
|
37858
|
+
} catch (error) {
|
|
37859
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37860
|
+
return { ok: false, error: lookupFailed("leverageYield", "getApr", error) };
|
|
37861
|
+
}
|
|
37862
|
+
}
|
|
37863
|
+
/**
|
|
37864
|
+
* Off-chain LSD staking-APR for the vault's underlying asset. Looks the vault up in the
|
|
37865
|
+
* registry, hits DefiLlama's per-pool chart endpoint for the configured `poolId`, and on
|
|
37866
|
+
* any fetch failure returns the registry's hardcoded `fallbackAprPct` with `stale: true`.
|
|
37867
|
+
*
|
|
37868
|
+
* Always resolves to `{ ok: true, ... }` for a known vault — the fallback path replaces
|
|
37869
|
+
* the error, since a missing LSD APR shouldn't break the parent call. Returns
|
|
37870
|
+
* `{ aprRay: 0n, stale: true, label: 'no LSD source' }` for vaults without an
|
|
37871
|
+
* `lsdSource` configured (non-LSD strategies); callers can treat that as "skip LSD".
|
|
37872
|
+
*/
|
|
37873
|
+
async getLsdApr(vault) {
|
|
37874
|
+
try {
|
|
37875
|
+
const cfg = this.getVaultByAddress(vault);
|
|
37876
|
+
const source = cfg?.lsdSource;
|
|
37877
|
+
if (!source) {
|
|
37878
|
+
return { ok: true, value: { aprRay: 0n, label: "no LSD source", stale: true } };
|
|
37879
|
+
}
|
|
37880
|
+
try {
|
|
37881
|
+
const aprPct = await fetchDefillamaApr(source.poolId);
|
|
37882
|
+
return { ok: true, value: { aprRay: pctToRay(aprPct), label: source.label, stale: false } };
|
|
37883
|
+
} catch (fetchError) {
|
|
37884
|
+
this.config.logger.warn("[leverageYield] DefiLlama APR fetch failed; using fallbackAprPct", {
|
|
37885
|
+
vault,
|
|
37886
|
+
poolId: source.poolId,
|
|
37887
|
+
fallbackAprPct: source.fallbackAprPct,
|
|
37888
|
+
error: fetchError instanceof Error ? fetchError.message : String(fetchError)
|
|
37889
|
+
});
|
|
37890
|
+
return {
|
|
37891
|
+
ok: true,
|
|
37892
|
+
value: { aprRay: pctToRay(source.fallbackAprPct), label: `${source.label} (fallback)`, stale: true }
|
|
37893
|
+
};
|
|
37894
|
+
}
|
|
37895
|
+
} catch (error) {
|
|
37896
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37897
|
+
return { ok: false, error: lookupFailed("leverageYield", "getLsdApr", error) };
|
|
37898
|
+
}
|
|
37899
|
+
}
|
|
37900
|
+
/**
|
|
37901
|
+
* Combined view of {@link getApr} + {@link getLsdApr}: re-applies the vault's leverage
|
|
37902
|
+
* formula with the LSD's native staking yield folded into the supply side, exposing the
|
|
37903
|
+
* **effective** net APR that LSD-backed strategies actually earn. The AAVE-only
|
|
37904
|
+
* `netAprRay` is preserved on the return value for callers who want to display both.
|
|
37905
|
+
*
|
|
37906
|
+
* effectiveSupply = supplyAprRay + lsdApr.aprRay
|
|
37907
|
+
* effectiveNet = effectiveSupply + leverage × (effectiveSupply − borrowAprRay)
|
|
37908
|
+
*
|
|
37909
|
+
* Fetches AAVE rates and the LSD APR in parallel for one round-trip's worth of latency.
|
|
37910
|
+
*/
|
|
37911
|
+
async getEffectiveApr(vault) {
|
|
37912
|
+
try {
|
|
37913
|
+
const [aprResult, lsdResult] = await Promise.all([this.getApr(vault), this.getLsdApr(vault)]);
|
|
37914
|
+
if (!aprResult.ok) return aprResult;
|
|
37915
|
+
if (!lsdResult.ok) return lsdResult;
|
|
37916
|
+
const apr = aprResult.value;
|
|
37917
|
+
const lsd = lsdResult.value;
|
|
37918
|
+
const effectiveSupplyAprRay = apr.supplyAprRay + lsd.aprRay;
|
|
37919
|
+
const spreadRay = effectiveSupplyAprRay - apr.borrowAprRay;
|
|
37920
|
+
const WAD2 = 1000000000000000000n;
|
|
37921
|
+
const effectiveNetAprRay = effectiveSupplyAprRay + spreadRay * apr.leverageMultiplierWad / WAD2;
|
|
37922
|
+
return {
|
|
37923
|
+
ok: true,
|
|
37924
|
+
value: { ...apr, lsdApr: lsd, effectiveSupplyAprRay, effectiveNetAprRay }
|
|
37925
|
+
};
|
|
37926
|
+
} catch (error) {
|
|
37927
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37928
|
+
return { ok: false, error: lookupFailed("leverageYield", "getEffectiveApr", error) };
|
|
37929
|
+
}
|
|
37930
|
+
}
|
|
37931
|
+
/** Synchronously withdrawable assets for `owner` (clamped against leverage HF floor). */
|
|
37932
|
+
async getMaxWithdraw(vault, owner) {
|
|
37933
|
+
const inner = await Erc4626Service.getMaxWithdraw(vault, owner, this.hubProvider.publicClient);
|
|
37934
|
+
if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "getMaxWithdraw", inner.error) };
|
|
37935
|
+
return { ok: true, value: inner.value };
|
|
37936
|
+
}
|
|
37937
|
+
/** Total underlying assets currently held by the vault (vault-asset units, 18 decimals) — TVL. */
|
|
37938
|
+
async getTotalAssets(vault) {
|
|
37939
|
+
const inner = await Erc4626Service.getTotalAssets(vault, this.hubProvider.publicClient);
|
|
37940
|
+
if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "getTotalAssets", inner.error) };
|
|
37941
|
+
return { ok: true, value: inner.value };
|
|
37942
|
+
}
|
|
37943
|
+
/** Shares minted for a given asset deposit. */
|
|
37944
|
+
async previewDeposit(vault, assets) {
|
|
37945
|
+
const inner = await Erc4626Service.previewDeposit(vault, assets, this.hubProvider.publicClient);
|
|
37946
|
+
if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewDeposit", inner.error) };
|
|
37947
|
+
return { ok: true, value: inner.value };
|
|
37948
|
+
}
|
|
37949
|
+
/** Shares burned for a given asset withdrawal. */
|
|
37950
|
+
async previewWithdraw(vault, assets) {
|
|
37951
|
+
const inner = await Erc4626Service.previewWithdraw(vault, assets, this.hubProvider.publicClient);
|
|
37952
|
+
if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewWithdraw", inner.error) };
|
|
37953
|
+
return { ok: true, value: inner.value };
|
|
37954
|
+
}
|
|
37955
|
+
/** Assets received for a given share redemption. */
|
|
37956
|
+
async previewRedeem(vault, shares) {
|
|
37957
|
+
const inner = await Erc4626Service.previewRedeem(vault, shares, this.hubProvider.publicClient);
|
|
37958
|
+
if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewRedeem", inner.error) };
|
|
37959
|
+
return { ok: true, value: inner.value };
|
|
37960
|
+
}
|
|
37961
|
+
/** Vault shares held by `owner`. */
|
|
37962
|
+
async getShareBalance(vault, owner) {
|
|
37963
|
+
try {
|
|
37964
|
+
const value = await this.hubProvider.publicClient.readContract({
|
|
37965
|
+
address: vault,
|
|
37966
|
+
abi: erc20Abi$1,
|
|
37967
|
+
functionName: "balanceOf",
|
|
37968
|
+
args: [owner]
|
|
37969
|
+
});
|
|
37970
|
+
return { ok: true, value };
|
|
37971
|
+
} catch (error) {
|
|
37972
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37973
|
+
return { ok: false, error: lookupFailed("leverageYield", "getShareBalance", error) };
|
|
37974
|
+
}
|
|
37975
|
+
}
|
|
37976
|
+
/**
|
|
37977
|
+
* Convenience: resolves the user's hub wallet from `(srcChainKey, srcAddress)` and
|
|
37978
|
+
* returns its on-chain `maxWithdraw`, less {@link MAX_WITHDRAW_DUST_BUFFER}. The trim
|
|
37979
|
+
* keeps the value safe for an asset-denominated ERC-4626 `withdraw` — the raw
|
|
37980
|
+
* `maxWithdraw` can trip the round-up that asks for one more share than the user holds.
|
|
37981
|
+
*/
|
|
37982
|
+
async getMaxWithdrawForUser(vault, srcChainKey, srcAddress) {
|
|
37983
|
+
try {
|
|
37984
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(srcAddress, srcChainKey);
|
|
37985
|
+
const maxWithdrawResult = await this.getMaxWithdraw(vault, hubWallet);
|
|
37986
|
+
if (!maxWithdrawResult.ok) return maxWithdrawResult;
|
|
37987
|
+
const buffered = maxWithdrawResult.value > MAX_WITHDRAW_DUST_BUFFER ? maxWithdrawResult.value - MAX_WITHDRAW_DUST_BUFFER : 0n;
|
|
37988
|
+
return { ok: true, value: buffered };
|
|
37989
|
+
} catch (error) {
|
|
37990
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
37991
|
+
return { ok: false, error: lookupFailed("leverageYield", "getMaxWithdrawForUser", error, { srcChainKey }) };
|
|
37992
|
+
}
|
|
37993
|
+
}
|
|
37994
|
+
/**
|
|
37995
|
+
* Convenience: resolves the user's hub wallet from `(srcChainKey, srcAddress)` and
|
|
37996
|
+
* returns its on-chain share balance.
|
|
37997
|
+
*/
|
|
37998
|
+
async getShareBalanceForUser(vault, srcChainKey, srcAddress) {
|
|
37999
|
+
try {
|
|
38000
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(srcAddress, srcChainKey);
|
|
38001
|
+
return await this.getShareBalance(vault, hubWallet);
|
|
38002
|
+
} catch (error) {
|
|
38003
|
+
if (isLeverageYieldLookupError(error)) return { ok: false, error };
|
|
38004
|
+
return { ok: false, error: lookupFailed("leverageYield", "getShareBalanceForUser", error, { srcChainKey }) };
|
|
38005
|
+
}
|
|
38006
|
+
}
|
|
38007
|
+
};
|
|
38008
|
+
|
|
37090
38009
|
// src/shared/entities/Sodax.ts
|
|
37091
38010
|
var Sodax = class {
|
|
37092
38011
|
instanceConfig;
|
|
@@ -37108,6 +38027,8 @@ var Sodax = class {
|
|
|
37108
38027
|
// Recovery service for withdrawing stuck hub-wallet assets back to a spoke chain
|
|
37109
38028
|
dex;
|
|
37110
38029
|
// Dex service enabling DEX operations
|
|
38030
|
+
leverageYield;
|
|
38031
|
+
// Leverage-yield service: cross-chain deposits / withdrawals into ERC-4626 leverage vaults on Sonic
|
|
37111
38032
|
config;
|
|
37112
38033
|
// Config service enabling configuration data fetching from the backend API or fallbacking to default values
|
|
37113
38034
|
hubProvider;
|
|
@@ -37153,6 +38074,11 @@ var Sodax = class {
|
|
|
37153
38074
|
config: this.config,
|
|
37154
38075
|
spoke: this.spoke
|
|
37155
38076
|
});
|
|
38077
|
+
this.leverageYield = new LeverageYieldService({
|
|
38078
|
+
hubProvider: this.hubProvider,
|
|
38079
|
+
config: this.config,
|
|
38080
|
+
spoke: this.spoke
|
|
38081
|
+
});
|
|
37156
38082
|
}
|
|
37157
38083
|
/**
|
|
37158
38084
|
* Initializes the Sodax instance with dynamic configuration.
|
|
@@ -37193,4 +38119,4 @@ var isPartnerError = isCodeMember(PARTNER_CODES);
|
|
|
37193
38119
|
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
37194
38120
|
*/
|
|
37195
38121
|
|
|
37196
|
-
export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LockupMultiplier, LockupPeriod, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType, isSubmitSwapTxResponse, isSubmitSwapTxStatusResponse, isSuiChainKey, isSuiChainKeyType, isSupportedBitcoinAddressType, isSwapCreateIntentError, isSwapError, isSwapSupportedToken, isUndefinedOrValidWalletProviderForChainKey, isUnifiedBnUSDMigrateParams, isValidWalletProviderForChainKey, kaiaSupportedTokens, lightlinkSupportedTokens, lookupFailed, mapRelayFailure, mergeSodaxConfig, messageOf, migrationInvariant, mintPositionParamsAbi, mmInvariant, modifyLiquidityParamsAbi, moneyMarketConfig, moneyMarketReserveAssets, moneyMarketSupportedTokens, nativeToUSD, nearSupportedTokens, newbnUSDSpokeChainIds, normalize, normalizeBN, normalizePsbtToBase64, normalizeSignatureToBase64, normalizedToUsd, optimismSupportedTokens, pancakeSwapInfinityDefaultHookAbi, pancakeSwapInfinityPoolManagerAbi, pancakeSwapInfinityPositionManagerAbi, parseToStroops, parseTokenArrayFromJson, partnerInvariant, permit2Abi, polygonSupportedTokens, poolAbi, poolKeyAbi, randomUint256, rayDiv, rayMul, rayPow, rayToWad, recoveryInvariant, redbellySupportedTokens, relayConfig, relayTxAndWaitPacket, requestAddress, requestJsonRpc, requestSigning, resolveLogger, retry, reverseEncodeAddress, serializeAddressData, silentLogger, sleep, sodaxConfig, sodaxInvariant, solanaSupportedTokens, solverConfig, sonicSupportedTokens, sonicWalletFactoryAbi, spokeAssetManagerAbi, spokeChainConfig, spokeChainKeysSet, stacksSupportedTokens, stakedSodaAbi, stakingInvariant, stakingRouterAbi, stataTokenFactoryAbi, stellarSupportedTokens, submitTransaction, suiSupportedTokens, supportedSpokeChains, supportedTokensByChain, swapExactInSingleParamsAbi, swapInvariant, swapSupportedTokens, swapsConfig, uiPoolDataAbi, universalRouterAbi, unknownFailed, usesBip322MessageSigning, valueToBigNumber, valueToZDBigNumber, variableDebtTokenAbi, vaultTokenAbi, verifyFailed, wadToRay, waitForStacksTransaction, waitForTransactionReceipt, waitUntilIntentExecuted, walletFactoryAbi, wrappedSonicAbi };
|
|
38122
|
+
export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LeverageYieldService, LockupMultiplier, LockupPeriod, LsodaSymbols, LsodaTokens, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isLeverageYieldAllowanceCheckError, isLeverageYieldApproveError, isLeverageYieldCreateIntentError, isLeverageYieldError, isLeverageYieldLookupError, isLeverageYieldPostExecutionError, isLeverageYieldSwapError, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType, isSubmitSwapTxResponse, isSubmitSwapTxStatusResponse, isSuiChainKey, isSuiChainKeyType, isSupportedBitcoinAddressType, isSwapCreateIntentError, isSwapError, isSwapSupportedToken, isUndefinedOrValidWalletProviderForChainKey, isUnifiedBnUSDMigrateParams, isValidWalletProviderForChainKey, kaiaSupportedTokens, leverageYieldConfig, leverageYieldInvariant, leverageYieldVaults, lightlinkSupportedTokens, lookupFailed, mapRelayFailure, mergeSodaxConfig, messageOf, migrationInvariant, mintPositionParamsAbi, mmInvariant, modifyLiquidityParamsAbi, moneyMarketConfig, moneyMarketReserveAssets, moneyMarketSupportedTokens, nativeToUSD, nearSupportedTokens, newbnUSDSpokeChainIds, normalize, normalizeBN, normalizePsbtToBase64, normalizeSignatureToBase64, normalizedToUsd, optimismSupportedTokens, pancakeSwapInfinityDefaultHookAbi, pancakeSwapInfinityPoolManagerAbi, pancakeSwapInfinityPositionManagerAbi, parseToStroops, parseTokenArrayFromJson, partnerInvariant, permit2Abi, polygonSupportedTokens, poolAbi, poolKeyAbi, randomUint256, rayDiv, rayMul, rayPow, rayToWad, recoveryInvariant, redbellySupportedTokens, relayConfig, relayTxAndWaitPacket, requestAddress, requestJsonRpc, requestSigning, resolveLogger, retry, reverseEncodeAddress, serializeAddressData, silentLogger, sleep, sodaxConfig, sodaxInvariant, solanaSupportedTokens, solverConfig, sonicSupportedTokens, sonicWalletFactoryAbi, spokeAssetManagerAbi, spokeChainConfig, spokeChainKeysSet, stacksSupportedTokens, stakedSodaAbi, stakingInvariant, stakingRouterAbi, stataTokenFactoryAbi, stellarSupportedTokens, submitTransaction, suiSupportedTokens, supportedSpokeChains, supportedTokensByChain, swapExactInSingleParamsAbi, swapInvariant, swapSupportedTokens, swapsConfig, uiPoolDataAbi, universalRouterAbi, unknownFailed, usesBip322MessageSigning, valueToBigNumber, valueToZDBigNumber, variableDebtTokenAbi, vaultTokenAbi, verifyFailed, wadToRay, waitForStacksTransaction, waitForTransactionReceipt, waitUntilIntentExecuted, walletFactoryAbi, wrappedSonicAbi };
|