@shogun-sdk/intents-sdk 1.2.6-test.15 → 1.2.6-test.17

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.
Files changed (35) hide show
  1. package/dist/index.cjs +535 -484
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +121 -43
  4. package/dist/index.d.ts +121 -43
  5. package/dist/index.js +369 -318
  6. package/dist/index.js.map +1 -1
  7. package/package.json +10 -7
  8. package/src/auth/siwe.ts +9 -7
  9. package/src/constants.ts +32 -17
  10. package/src/core/evm/intent-helpers.ts +131 -8
  11. package/src/core/evm/intent-provider.ts +5 -4
  12. package/src/core/evm/permit2.ts +36 -0
  13. package/src/core/orders/api/fetch.ts +12 -36
  14. package/src/core/orders/api/index.ts +2 -3
  15. package/src/core/orders/cross-chain.ts +3 -0
  16. package/src/core/orders/single-chain.ts +21 -8
  17. package/src/core/sdk.ts +11 -2
  18. package/src/core/solana/dca/create-order.ts +6 -19
  19. package/src/core/solana/intent-helpers.ts +12 -20
  20. package/src/core/solana/order-instructions.ts +12 -37
  21. package/src/core/sui/intent-helpers.ts +4 -1
  22. package/src/index.ts +4 -7
  23. package/src/types/api.ts +14 -3
  24. package/src/types/intent.ts +36 -2
  25. package/src/utils/base-validator.ts +0 -4
  26. package/src/utils/generate-execution-details-hash.ts +9 -32
  27. package/src/utils/quote/address.ts +4 -0
  28. package/src/utils/quote/aggregator.ts +29 -9
  29. package/src/utils/quote/pricing/constants.ts +33 -0
  30. package/src/utils/quote/pricing/decimals.ts +11 -0
  31. package/src/utils/quote/pricing/estimate-amount-out.ts +36 -0
  32. package/src/utils/quote/pricing/expenses.ts +62 -0
  33. package/src/utils/quote/pricing/gas.ts +28 -0
  34. package/src/core/solana/transaction-options.ts +0 -83
  35. package/src/utils/auctioneer-headers.ts +0 -32
@@ -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
+ }
@@ -1,83 +0,0 @@
1
- import { type Address, address, createNoopSigner, type TransactionSigner } from '@solana/kit';
2
- import { SOLANA_MIN_TIP_LAMPORTS, SOLANA_TIP_ACCOUNTS } from '../../constants.js';
3
-
4
- export type SolanaTransactionOptions = {
5
- rpcUrl?: string;
6
- feePayer?: string;
7
- tipAmountSol?: number | string;
8
- tipLamports?: bigint;
9
- tipAccount?: string;
10
- tipAccounts?: readonly string[];
11
- };
12
-
13
- export function resolveSolanaFeePayer(
14
- userSigner: TransactionSigner<Address>,
15
- feePayer?: string,
16
- ): TransactionSigner<Address> {
17
- if (!feePayer || feePayer === userSigner.address) {
18
- return userSigner;
19
- }
20
-
21
- const feePayerAddress = address(feePayer as Address);
22
- return createNoopSigner(feePayerAddress);
23
- }
24
-
25
- export function resolveSolanaTip(
26
- options?: Pick<SolanaTransactionOptions, 'tipAmountSol' | 'tipLamports' | 'tipAccount' | 'tipAccounts'>,
27
- ): { lamports: bigint; account: Address } | undefined {
28
- const lamports = normalizeTipLamports(options);
29
- if (!lamports) {
30
- return undefined;
31
- }
32
-
33
- const selectedTipAccount = options?.tipAccount ?? pickRandomTipAccount(options?.tipAccounts ?? SOLANA_TIP_ACCOUNTS);
34
-
35
- return {
36
- lamports,
37
- account: address(selectedTipAccount as Address),
38
- };
39
- }
40
-
41
- function normalizeTipLamports(
42
- options?: Pick<SolanaTransactionOptions, 'tipAmountSol' | 'tipLamports'>,
43
- ): bigint | undefined {
44
- if (!options) {
45
- return undefined;
46
- }
47
-
48
- if (options.tipLamports !== undefined) {
49
- if (options.tipLamports <= 0n) {
50
- return undefined;
51
- }
52
-
53
- return options.tipLamports < SOLANA_MIN_TIP_LAMPORTS ? SOLANA_MIN_TIP_LAMPORTS : options.tipLamports;
54
- }
55
-
56
- if (options.tipAmountSol === undefined || options.tipAmountSol === null || options.tipAmountSol === '') {
57
- return undefined;
58
- }
59
-
60
- const tipInSol = Number(options.tipAmountSol);
61
- if (!Number.isFinite(tipInSol)) {
62
- throw new Error('Invalid Solana tip amount');
63
- }
64
- if (tipInSol <= 0) {
65
- return undefined;
66
- }
67
-
68
- const tipLamports = BigInt(Math.round(tipInSol * 1_000_000_000));
69
- return tipLamports < SOLANA_MIN_TIP_LAMPORTS ? SOLANA_MIN_TIP_LAMPORTS : tipLamports;
70
- }
71
-
72
- function pickRandomTipAccount(accounts: readonly string[]): string {
73
- if (!accounts.length) {
74
- throw new Error('No Solana tip accounts configured');
75
- }
76
-
77
- const index = Math.floor(Math.random() * accounts.length);
78
- const selected = accounts[index];
79
- if (!selected) {
80
- throw new Error('No Solana tip account selected');
81
- }
82
- return selected;
83
- }
@@ -1,32 +0,0 @@
1
- export const DEV_ACCESS_STORAGE_KEY = 'x-dev-access';
2
- export const DEV_ACCESS_HEADER = 'x-dev-access';
3
-
4
- export function getDevAccessHeaderValue(): string | undefined {
5
- try {
6
- if (typeof globalThis === 'undefined') {
7
- return undefined;
8
- }
9
-
10
- const storage = (globalThis as { localStorage?: Storage }).localStorage;
11
- if (!storage?.getItem) {
12
- return undefined;
13
- }
14
-
15
- const value = storage.getItem(DEV_ACCESS_STORAGE_KEY)?.trim();
16
- return value ? value : undefined;
17
- } catch {
18
- return undefined;
19
- }
20
- }
21
-
22
- export function withAuctioneerHeaders(headers: Record<string, string> = {}): Record<string, string> {
23
- const value = getDevAccessHeaderValue();
24
- if (!value) {
25
- return headers;
26
- }
27
-
28
- return {
29
- ...headers,
30
- [DEV_ACCESS_HEADER]: value,
31
- };
32
- }