@shogun-sdk/intents-sdk 1.2.6-test.14 → 1.2.6-test.16
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 +277 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -22
- package/dist/index.d.ts +109 -22
- package/dist/index.js +277 -99
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/src/auth/siwe.ts +10 -11
- package/src/constants.ts +32 -8
- package/src/core/evm/intent-helpers.ts +131 -8
- package/src/core/evm/intent-provider.ts +5 -4
- package/src/core/evm/permit2.ts +36 -0
- package/src/core/orders/api/fetch.ts +12 -39
- package/src/core/orders/cross-chain.ts +3 -0
- package/src/core/orders/single-chain.ts +21 -8
- package/src/core/sdk.ts +12 -6
- package/src/core/solana/intent-helpers.ts +6 -4
- package/src/core/sui/intent-helpers.ts +4 -1
- package/src/index.ts +4 -0
- package/src/types/api.ts +14 -3
- package/src/types/intent.ts +36 -2
- package/src/utils/base-validator.ts +0 -4
- package/src/utils/generate-execution-details-hash.ts +9 -32
- package/src/utils/quote/address.ts +4 -0
- package/src/utils/quote/aggregator.ts +29 -9
- package/src/utils/quote/pricing/constants.ts +33 -0
- package/src/utils/quote/pricing/decimals.ts +11 -0
- package/src/utils/quote/pricing/estimate-amount-out.ts +36 -0
- package/src/utils/quote/pricing/expenses.ts +62 -0
- package/src/utils/quote/pricing/gas.ts +28 -0
package/src/types/intent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SupportedChain } from '../chains.js';
|
|
2
2
|
import type { CrossChainOrder } from '../core/orders/cross-chain.js';
|
|
3
|
-
import type { ExtraTransfer } from '../core/orders/common.js';
|
|
3
|
+
import type { ExtraTransfer, StopLossType } from '../core/orders/common.js';
|
|
4
4
|
import type { SingleChainOrder } from '../core/orders/single-chain.js';
|
|
5
5
|
import type { DcaSingleChainOrder } from '../core/orders/dca-single-chain.js';
|
|
6
6
|
|
|
@@ -20,7 +20,11 @@ export type ExecutionDetails = {
|
|
|
20
20
|
/** Extra transfers to be made */
|
|
21
21
|
extraTransfers?: ExtraTransfer[];
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
/** Stop loss type, must match the auctioneer's `stopLossType` field */
|
|
24
|
+
stopLossType?: StopLossType;
|
|
25
|
+
/** Initial trigger price (tokenIn/tokenOut) that arms the stop loss */
|
|
26
|
+
stopLossTriggerPrice?: string;
|
|
27
|
+
/** Take profit minimum amount out */
|
|
24
28
|
takeProfitMinOut?: bigint;
|
|
25
29
|
};
|
|
26
30
|
|
|
@@ -96,6 +100,36 @@ export type SingleChainUserIntentRequest = {
|
|
|
96
100
|
};
|
|
97
101
|
};
|
|
98
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Source chain data for a cross-chain DCA order. Mirrors the auctioneer's
|
|
105
|
+
* `CrossChainDcaOrderGenericRequestData` (common cross-chain fields + flattened
|
|
106
|
+
* `CommonDcaOrderData`). The destination fields live in `executionDetails`.
|
|
107
|
+
*/
|
|
108
|
+
export type DcaCrossChainSourceChainData = {
|
|
109
|
+
user: string;
|
|
110
|
+
srcChainId: SupportedChain;
|
|
111
|
+
tokenIn: string;
|
|
112
|
+
minStablecoinsAmount: bigint;
|
|
113
|
+
deadline: number;
|
|
114
|
+
executionDetailsHash: ExecutionDetailsHash;
|
|
115
|
+
/** Flattened CommonDcaOrderData */
|
|
116
|
+
startTime: number;
|
|
117
|
+
amountInPerInterval: bigint;
|
|
118
|
+
totalIntervals: number;
|
|
119
|
+
intervalDuration: number;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type DcaCrossChainUserIntentRequest = {
|
|
123
|
+
genericData: DcaCrossChainSourceChainData;
|
|
124
|
+
/** JSON-stringified execution details for the destination chain */
|
|
125
|
+
executionDetails: string;
|
|
126
|
+
chainSpecificData: {
|
|
127
|
+
EVM?: DcaSingleChainEVMPreparedData;
|
|
128
|
+
Solana?: DcaSingleChainSolanaPreparedData;
|
|
129
|
+
Sui?: DcaSingleChainSuiPreparedData;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
99
133
|
export type ChainPreparedData = EvmPreparedData | SuiPreparedData | SolanaPreparedData;
|
|
100
134
|
|
|
101
135
|
export type CrossChainOrderPrepared = {
|
|
@@ -32,10 +32,6 @@ export abstract class BaseValidator implements IChainValidator {
|
|
|
32
32
|
this.validateAmount(order.amountIn);
|
|
33
33
|
this.validateAmount(order.amountOutMin ?? 1n);
|
|
34
34
|
|
|
35
|
-
if (order.stopLossMaxOut) {
|
|
36
|
-
this.validateAmount(order.stopLossMaxOut);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
35
|
if (order.takeProfitMinOut) {
|
|
40
36
|
this.validateAmount(order.takeProfitMinOut);
|
|
41
37
|
}
|
|
@@ -1,36 +1,13 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
-
import type { ExtraTransfer } from '../core/orders/common.js';
|
|
3
|
-
import { Parsers } from './parsers.js';
|
|
4
|
-
|
|
5
|
-
export function generateExecutionDetailsHash({
|
|
6
|
-
destChainId,
|
|
7
|
-
destinationAddress,
|
|
8
|
-
tokenOut,
|
|
9
|
-
amountOutMin,
|
|
10
|
-
stopLossMaxOut,
|
|
11
|
-
takeProfitMinOut,
|
|
12
|
-
extraTransfers,
|
|
13
|
-
}: {
|
|
14
|
-
destChainId: number;
|
|
15
|
-
destinationAddress: string;
|
|
16
|
-
tokenOut: string;
|
|
17
|
-
amountOutMin: string;
|
|
18
|
-
stopLossMaxOut?: string;
|
|
19
|
-
takeProfitMinOut?: string;
|
|
20
|
-
extraTransfers?: ExtraTransfer[];
|
|
21
|
-
}): string {
|
|
22
|
-
const executionDetails = JSON.stringify(
|
|
23
|
-
{
|
|
24
|
-
destChainId,
|
|
25
|
-
destinationAddress,
|
|
26
|
-
tokenOut,
|
|
27
|
-
amountOutMin,
|
|
28
|
-
stopLossMaxOut,
|
|
29
|
-
takeProfitMinOut,
|
|
30
|
-
extraTransfers,
|
|
31
|
-
},
|
|
32
|
-
Parsers.bigIntReplacer,
|
|
33
|
-
);
|
|
34
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Computes the SHA-256 hash the auctioneer expects for cross-chain execution details.
|
|
5
|
+
*
|
|
6
|
+
* The auctioneer recomputes sha256 over the exact `executionDetails` JSON string it
|
|
7
|
+
* receives and rejects the order when it differs (hash mismatch). Callers therefore MUST
|
|
8
|
+
* hash the same serialized string they send on the wire — pass that string here directly
|
|
9
|
+
* instead of re-serializing a parallel object, which is how key-order/field drift creeps in.
|
|
10
|
+
*/
|
|
11
|
+
export function generateExecutionDetailsHash(executionDetails: string): string {
|
|
35
12
|
return '0x' + createHash('sha256').update(executionDetails).digest('hex');
|
|
36
13
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Case-insensitive address equality; false if either address is missing. */
|
|
2
|
+
export function compareAddresses(firstAddress?: string, secondAddress?: string): boolean {
|
|
3
|
+
return !!firstAddress && !!secondAddress && firstAddress.toLowerCase() === secondAddress.toLowerCase();
|
|
4
|
+
}
|
|
@@ -9,10 +9,11 @@ import { LiquidSwapQuoteProvider, type LiquidSwapQuoteResponse } from './liquids
|
|
|
9
9
|
import { RaydiumQuoteProvider, type RaydiumPumpQuoteParams, type RaydiumQuoteResponse } from './raydium.js';
|
|
10
10
|
import { PumpFunQuoteProvider } from './pumpfun/index.js';
|
|
11
11
|
import { RelayQuoteProvider } from './relay.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
12
|
+
import { convertDecimals } from './pricing/decimals.js';
|
|
13
|
+
import { estimateAmountOut, IntentNotViableError } from './pricing/estimate-amount-out.js';
|
|
14
|
+
import { estimateExpensesInTokenOut } from './pricing/expenses.js';
|
|
15
|
+
import { DEFAULT_COMMISSION_BPS, CROSS_CHAIN_COMMISSION_DENOMINATOR, EVM_CROSS_CHAIN_GAS_LIMIT } from './pricing/constants.js';
|
|
16
|
+
import { compareAddresses } from './address.js';
|
|
16
17
|
|
|
17
18
|
type SingleChainQuoteParams = {
|
|
18
19
|
chainId: ChainID;
|
|
@@ -95,6 +96,7 @@ export class QuoteProvider {
|
|
|
95
96
|
},
|
|
96
97
|
};
|
|
97
98
|
} catch (e) {
|
|
99
|
+
if (e instanceof IntentNotViableError) throw e;
|
|
98
100
|
console.error('Error getting quote from routers:', e);
|
|
99
101
|
throw new Error('Failed to get quote from routers');
|
|
100
102
|
}
|
|
@@ -136,12 +138,22 @@ export class QuoteProvider {
|
|
|
136
138
|
tokenOut: sourceStable.address,
|
|
137
139
|
};
|
|
138
140
|
|
|
139
|
-
const sourceQuote = await
|
|
141
|
+
const [sourceQuote, expenses] = await Promise.all([
|
|
142
|
+
this.getSingleChainQuote(sourceSingleChainQuoteParams),
|
|
143
|
+
estimateExpensesInTokenOut({
|
|
144
|
+
chainId: params.destChainId,
|
|
145
|
+
tokenOut: params.tokenOut,
|
|
146
|
+
gasLimit: EVM_CROSS_CHAIN_GAS_LIMIT,
|
|
147
|
+
getQuote: (p) => this.getSingleChainQuote(p),
|
|
148
|
+
}),
|
|
149
|
+
]);
|
|
140
150
|
|
|
141
151
|
// Step 2: Normalize stable amount between source and destination ---
|
|
142
152
|
// Adjust for decimal difference between stables (e.g. 6 → 18)
|
|
143
|
-
const normalizedBridgeAmount =
|
|
144
|
-
|
|
153
|
+
const normalizedBridgeAmount = convertDecimals(
|
|
154
|
+
sourceQuote.amountOut,
|
|
155
|
+
sourceStable.decimals,
|
|
156
|
+
destStable.decimals,
|
|
145
157
|
);
|
|
146
158
|
|
|
147
159
|
// Step 3: Get quote from dest bridge stable → target token ---
|
|
@@ -154,17 +166,25 @@ export class QuoteProvider {
|
|
|
154
166
|
|
|
155
167
|
const destQuote = await this.getSingleChainQuote(destSingleChainQuoteParams);
|
|
156
168
|
|
|
157
|
-
//
|
|
169
|
+
// Step 4: Compute stable min-amount with correct decimals ---
|
|
158
170
|
const estimatedAmountInAsMinStablecoinAmount = BigInt(
|
|
159
171
|
Math.floor(sourceQuote.amountInUsd * 10 ** sourceStable.decimals),
|
|
160
172
|
);
|
|
161
173
|
|
|
174
|
+
const swapOutput = destQuote.amountOutMin ?? destQuote.amountOut;
|
|
175
|
+
const estimatedAmountOutReduced = estimateAmountOut(
|
|
176
|
+
swapOutput,
|
|
177
|
+
DEFAULT_COMMISSION_BPS,
|
|
178
|
+
expenses,
|
|
179
|
+
CROSS_CHAIN_COMMISSION_DENOMINATOR,
|
|
180
|
+
);
|
|
181
|
+
|
|
162
182
|
return {
|
|
163
183
|
estimatedAmountOut: destQuote.amountOut,
|
|
164
184
|
estimatedAmountOutUsd: destQuote.amountOutUsd,
|
|
165
185
|
amountInUsd: sourceQuote.amountInUsd,
|
|
166
186
|
estimatedAmountInAsMinStablecoinAmount,
|
|
167
|
-
estimatedAmountOutReduced
|
|
187
|
+
estimatedAmountOutReduced,
|
|
168
188
|
estimatedAmountOutUsdReduced: destQuote.amountOutUsd,
|
|
169
189
|
};
|
|
170
190
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ChainID } from '../../../chains.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Solver commission in basis points. MUST equal the solver's COMMISSION env value
|
|
5
|
+
* (solver/src/config.rs). Update both together to avoid quote divergence.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_COMMISSION_BPS = 50n; // 0.5% — placeholder, confirm against solver COMMISSION
|
|
8
|
+
|
|
9
|
+
/** Single-chain divisor — mirrors evaluate.rs:130-131 (`commission / 10_000`). */
|
|
10
|
+
export const SINGLE_CHAIN_COMMISSION_DENOMINATOR = 10_000n;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Cross-chain divisor — mirrors cross_chain_estimation.rs:213-214 (`commission / 100_000`).
|
|
14
|
+
* The asymmetry with the single-chain divisor is intentional (verbatim solver mirror);
|
|
15
|
+
* confirm with the solver team whether this is a unit choice or a bug before relying on it.
|
|
16
|
+
*/
|
|
17
|
+
export const CROSS_CHAIN_COMMISSION_DENOMINATOR = 100_000n;
|
|
18
|
+
|
|
19
|
+
/** EVM fulfillment gas units — mirrors solver/src/constants/chains.rs (EVM single-chain). */
|
|
20
|
+
export const EVM_SINGLE_CHAIN_GAS_LIMIT = 3_000_000n;
|
|
21
|
+
|
|
22
|
+
/** EVM cross-chain fulfillment gas units — mirrors solver/src/constants/chains.rs (EVM cross-chain). */
|
|
23
|
+
export const EVM_CROSS_CHAIN_GAS_LIMIT = 2_000_000n;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fixed native-token gas cost for non-EVM chains, in the chain's smallest unit.
|
|
27
|
+
* Mirrors solver/src/constants/chains.rs: Sui = 20_000_000 MIST; Solana base = 200_000 lamports
|
|
28
|
+
* (single-receiver default; per-receiver ATA cost is not modeled at quote time).
|
|
29
|
+
*/
|
|
30
|
+
export const NON_EVM_FIXED_NATIVE_GAS_COST: Partial<Record<ChainID, bigint>> = {
|
|
31
|
+
[ChainID.Sui]: 20_000_000n,
|
|
32
|
+
[ChainID.Solana]: 200_000n,
|
|
33
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integer decimal conversion between two tokens, mirroring solver cross_chain_estimation.rs:205-211.
|
|
3
|
+
* Uses BigInt powers of ten to avoid the float precision loss of `Math.floor(Number(...))`.
|
|
4
|
+
*/
|
|
5
|
+
export function convertDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint {
|
|
6
|
+
const diff = toDecimals - fromDecimals;
|
|
7
|
+
if (diff >= 0) {
|
|
8
|
+
return amount * 10n ** BigInt(diff);
|
|
9
|
+
}
|
|
10
|
+
return amount / 10n ** BigInt(-diff);
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Expense components, all expressed in the output token's smallest units. */
|
|
2
|
+
export type Expenses = {
|
|
3
|
+
gasInTokenOut: bigint;
|
|
4
|
+
protocolFeeInTokenOut: bigint;
|
|
5
|
+
extraTransfersInTokenOut: bigint;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/** Thrown when total expenses meet or exceed the swap output, mirroring the solver's rejection. */
|
|
9
|
+
export class IntentNotViableError extends Error {
|
|
10
|
+
constructor(message: string) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'IntentNotViableError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Ports solver_rust evaluate.rs: final amount = swapOutput − expenses − commission.
|
|
18
|
+
* `commissionBps` is basis points; `commissionDenominator` selects single-chain (10_000n)
|
|
19
|
+
* vs cross-chain (100_000n) semantics. Throws IntentNotViableError when nothing is left.
|
|
20
|
+
*/
|
|
21
|
+
export function estimateAmountOut(
|
|
22
|
+
swapOutput: bigint,
|
|
23
|
+
commissionBps: bigint,
|
|
24
|
+
expenses: Expenses,
|
|
25
|
+
commissionDenominator = 10_000n,
|
|
26
|
+
): bigint {
|
|
27
|
+
const commissionFee = (swapOutput * commissionBps) / commissionDenominator;
|
|
28
|
+
const total =
|
|
29
|
+
expenses.gasInTokenOut + expenses.protocolFeeInTokenOut + expenses.extraTransfersInTokenOut + commissionFee;
|
|
30
|
+
|
|
31
|
+
if (total >= swapOutput) {
|
|
32
|
+
throw new IntentNotViableError(`Total expenses (${total}) meet or exceed swap output (${swapOutput})`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return swapOutput - total;
|
|
36
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ChainID, type SupportedChain } from '../../../chains.js';
|
|
2
|
+
import {
|
|
3
|
+
NATIVE_EVM_ETH_ADDRESSES,
|
|
4
|
+
NATIVE_SOLANA_TOKEN_ADDRESS,
|
|
5
|
+
NATIVE_SUI_TOKEN_ADDRESS,
|
|
6
|
+
isNativeEvmToken,
|
|
7
|
+
} from '../../../constants.js';
|
|
8
|
+
import { compareAddresses } from '../address.js';
|
|
9
|
+
import type { Expenses } from './estimate-amount-out.js';
|
|
10
|
+
import { getNativeGasCost } from './gas.js';
|
|
11
|
+
|
|
12
|
+
/** Quotes a native->tokenOut swap on the given chain. Injected to keep this module a leaf (no dependency on the aggregator). */
|
|
13
|
+
type GasQuoteFn = (params: {
|
|
14
|
+
chainId: SupportedChain;
|
|
15
|
+
amount: bigint;
|
|
16
|
+
tokenIn: string;
|
|
17
|
+
tokenOut: string;
|
|
18
|
+
}) => Promise<{ amountOut: bigint }>;
|
|
19
|
+
|
|
20
|
+
function nativeTokenAddressForChain(chainId: SupportedChain): string {
|
|
21
|
+
if (chainId === ChainID.Solana) return NATIVE_SOLANA_TOKEN_ADDRESS;
|
|
22
|
+
if (chainId === ChainID.Sui) return NATIVE_SUI_TOKEN_ADDRESS;
|
|
23
|
+
// EVM native sentinel addresses share the same 0xEee... value; use the first.
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
25
|
+
return NATIVE_EVM_ETH_ADDRESSES[0]!;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isNativeToken(chainId: SupportedChain, address: string): boolean {
|
|
29
|
+
if (chainId === ChainID.Solana) return compareAddresses(address, NATIVE_SOLANA_TOKEN_ADDRESS);
|
|
30
|
+
if (chainId === ChainID.Sui) return compareAddresses(address, NATIVE_SUI_TOKEN_ADDRESS);
|
|
31
|
+
return isNativeEvmToken(address);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Builds the Expenses bundle in the output token. Gas is fetched in native units and
|
|
36
|
+
* swapped into tokenOut via the injected quote fn, mirroring how the solver converts
|
|
37
|
+
* expenses into the output token. protocolFee/extraTransfers are reserved (0n) for now.
|
|
38
|
+
*/
|
|
39
|
+
export async function estimateExpensesInTokenOut(params: {
|
|
40
|
+
chainId: SupportedChain;
|
|
41
|
+
tokenOut: string;
|
|
42
|
+
gasLimit: bigint;
|
|
43
|
+
getQuote: GasQuoteFn;
|
|
44
|
+
rpcProviderUrl?: string;
|
|
45
|
+
}): Promise<Expenses> {
|
|
46
|
+
const { chainId, tokenOut, gasLimit, getQuote, rpcProviderUrl } = params;
|
|
47
|
+
|
|
48
|
+
const nativeGasCost = await getNativeGasCost({ chainId, gasLimit, rpcProviderUrl });
|
|
49
|
+
|
|
50
|
+
const gasInTokenOut = isNativeToken(chainId, tokenOut)
|
|
51
|
+
? nativeGasCost
|
|
52
|
+
: (
|
|
53
|
+
await getQuote({
|
|
54
|
+
chainId,
|
|
55
|
+
amount: nativeGasCost,
|
|
56
|
+
tokenIn: nativeTokenAddressForChain(chainId),
|
|
57
|
+
tokenOut,
|
|
58
|
+
})
|
|
59
|
+
).amountOut;
|
|
60
|
+
|
|
61
|
+
return { gasInTokenOut, protocolFeeInTokenOut: 0n, extraTransfersInTokenOut: 0n };
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getGasPrice } from 'viem/actions';
|
|
2
|
+
import { isEvmChain, type SupportedChain } from '../../../chains.js';
|
|
3
|
+
import { ChainProvider } from '../../../core/evm/chain-provider.js';
|
|
4
|
+
import { NON_EVM_FIXED_NATIVE_GAS_COST } from './constants.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Gas cost in the chain's native smallest unit (wei / lamports / MIST).
|
|
8
|
+
* EVM: live gas price × gas limit. Non-EVM: solver-mirrored fixed cost.
|
|
9
|
+
*/
|
|
10
|
+
export async function getNativeGasCost(params: {
|
|
11
|
+
chainId: SupportedChain;
|
|
12
|
+
gasLimit: bigint;
|
|
13
|
+
rpcProviderUrl?: string;
|
|
14
|
+
}): Promise<bigint> {
|
|
15
|
+
const { chainId, gasLimit, rpcProviderUrl } = params;
|
|
16
|
+
|
|
17
|
+
if (isEvmChain(chainId)) {
|
|
18
|
+
const client = ChainProvider.getClient(chainId, rpcProviderUrl);
|
|
19
|
+
const gasPrice = await getGasPrice(client);
|
|
20
|
+
return gasLimit * gasPrice;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const fixed = NON_EVM_FIXED_NATIVE_GAS_COST[chainId];
|
|
24
|
+
if (fixed === undefined) {
|
|
25
|
+
throw new Error(`No fixed native gas cost configured for chain ${chainId}`);
|
|
26
|
+
}
|
|
27
|
+
return fixed;
|
|
28
|
+
}
|