@shogun-sdk/intents-sdk 1.4.2 → 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 +246 -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 +246 -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/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
|
@@ -1,23 +1,88 @@
|
|
|
1
1
|
import { getGasPrice } from 'viem/actions';
|
|
2
|
-
import { isEvmChain, type SupportedChain } from '../../../chains.js';
|
|
2
|
+
import { ChainID, isEvmChain, type SupportedChain } from '../../../chains.js';
|
|
3
3
|
import { ChainProvider } from '../../../core/evm/chain-provider.js';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
EVM_CROSS_CHAIN_GAS_LIMIT,
|
|
6
|
+
EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT,
|
|
7
|
+
EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT,
|
|
8
|
+
EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
9
|
+
GAS_PRICE_SAFETY_MARGIN_BPS,
|
|
10
|
+
NON_EVM_FIXED_NATIVE_GAS_COST,
|
|
11
|
+
SOLANA_BASE_TX_COST,
|
|
12
|
+
SOLANA_CLAIM_TOKENS_COST,
|
|
13
|
+
SOLANA_CREATE_ATA_COST,
|
|
14
|
+
SOLANA_CREATE_EMPTY_ACC_COST,
|
|
15
|
+
SOLANA_JITO_TIP,
|
|
16
|
+
SOLANA_START_WITHOUT_SWAP_COST,
|
|
17
|
+
} from './constants.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Which solver execution the gas estimate models. crossChainSourceNoSwap is the source
|
|
21
|
+
* leg when token_in needs no swap into the stablecoin (start_order_execution_without_swap).
|
|
22
|
+
*/
|
|
23
|
+
export type GasFlow = 'singleChain' | 'crossChainSource' | 'crossChainSourceNoSwap' | 'crossChainDest';
|
|
24
|
+
|
|
25
|
+
/** EVM gas units per execution flow — pairs each flow with its solver gas limit in one place. */
|
|
26
|
+
const EVM_GAS_LIMIT_BY_FLOW: Record<GasFlow, bigint> = {
|
|
27
|
+
singleChain: EVM_SINGLE_CHAIN_GAS_LIMIT,
|
|
28
|
+
crossChainSource: EVM_CROSS_CHAIN_SOURCE_GAS_LIMIT,
|
|
29
|
+
crossChainSourceNoSwap: EVM_CROSS_CHAIN_SOURCE_NO_SWAP_GAS_LIMIT,
|
|
30
|
+
crossChainDest: EVM_CROSS_CHAIN_GAS_LIMIT,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** Pads the execution-price component of gas (fees/tips), never rent-exempt deposits. */
|
|
34
|
+
function padGasPrice(amount: bigint): bigint {
|
|
35
|
+
return (amount * (10_000n + GAS_PRICE_SAFETY_MARGIN_BPS)) / 10_000n;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Mirrors solver chains.rs Solana branches with gas_price = 1 (the solver's unwrap_or default).
|
|
40
|
+
* ATA creation scales with payout receivers; cross-chain adds the escrow PDA / claim legs.
|
|
41
|
+
* Only the transaction/tip component takes the safety margin — rent-exempt account
|
|
42
|
+
* creation (ATA, escrow PDA) is runtime-fixed and cannot drift.
|
|
43
|
+
*/
|
|
44
|
+
function solanaNativeGasCost(flow: GasFlow, uniqueReceivers: number): bigint {
|
|
45
|
+
switch (flow) {
|
|
46
|
+
case 'crossChainSource':
|
|
47
|
+
// start_order_execution_with_swap_cost + claim_tokens_cost (receivers do not apply)
|
|
48
|
+
return padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP + SOLANA_CLAIM_TOKENS_COST);
|
|
49
|
+
case 'crossChainSourceNoSwap':
|
|
50
|
+
// start_order_execution_without_swap_cost + claim_tokens_cost
|
|
51
|
+
return padGasPrice(SOLANA_START_WITHOUT_SWAP_COST + SOLANA_CLAIM_TOKENS_COST);
|
|
52
|
+
case 'crossChainDest':
|
|
53
|
+
// fulfill_cross_chain_order_cost
|
|
54
|
+
return (
|
|
55
|
+
SOLANA_CREATE_EMPTY_ACC_COST +
|
|
56
|
+
SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) +
|
|
57
|
+
padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP)
|
|
58
|
+
);
|
|
59
|
+
case 'singleChain':
|
|
60
|
+
// fulfill_single_chain_order_cost
|
|
61
|
+
return SOLANA_CREATE_ATA_COST * BigInt(uniqueReceivers) + padGasPrice(SOLANA_BASE_TX_COST + SOLANA_JITO_TIP);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
5
64
|
|
|
6
65
|
/**
|
|
7
66
|
* Gas cost in the chain's native smallest unit (wei / lamports / MIST).
|
|
8
|
-
* EVM: live gas price × gas limit.
|
|
67
|
+
* EVM: live gas price × the flow's gas limit. Solana: solver-mirrored per-flow formula.
|
|
68
|
+
* Other non-EVM: solver-mirrored fixed cost.
|
|
9
69
|
*/
|
|
10
70
|
export async function getNativeGasCost(params: {
|
|
11
71
|
chainId: SupportedChain;
|
|
12
|
-
|
|
72
|
+
flow?: GasFlow;
|
|
73
|
+
uniqueReceivers?: number;
|
|
13
74
|
rpcProviderUrl?: string;
|
|
14
75
|
}): Promise<bigint> {
|
|
15
|
-
const { chainId,
|
|
76
|
+
const { chainId, flow = 'singleChain', uniqueReceivers = 1, rpcProviderUrl } = params;
|
|
16
77
|
|
|
17
78
|
if (isEvmChain(chainId)) {
|
|
18
79
|
const client = ChainProvider.getClient(chainId, rpcProviderUrl);
|
|
19
80
|
const gasPrice = await getGasPrice(client);
|
|
20
|
-
return
|
|
81
|
+
return padGasPrice(EVM_GAS_LIMIT_BY_FLOW[flow] * gasPrice);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (chainId === ChainID.Solana) {
|
|
85
|
+
return solanaNativeGasCost(flow, uniqueReceivers);
|
|
21
86
|
}
|
|
22
87
|
|
|
23
88
|
const fixed = NON_EVM_FIXED_NATIVE_GAS_COST[chainId];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SOLVER_DEFAULT_SLIPPAGE_BPS } from './constants.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mirrors the solver's get_limit_amount (swap_estimator_rust/src/utils/limit_amount.rs)
|
|
5
|
+
* with Slippage::Percent(DEFAULT_SLIPPAGE): the diff is `mul_div(amount, slippage, base,
|
|
6
|
+
* round_up=true)` — always rounded UP — then subtracted for ExactIn (swap outputs are
|
|
7
|
+
* worst-cased down) or added for ExactOut (expense valuations are worst-cased up).
|
|
8
|
+
*/
|
|
9
|
+
function slippageDiff(amountQuote: bigint): bigint {
|
|
10
|
+
return (amountQuote * SOLVER_DEFAULT_SLIPPAGE_BPS + 9_999n) / 10_000n;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Swap output the solver actually credits: `amount_limit`, not the nominal quote. */
|
|
14
|
+
export function exactInLimitAmount(amountQuote: bigint): bigint {
|
|
15
|
+
return amountQuote - slippageDiff(amountQuote);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Expense valuation the solver actually charges: quote plus the rounded-up slippage diff. */
|
|
19
|
+
export function exactOutLimitAmount(amountQuote: bigint): bigint {
|
|
20
|
+
return amountQuote + slippageDiff(amountQuote);
|
|
21
|
+
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type LaunchpadPoolInfo,
|
|
11
11
|
} from '@raydium-io/raydium-sdk-v2';
|
|
12
12
|
import { type SimpleQuote } from './aggregator.js';
|
|
13
|
+
import { compareAddresses } from './address.js';
|
|
13
14
|
import { Connection, clusterApiUrl, PublicKey } from '@solana/web3.js'; // Used this package for raydium-sdk-v2 compatibility
|
|
14
15
|
import BN from 'bn.js';
|
|
15
16
|
import { Decimal } from 'decimal.js';
|
|
@@ -51,10 +52,6 @@ const platformConfigCache = new Map<
|
|
|
51
52
|
|
|
52
53
|
const mintInfoCache = new Map<string, Awaited<ReturnType<Raydium['token']['getTokenInfo']>>>();
|
|
53
54
|
|
|
54
|
-
// Local implementation of compareAddresses function
|
|
55
|
-
const compareAddresses = (firstAddress?: string, secondAddress?: string): boolean => {
|
|
56
|
-
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
57
|
-
};
|
|
58
55
|
|
|
59
56
|
const LAUNCHPAD_WHITELISTED_QUOTE_TOKENS = [
|
|
60
57
|
new PublicKey('So11111111111111111111111111111111111111112'), // WSOL
|