@t2000/sdk 4.1.4 → 4.2.1
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/adapters/index.d.cts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +32 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -113
- package/dist/index.d.ts +14 -113
- package/dist/index.js +32 -6
- package/dist/index.js.map +1 -1
- package/dist/{types-CIclvR39.d.cts → types-8CNP74n6.d.cts} +1 -1
- package/dist/{types-B63ogqZZ.d.ts → types-BTbqE8AE.d.ts} +1 -1
- package/dist/{types-HJGbXJ37.d.cts → types-DUmk5ivZ.d.cts} +153 -2
- package/dist/{types-HJGbXJ37.d.ts → types-DUmk5ivZ.d.ts} +153 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
2
2
|
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
3
3
|
import { SuiGrpcClient } from '@mysten/sui/grpc';
|
|
4
|
-
import { T as TransactionLeg, k as TransactionRecord } from './types-
|
|
4
|
+
import { T as TransactionLeg, k as TransactionRecord } from './types-DUmk5ivZ.cjs';
|
|
5
5
|
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
2
2
|
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
3
3
|
import { SuiGrpcClient } from '@mysten/sui/grpc';
|
|
4
|
-
import { T as TransactionLeg, k as TransactionRecord } from './types-
|
|
4
|
+
import { T as TransactionLeg, k as TransactionRecord } from './types-DUmk5ivZ.js';
|
|
5
5
|
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,7 +1,149 @@
|
|
|
1
1
|
import { RouterDataV3 } from '@cetusprotocol/aggregator-sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { TransactionObjectArgument, Transaction } from '@mysten/sui/transactions';
|
|
3
3
|
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Wallet-side coin selection helpers — single source of truth for the
|
|
7
|
+
* "produce a `Coin<T>` argument holding `amount` raw units of `coinType`,
|
|
8
|
+
* owned by `address`" pattern. Used by every wallet-mode appender that
|
|
9
|
+
* needs a coin input (save, send, swap, repay, stake, etc.).
|
|
10
|
+
*
|
|
11
|
+
* **2026-05-22 — address-balance migration.** Sui mainnet's address-balance
|
|
12
|
+
* feature ships funds account-style instead of as discrete `Coin<T>` objects.
|
|
13
|
+
* After a payment via `0x2::balance::send_funds`, the leftover lands in the
|
|
14
|
+
* sender's address balance with a synthetic "coin reservation" representing
|
|
15
|
+
* the deposit. `client.getCoins()` correctly filters those reservations out
|
|
16
|
+
* (they aren't real owned objects), so the old fetch+merge+split pattern
|
|
17
|
+
* threw `INSUFFICIENT_BALANCE` for users whose stables had drifted into
|
|
18
|
+
* address balance — even when `getBalance().totalBalance` showed plenty.
|
|
19
|
+
*
|
|
20
|
+
* The fix is structural: hand the work to `coinWithBalance({ type, balance })`
|
|
21
|
+
* from `@mysten/sui/transactions`. Its build-time resolver inspects coins +
|
|
22
|
+
* address balance together (`getBalance` + `listCoins`), then emits the
|
|
23
|
+
* right shape — direct `redeem_funds` from address balance when AB ≥
|
|
24
|
+
* required, or merge-and-split across coins + AB withdrawal when not. Multi
|
|
25
|
+
* intents per coin type get batched into a single merge in one PTB, so the
|
|
26
|
+
* old per-PTB merge cache is no longer needed.
|
|
27
|
+
*
|
|
28
|
+
* Pre-flight uses `client.getBalance().totalBalance` (sums coins + AB)
|
|
29
|
+
* instead of summing the paginated `getCoins` page. That's the OTHER half
|
|
30
|
+
* of the migration — the legacy path could see `0` from `getCoins` and
|
|
31
|
+
* mistakenly throw before `coinWithBalance` ever ran.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
interface CoinPage {
|
|
35
|
+
ids: string[];
|
|
36
|
+
totalBalance: bigint;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sum every coin of `coinType` owned by `owner`, INCLUDING address balance.
|
|
40
|
+
* Returns the IDs of any discrete coin objects that exist (callers
|
|
41
|
+
* occasionally need this for non-`coinWithBalance` paths, e.g. SUIns name
|
|
42
|
+
* registration which expects raw object IDs).
|
|
43
|
+
*
|
|
44
|
+
* Pre-2026-05-22 this function paginated `client.getCoins` and summed
|
|
45
|
+
* the page balances. That misses address-balance funds (the SDK filters
|
|
46
|
+
* them out of `getCoins` for back-compat). The new implementation calls
|
|
47
|
+
* `getBalance` for the canonical total and `getCoins` for the optional
|
|
48
|
+
* ID list — both round-trips, but they happen in parallel.
|
|
49
|
+
*/
|
|
50
|
+
declare function fetchAllCoins(client: SuiJsonRpcClient, owner: string, coinType: string): Promise<CoinPage>;
|
|
51
|
+
interface SelectAndSplitResult {
|
|
52
|
+
/** TransactionObjectArgument for a coin holding `effectiveAmount` raw units. */
|
|
53
|
+
coin: TransactionObjectArgument;
|
|
54
|
+
/** Actual raw amount the returned coin holds. May be < requested if `swapAll` is true. */
|
|
55
|
+
effectiveAmount: bigint;
|
|
56
|
+
/** True iff the request consumed the entire wallet balance (no split needed). */
|
|
57
|
+
swapAll: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Wallet-mode coin selection prelude. Pre-flights against
|
|
61
|
+
* `getBalance().totalBalance` (coins + address balance combined), then
|
|
62
|
+
* returns a `coinWithBalance({ type, balance })` argument that the
|
|
63
|
+
* `@mysten/sui` resolver fulfills at build time.
|
|
64
|
+
*
|
|
65
|
+
* Throws `T2000Error` (`INSUFFICIENT_BALANCE`) when:
|
|
66
|
+
* - `amount` is bigger than the total balance AND the caller did NOT
|
|
67
|
+
* opt into `swapAll: true` clipping.
|
|
68
|
+
* - `amount === 'all'` AND total balance is zero.
|
|
69
|
+
*
|
|
70
|
+
* @param tx — PTB to register the `coinWithBalance` intent against.
|
|
71
|
+
* @param client — Sui RPC client for the pre-flight `getBalance` lookup.
|
|
72
|
+
* @param owner — wallet address whose coins to source from.
|
|
73
|
+
* @param coinType — fully-qualified Sui coin type (e.g. `"0x...::usdc::USDC"`).
|
|
74
|
+
* @param amount — raw amount to source (in MIST / smallest unit). Pass
|
|
75
|
+
* `'all'` to consume the entire balance.
|
|
76
|
+
* @param options.allowSwapAll — if true (default), `amount` >= totalBalance
|
|
77
|
+
* auto-clips to total. If false, throws when the request would over-consume.
|
|
78
|
+
* @param options.sponsoredContext — when true, source ONLY from discrete coin
|
|
79
|
+
* objects (never the address balance). See the long note below — this exists
|
|
80
|
+
* because Enoki's gas station can't yet deserialize a `TransactionData` that
|
|
81
|
+
* contains the address-balance `FundsWithdrawal` reservation that
|
|
82
|
+
* `coinWithBalance` emits. Self-funded callers leave this false: the fullnode
|
|
83
|
+
* handles `FundsWithdrawal` fine, so the address-balance path is preferred
|
|
84
|
+
* (it can reach funds that aren't held as coin objects).
|
|
85
|
+
*
|
|
86
|
+
* @returns
|
|
87
|
+
* - `coin` — `TransactionObjectArgument` ready for downstream consumption.
|
|
88
|
+
* - `effectiveAmount` — the raw amount the returned coin holds (handles
|
|
89
|
+
* swapAll clipping).
|
|
90
|
+
* - `swapAll` — true iff the entire balance was consumed.
|
|
91
|
+
*/
|
|
92
|
+
declare function selectAndSplitCoin(tx: Transaction, client: SuiJsonRpcClient, owner: string, coinType: string, amount: bigint | 'all', options?: {
|
|
93
|
+
allowSwapAll?: boolean;
|
|
94
|
+
sponsoredContext?: boolean;
|
|
95
|
+
}): Promise<SelectAndSplitResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Coin-object-only selection for sponsored (Enoki) transactions. Fetches the
|
|
98
|
+
* owner's discrete `Coin<T>` objects (NOT the address balance — `getCoins`
|
|
99
|
+
* excludes it), merges them, and splits the requested amount. Never emits a
|
|
100
|
+
* `FundsWithdrawal` reservation, so the resulting `TransactionData` stays on
|
|
101
|
+
* the shape Enoki's gas station can serialize.
|
|
102
|
+
*
|
|
103
|
+
* Throws `ADDRESS_BALANCE_UNSPONSORABLE` when the coin objects don't cover the
|
|
104
|
+
* request — which, for a user whose `getBalance().totalBalance` shows funds,
|
|
105
|
+
* means those funds live in the address balance (e.g. received via a gasless
|
|
106
|
+
* stablecoin transfer) and can't be moved through a sponsored transaction yet.
|
|
107
|
+
*/
|
|
108
|
+
/**
|
|
109
|
+
* Per-PTB cache of merged sponsored coin-object primaries, keyed by coin
|
|
110
|
+
* type. The FIRST `selectCoinObjectsOnly` call for a given coin type in a
|
|
111
|
+
* PTB fetches the owner's discrete `Coin<T>` objects, merges them into one
|
|
112
|
+
* `primary`, and records it here alongside the remaining (unspent) balance.
|
|
113
|
+
* EVERY subsequent leg sourcing the same coin type splits from that cached
|
|
114
|
+
* `primary` instead of re-fetching + re-merging.
|
|
115
|
+
*
|
|
116
|
+
* Why this exists (S.xxx, 2026-06-02): a sponsored bundle with 2+ legs
|
|
117
|
+
* sourcing the same coin (e.g. `SUI→WAL` + `SUI→DEEP`) called
|
|
118
|
+
* `selectCoinObjectsOnly` once per leg. Each call emitted its own
|
|
119
|
+
* `mergeCoins` over the SAME coin objects, so the second leg's merge
|
|
120
|
+
* referenced coins the first leg already consumed → Enoki dry-run failed
|
|
121
|
+
* with `CommandArgumentError { ArgumentWithoutValue }`. Non-SUI legs dodge
|
|
122
|
+
* this because they go through `coinWithBalance`, whose resolver batches
|
|
123
|
+
* all intents for one coin type into a single build-time merge. The SUI
|
|
124
|
+
* sponsored path has no such batching, so the cache supplies it.
|
|
125
|
+
*/
|
|
126
|
+
type SponsoredCoinMergeCache = Map<string, {
|
|
127
|
+
primary: TransactionObjectArgument;
|
|
128
|
+
remaining: bigint;
|
|
129
|
+
}>;
|
|
130
|
+
/**
|
|
131
|
+
* SUI-specific coin selection. Branches on sponsorship context:
|
|
132
|
+
*
|
|
133
|
+
* - **Self-funded (`sponsoredContext: false`)** — splits from `tx.gas`
|
|
134
|
+
* directly (the user's gas coin IS their SUI). More efficient — no
|
|
135
|
+
* `getBalance` RTT.
|
|
136
|
+
*
|
|
137
|
+
* - **Sponsored (`sponsoredContext: true`)** — sources from the user's
|
|
138
|
+
* discrete SUI coin objects (`selectCoinObjectsOnly`). This both (a) avoids
|
|
139
|
+
* `tx.gas`, which belongs to the Enoki sponsor — NOT the user — under
|
|
140
|
+
* sponsored flows (the original S.260 reason for `useGasCoin: false`), AND
|
|
141
|
+
* (b) avoids `coinWithBalance`'s address-balance `FundsWithdrawal`, which
|
|
142
|
+
* Enoki's gas station can't deserialize (issue #93). If the user's SUI is
|
|
143
|
+
* address-balance-only, it raises `ADDRESS_BALANCE_UNSPONSORABLE`.
|
|
144
|
+
*/
|
|
145
|
+
declare function selectSuiCoin(tx: Transaction, client: SuiJsonRpcClient, owner: string, amountMist: bigint, sponsoredContext: boolean, mergeCache?: SponsoredCoinMergeCache): Promise<SelectAndSplitResult>;
|
|
146
|
+
|
|
5
147
|
/**
|
|
6
148
|
* Cetus Aggregator V3 SDK wrapper — the ONLY file that imports @cetusprotocol/aggregator-sdk.
|
|
7
149
|
* Documented CLAUDE.md exception: multi-DEX routing cannot be feasibly replaced by thin tx builders.
|
|
@@ -252,6 +394,15 @@ declare function addSwapToTx(tx: Transaction, client: SuiJsonRpcClient, address:
|
|
|
252
394
|
* threads this through via `composeTx({ sponsoredContext: true })`.
|
|
253
395
|
*/
|
|
254
396
|
sponsoredContext?: boolean;
|
|
397
|
+
/**
|
|
398
|
+
* Per-PTB merge cache for sponsored SUI sourcing. Provided by
|
|
399
|
+
* `composeTx`'s orchestration loop so multiple SUI-source legs in one
|
|
400
|
+
* bundle share a single merged primary coin instead of each emitting
|
|
401
|
+
* its own `mergeCoins` (the second of which references already-consumed
|
|
402
|
+
* coins → Enoki dry-run `ArgumentWithoutValue`). Single swaps / non-SUI
|
|
403
|
+
* sources don't need it; omit. See `SponsoredCoinMergeCache` JSDoc.
|
|
404
|
+
*/
|
|
405
|
+
suiMergeCache?: SponsoredCoinMergeCache;
|
|
255
406
|
}): Promise<{
|
|
256
407
|
coin: TransactionObjectArgument;
|
|
257
408
|
effectiveAmountIn: number;
|
|
@@ -564,4 +715,4 @@ interface FinancialSummary {
|
|
|
564
715
|
fetchedAt: number;
|
|
565
716
|
}
|
|
566
717
|
|
|
567
|
-
export { type AssetRates as A, type BalanceResponse as B, type ClaimRewardsResult as C, type DepositInfo as D, type EarningsResult as E, type FundStatusResult as F, type GasReserve as G, type HealthFactorResult as H,
|
|
718
|
+
export { type AssetRates as A, type BalanceResponse as B, type ClaimRewardsResult as C, type DepositInfo as D, type EarningsResult as E, type FundStatusResult as F, type GasReserve as G, type HealthFactorResult as H, addSwapToTx as I, deserializeCetusRoute as J, fetchAllCoins as K, isCetusRouteFresh as L, type MaxBorrowResult as M, selectAndSplitCoin as N, OVERLAY_FEE_RATE as O, type PayOptions as P, selectSuiCoin as Q, type RatesResult as R, type SaveResult as S, type TransactionLeg as T, serializeCetusRoute as U, verifyCetusRouteCoinMatch as V, type WithdrawResult as W, type BorrowResult as a, type MaxWithdrawResult as b, type OverlayFeeConfig as c, type PayResult as d, type PendingReward as e, type PositionEntry as f, type PositionsResult as g, type RepayResult as h, type SendResult as i, type SwapRouteResult as j, type TransactionRecord as k, buildSwapTx as l, findSwapRoute as m, type T2000Options as n, type SwapResult as o, type SwapQuoteResult as p, type PaymentRequest as q, type CompoundRewardsResult as r, type SponsoredCoinMergeCache as s, type FinancialSummary as t, type CoinPage as u, type HFAlertLevel as v, type SelectAndSplitResult as w, type SerializedCetusRoute as x, type SerializedCetusRoutePath as y, type SerializedRouterDataV3 as z };
|
|
@@ -1,7 +1,149 @@
|
|
|
1
1
|
import { RouterDataV3 } from '@cetusprotocol/aggregator-sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { TransactionObjectArgument, Transaction } from '@mysten/sui/transactions';
|
|
3
3
|
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Wallet-side coin selection helpers — single source of truth for the
|
|
7
|
+
* "produce a `Coin<T>` argument holding `amount` raw units of `coinType`,
|
|
8
|
+
* owned by `address`" pattern. Used by every wallet-mode appender that
|
|
9
|
+
* needs a coin input (save, send, swap, repay, stake, etc.).
|
|
10
|
+
*
|
|
11
|
+
* **2026-05-22 — address-balance migration.** Sui mainnet's address-balance
|
|
12
|
+
* feature ships funds account-style instead of as discrete `Coin<T>` objects.
|
|
13
|
+
* After a payment via `0x2::balance::send_funds`, the leftover lands in the
|
|
14
|
+
* sender's address balance with a synthetic "coin reservation" representing
|
|
15
|
+
* the deposit. `client.getCoins()` correctly filters those reservations out
|
|
16
|
+
* (they aren't real owned objects), so the old fetch+merge+split pattern
|
|
17
|
+
* threw `INSUFFICIENT_BALANCE` for users whose stables had drifted into
|
|
18
|
+
* address balance — even when `getBalance().totalBalance` showed plenty.
|
|
19
|
+
*
|
|
20
|
+
* The fix is structural: hand the work to `coinWithBalance({ type, balance })`
|
|
21
|
+
* from `@mysten/sui/transactions`. Its build-time resolver inspects coins +
|
|
22
|
+
* address balance together (`getBalance` + `listCoins`), then emits the
|
|
23
|
+
* right shape — direct `redeem_funds` from address balance when AB ≥
|
|
24
|
+
* required, or merge-and-split across coins + AB withdrawal when not. Multi
|
|
25
|
+
* intents per coin type get batched into a single merge in one PTB, so the
|
|
26
|
+
* old per-PTB merge cache is no longer needed.
|
|
27
|
+
*
|
|
28
|
+
* Pre-flight uses `client.getBalance().totalBalance` (sums coins + AB)
|
|
29
|
+
* instead of summing the paginated `getCoins` page. That's the OTHER half
|
|
30
|
+
* of the migration — the legacy path could see `0` from `getCoins` and
|
|
31
|
+
* mistakenly throw before `coinWithBalance` ever ran.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
interface CoinPage {
|
|
35
|
+
ids: string[];
|
|
36
|
+
totalBalance: bigint;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sum every coin of `coinType` owned by `owner`, INCLUDING address balance.
|
|
40
|
+
* Returns the IDs of any discrete coin objects that exist (callers
|
|
41
|
+
* occasionally need this for non-`coinWithBalance` paths, e.g. SUIns name
|
|
42
|
+
* registration which expects raw object IDs).
|
|
43
|
+
*
|
|
44
|
+
* Pre-2026-05-22 this function paginated `client.getCoins` and summed
|
|
45
|
+
* the page balances. That misses address-balance funds (the SDK filters
|
|
46
|
+
* them out of `getCoins` for back-compat). The new implementation calls
|
|
47
|
+
* `getBalance` for the canonical total and `getCoins` for the optional
|
|
48
|
+
* ID list — both round-trips, but they happen in parallel.
|
|
49
|
+
*/
|
|
50
|
+
declare function fetchAllCoins(client: SuiJsonRpcClient, owner: string, coinType: string): Promise<CoinPage>;
|
|
51
|
+
interface SelectAndSplitResult {
|
|
52
|
+
/** TransactionObjectArgument for a coin holding `effectiveAmount` raw units. */
|
|
53
|
+
coin: TransactionObjectArgument;
|
|
54
|
+
/** Actual raw amount the returned coin holds. May be < requested if `swapAll` is true. */
|
|
55
|
+
effectiveAmount: bigint;
|
|
56
|
+
/** True iff the request consumed the entire wallet balance (no split needed). */
|
|
57
|
+
swapAll: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Wallet-mode coin selection prelude. Pre-flights against
|
|
61
|
+
* `getBalance().totalBalance` (coins + address balance combined), then
|
|
62
|
+
* returns a `coinWithBalance({ type, balance })` argument that the
|
|
63
|
+
* `@mysten/sui` resolver fulfills at build time.
|
|
64
|
+
*
|
|
65
|
+
* Throws `T2000Error` (`INSUFFICIENT_BALANCE`) when:
|
|
66
|
+
* - `amount` is bigger than the total balance AND the caller did NOT
|
|
67
|
+
* opt into `swapAll: true` clipping.
|
|
68
|
+
* - `amount === 'all'` AND total balance is zero.
|
|
69
|
+
*
|
|
70
|
+
* @param tx — PTB to register the `coinWithBalance` intent against.
|
|
71
|
+
* @param client — Sui RPC client for the pre-flight `getBalance` lookup.
|
|
72
|
+
* @param owner — wallet address whose coins to source from.
|
|
73
|
+
* @param coinType — fully-qualified Sui coin type (e.g. `"0x...::usdc::USDC"`).
|
|
74
|
+
* @param amount — raw amount to source (in MIST / smallest unit). Pass
|
|
75
|
+
* `'all'` to consume the entire balance.
|
|
76
|
+
* @param options.allowSwapAll — if true (default), `amount` >= totalBalance
|
|
77
|
+
* auto-clips to total. If false, throws when the request would over-consume.
|
|
78
|
+
* @param options.sponsoredContext — when true, source ONLY from discrete coin
|
|
79
|
+
* objects (never the address balance). See the long note below — this exists
|
|
80
|
+
* because Enoki's gas station can't yet deserialize a `TransactionData` that
|
|
81
|
+
* contains the address-balance `FundsWithdrawal` reservation that
|
|
82
|
+
* `coinWithBalance` emits. Self-funded callers leave this false: the fullnode
|
|
83
|
+
* handles `FundsWithdrawal` fine, so the address-balance path is preferred
|
|
84
|
+
* (it can reach funds that aren't held as coin objects).
|
|
85
|
+
*
|
|
86
|
+
* @returns
|
|
87
|
+
* - `coin` — `TransactionObjectArgument` ready for downstream consumption.
|
|
88
|
+
* - `effectiveAmount` — the raw amount the returned coin holds (handles
|
|
89
|
+
* swapAll clipping).
|
|
90
|
+
* - `swapAll` — true iff the entire balance was consumed.
|
|
91
|
+
*/
|
|
92
|
+
declare function selectAndSplitCoin(tx: Transaction, client: SuiJsonRpcClient, owner: string, coinType: string, amount: bigint | 'all', options?: {
|
|
93
|
+
allowSwapAll?: boolean;
|
|
94
|
+
sponsoredContext?: boolean;
|
|
95
|
+
}): Promise<SelectAndSplitResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Coin-object-only selection for sponsored (Enoki) transactions. Fetches the
|
|
98
|
+
* owner's discrete `Coin<T>` objects (NOT the address balance — `getCoins`
|
|
99
|
+
* excludes it), merges them, and splits the requested amount. Never emits a
|
|
100
|
+
* `FundsWithdrawal` reservation, so the resulting `TransactionData` stays on
|
|
101
|
+
* the shape Enoki's gas station can serialize.
|
|
102
|
+
*
|
|
103
|
+
* Throws `ADDRESS_BALANCE_UNSPONSORABLE` when the coin objects don't cover the
|
|
104
|
+
* request — which, for a user whose `getBalance().totalBalance` shows funds,
|
|
105
|
+
* means those funds live in the address balance (e.g. received via a gasless
|
|
106
|
+
* stablecoin transfer) and can't be moved through a sponsored transaction yet.
|
|
107
|
+
*/
|
|
108
|
+
/**
|
|
109
|
+
* Per-PTB cache of merged sponsored coin-object primaries, keyed by coin
|
|
110
|
+
* type. The FIRST `selectCoinObjectsOnly` call for a given coin type in a
|
|
111
|
+
* PTB fetches the owner's discrete `Coin<T>` objects, merges them into one
|
|
112
|
+
* `primary`, and records it here alongside the remaining (unspent) balance.
|
|
113
|
+
* EVERY subsequent leg sourcing the same coin type splits from that cached
|
|
114
|
+
* `primary` instead of re-fetching + re-merging.
|
|
115
|
+
*
|
|
116
|
+
* Why this exists (S.xxx, 2026-06-02): a sponsored bundle with 2+ legs
|
|
117
|
+
* sourcing the same coin (e.g. `SUI→WAL` + `SUI→DEEP`) called
|
|
118
|
+
* `selectCoinObjectsOnly` once per leg. Each call emitted its own
|
|
119
|
+
* `mergeCoins` over the SAME coin objects, so the second leg's merge
|
|
120
|
+
* referenced coins the first leg already consumed → Enoki dry-run failed
|
|
121
|
+
* with `CommandArgumentError { ArgumentWithoutValue }`. Non-SUI legs dodge
|
|
122
|
+
* this because they go through `coinWithBalance`, whose resolver batches
|
|
123
|
+
* all intents for one coin type into a single build-time merge. The SUI
|
|
124
|
+
* sponsored path has no such batching, so the cache supplies it.
|
|
125
|
+
*/
|
|
126
|
+
type SponsoredCoinMergeCache = Map<string, {
|
|
127
|
+
primary: TransactionObjectArgument;
|
|
128
|
+
remaining: bigint;
|
|
129
|
+
}>;
|
|
130
|
+
/**
|
|
131
|
+
* SUI-specific coin selection. Branches on sponsorship context:
|
|
132
|
+
*
|
|
133
|
+
* - **Self-funded (`sponsoredContext: false`)** — splits from `tx.gas`
|
|
134
|
+
* directly (the user's gas coin IS their SUI). More efficient — no
|
|
135
|
+
* `getBalance` RTT.
|
|
136
|
+
*
|
|
137
|
+
* - **Sponsored (`sponsoredContext: true`)** — sources from the user's
|
|
138
|
+
* discrete SUI coin objects (`selectCoinObjectsOnly`). This both (a) avoids
|
|
139
|
+
* `tx.gas`, which belongs to the Enoki sponsor — NOT the user — under
|
|
140
|
+
* sponsored flows (the original S.260 reason for `useGasCoin: false`), AND
|
|
141
|
+
* (b) avoids `coinWithBalance`'s address-balance `FundsWithdrawal`, which
|
|
142
|
+
* Enoki's gas station can't deserialize (issue #93). If the user's SUI is
|
|
143
|
+
* address-balance-only, it raises `ADDRESS_BALANCE_UNSPONSORABLE`.
|
|
144
|
+
*/
|
|
145
|
+
declare function selectSuiCoin(tx: Transaction, client: SuiJsonRpcClient, owner: string, amountMist: bigint, sponsoredContext: boolean, mergeCache?: SponsoredCoinMergeCache): Promise<SelectAndSplitResult>;
|
|
146
|
+
|
|
5
147
|
/**
|
|
6
148
|
* Cetus Aggregator V3 SDK wrapper — the ONLY file that imports @cetusprotocol/aggregator-sdk.
|
|
7
149
|
* Documented CLAUDE.md exception: multi-DEX routing cannot be feasibly replaced by thin tx builders.
|
|
@@ -252,6 +394,15 @@ declare function addSwapToTx(tx: Transaction, client: SuiJsonRpcClient, address:
|
|
|
252
394
|
* threads this through via `composeTx({ sponsoredContext: true })`.
|
|
253
395
|
*/
|
|
254
396
|
sponsoredContext?: boolean;
|
|
397
|
+
/**
|
|
398
|
+
* Per-PTB merge cache for sponsored SUI sourcing. Provided by
|
|
399
|
+
* `composeTx`'s orchestration loop so multiple SUI-source legs in one
|
|
400
|
+
* bundle share a single merged primary coin instead of each emitting
|
|
401
|
+
* its own `mergeCoins` (the second of which references already-consumed
|
|
402
|
+
* coins → Enoki dry-run `ArgumentWithoutValue`). Single swaps / non-SUI
|
|
403
|
+
* sources don't need it; omit. See `SponsoredCoinMergeCache` JSDoc.
|
|
404
|
+
*/
|
|
405
|
+
suiMergeCache?: SponsoredCoinMergeCache;
|
|
255
406
|
}): Promise<{
|
|
256
407
|
coin: TransactionObjectArgument;
|
|
257
408
|
effectiveAmountIn: number;
|
|
@@ -564,4 +715,4 @@ interface FinancialSummary {
|
|
|
564
715
|
fetchedAt: number;
|
|
565
716
|
}
|
|
566
717
|
|
|
567
|
-
export { type AssetRates as A, type BalanceResponse as B, type ClaimRewardsResult as C, type DepositInfo as D, type EarningsResult as E, type FundStatusResult as F, type GasReserve as G, type HealthFactorResult as H,
|
|
718
|
+
export { type AssetRates as A, type BalanceResponse as B, type ClaimRewardsResult as C, type DepositInfo as D, type EarningsResult as E, type FundStatusResult as F, type GasReserve as G, type HealthFactorResult as H, addSwapToTx as I, deserializeCetusRoute as J, fetchAllCoins as K, isCetusRouteFresh as L, type MaxBorrowResult as M, selectAndSplitCoin as N, OVERLAY_FEE_RATE as O, type PayOptions as P, selectSuiCoin as Q, type RatesResult as R, type SaveResult as S, type TransactionLeg as T, serializeCetusRoute as U, verifyCetusRouteCoinMatch as V, type WithdrawResult as W, type BorrowResult as a, type MaxWithdrawResult as b, type OverlayFeeConfig as c, type PayResult as d, type PendingReward as e, type PositionEntry as f, type PositionsResult as g, type RepayResult as h, type SendResult as i, type SwapRouteResult as j, type TransactionRecord as k, buildSwapTx as l, findSwapRoute as m, type T2000Options as n, type SwapResult as o, type SwapQuoteResult as p, type PaymentRequest as q, type CompoundRewardsResult as r, type SponsoredCoinMergeCache as s, type FinancialSummary as t, type CoinPage as u, type HFAlertLevel as v, type SelectAndSplitResult as w, type SerializedCetusRoute as x, type SerializedCetusRoutePath as y, type SerializedRouterDataV3 as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t2000/sdk",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "TypeScript SDK for Agent Wallets on Sui — gasless USDC + USDsui transfers, Cetus swap routing, NAVI lending (programmatic), MPP paid API access, zkLogin compatible.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|