@shogun-sdk/intents-sdk 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +249 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -2
- package/dist/index.d.ts +58 -2
- package/dist/index.js +249 -102
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/core/orders/cross-chain.ts +5 -1
- package/src/core/orders/single-chain.ts +11 -21
- package/src/index.ts +10 -1
- package/src/utils/quote/aggregator.ts +187 -58
- package/src/utils/quote/paraswap.ts +7 -0
- package/src/utils/quote/pricing/constants.ts +50 -6
- package/src/utils/quote/pricing/expenses.ts +78 -22
- package/src/utils/quote/pricing/gas.ts +71 -6
- package/src/utils/quote/pricing/limit-amount.ts +21 -0
- package/src/utils/quote/raydium.ts +1 -4
package/dist/index.js
CHANGED
|
@@ -4841,6 +4841,9 @@ var ParaswapQuoteProvider = class {
|
|
|
4841
4841
|
}
|
|
4842
4842
|
async getQuote(paraswapParams) {
|
|
4843
4843
|
const params = { ...paraswapParams };
|
|
4844
|
+
if (isNativeEvmToken(params.srcToken)) {
|
|
4845
|
+
params.srcToken = WRAPPED_ETH_ADDRESSES[this.chainId];
|
|
4846
|
+
}
|
|
4844
4847
|
if (isNativeEvmToken(params.destToken)) {
|
|
4845
4848
|
params.destToken = WRAPPED_ETH_ADDRESSES[this.chainId];
|
|
4846
4849
|
}
|
|
@@ -4977,6 +4980,13 @@ import {
|
|
|
4977
4980
|
PlatformConfig,
|
|
4978
4981
|
Curve
|
|
4979
4982
|
} from "@raydium-io/raydium-sdk-v2";
|
|
4983
|
+
|
|
4984
|
+
// src/utils/quote/address.ts
|
|
4985
|
+
function compareAddresses(firstAddress, secondAddress) {
|
|
4986
|
+
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
// src/utils/quote/raydium.ts
|
|
4980
4990
|
import { Connection, clusterApiUrl, PublicKey as PublicKey2 } from "@solana/web3.js";
|
|
4981
4991
|
import BN2 from "bn.js";
|
|
4982
4992
|
import { Decimal } from "decimal.js";
|
|
@@ -4995,9 +5005,6 @@ var launchpadPoolCache = /* @__PURE__ */ new Map();
|
|
|
4995
5005
|
var launchpadPoolInfoCache = /* @__PURE__ */ new Map();
|
|
4996
5006
|
var platformConfigCache = /* @__PURE__ */ new Map();
|
|
4997
5007
|
var mintInfoCache = /* @__PURE__ */ new Map();
|
|
4998
|
-
var compareAddresses = (firstAddress, secondAddress) => {
|
|
4999
|
-
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
5000
|
-
};
|
|
5001
5008
|
var LAUNCHPAD_WHITELISTED_QUOTE_TOKENS = [
|
|
5002
5009
|
new PublicKey2("So11111111111111111111111111111111111111112"),
|
|
5003
5010
|
// WSOL
|
|
@@ -6094,33 +6101,63 @@ function estimateAmountOut(swapOutput, commissionBps, expenses, commissionDenomi
|
|
|
6094
6101
|
// src/utils/quote/pricing/expenses.ts
|
|
6095
6102
|
init_constants();
|
|
6096
6103
|
|
|
6097
|
-
// src/utils/quote/address.ts
|
|
6098
|
-
function compareAddresses2(firstAddress, secondAddress) {
|
|
6099
|
-
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
6100
|
-
}
|
|
6101
|
-
|
|
6102
6104
|
// src/utils/quote/pricing/gas.ts
|
|
6103
6105
|
init_chains();
|
|
6104
6106
|
import { getGasPrice } from "viem/actions";
|
|
6105
6107
|
|
|
6106
6108
|
// src/utils/quote/pricing/constants.ts
|
|
6107
|
-
var DEFAULT_COMMISSION_BPS =
|
|
6109
|
+
var DEFAULT_COMMISSION_BPS = 0n;
|
|
6110
|
+
var SOLVER_DEFAULT_SLIPPAGE_BPS = 5n;
|
|
6111
|
+
var DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS = 50;
|
|
6112
|
+
var DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS = 25;
|
|
6108
6113
|
var SINGLE_CHAIN_COMMISSION_DENOMINATOR = 10000n;
|
|
6109
6114
|
var CROSS_CHAIN_COMMISSION_DENOMINATOR = 100000n;
|
|
6110
6115
|
var EVM_SINGLE_CHAIN_GAS_LIMIT = 3000000n;
|
|
6111
6116
|
var EVM_CROSS_CHAIN_GAS_LIMIT = 2000000n;
|
|
6117
|
+
var EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT = 1220000n;
|
|
6118
|
+
var EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT = 620000n;
|
|
6119
|
+
var GAS_PRICE_SAFETY_MARGIN_BPS = 2000n;
|
|
6112
6120
|
var NON_EVM_FIXED_NATIVE_GAS_COST = {
|
|
6113
|
-
[101 /* Sui */]: 20000000n
|
|
6114
|
-
[7565164 /* Solana */]: 200000n
|
|
6121
|
+
[101 /* Sui */]: 20000000n
|
|
6115
6122
|
};
|
|
6123
|
+
var SOLANA_CREATE_ATA_COST = 2050000n;
|
|
6124
|
+
var SOLANA_CREATE_EMPTY_ACC_COST = 890880n;
|
|
6125
|
+
var SOLANA_JITO_TIP = 500000n;
|
|
6126
|
+
var SOLANA_BASE_TX_COST = 200000n;
|
|
6127
|
+
var SOLANA_CLAIM_TOKENS_COST = 300000n;
|
|
6128
|
+
var SOLANA_START_WITHOUT_SWAP_COST = 300000n;
|
|
6116
6129
|
|
|
6117
6130
|
// src/utils/quote/pricing/gas.ts
|
|
6131
|
+
var EVM_GAS_LIMIT_BY_FLOW = {
|
|
6132
|
+
singleChain: EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
6133
|
+
crossChainSource: EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT,
|
|
6134
|
+
crossChainSourceNoSwap: EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT,
|
|
6135
|
+
crossChainDest: EVM_CROSS_CHAIN_GAS_LIMIT
|
|
6136
|
+
};
|
|
6137
|
+
function padGasPrice(amount) {
|
|
6138
|
+
return amount * (10000n + GAS_PRICE_SAFETY_MARGIN_BPS) / 10000n;
|
|
6139
|
+
}
|
|
6140
|
+
function solanaNativeGasCost(flow, uniqueReceivers) {
|
|
6141
|
+
switch (flow) {
|
|
6142
|
+
case "crossChainSource":
|
|
6143
|
+
return padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP + SOLANA_CLAIM_TOKENS_COST);
|
|
6144
|
+
case "crossChainSourceNoSwap":
|
|
6145
|
+
return padGasPrice(SOLANA_START_WITHOUT_SWAP_COST + SOLANA_CLAIM_TOKENS_COST);
|
|
6146
|
+
case "crossChainDest":
|
|
6147
|
+
return SOLANA_CREATE_EMPTY_ACC_COST + SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) + padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP);
|
|
6148
|
+
case "singleChain":
|
|
6149
|
+
return SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) + padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP);
|
|
6150
|
+
}
|
|
6151
|
+
}
|
|
6118
6152
|
async function getNativeGasCost(params) {
|
|
6119
|
-
const { chainId,
|
|
6153
|
+
const { chainId, flow = "singleChain", uniqueReceivers = 1, rpcProviderUrl } = params;
|
|
6120
6154
|
if (isEvmChain(chainId)) {
|
|
6121
6155
|
const client = ChainProvider.getClient(chainId, rpcProviderUrl);
|
|
6122
6156
|
const gasPrice = await getGasPrice(client);
|
|
6123
|
-
return
|
|
6157
|
+
return padGasPrice(EVM_GAS_LIMIT_BY_FLOW[flow] * gasPrice);
|
|
6158
|
+
}
|
|
6159
|
+
if (chainId === 7565164 /* Solana */) {
|
|
6160
|
+
return solanaNativeGasCost(flow, uniqueReceivers);
|
|
6124
6161
|
}
|
|
6125
6162
|
const fixed = NON_EVM_FIXED_NATIVE_GAS_COST[chainId];
|
|
6126
6163
|
if (fixed === void 0) {
|
|
@@ -6129,51 +6166,142 @@ async function getNativeGasCost(params) {
|
|
|
6129
6166
|
return fixed;
|
|
6130
6167
|
}
|
|
6131
6168
|
|
|
6169
|
+
// src/utils/quote/pricing/limit-amount.ts
|
|
6170
|
+
function slippageDiff(amountQuote) {
|
|
6171
|
+
return (amountQuote * SOLVER_DEFAULT_SLIPPAGE_BPS + 9999n) / 10000n;
|
|
6172
|
+
}
|
|
6173
|
+
function exactInLimitAmount(amountQuote) {
|
|
6174
|
+
return amountQuote - slippageDiff(amountQuote);
|
|
6175
|
+
}
|
|
6176
|
+
function exactOutLimitAmount(amountQuote) {
|
|
6177
|
+
return amountQuote + slippageDiff(amountQuote);
|
|
6178
|
+
}
|
|
6179
|
+
|
|
6132
6180
|
// src/utils/quote/pricing/expenses.ts
|
|
6133
6181
|
function nativeTokenAddressForChain(chainId) {
|
|
6134
6182
|
if (chainId === 7565164 /* Solana */) return NATIVE_SOLANA_TOKEN_ADDRESS;
|
|
6135
6183
|
if (chainId === 101 /* Sui */) return NATIVE_SUI_TOKEN_ADDRESS;
|
|
6136
6184
|
return NATIVE_EVM_ETH_ADDRESSES[0];
|
|
6137
6185
|
}
|
|
6138
|
-
function
|
|
6139
|
-
if (chainId === 7565164 /* Solana */)
|
|
6140
|
-
|
|
6141
|
-
|
|
6186
|
+
function isNativeOrWrappedNative(chainId, address9) {
|
|
6187
|
+
if (chainId === 7565164 /* Solana */) {
|
|
6188
|
+
return compareAddresses(address9, NATIVE_SOLANA_TOKEN_ADDRESS) || compareAddresses(address9, WRAPPED_SOL_MINT_ADDRESS);
|
|
6189
|
+
}
|
|
6190
|
+
if (chainId === 101 /* Sui */) return compareAddresses(address9, NATIVE_SUI_TOKEN_ADDRESS);
|
|
6191
|
+
return isNativeEvmToken(address9) || compareAddresses(address9, WRAPPED_ETH_ADDRESSES[chainId]);
|
|
6142
6192
|
}
|
|
6143
6193
|
async function estimateExpensesInTokenOut(params) {
|
|
6144
|
-
const { chainId, tokenOut,
|
|
6145
|
-
const
|
|
6146
|
-
const
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6194
|
+
const { chainId, tokenOut, getQuote, extraTransfers, protocolFeeInTokenOut, flow, rpcProviderUrl } = params;
|
|
6195
|
+
const padDirectAmounts = (flow ?? "singleChain") === "singleChain";
|
|
6196
|
+
const padDirect = (amount) => padDirectAmounts ? exactOutLimitAmount(amount) : amount;
|
|
6197
|
+
const extraTransfersPromise = Promise.all(
|
|
6198
|
+
(extraTransfers ?? []).map(
|
|
6199
|
+
(transfer) => compareAddresses(transfer.token, tokenOut) ? Promise.resolve(padDirect(transfer.amount)) : getQuote({ chainId, amount: transfer.amount, tokenIn: transfer.token, tokenOut }).then(
|
|
6200
|
+
(q) => exactOutLimitAmount(q.amountOut)
|
|
6201
|
+
)
|
|
6202
|
+
)
|
|
6203
|
+
);
|
|
6204
|
+
extraTransfersPromise.catch(() => {
|
|
6205
|
+
});
|
|
6206
|
+
const uniqueReceivers = 1 + (extraTransfers?.length ?? 0);
|
|
6207
|
+
const nativeGasCost = await getNativeGasCost({ chainId, flow, uniqueReceivers, rpcProviderUrl });
|
|
6208
|
+
const gasInTokenOut = exactOutLimitAmount(
|
|
6209
|
+
isNativeOrWrappedNative(chainId, tokenOut) || nativeGasCost === 0n ? nativeGasCost : (await getQuote({
|
|
6210
|
+
chainId,
|
|
6211
|
+
amount: nativeGasCost,
|
|
6212
|
+
tokenIn: nativeTokenAddressForChain(chainId),
|
|
6213
|
+
tokenOut
|
|
6214
|
+
})).amountOut
|
|
6215
|
+
);
|
|
6216
|
+
const extraTransferAmounts = await extraTransfersPromise;
|
|
6217
|
+
const extraTransfersInTokenOut = extraTransferAmounts.reduce((sum, amount) => sum + amount, 0n);
|
|
6218
|
+
return {
|
|
6219
|
+
gasInTokenOut,
|
|
6220
|
+
protocolFeeInTokenOut: padDirect(protocolFeeInTokenOut ?? 0n),
|
|
6221
|
+
extraTransfersInTokenOut
|
|
6222
|
+
};
|
|
6153
6223
|
}
|
|
6154
6224
|
|
|
6155
6225
|
// src/utils/quote/aggregator.ts
|
|
6156
6226
|
var QuoteProvider = class _QuoteProvider {
|
|
6227
|
+
/**
|
|
6228
|
+
* Gross cross-chain quote: two nominal swap legs joined by the bridge stablecoin,
|
|
6229
|
+
* with no solver expense model (no gas, commission or amount_limit haircuts).
|
|
6230
|
+
* For the amount the solver will actually accept as amountOutMin, use
|
|
6231
|
+
* getCrossChainNetQuote instead.
|
|
6232
|
+
*/
|
|
6157
6233
|
static async getQuote(params) {
|
|
6158
6234
|
try {
|
|
6159
|
-
|
|
6160
|
-
return {
|
|
6161
|
-
...quote,
|
|
6162
|
-
tokenIn: {
|
|
6163
|
-
address: params.tokenIn,
|
|
6164
|
-
chainId: params.sourceChainId
|
|
6165
|
-
},
|
|
6166
|
-
tokenOut: {
|
|
6167
|
-
address: params.tokenOut,
|
|
6168
|
-
chainId: params.destChainId
|
|
6169
|
-
}
|
|
6170
|
-
};
|
|
6235
|
+
return this.adaptQuoteResponse(await this.getGrossQuoteFromRouters(params), params);
|
|
6171
6236
|
} catch (e) {
|
|
6172
|
-
if (e instanceof IntentNotViableError) throw e;
|
|
6173
6237
|
console.error("Error getting quote from routers:", e);
|
|
6174
6238
|
throw new Error("Failed to get quote from routers");
|
|
6175
6239
|
}
|
|
6176
6240
|
}
|
|
6241
|
+
/**
|
|
6242
|
+
* Net cross-chain quote mirroring the solver's estimation exactly: swap legs credited
|
|
6243
|
+
* at amount_limit, source/dest gas, commission and extra transfers subtracted from the
|
|
6244
|
+
* bridged stablecoin amount. estimatedAmountOutReduced is the max amountOutMin the
|
|
6245
|
+
* solver will accept; throws IntentNotViableError when expenses exceed a leg.
|
|
6246
|
+
*/
|
|
6247
|
+
static async getCrossChainNetQuote(params) {
|
|
6248
|
+
try {
|
|
6249
|
+
return this.adaptQuoteResponse(await this.getNetQuoteFromRouters(params), params);
|
|
6250
|
+
} catch (e) {
|
|
6251
|
+
if (e instanceof IntentNotViableError) throw e;
|
|
6252
|
+
console.error("Error getting net quote from routers:", e);
|
|
6253
|
+
throw new Error("Failed to get net quote from routers");
|
|
6254
|
+
}
|
|
6255
|
+
}
|
|
6256
|
+
/** Adds the tokenIn/tokenOut metadata fields QuoteResponse carries on top of the internal shape. */
|
|
6257
|
+
static adaptQuoteResponse(quote, params) {
|
|
6258
|
+
return {
|
|
6259
|
+
...quote,
|
|
6260
|
+
tokenIn: {
|
|
6261
|
+
address: params.tokenIn,
|
|
6262
|
+
chainId: params.sourceChainId
|
|
6263
|
+
},
|
|
6264
|
+
tokenOut: {
|
|
6265
|
+
address: params.tokenOut,
|
|
6266
|
+
chainId: params.destChainId
|
|
6267
|
+
}
|
|
6268
|
+
};
|
|
6269
|
+
}
|
|
6270
|
+
/**
|
|
6271
|
+
* The pre-solver-parity quote path: nominal source leg, decimal-normalized bridge,
|
|
6272
|
+
* nominal dest leg. estimatedAmountOutReduced only reflects the dest provider's own
|
|
6273
|
+
* amountOutMin when it reports one.
|
|
6274
|
+
*/
|
|
6275
|
+
static async getGrossQuoteFromRouters(params) {
|
|
6276
|
+
const sourceStable = getStableForChain(params.sourceChainId);
|
|
6277
|
+
const destStable = getStableForChain(params.destChainId);
|
|
6278
|
+
const sourceQuote = await this.getSingleChainQuote({
|
|
6279
|
+
chainId: params.sourceChainId,
|
|
6280
|
+
amount: params.amount,
|
|
6281
|
+
tokenIn: params.tokenIn,
|
|
6282
|
+
tokenOut: sourceStable.address,
|
|
6283
|
+
slippageBps: params.slippageBps
|
|
6284
|
+
});
|
|
6285
|
+
const normalizedBridgeAmount = convertDecimals(sourceQuote.amountOut, sourceStable.decimals, destStable.decimals);
|
|
6286
|
+
const destQuote = await this.getSingleChainQuote({
|
|
6287
|
+
chainId: params.destChainId,
|
|
6288
|
+
amount: normalizedBridgeAmount,
|
|
6289
|
+
tokenIn: destStable.address,
|
|
6290
|
+
tokenOut: params.tokenOut,
|
|
6291
|
+
slippageBps: params.slippageBps
|
|
6292
|
+
});
|
|
6293
|
+
const estimatedAmountInAsMinStablecoinAmount = BigInt(
|
|
6294
|
+
Math.floor(sourceQuote.amountInUsd * 10 ** sourceStable.decimals)
|
|
6295
|
+
);
|
|
6296
|
+
return {
|
|
6297
|
+
estimatedAmountOut: destQuote.amountOut,
|
|
6298
|
+
estimatedAmountOutUsd: destQuote.amountOutUsd,
|
|
6299
|
+
amountInUsd: sourceQuote.amountInUsd,
|
|
6300
|
+
estimatedAmountInAsMinStablecoinAmount,
|
|
6301
|
+
estimatedAmountOutReduced: destQuote.amountOutMin || destQuote.amountOut,
|
|
6302
|
+
estimatedAmountOutUsdReduced: destQuote.amountOutUsd
|
|
6303
|
+
};
|
|
6304
|
+
}
|
|
6177
6305
|
/**
|
|
6178
6306
|
* Get a quote for Solana with explicit provider selection
|
|
6179
6307
|
* @param params - Quote parameters including provider preference
|
|
@@ -6190,46 +6318,56 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6190
6318
|
};
|
|
6191
6319
|
return this.getSingleChainQuote(singleChainParams);
|
|
6192
6320
|
}
|
|
6193
|
-
static async
|
|
6321
|
+
static async getNetQuoteFromRouters(params) {
|
|
6194
6322
|
const sourceStable = getStableForChain(params.sourceChainId);
|
|
6195
6323
|
const destStable = getStableForChain(params.destChainId);
|
|
6196
|
-
const
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6324
|
+
const getQuote = (p) => this.getSingleChainQuote(p);
|
|
6325
|
+
const sourceIsStable = compareAddresses(params.tokenIn, sourceStable.address);
|
|
6326
|
+
const destIsStable = compareAddresses(params.tokenOut, destStable.address);
|
|
6327
|
+
const [sourceQuote, sourceExpenses, destExpenses] = await Promise.all([
|
|
6328
|
+
// Step 1: source quote tokenIn -> source stablecoin
|
|
6329
|
+
this.getSingleChainQuote({
|
|
6330
|
+
chainId: params.sourceChainId,
|
|
6331
|
+
amount: params.amount,
|
|
6332
|
+
tokenIn: params.tokenIn,
|
|
6333
|
+
tokenOut: sourceStable.address,
|
|
6334
|
+
slippageBps: params.slippageBps ?? DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS
|
|
6335
|
+
}),
|
|
6336
|
+
// Step 2 input: source-chain gas valued in the source stablecoin. A stablecoin
|
|
6337
|
+
// token_in needs no source swap, so the solver charges start_without_swap gas.
|
|
6338
|
+
estimateExpensesInTokenOut({
|
|
6339
|
+
chainId: params.sourceChainId,
|
|
6340
|
+
tokenOut: sourceStable.address,
|
|
6341
|
+
getQuote,
|
|
6342
|
+
flow: sourceIsStable ? "crossChainSourceNoSwap" : "crossChainSource"
|
|
6343
|
+
}),
|
|
6344
|
+
// Step 4 input: dest gas + extra transfers valued in the dest stablecoin
|
|
6204
6345
|
estimateExpensesInTokenOut({
|
|
6205
6346
|
chainId: params.destChainId,
|
|
6206
|
-
tokenOut:
|
|
6207
|
-
|
|
6208
|
-
|
|
6347
|
+
tokenOut: destStable.address,
|
|
6348
|
+
getQuote,
|
|
6349
|
+
extraTransfers: params.extraTransfers,
|
|
6350
|
+
flow: "crossChainDest"
|
|
6209
6351
|
})
|
|
6210
6352
|
]);
|
|
6211
|
-
const
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
const destSingleChainQuoteParams = {
|
|
6217
|
-
chainId: params.destChainId,
|
|
6218
|
-
amount: normalizedBridgeAmount,
|
|
6219
|
-
tokenIn: destStable.address,
|
|
6220
|
-
tokenOut: params.tokenOut
|
|
6221
|
-
};
|
|
6222
|
-
const destQuote = await this.getSingleChainQuote(destSingleChainQuoteParams);
|
|
6223
|
-
const estimatedAmountInAsMinStablecoinAmount = BigInt(
|
|
6224
|
-
Math.floor(sourceQuote.amountInUsd * 10 ** sourceStable.decimals)
|
|
6225
|
-
);
|
|
6226
|
-
const swapOutput = destQuote.amountOutMin ?? destQuote.amountOut;
|
|
6227
|
-
const estimatedAmountOutReduced = estimateAmountOut(
|
|
6228
|
-
swapOutput,
|
|
6353
|
+
const sourceStableOut = sourceIsStable ? sourceQuote.amountOut : exactInLimitAmount(sourceQuote.amountOut);
|
|
6354
|
+
const sourceStableAfterGas = estimateAmountOut(sourceStableOut, 0n, sourceExpenses);
|
|
6355
|
+
const normalizedBridgeAmount = convertDecimals(sourceStableAfterGas, sourceStable.decimals, destStable.decimals);
|
|
6356
|
+
const bridgedNet = estimateAmountOut(
|
|
6357
|
+
normalizedBridgeAmount,
|
|
6229
6358
|
DEFAULT_COMMISSION_BPS,
|
|
6230
|
-
|
|
6359
|
+
destExpenses,
|
|
6231
6360
|
CROSS_CHAIN_COMMISSION_DENOMINATOR
|
|
6232
6361
|
);
|
|
6362
|
+
const destQuote = await this.getSingleChainQuote({
|
|
6363
|
+
chainId: params.destChainId,
|
|
6364
|
+
amount: bridgedNet,
|
|
6365
|
+
tokenIn: destStable.address,
|
|
6366
|
+
tokenOut: params.tokenOut,
|
|
6367
|
+
slippageBps: params.slippageBps ?? DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS
|
|
6368
|
+
});
|
|
6369
|
+
const estimatedAmountInAsMinStablecoinAmount = sourceStableOut;
|
|
6370
|
+
const estimatedAmountOutReduced = destIsStable ? destQuote.amountOut : exactInLimitAmount(destQuote.amountOut);
|
|
6233
6371
|
return {
|
|
6234
6372
|
estimatedAmountOut: destQuote.amountOut,
|
|
6235
6373
|
estimatedAmountOutUsd: destQuote.amountOutUsd,
|
|
@@ -6240,12 +6378,12 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6240
6378
|
};
|
|
6241
6379
|
}
|
|
6242
6380
|
static async getSingleChainQuote(params) {
|
|
6243
|
-
if (
|
|
6381
|
+
if (compareAddresses(params.tokenIn, params.tokenOut)) {
|
|
6244
6382
|
let amountUsd = 0;
|
|
6245
6383
|
const stable = getStableForChain(params.chainId);
|
|
6246
6384
|
const stableAddress = stable.address;
|
|
6247
6385
|
const stableDecimals = stable.decimals;
|
|
6248
|
-
if (
|
|
6386
|
+
if (compareAddresses(params.tokenIn, stableAddress)) {
|
|
6249
6387
|
amountUsd = Number(params.amount) / 10 ** stableDecimals;
|
|
6250
6388
|
}
|
|
6251
6389
|
return {
|
|
@@ -6304,6 +6442,22 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6304
6442
|
}
|
|
6305
6443
|
throw new Error(`Unsupported chain for quote: ${params.chainId}`);
|
|
6306
6444
|
}
|
|
6445
|
+
static async getSingleChainNetQuote(params) {
|
|
6446
|
+
const [quote, expenses] = await Promise.all([
|
|
6447
|
+
this.getSingleChainQuote(params),
|
|
6448
|
+
estimateExpensesInTokenOut({
|
|
6449
|
+
chainId: params.chainId,
|
|
6450
|
+
tokenOut: params.tokenOut,
|
|
6451
|
+
getQuote: (p) => this.getSingleChainQuote(p),
|
|
6452
|
+
extraTransfers: params.extraTransfers,
|
|
6453
|
+
protocolFeeInTokenOut: params.protocolFeeInTokenOut,
|
|
6454
|
+
flow: "singleChain"
|
|
6455
|
+
})
|
|
6456
|
+
]);
|
|
6457
|
+
const swapOutput = exactInLimitAmount(quote.amountOut);
|
|
6458
|
+
const netAmountOut = estimateAmountOut(swapOutput, DEFAULT_COMMISSION_BPS, expenses, SINGLE_CHAIN_COMMISSION_DENOMINATOR);
|
|
6459
|
+
return { quote, netAmountOut, expenses };
|
|
6460
|
+
}
|
|
6307
6461
|
static transformLiquidSwapQuote(liquidSwapQuote) {
|
|
6308
6462
|
return {
|
|
6309
6463
|
amountIn: liquidSwapQuote.execution.details.amountIn,
|
|
@@ -6348,8 +6502,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6348
6502
|
tokenIn: params.tokenIn,
|
|
6349
6503
|
tokenOut: params.tokenOut,
|
|
6350
6504
|
swapMode: "ExactIn",
|
|
6351
|
-
slippageBps: params.slippageBps ? params.slippageBps :
|
|
6352
|
-
// Default 0.2% slippage
|
|
6505
|
+
slippageBps: params.slippageBps ? params.slippageBps : DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6353
6506
|
});
|
|
6354
6507
|
}
|
|
6355
6508
|
static async getParaswapQuote(params) {
|
|
@@ -6384,8 +6537,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6384
6537
|
inputMint: params.tokenIn,
|
|
6385
6538
|
outputMint: params.tokenOut,
|
|
6386
6539
|
amount: params.amount.toString(),
|
|
6387
|
-
slippageBps: params.slippageBps ||
|
|
6388
|
-
// Default 0.2% slippage
|
|
6540
|
+
slippageBps: params.slippageBps || DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6389
6541
|
};
|
|
6390
6542
|
try {
|
|
6391
6543
|
return this.transformRaydiumQuote(await raydiumQuoter.getQuote(request));
|
|
@@ -6400,8 +6552,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6400
6552
|
inputMint: params.tokenIn,
|
|
6401
6553
|
outputMint: params.tokenOut,
|
|
6402
6554
|
amount: params.amount.toString(),
|
|
6403
|
-
slippageBps: params.slippageBps ||
|
|
6404
|
-
// Default 0.2% slippage
|
|
6555
|
+
slippageBps: params.slippageBps || DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6405
6556
|
};
|
|
6406
6557
|
return simpleQuoteToQuote(await pumpfunQuoter.getQuote(request), "pumpfun");
|
|
6407
6558
|
}
|
|
@@ -6414,9 +6565,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6414
6565
|
const stableAddress = stable.address;
|
|
6415
6566
|
const stableDecimals = stable.decimals;
|
|
6416
6567
|
let amountUsd = 0;
|
|
6417
|
-
if (
|
|
6568
|
+
if (compareAddresses(request.tokenIn, stableAddress)) {
|
|
6418
6569
|
amountUsd = Number(quote.coinIn.amount) / 10 ** stableDecimals;
|
|
6419
|
-
} else if (
|
|
6570
|
+
} else if (compareAddresses(request.tokenOut, stableAddress)) {
|
|
6420
6571
|
amountUsd = Number(quote.coinOut.amount) / 10 ** stableDecimals;
|
|
6421
6572
|
}
|
|
6422
6573
|
return {
|
|
@@ -6485,9 +6636,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6485
6636
|
const stableDecimals = stable.decimals;
|
|
6486
6637
|
let amountUsd = 0;
|
|
6487
6638
|
const priceImpact = quote.priceImpactPct ? Number(quote.priceImpactPct) * 100 : 0;
|
|
6488
|
-
if (
|
|
6639
|
+
if (compareAddresses(quote.outputMint, stableAddress)) {
|
|
6489
6640
|
amountUsd = amountOut / 10 ** stableDecimals;
|
|
6490
|
-
} else if (
|
|
6641
|
+
} else if (compareAddresses(quote.inputMint, stableAddress)) {
|
|
6491
6642
|
amountUsd = amountIn / 10 ** stableDecimals;
|
|
6492
6643
|
}
|
|
6493
6644
|
return {
|
|
@@ -6511,9 +6662,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6511
6662
|
const stableDecimals = stable.decimals;
|
|
6512
6663
|
let amountUsd = 0;
|
|
6513
6664
|
const priceImpact = Number(raydiumQuote.data.priceImpactPct) * 100;
|
|
6514
|
-
if (
|
|
6665
|
+
if (compareAddresses(raydiumQuote.data.outputMint, stableAddress)) {
|
|
6515
6666
|
amountUsd = Number(amountOut) / 10 ** stableDecimals;
|
|
6516
|
-
} else if (
|
|
6667
|
+
} else if (compareAddresses(raydiumQuote.data.inputMint, stableAddress)) {
|
|
6517
6668
|
amountUsd = Number(amountIn) / 10 ** stableDecimals;
|
|
6518
6669
|
}
|
|
6519
6670
|
return {
|
|
@@ -6666,12 +6817,14 @@ var CrossChainOrder = class _CrossChainOrder {
|
|
|
6666
6817
|
};
|
|
6667
6818
|
}
|
|
6668
6819
|
if (!minStablecoinAmount || !destinationTokenMinAmount) {
|
|
6669
|
-
const quote = await QuoteProvider.
|
|
6820
|
+
const quote = await QuoteProvider.getCrossChainNetQuote({
|
|
6670
6821
|
sourceChainId: input.sourceChainId,
|
|
6671
6822
|
tokenIn: input.sourceTokenAddress,
|
|
6672
6823
|
amount: input.sourceTokenAmount,
|
|
6673
6824
|
destChainId: input.destinationChainId,
|
|
6674
|
-
tokenOut: input.destinationTokenAddress
|
|
6825
|
+
tokenOut: input.destinationTokenAddress,
|
|
6826
|
+
extraTransfers: input.extraTransfers,
|
|
6827
|
+
slippageBps: input.slippageBps
|
|
6675
6828
|
});
|
|
6676
6829
|
return {
|
|
6677
6830
|
destinationTokenMinAmount: quote.estimatedAmountOutReduced,
|
|
@@ -6878,22 +7031,15 @@ var SingleChainOrder = class _SingleChainOrder {
|
|
|
6878
7031
|
});
|
|
6879
7032
|
switch (scenario) {
|
|
6880
7033
|
case "QUOTE_REQUIRED": {
|
|
6881
|
-
const
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
tokenOut: input.tokenOut,
|
|
6891
|
-
gasLimit: EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
6892
|
-
getQuote: (p) => QuoteProvider.getSingleChainQuote(p)
|
|
6893
|
-
})
|
|
6894
|
-
]);
|
|
6895
|
-
const swapOutput = quote.amountOutMin ?? quote.amountOut;
|
|
6896
|
-
return estimateAmountOut(swapOutput, DEFAULT_COMMISSION_BPS, expenses, SINGLE_CHAIN_COMMISSION_DENOMINATOR);
|
|
7034
|
+
const { netAmountOut } = await QuoteProvider.getSingleChainNetQuote({
|
|
7035
|
+
chainId: input.chainId,
|
|
7036
|
+
amount: input.amountIn,
|
|
7037
|
+
tokenIn: input.tokenIn,
|
|
7038
|
+
tokenOut: input.tokenOut,
|
|
7039
|
+
extraTransfers: input.extraTransfers,
|
|
7040
|
+
slippageBps: input.slippageBps
|
|
7041
|
+
});
|
|
7042
|
+
return netAmountOut;
|
|
6897
7043
|
}
|
|
6898
7044
|
case "USE_PROVIDED_AMOUNT":
|
|
6899
7045
|
return amountOutMin;
|
|
@@ -9159,6 +9305,7 @@ export {
|
|
|
9159
9305
|
EVMSDK,
|
|
9160
9306
|
EVM_ZERO_ADDRESS,
|
|
9161
9307
|
EVM_ZERO_SIGNATURE,
|
|
9308
|
+
IntentNotViableError,
|
|
9162
9309
|
IntentsOrderType,
|
|
9163
9310
|
MAX_UINT_128,
|
|
9164
9311
|
MAX_UINT_256,
|