@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.cjs
CHANGED
|
@@ -399,6 +399,7 @@ __export(index_exports, {
|
|
|
399
399
|
EVMSDK: () => EVMSDK,
|
|
400
400
|
EVM_ZERO_ADDRESS: () => EVM_ZERO_ADDRESS,
|
|
401
401
|
EVM_ZERO_SIGNATURE: () => EVM_ZERO_SIGNATURE,
|
|
402
|
+
IntentNotViableError: () => IntentNotViableError,
|
|
402
403
|
IntentsOrderType: () => IntentsOrderType,
|
|
403
404
|
MAX_UINT_128: () => MAX_UINT_128,
|
|
404
405
|
MAX_UINT_256: () => MAX_UINT_256,
|
|
@@ -4790,6 +4791,9 @@ var ParaswapQuoteProvider = class {
|
|
|
4790
4791
|
}
|
|
4791
4792
|
async getQuote(paraswapParams) {
|
|
4792
4793
|
const params = { ...paraswapParams };
|
|
4794
|
+
if (isNativeEvmToken(params.srcToken)) {
|
|
4795
|
+
params.srcToken = WRAPPED_ETH_ADDRESSES[this.chainId];
|
|
4796
|
+
}
|
|
4793
4797
|
if (isNativeEvmToken(params.destToken)) {
|
|
4794
4798
|
params.destToken = WRAPPED_ETH_ADDRESSES[this.chainId];
|
|
4795
4799
|
}
|
|
@@ -4919,6 +4923,13 @@ var LiquidSwapQuoteProvider = class {
|
|
|
4919
4923
|
// src/utils/quote/raydium.ts
|
|
4920
4924
|
init_constants();
|
|
4921
4925
|
var import_raydium_sdk_v2 = require("@raydium-io/raydium-sdk-v2");
|
|
4926
|
+
|
|
4927
|
+
// src/utils/quote/address.ts
|
|
4928
|
+
function compareAddresses(firstAddress, secondAddress) {
|
|
4929
|
+
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
4930
|
+
}
|
|
4931
|
+
|
|
4932
|
+
// src/utils/quote/raydium.ts
|
|
4922
4933
|
var import_web32 = require("@solana/web3.js");
|
|
4923
4934
|
var import_bn2 = __toESM(require("bn.js"), 1);
|
|
4924
4935
|
var import_decimal = require("decimal.js");
|
|
@@ -4937,9 +4948,6 @@ var launchpadPoolCache = /* @__PURE__ */ new Map();
|
|
|
4937
4948
|
var launchpadPoolInfoCache = /* @__PURE__ */ new Map();
|
|
4938
4949
|
var platformConfigCache = /* @__PURE__ */ new Map();
|
|
4939
4950
|
var mintInfoCache = /* @__PURE__ */ new Map();
|
|
4940
|
-
var compareAddresses = (firstAddress, secondAddress) => {
|
|
4941
|
-
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
4942
|
-
};
|
|
4943
4951
|
var LAUNCHPAD_WHITELISTED_QUOTE_TOKENS = [
|
|
4944
4952
|
new import_web32.PublicKey("So11111111111111111111111111111111111111112"),
|
|
4945
4953
|
// WSOL
|
|
@@ -6021,33 +6029,63 @@ function estimateAmountOut(swapOutput, commissionBps, expenses, commissionDenomi
|
|
|
6021
6029
|
// src/utils/quote/pricing/expenses.ts
|
|
6022
6030
|
init_constants();
|
|
6023
6031
|
|
|
6024
|
-
// src/utils/quote/address.ts
|
|
6025
|
-
function compareAddresses2(firstAddress, secondAddress) {
|
|
6026
|
-
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
6027
|
-
}
|
|
6028
|
-
|
|
6029
6032
|
// src/utils/quote/pricing/gas.ts
|
|
6030
6033
|
var import_actions = require("viem/actions");
|
|
6031
6034
|
init_chains();
|
|
6032
6035
|
|
|
6033
6036
|
// src/utils/quote/pricing/constants.ts
|
|
6034
|
-
var DEFAULT_COMMISSION_BPS =
|
|
6037
|
+
var DEFAULT_COMMISSION_BPS = 0n;
|
|
6038
|
+
var SOLVER_DEFAULT_SLIPPAGE_BPS = 5n;
|
|
6039
|
+
var DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS = 50;
|
|
6040
|
+
var DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS = 25;
|
|
6035
6041
|
var SINGLE_CHAIN_COMMISSION_DENOMINATOR = 10000n;
|
|
6036
6042
|
var CROSS_CHAIN_COMMISSION_DENOMINATOR = 100000n;
|
|
6037
6043
|
var EVM_SINGLE_CHAIN_GAS_LIMIT = 3000000n;
|
|
6038
6044
|
var EVM_CROSS_CHAIN_GAS_LIMIT = 2000000n;
|
|
6045
|
+
var EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT = 1220000n;
|
|
6046
|
+
var EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT = 620000n;
|
|
6047
|
+
var GAS_PRICE_SAFETY_MARGIN_BPS = 2000n;
|
|
6039
6048
|
var NON_EVM_FIXED_NATIVE_GAS_COST = {
|
|
6040
|
-
[101 /* Sui */]: 20000000n
|
|
6041
|
-
[7565164 /* Solana */]: 200000n
|
|
6049
|
+
[101 /* Sui */]: 20000000n
|
|
6042
6050
|
};
|
|
6051
|
+
var SOLANA_CREATE_ATA_COST = 2050000n;
|
|
6052
|
+
var SOLANA_CREATE_EMPTY_ACC_COST = 890880n;
|
|
6053
|
+
var SOLANA_JITO_TIP = 500000n;
|
|
6054
|
+
var SOLANA_BASE_TX_COST = 200000n;
|
|
6055
|
+
var SOLANA_CLAIM_TOKENS_COST = 300000n;
|
|
6056
|
+
var SOLANA_START_WITHOUT_SWAP_COST = 300000n;
|
|
6043
6057
|
|
|
6044
6058
|
// src/utils/quote/pricing/gas.ts
|
|
6059
|
+
var EVM_GAS_LIMIT_BY_FLOW = {
|
|
6060
|
+
singleChain: EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
6061
|
+
crossChainSource: EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT,
|
|
6062
|
+
crossChainSourceNoSwap: EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT,
|
|
6063
|
+
crossChainDest: EVM_CROSS_CHAIN_GAS_LIMIT
|
|
6064
|
+
};
|
|
6065
|
+
function padGasPrice(amount) {
|
|
6066
|
+
return amount * (10000n + GAS_PRICE_SAFETY_MARGIN_BPS) / 10000n;
|
|
6067
|
+
}
|
|
6068
|
+
function solanaNativeGasCost(flow, uniqueReceivers) {
|
|
6069
|
+
switch (flow) {
|
|
6070
|
+
case "crossChainSource":
|
|
6071
|
+
return padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP + SOLANA_CLAIM_TOKENS_COST);
|
|
6072
|
+
case "crossChainSourceNoSwap":
|
|
6073
|
+
return padGasPrice(SOLANA_START_WITHOUT_SWAP_COST + SOLANA_CLAIM_TOKENS_COST);
|
|
6074
|
+
case "crossChainDest":
|
|
6075
|
+
return SOLANA_CREATE_EMPTY_ACC_COST + SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) + padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP);
|
|
6076
|
+
case "singleChain":
|
|
6077
|
+
return SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) + padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP);
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6045
6080
|
async function getNativeGasCost(params) {
|
|
6046
|
-
const { chainId,
|
|
6081
|
+
const { chainId, flow = "singleChain", uniqueReceivers = 1, rpcProviderUrl } = params;
|
|
6047
6082
|
if (isEvmChain(chainId)) {
|
|
6048
6083
|
const client = ChainProvider.getClient(chainId, rpcProviderUrl);
|
|
6049
6084
|
const gasPrice = await (0, import_actions.getGasPrice)(client);
|
|
6050
|
-
return
|
|
6085
|
+
return padGasPrice(EVM_GAS_LIMIT_BY_FLOW[flow] * gasPrice);
|
|
6086
|
+
}
|
|
6087
|
+
if (chainId === 7565164 /* Solana */) {
|
|
6088
|
+
return solanaNativeGasCost(flow, uniqueReceivers);
|
|
6051
6089
|
}
|
|
6052
6090
|
const fixed = NON_EVM_FIXED_NATIVE_GAS_COST[chainId];
|
|
6053
6091
|
if (fixed === void 0) {
|
|
@@ -6056,51 +6094,142 @@ async function getNativeGasCost(params) {
|
|
|
6056
6094
|
return fixed;
|
|
6057
6095
|
}
|
|
6058
6096
|
|
|
6097
|
+
// src/utils/quote/pricing/limit-amount.ts
|
|
6098
|
+
function slippageDiff(amountQuote) {
|
|
6099
|
+
return (amountQuote * SOLVER_DEFAULT_SLIPPAGE_BPS + 9999n) / 10000n;
|
|
6100
|
+
}
|
|
6101
|
+
function exactInLimitAmount(amountQuote) {
|
|
6102
|
+
return amountQuote - slippageDiff(amountQuote);
|
|
6103
|
+
}
|
|
6104
|
+
function exactOutLimitAmount(amountQuote) {
|
|
6105
|
+
return amountQuote + slippageDiff(amountQuote);
|
|
6106
|
+
}
|
|
6107
|
+
|
|
6059
6108
|
// src/utils/quote/pricing/expenses.ts
|
|
6060
6109
|
function nativeTokenAddressForChain(chainId) {
|
|
6061
6110
|
if (chainId === 7565164 /* Solana */) return NATIVE_SOLANA_TOKEN_ADDRESS;
|
|
6062
6111
|
if (chainId === 101 /* Sui */) return NATIVE_SUI_TOKEN_ADDRESS;
|
|
6063
6112
|
return NATIVE_EVM_ETH_ADDRESSES[0];
|
|
6064
6113
|
}
|
|
6065
|
-
function
|
|
6066
|
-
if (chainId === 7565164 /* Solana */)
|
|
6067
|
-
|
|
6068
|
-
|
|
6114
|
+
function isNativeOrWrappedNative(chainId, address9) {
|
|
6115
|
+
if (chainId === 7565164 /* Solana */) {
|
|
6116
|
+
return compareAddresses(address9, NATIVE_SOLANA_TOKEN_ADDRESS) || compareAddresses(address9, WRAPPED_SOL_MINT_ADDRESS);
|
|
6117
|
+
}
|
|
6118
|
+
if (chainId === 101 /* Sui */) return compareAddresses(address9, NATIVE_SUI_TOKEN_ADDRESS);
|
|
6119
|
+
return isNativeEvmToken(address9) || compareAddresses(address9, WRAPPED_ETH_ADDRESSES[chainId]);
|
|
6069
6120
|
}
|
|
6070
6121
|
async function estimateExpensesInTokenOut(params) {
|
|
6071
|
-
const { chainId, tokenOut,
|
|
6072
|
-
const
|
|
6073
|
-
const
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6122
|
+
const { chainId, tokenOut, getQuote, extraTransfers, protocolFeeInTokenOut, flow, rpcProviderUrl } = params;
|
|
6123
|
+
const padDirectAmounts = (flow ?? "singleChain") === "singleChain";
|
|
6124
|
+
const padDirect = (amount) => padDirectAmounts ? exactOutLimitAmount(amount) : amount;
|
|
6125
|
+
const extraTransfersPromise = Promise.all(
|
|
6126
|
+
(extraTransfers ?? []).map(
|
|
6127
|
+
(transfer) => compareAddresses(transfer.token, tokenOut) ? Promise.resolve(padDirect(transfer.amount)) : getQuote({ chainId, amount: transfer.amount, tokenIn: transfer.token, tokenOut }).then(
|
|
6128
|
+
(q) => exactOutLimitAmount(q.amountOut)
|
|
6129
|
+
)
|
|
6130
|
+
)
|
|
6131
|
+
);
|
|
6132
|
+
extraTransfersPromise.catch(() => {
|
|
6133
|
+
});
|
|
6134
|
+
const uniqueReceivers = 1 + (extraTransfers?.length ?? 0);
|
|
6135
|
+
const nativeGasCost = await getNativeGasCost({ chainId, flow, uniqueReceivers, rpcProviderUrl });
|
|
6136
|
+
const gasInTokenOut = exactOutLimitAmount(
|
|
6137
|
+
isNativeOrWrappedNative(chainId, tokenOut) || nativeGasCost === 0n ? nativeGasCost : (await getQuote({
|
|
6138
|
+
chainId,
|
|
6139
|
+
amount: nativeGasCost,
|
|
6140
|
+
tokenIn: nativeTokenAddressForChain(chainId),
|
|
6141
|
+
tokenOut
|
|
6142
|
+
})).amountOut
|
|
6143
|
+
);
|
|
6144
|
+
const extraTransferAmounts = await extraTransfersPromise;
|
|
6145
|
+
const extraTransfersInTokenOut = extraTransferAmounts.reduce((sum, amount) => sum + amount, 0n);
|
|
6146
|
+
return {
|
|
6147
|
+
gasInTokenOut,
|
|
6148
|
+
protocolFeeInTokenOut: padDirect(protocolFeeInTokenOut ?? 0n),
|
|
6149
|
+
extraTransfersInTokenOut
|
|
6150
|
+
};
|
|
6080
6151
|
}
|
|
6081
6152
|
|
|
6082
6153
|
// src/utils/quote/aggregator.ts
|
|
6083
6154
|
var QuoteProvider = class _QuoteProvider {
|
|
6155
|
+
/**
|
|
6156
|
+
* Gross cross-chain quote: two nominal swap legs joined by the bridge stablecoin,
|
|
6157
|
+
* with no solver expense model (no gas, commission or amount_limit haircuts).
|
|
6158
|
+
* For the amount the solver will actually accept as amountOutMin, use
|
|
6159
|
+
* getCrossChainNetQuote instead.
|
|
6160
|
+
*/
|
|
6084
6161
|
static async getQuote(params) {
|
|
6085
6162
|
try {
|
|
6086
|
-
|
|
6087
|
-
return {
|
|
6088
|
-
...quote,
|
|
6089
|
-
tokenIn: {
|
|
6090
|
-
address: params.tokenIn,
|
|
6091
|
-
chainId: params.sourceChainId
|
|
6092
|
-
},
|
|
6093
|
-
tokenOut: {
|
|
6094
|
-
address: params.tokenOut,
|
|
6095
|
-
chainId: params.destChainId
|
|
6096
|
-
}
|
|
6097
|
-
};
|
|
6163
|
+
return this.adaptQuoteResponse(await this.getGrossQuoteFromRouters(params), params);
|
|
6098
6164
|
} catch (e) {
|
|
6099
|
-
if (e instanceof IntentNotViableError) throw e;
|
|
6100
6165
|
console.error("Error getting quote from routers:", e);
|
|
6101
6166
|
throw new Error("Failed to get quote from routers");
|
|
6102
6167
|
}
|
|
6103
6168
|
}
|
|
6169
|
+
/**
|
|
6170
|
+
* Net cross-chain quote mirroring the solver's estimation exactly: swap legs credited
|
|
6171
|
+
* at amount_limit, source/dest gas, commission and extra transfers subtracted from the
|
|
6172
|
+
* bridged stablecoin amount. estimatedAmountOutReduced is the max amountOutMin the
|
|
6173
|
+
* solver will accept; throws IntentNotViableError when expenses exceed a leg.
|
|
6174
|
+
*/
|
|
6175
|
+
static async getCrossChainNetQuote(params) {
|
|
6176
|
+
try {
|
|
6177
|
+
return this.adaptQuoteResponse(await this.getNetQuoteFromRouters(params), params);
|
|
6178
|
+
} catch (e) {
|
|
6179
|
+
if (e instanceof IntentNotViableError) throw e;
|
|
6180
|
+
console.error("Error getting net quote from routers:", e);
|
|
6181
|
+
throw new Error("Failed to get net quote from routers");
|
|
6182
|
+
}
|
|
6183
|
+
}
|
|
6184
|
+
/** Adds the tokenIn/tokenOut metadata fields QuoteResponse carries on top of the internal shape. */
|
|
6185
|
+
static adaptQuoteResponse(quote, params) {
|
|
6186
|
+
return {
|
|
6187
|
+
...quote,
|
|
6188
|
+
tokenIn: {
|
|
6189
|
+
address: params.tokenIn,
|
|
6190
|
+
chainId: params.sourceChainId
|
|
6191
|
+
},
|
|
6192
|
+
tokenOut: {
|
|
6193
|
+
address: params.tokenOut,
|
|
6194
|
+
chainId: params.destChainId
|
|
6195
|
+
}
|
|
6196
|
+
};
|
|
6197
|
+
}
|
|
6198
|
+
/**
|
|
6199
|
+
* The pre-solver-parity quote path: nominal source leg, decimal-normalized bridge,
|
|
6200
|
+
* nominal dest leg. estimatedAmountOutReduced only reflects the dest provider's own
|
|
6201
|
+
* amountOutMin when it reports one.
|
|
6202
|
+
*/
|
|
6203
|
+
static async getGrossQuoteFromRouters(params) {
|
|
6204
|
+
const sourceStable = getStableForChain(params.sourceChainId);
|
|
6205
|
+
const destStable = getStableForChain(params.destChainId);
|
|
6206
|
+
const sourceQuote = await this.getSingleChainQuote({
|
|
6207
|
+
chainId: params.sourceChainId,
|
|
6208
|
+
amount: params.amount,
|
|
6209
|
+
tokenIn: params.tokenIn,
|
|
6210
|
+
tokenOut: sourceStable.address,
|
|
6211
|
+
slippageBps: params.slippageBps
|
|
6212
|
+
});
|
|
6213
|
+
const normalizedBridgeAmount = convertDecimals(sourceQuote.amountOut, sourceStable.decimals, destStable.decimals);
|
|
6214
|
+
const destQuote = await this.getSingleChainQuote({
|
|
6215
|
+
chainId: params.destChainId,
|
|
6216
|
+
amount: normalizedBridgeAmount,
|
|
6217
|
+
tokenIn: destStable.address,
|
|
6218
|
+
tokenOut: params.tokenOut,
|
|
6219
|
+
slippageBps: params.slippageBps
|
|
6220
|
+
});
|
|
6221
|
+
const estimatedAmountInAsMinStablecoinAmount = BigInt(
|
|
6222
|
+
Math.floor(sourceQuote.amountInUsd * 10 ** sourceStable.decimals)
|
|
6223
|
+
);
|
|
6224
|
+
return {
|
|
6225
|
+
estimatedAmountOut: destQuote.amountOut,
|
|
6226
|
+
estimatedAmountOutUsd: destQuote.amountOutUsd,
|
|
6227
|
+
amountInUsd: sourceQuote.amountInUsd,
|
|
6228
|
+
estimatedAmountInAsMinStablecoinAmount,
|
|
6229
|
+
estimatedAmountOutReduced: destQuote.amountOutMin || destQuote.amountOut,
|
|
6230
|
+
estimatedAmountOutUsdReduced: destQuote.amountOutUsd
|
|
6231
|
+
};
|
|
6232
|
+
}
|
|
6104
6233
|
/**
|
|
6105
6234
|
* Get a quote for Solana with explicit provider selection
|
|
6106
6235
|
* @param params - Quote parameters including provider preference
|
|
@@ -6117,46 +6246,56 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6117
6246
|
};
|
|
6118
6247
|
return this.getSingleChainQuote(singleChainParams);
|
|
6119
6248
|
}
|
|
6120
|
-
static async
|
|
6249
|
+
static async getNetQuoteFromRouters(params) {
|
|
6121
6250
|
const sourceStable = getStableForChain(params.sourceChainId);
|
|
6122
6251
|
const destStable = getStableForChain(params.destChainId);
|
|
6123
|
-
const
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6252
|
+
const getQuote = (p) => this.getSingleChainQuote(p);
|
|
6253
|
+
const sourceIsStable = compareAddresses(params.tokenIn, sourceStable.address);
|
|
6254
|
+
const destIsStable = compareAddresses(params.tokenOut, destStable.address);
|
|
6255
|
+
const [sourceQuote, sourceExpenses, destExpenses] = await Promise.all([
|
|
6256
|
+
// Step 1: source quote tokenIn -> source stablecoin
|
|
6257
|
+
this.getSingleChainQuote({
|
|
6258
|
+
chainId: params.sourceChainId,
|
|
6259
|
+
amount: params.amount,
|
|
6260
|
+
tokenIn: params.tokenIn,
|
|
6261
|
+
tokenOut: sourceStable.address,
|
|
6262
|
+
slippageBps: params.slippageBps ?? DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS
|
|
6263
|
+
}),
|
|
6264
|
+
// Step 2 input: source-chain gas valued in the source stablecoin. A stablecoin
|
|
6265
|
+
// token_in needs no source swap, so the solver charges start_without_swap gas.
|
|
6266
|
+
estimateExpensesInTokenOut({
|
|
6267
|
+
chainId: params.sourceChainId,
|
|
6268
|
+
tokenOut: sourceStable.address,
|
|
6269
|
+
getQuote,
|
|
6270
|
+
flow: sourceIsStable ? "crossChainSourceNoSwap" : "crossChainSource"
|
|
6271
|
+
}),
|
|
6272
|
+
// Step 4 input: dest gas + extra transfers valued in the dest stablecoin
|
|
6131
6273
|
estimateExpensesInTokenOut({
|
|
6132
6274
|
chainId: params.destChainId,
|
|
6133
|
-
tokenOut:
|
|
6134
|
-
|
|
6135
|
-
|
|
6275
|
+
tokenOut: destStable.address,
|
|
6276
|
+
getQuote,
|
|
6277
|
+
extraTransfers: params.extraTransfers,
|
|
6278
|
+
flow: "crossChainDest"
|
|
6136
6279
|
})
|
|
6137
6280
|
]);
|
|
6138
|
-
const
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
const destSingleChainQuoteParams = {
|
|
6144
|
-
chainId: params.destChainId,
|
|
6145
|
-
amount: normalizedBridgeAmount,
|
|
6146
|
-
tokenIn: destStable.address,
|
|
6147
|
-
tokenOut: params.tokenOut
|
|
6148
|
-
};
|
|
6149
|
-
const destQuote = await this.getSingleChainQuote(destSingleChainQuoteParams);
|
|
6150
|
-
const estimatedAmountInAsMinStablecoinAmount = BigInt(
|
|
6151
|
-
Math.floor(sourceQuote.amountInUsd * 10 ** sourceStable.decimals)
|
|
6152
|
-
);
|
|
6153
|
-
const swapOutput = destQuote.amountOutMin ?? destQuote.amountOut;
|
|
6154
|
-
const estimatedAmountOutReduced = estimateAmountOut(
|
|
6155
|
-
swapOutput,
|
|
6281
|
+
const sourceStableOut = sourceIsStable ? sourceQuote.amountOut : exactInLimitAmount(sourceQuote.amountOut);
|
|
6282
|
+
const sourceStableAfterGas = estimateAmountOut(sourceStableOut, 0n, sourceExpenses);
|
|
6283
|
+
const normalizedBridgeAmount = convertDecimals(sourceStableAfterGas, sourceStable.decimals, destStable.decimals);
|
|
6284
|
+
const bridgedNet = estimateAmountOut(
|
|
6285
|
+
normalizedBridgeAmount,
|
|
6156
6286
|
DEFAULT_COMMISSION_BPS,
|
|
6157
|
-
|
|
6287
|
+
destExpenses,
|
|
6158
6288
|
CROSS_CHAIN_COMMISSION_DENOMINATOR
|
|
6159
6289
|
);
|
|
6290
|
+
const destQuote = await this.getSingleChainQuote({
|
|
6291
|
+
chainId: params.destChainId,
|
|
6292
|
+
amount: bridgedNet,
|
|
6293
|
+
tokenIn: destStable.address,
|
|
6294
|
+
tokenOut: params.tokenOut,
|
|
6295
|
+
slippageBps: params.slippageBps ?? DEFAULT_CROSS_CHAIN_SLIPPAGE_BPS
|
|
6296
|
+
});
|
|
6297
|
+
const estimatedAmountInAsMinStablecoinAmount = sourceStableOut;
|
|
6298
|
+
const estimatedAmountOutReduced = destIsStable ? destQuote.amountOut : exactInLimitAmount(destQuote.amountOut);
|
|
6160
6299
|
return {
|
|
6161
6300
|
estimatedAmountOut: destQuote.amountOut,
|
|
6162
6301
|
estimatedAmountOutUsd: destQuote.amountOutUsd,
|
|
@@ -6167,12 +6306,12 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6167
6306
|
};
|
|
6168
6307
|
}
|
|
6169
6308
|
static async getSingleChainQuote(params) {
|
|
6170
|
-
if (
|
|
6309
|
+
if (compareAddresses(params.tokenIn, params.tokenOut)) {
|
|
6171
6310
|
let amountUsd = 0;
|
|
6172
6311
|
const stable = getStableForChain(params.chainId);
|
|
6173
6312
|
const stableAddress = stable.address;
|
|
6174
6313
|
const stableDecimals = stable.decimals;
|
|
6175
|
-
if (
|
|
6314
|
+
if (compareAddresses(params.tokenIn, stableAddress)) {
|
|
6176
6315
|
amountUsd = Number(params.amount) / 10 ** stableDecimals;
|
|
6177
6316
|
}
|
|
6178
6317
|
return {
|
|
@@ -6231,6 +6370,22 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6231
6370
|
}
|
|
6232
6371
|
throw new Error(`Unsupported chain for quote: ${params.chainId}`);
|
|
6233
6372
|
}
|
|
6373
|
+
static async getSingleChainNetQuote(params) {
|
|
6374
|
+
const [quote, expenses] = await Promise.all([
|
|
6375
|
+
this.getSingleChainQuote(params),
|
|
6376
|
+
estimateExpensesInTokenOut({
|
|
6377
|
+
chainId: params.chainId,
|
|
6378
|
+
tokenOut: params.tokenOut,
|
|
6379
|
+
getQuote: (p) => this.getSingleChainQuote(p),
|
|
6380
|
+
extraTransfers: params.extraTransfers,
|
|
6381
|
+
protocolFeeInTokenOut: params.protocolFeeInTokenOut,
|
|
6382
|
+
flow: "singleChain"
|
|
6383
|
+
})
|
|
6384
|
+
]);
|
|
6385
|
+
const swapOutput = exactInLimitAmount(quote.amountOut);
|
|
6386
|
+
const netAmountOut = estimateAmountOut(swapOutput, DEFAULT_COMMISSION_BPS, expenses, SINGLE_CHAIN_COMMISSION_DENOMINATOR);
|
|
6387
|
+
return { quote, netAmountOut, expenses };
|
|
6388
|
+
}
|
|
6234
6389
|
static transformLiquidSwapQuote(liquidSwapQuote) {
|
|
6235
6390
|
return {
|
|
6236
6391
|
amountIn: liquidSwapQuote.execution.details.amountIn,
|
|
@@ -6275,8 +6430,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6275
6430
|
tokenIn: params.tokenIn,
|
|
6276
6431
|
tokenOut: params.tokenOut,
|
|
6277
6432
|
swapMode: "ExactIn",
|
|
6278
|
-
slippageBps: params.slippageBps ? params.slippageBps :
|
|
6279
|
-
// Default 0.2% slippage
|
|
6433
|
+
slippageBps: params.slippageBps ? params.slippageBps : DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6280
6434
|
});
|
|
6281
6435
|
}
|
|
6282
6436
|
static async getParaswapQuote(params) {
|
|
@@ -6311,8 +6465,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6311
6465
|
inputMint: params.tokenIn,
|
|
6312
6466
|
outputMint: params.tokenOut,
|
|
6313
6467
|
amount: params.amount.toString(),
|
|
6314
|
-
slippageBps: params.slippageBps ||
|
|
6315
|
-
// Default 0.2% slippage
|
|
6468
|
+
slippageBps: params.slippageBps || DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6316
6469
|
};
|
|
6317
6470
|
try {
|
|
6318
6471
|
return this.transformRaydiumQuote(await raydiumQuoter.getQuote(request));
|
|
@@ -6327,8 +6480,7 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6327
6480
|
inputMint: params.tokenIn,
|
|
6328
6481
|
outputMint: params.tokenOut,
|
|
6329
6482
|
amount: params.amount.toString(),
|
|
6330
|
-
slippageBps: params.slippageBps ||
|
|
6331
|
-
// Default 0.2% slippage
|
|
6483
|
+
slippageBps: params.slippageBps || DEFAULT_SINGLE_CHAIN_SLIPPAGE_BPS
|
|
6332
6484
|
};
|
|
6333
6485
|
return simpleQuoteToQuote(await pumpfunQuoter.getQuote(request), "pumpfun");
|
|
6334
6486
|
}
|
|
@@ -6341,9 +6493,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6341
6493
|
const stableAddress = stable.address;
|
|
6342
6494
|
const stableDecimals = stable.decimals;
|
|
6343
6495
|
let amountUsd = 0;
|
|
6344
|
-
if (
|
|
6496
|
+
if (compareAddresses(request.tokenIn, stableAddress)) {
|
|
6345
6497
|
amountUsd = Number(quote.coinIn.amount) / 10 ** stableDecimals;
|
|
6346
|
-
} else if (
|
|
6498
|
+
} else if (compareAddresses(request.tokenOut, stableAddress)) {
|
|
6347
6499
|
amountUsd = Number(quote.coinOut.amount) / 10 ** stableDecimals;
|
|
6348
6500
|
}
|
|
6349
6501
|
return {
|
|
@@ -6412,9 +6564,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6412
6564
|
const stableDecimals = stable.decimals;
|
|
6413
6565
|
let amountUsd = 0;
|
|
6414
6566
|
const priceImpact = quote.priceImpactPct ? Number(quote.priceImpactPct) * 100 : 0;
|
|
6415
|
-
if (
|
|
6567
|
+
if (compareAddresses(quote.outputMint, stableAddress)) {
|
|
6416
6568
|
amountUsd = amountOut / 10 ** stableDecimals;
|
|
6417
|
-
} else if (
|
|
6569
|
+
} else if (compareAddresses(quote.inputMint, stableAddress)) {
|
|
6418
6570
|
amountUsd = amountIn / 10 ** stableDecimals;
|
|
6419
6571
|
}
|
|
6420
6572
|
return {
|
|
@@ -6438,9 +6590,9 @@ var QuoteProvider = class _QuoteProvider {
|
|
|
6438
6590
|
const stableDecimals = stable.decimals;
|
|
6439
6591
|
let amountUsd = 0;
|
|
6440
6592
|
const priceImpact = Number(raydiumQuote.data.priceImpactPct) * 100;
|
|
6441
|
-
if (
|
|
6593
|
+
if (compareAddresses(raydiumQuote.data.outputMint, stableAddress)) {
|
|
6442
6594
|
amountUsd = Number(amountOut) / 10 ** stableDecimals;
|
|
6443
|
-
} else if (
|
|
6595
|
+
} else if (compareAddresses(raydiumQuote.data.inputMint, stableAddress)) {
|
|
6444
6596
|
amountUsd = Number(amountIn) / 10 ** stableDecimals;
|
|
6445
6597
|
}
|
|
6446
6598
|
return {
|
|
@@ -6593,12 +6745,14 @@ var CrossChainOrder = class _CrossChainOrder {
|
|
|
6593
6745
|
};
|
|
6594
6746
|
}
|
|
6595
6747
|
if (!minStablecoinAmount || !destinationTokenMinAmount) {
|
|
6596
|
-
const quote = await QuoteProvider.
|
|
6748
|
+
const quote = await QuoteProvider.getCrossChainNetQuote({
|
|
6597
6749
|
sourceChainId: input.sourceChainId,
|
|
6598
6750
|
tokenIn: input.sourceTokenAddress,
|
|
6599
6751
|
amount: input.sourceTokenAmount,
|
|
6600
6752
|
destChainId: input.destinationChainId,
|
|
6601
|
-
tokenOut: input.destinationTokenAddress
|
|
6753
|
+
tokenOut: input.destinationTokenAddress,
|
|
6754
|
+
extraTransfers: input.extraTransfers,
|
|
6755
|
+
slippageBps: input.slippageBps
|
|
6602
6756
|
});
|
|
6603
6757
|
return {
|
|
6604
6758
|
destinationTokenMinAmount: quote.estimatedAmountOutReduced,
|
|
@@ -6805,22 +6959,15 @@ var SingleChainOrder = class _SingleChainOrder {
|
|
|
6805
6959
|
});
|
|
6806
6960
|
switch (scenario) {
|
|
6807
6961
|
case "QUOTE_REQUIRED": {
|
|
6808
|
-
const
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
tokenOut: input.tokenOut,
|
|
6818
|
-
gasLimit: EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
6819
|
-
getQuote: (p) => QuoteProvider.getSingleChainQuote(p)
|
|
6820
|
-
})
|
|
6821
|
-
]);
|
|
6822
|
-
const swapOutput = quote.amountOutMin ?? quote.amountOut;
|
|
6823
|
-
return estimateAmountOut(swapOutput, DEFAULT_COMMISSION_BPS, expenses, SINGLE_CHAIN_COMMISSION_DENOMINATOR);
|
|
6962
|
+
const { netAmountOut } = await QuoteProvider.getSingleChainNetQuote({
|
|
6963
|
+
chainId: input.chainId,
|
|
6964
|
+
amount: input.amountIn,
|
|
6965
|
+
tokenIn: input.tokenIn,
|
|
6966
|
+
tokenOut: input.tokenOut,
|
|
6967
|
+
extraTransfers: input.extraTransfers,
|
|
6968
|
+
slippageBps: input.slippageBps
|
|
6969
|
+
});
|
|
6970
|
+
return netAmountOut;
|
|
6824
6971
|
}
|
|
6825
6972
|
case "USE_PROVIDED_AMOUNT":
|
|
6826
6973
|
return amountOutMin;
|