@0block.io/sdk 0.1.0 → 0.3.0
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/README.md +50 -4
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/idl/tenantWrapper.d.ts +166 -5
- package/dist/idl/tenantWrapper.js +371 -6
- package/dist/index.d.ts +3 -2
- package/dist/index.js +14 -11
- package/dist/landing.d.ts +66 -0
- package/dist/landing.js +78 -0
- package/dist/pda.d.ts +6 -0
- package/dist/pda.js +18 -1
- package/dist/swap.js +25 -3
- package/dist/transaction.d.ts +31 -0
- package/dist/transaction.js +103 -18
- package/dist/types.d.ts +23 -4
- package/package.json +3 -3
package/dist/pda.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ export declare function toPk(address: Address): web3.PublicKey;
|
|
|
6
6
|
export declare function deriveAta(owner: Address, mint: Address, tokenProgram?: Address): web3.PublicKey;
|
|
7
7
|
/** Tenant wrapper config PDA (seeds: ["tenant_wrapper_config"]). */
|
|
8
8
|
export declare function deriveWrapperConfig(wrapperProgramId: Address): web3.PublicKey;
|
|
9
|
+
/**
|
|
10
|
+
* Per-order replay-marker PDA (seeds: ["order", payer, order_id LE bytes]).
|
|
11
|
+
* Its existence is the wrapper's exactly-once gate: a second swap with the
|
|
12
|
+
* same (payer, order_id) fails at account creation and reverts entirely.
|
|
13
|
+
*/
|
|
14
|
+
export declare function deriveOrderMarker(wrapperProgramId: Address, payer: Address, orderId: bigint): web3.PublicKey;
|
|
9
15
|
/** Router GlobalConfig PDA (seeds: ["config"]). */
|
|
10
16
|
export declare function deriveRouterGlobalConfig(routerProgramId: Address): web3.PublicKey;
|
|
11
17
|
/** Router TenantConfig PDA (seeds: ["tenant", wrapper_program]). */
|
package/dist/pda.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as web3 from "@solana/web3.js";
|
|
2
|
-
import { ASSOCIATED_TOKEN_PROGRAM_ID, SEED_PUMPFUN_BONDING_CURVE, SEED_PUMPFUN_BONDING_CURVE_V2, SEED_PUMPFUN_CREATOR_VAULT, SEED_PUMPFUN_EVENT_AUTHORITY, SEED_PUMPFUN_FEE_CONFIG, SEED_PUMPFUN_GLOBAL, SEED_PUMPFUN_GLOBAL_VOLUME, SEED_PUMPFUN_USER_VOLUME, SEED_ROUTER_GLOBAL_CONFIG, SEED_ROUTER_TENANT, SEED_WRAPPER_CONFIG, TOKEN_PROGRAM_ID, } from "./constants.js";
|
|
2
|
+
import { ASSOCIATED_TOKEN_PROGRAM_ID, SEED_ORDER_MARKER, SEED_PUMPFUN_BONDING_CURVE, SEED_PUMPFUN_BONDING_CURVE_V2, SEED_PUMPFUN_CREATOR_VAULT, SEED_PUMPFUN_EVENT_AUTHORITY, SEED_PUMPFUN_FEE_CONFIG, SEED_PUMPFUN_GLOBAL, SEED_PUMPFUN_GLOBAL_VOLUME, SEED_PUMPFUN_USER_VOLUME, SEED_ROUTER_GLOBAL_CONFIG, SEED_ROUTER_TENANT, SEED_WRAPPER_CONFIG, TOKEN_PROGRAM_ID, } from "./constants.js";
|
|
3
3
|
/** Normalize an Address (base58 string or PublicKey) to a PublicKey. */
|
|
4
4
|
export function toPk(address) {
|
|
5
5
|
return typeof address === "string" ? new web3.PublicKey(address) : address;
|
|
@@ -15,6 +15,23 @@ export function deriveAta(owner, mint, tokenProgram = TOKEN_PROGRAM_ID) {
|
|
|
15
15
|
export function deriveWrapperConfig(wrapperProgramId) {
|
|
16
16
|
return pda([SEED_WRAPPER_CONFIG], toPk(wrapperProgramId));
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Per-order replay-marker PDA (seeds: ["order", payer, order_id LE bytes]).
|
|
20
|
+
* Its existence is the wrapper's exactly-once gate: a second swap with the
|
|
21
|
+
* same (payer, order_id) fails at account creation and reverts entirely.
|
|
22
|
+
*/
|
|
23
|
+
export function deriveOrderMarker(wrapperProgramId, payer, orderId) {
|
|
24
|
+
if (orderId <= 0n || orderId >= 1n << 128n) {
|
|
25
|
+
throw new Error("orderId must be a non-zero u128");
|
|
26
|
+
}
|
|
27
|
+
const le = new Uint8Array(16);
|
|
28
|
+
let n = orderId;
|
|
29
|
+
for (let i = 0; i < 16; i++) {
|
|
30
|
+
le[i] = Number(n & 0xffn);
|
|
31
|
+
n >>= 8n;
|
|
32
|
+
}
|
|
33
|
+
return pda([SEED_ORDER_MARKER, toPk(payer).toBytes(), le], toPk(wrapperProgramId));
|
|
34
|
+
}
|
|
18
35
|
/** Router GlobalConfig PDA (seeds: ["config"]). */
|
|
19
36
|
export function deriveRouterGlobalConfig(routerProgramId) {
|
|
20
37
|
return pda([SEED_ROUTER_GLOBAL_CONFIG], toPk(routerProgramId));
|
package/dist/swap.js
CHANGED
|
@@ -6,7 +6,7 @@ const { BN, BorshInstructionCoder } = anchor;
|
|
|
6
6
|
import { ASSOCIATED_TOKEN_PROGRAM_ID, FEE_MINT_ALLOWLIST, INSTRUCTIONS_SYSVAR_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, WSOL_MINT, } from "./constants.js";
|
|
7
7
|
import { TENANT_WRAPPER_IDL } from "./idl/tenantWrapper.js";
|
|
8
8
|
import { ROUTER_IDL } from "./idl/router.js";
|
|
9
|
-
import { deriveAta, derivePumpfunUserVolumeAccumulator, deriveRouterGlobalConfig, deriveRouterTenantConfig, deriveWrapperConfig, toPk, } from "./pda.js";
|
|
9
|
+
import { deriveAta, deriveOrderMarker, derivePumpfunUserVolumeAccumulator, deriveRouterGlobalConfig, deriveRouterTenantConfig, deriveWrapperConfig, toPk, } from "./pda.js";
|
|
10
10
|
import { buildPumpfunRemainingAccounts } from "./venues/pumpfun.js";
|
|
11
11
|
// One coder per program for the package lifetime; layouts derive from the
|
|
12
12
|
// vendored IDLs. NOTE: the raw (non-camelCased) IDLs are used, so encode()
|
|
@@ -53,6 +53,15 @@ export function buildPumpfunSwapInstruction(params) {
|
|
|
53
53
|
throw new Error("amountIn must be > 0");
|
|
54
54
|
if (params.minReturn <= 0n)
|
|
55
55
|
throw new Error("minReturn must be > 0");
|
|
56
|
+
if (context.mode === "tenant" && params.orderId === undefined) {
|
|
57
|
+
// The wrapper's order-marker replay gate makes order_id part of the dedup
|
|
58
|
+
// key, and its contract requires SERVER-AUTHORITATIVE ids — a random
|
|
59
|
+
// client-side default would silently break exactly-once semantics.
|
|
60
|
+
throw new Error("tenant mode requires an explicit orderId (server-authoritative, non-zero u128)");
|
|
61
|
+
}
|
|
62
|
+
if (params.orderId !== undefined && params.orderId === 0n) {
|
|
63
|
+
throw new Error("orderId must be non-zero");
|
|
64
|
+
}
|
|
56
65
|
const routerProgramId = context.routerProgramId;
|
|
57
66
|
const zeroblockFeeVault = context.zeroblockFeeVault;
|
|
58
67
|
const pumpMint = toPk(market.mint);
|
|
@@ -76,12 +85,18 @@ export function buildPumpfunSwapInstruction(params) {
|
|
|
76
85
|
const orderId = params.orderId ?? randomOrderId();
|
|
77
86
|
const dexVariant = side === "buy" ? { PumpfunBuy: {} } : { PumpfunSell: {} };
|
|
78
87
|
const amountIn = bnFromBigint(params.amountIn, "amountIn", 64);
|
|
88
|
+
const minReturn = bnFromBigint(params.minReturn, "minReturn", 64);
|
|
79
89
|
const swapArgs = {
|
|
80
90
|
amount_in: amountIn,
|
|
81
|
-
min_return:
|
|
91
|
+
min_return: minReturn,
|
|
82
92
|
amounts: [amountIn],
|
|
83
93
|
routes: [[{ dexes: [dexVariant], weights: Buffer.from([100]) }]],
|
|
84
|
-
|
|
94
|
+
// H2 (fail-closed slippage): the router REQUIRES an explicit downside
|
|
95
|
+
// bound via options.slippage and rejects a zero effective bound; the bare
|
|
96
|
+
// min_return field alone is not trusted. MinOut carries our computed bound.
|
|
97
|
+
// NOTE (M1): for sells the fee is skimmed from the wSOL output, and the
|
|
98
|
+
// bound is enforced on the user's NET receipt — quote accordingly.
|
|
99
|
+
options: { slippage: { MinOut: [minReturn] } },
|
|
85
100
|
};
|
|
86
101
|
// Random pick among the non-zero buyback recipients — the program validates
|
|
87
102
|
// membership on-chain, and ops pre-load all eight into the shared ALT.
|
|
@@ -134,6 +149,13 @@ export function buildPumpfunSwapInstruction(params) {
|
|
|
134
149
|
fixedKeys = [
|
|
135
150
|
{ pubkey: user, isWritable: true, isSigner: true },
|
|
136
151
|
{ pubkey: deriveWrapperConfig(wrapperProgramId), isWritable: false, isSigner: false },
|
|
152
|
+
// Exactly-once replay gate: init'd by the wrapper; a duplicate
|
|
153
|
+
// (payer, order_id) fails at create_account and reverts the swap.
|
|
154
|
+
{
|
|
155
|
+
pubkey: deriveOrderMarker(wrapperProgramId, user, orderId),
|
|
156
|
+
isWritable: true,
|
|
157
|
+
isSigner: false,
|
|
158
|
+
},
|
|
137
159
|
{ pubkey: routerProgramId, isWritable: false, isSigner: false },
|
|
138
160
|
{ pubkey: sourceTokenAccount, isWritable: true, isSigner: false },
|
|
139
161
|
{ pubkey: destinationTokenAccount, isWritable: true, isSigner: false },
|
package/dist/transaction.d.ts
CHANGED
|
@@ -17,3 +17,34 @@ export declare function buildPumpfunSwapTransaction(params: BuildPumpfunSwapPara
|
|
|
17
17
|
* requiredSigners order and return the wire-ready bytes.
|
|
18
18
|
*/
|
|
19
19
|
export declare function serializeWithSignatures(result: BuildSwapResult, signatures: Uint8Array[]): Uint8Array;
|
|
20
|
+
/**
|
|
21
|
+
* A submit template for a signer-and-submitter that is CHAIN-AGNOSTIC (e.g.
|
|
22
|
+
* sigcore): it signs `payload` and splices the raw signature into
|
|
23
|
+
* `wireTemplate` at `signatureOffset`, then broadcasts the result — with no
|
|
24
|
+
* knowledge of Solana's transaction format.
|
|
25
|
+
*
|
|
26
|
+
* The layout works because a Solana v0 transaction is
|
|
27
|
+
* `[compact-u16 sig count][sig0..sigN-1][message]`, and the bytes that get
|
|
28
|
+
* signed are exactly the `[message]` tail. `wireTemplate` is that full
|
|
29
|
+
* structure with the signature region zeroed; splicing the 64-byte signature
|
|
30
|
+
* over the zeros yields bytes identical to `serializeWithSignatures`.
|
|
31
|
+
*
|
|
32
|
+
* Single-signer only (the RAX flow): exactly one signature at a fixed offset.
|
|
33
|
+
*/
|
|
34
|
+
export interface SubmitTemplate {
|
|
35
|
+
/** The bytes the signer must sign (the transaction message). Hex-encoded. */
|
|
36
|
+
payloadHex: string;
|
|
37
|
+
/** Full wire transaction with the signature zeroed. Base64-encoded. */
|
|
38
|
+
wireTemplateBase64: string;
|
|
39
|
+
/** Byte offset in the template where the 64-byte signature is spliced in. */
|
|
40
|
+
signatureOffset: number;
|
|
41
|
+
/** Signature length in bytes (64 for ed25519). */
|
|
42
|
+
signatureLength: number;
|
|
43
|
+
/** The single required signer's base58 address (the user). */
|
|
44
|
+
signer: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Emit a chain-agnostic {@link SubmitTemplate} from a built single-signer
|
|
48
|
+
* transaction. The offset is derived from the wire layout, not assumed.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildSubmitTemplate(result: BuildSwapResult): SubmitTemplate;
|
package/dist/transaction.js
CHANGED
|
@@ -4,7 +4,7 @@ import { toPk } from "./pda.js";
|
|
|
4
4
|
import { buildComputeBudgetInstructions } from "./computeBudget.js";
|
|
5
5
|
import { buildPumpfunSwapInstruction } from "./swap.js";
|
|
6
6
|
import { buildTipInstruction, maskTipAccountInTables } from "./tip.js";
|
|
7
|
-
import {
|
|
7
|
+
import { closeAccountInstruction, createAtaIdempotentInstruction, unwrapWsolInstruction, wrapSolInstructions, } from "./wsol.js";
|
|
8
8
|
/** Rehydrate a streamed lookup table into web3.js form (compile-time only fields defaulted). */
|
|
9
9
|
export function toLookupTableAccount(data) {
|
|
10
10
|
return new web3.AddressLookupTableAccount({
|
|
@@ -45,26 +45,59 @@ export function buildPumpfunSwapTransaction(params) {
|
|
|
45
45
|
if (params.computeBudget) {
|
|
46
46
|
instructions.push(...buildComputeBudgetInstructions(params.computeBudget));
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
// TENANT MODE: the wrapper program manages the entire native-SOL lifecycle
|
|
49
|
+
// on-chain (ATA creation, wrap sized with exact on-chain fee headroom,
|
|
50
|
+
// post-swap sweep, proceeds unwrap, emptied-ATA cleanup) — the client adds
|
|
51
|
+
// NO wSOL/ATA instructions. DIRECT MODE: the router does none of that, so
|
|
52
|
+
// the client composes it here.
|
|
53
|
+
const clientManagesWsol = params.context.mode === "direct";
|
|
54
|
+
if (clientManagesWsol) {
|
|
55
|
+
if (params.side === "buy") {
|
|
56
|
+
if (params.wrapSol ?? true) {
|
|
57
|
+
// The router's input-side fee transfer draws from this same account
|
|
58
|
+
// AFTER the swap consumes amountIn — wrap fee headroom on top (ceil),
|
|
59
|
+
// or the fee transfer fails with insufficient funds.
|
|
60
|
+
const feeBps = BigInt(params.totalFeeBps ?? 0);
|
|
61
|
+
const feeHeadroom = (params.amountIn * feeBps + 9999n) / 10000n;
|
|
62
|
+
instructions.push(...wrapSolInstructions({ user, lamports: params.amountIn + feeHeadroom }));
|
|
63
|
+
}
|
|
64
|
+
instructions.push(createAtaIdempotentInstruction({
|
|
65
|
+
payer: user,
|
|
66
|
+
owner: user,
|
|
67
|
+
mint: toPk(params.market.mint),
|
|
68
|
+
tokenProgram: toPk(params.market.mintTokenProgram),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Selling into wSOL: the wSOL ATA may not exist between trades.
|
|
73
|
+
instructions.push(createAtaIdempotentInstruction({ payer: user, owner: user, mint: toPk("So11111111111111111111111111111111111111112") }));
|
|
53
74
|
}
|
|
54
|
-
instructions.push(createAtaIdempotentInstruction({
|
|
55
|
-
payer: user,
|
|
56
|
-
owner: user,
|
|
57
|
-
mint: toPk(params.market.mint),
|
|
58
|
-
tokenProgram: toPk(params.market.mintTokenProgram),
|
|
59
|
-
}));
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
// Selling into wSOL: the wSOL ATA may not exist between trades.
|
|
63
|
-
instructions.push(createAtaIdempotentInstruction({ payer: user, owner: user, mint: toPk("So11111111111111111111111111111111111111112") }));
|
|
64
75
|
}
|
|
65
76
|
instructions.push(swap.instruction);
|
|
66
|
-
if (
|
|
67
|
-
|
|
77
|
+
if (clientManagesWsol) {
|
|
78
|
+
if (params.side === "buy" && (params.wrapSol ?? true)) {
|
|
79
|
+
// Sweep the wSOL account after the swap: returns unused fee headroom and
|
|
80
|
+
// the ATA rent as native SOL (closing a native account pays out ALL its
|
|
81
|
+
// lamports — that IS the unwrap).
|
|
82
|
+
instructions.push(closeAccountInstruction({
|
|
83
|
+
account: swap.sourceTokenAccount,
|
|
84
|
+
destination: user,
|
|
85
|
+
owner: user,
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
if (params.side === "sell" && params.closeTokenAccount) {
|
|
89
|
+
// Full-balance sell: reclaim the empty token ATA's rent for the user.
|
|
90
|
+
// CloseAccount requires balance == 0, so a partial sell with this flag
|
|
91
|
+
// reverts the entire transaction (deliberate fail-loud behavior).
|
|
92
|
+
instructions.push(closeAccountInstruction({
|
|
93
|
+
account: swap.sourceTokenAccount,
|
|
94
|
+
destination: user,
|
|
95
|
+
owner: user,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
if (params.side === "sell" && (params.unwrapWsol ?? true)) {
|
|
99
|
+
instructions.push(unwrapWsolInstruction(user));
|
|
100
|
+
}
|
|
68
101
|
}
|
|
69
102
|
let tables = (params.lookupTables ?? []).map(toLookupTableAccount);
|
|
70
103
|
if (params.tip) {
|
|
@@ -104,3 +137,55 @@ export function serializeWithSignatures(result, signatures) {
|
|
|
104
137
|
}
|
|
105
138
|
return result.transaction.serialize();
|
|
106
139
|
}
|
|
140
|
+
/** compact-u16 (shortvec) encoded length — how Solana prefixes the sig array. */
|
|
141
|
+
function compactU16Length(n) {
|
|
142
|
+
if (n < 0x80)
|
|
143
|
+
return 1;
|
|
144
|
+
if (n < 0x4000)
|
|
145
|
+
return 2;
|
|
146
|
+
return 3;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Emit a chain-agnostic {@link SubmitTemplate} from a built single-signer
|
|
150
|
+
* transaction. The offset is derived from the wire layout, not assumed.
|
|
151
|
+
*/
|
|
152
|
+
export function buildSubmitTemplate(result) {
|
|
153
|
+
const header = result.transaction.message.header;
|
|
154
|
+
if (header.numRequiredSignatures !== 1) {
|
|
155
|
+
throw new Error(`submit template supports a single signer; got ${header.numRequiredSignatures}`);
|
|
156
|
+
}
|
|
157
|
+
const SIG_LEN = 64;
|
|
158
|
+
// Zeroed-signature serialization IS the template (web3.js fills missing
|
|
159
|
+
// signatures with 64 zero bytes), so no manual zeroing is needed.
|
|
160
|
+
const wireTemplate = result.transaction.serialize();
|
|
161
|
+
const signatureOffset = compactU16Length(1); // count prefix precedes sig 0
|
|
162
|
+
// Invariant: the payload (message) is the tail after [count][signature].
|
|
163
|
+
const messageStart = signatureOffset + SIG_LEN;
|
|
164
|
+
const templateTail = wireTemplate.slice(messageStart);
|
|
165
|
+
if (templateTail.length !== result.messageBytes.length ||
|
|
166
|
+
!templateTail.every((b, i) => b === result.messageBytes[i])) {
|
|
167
|
+
throw new Error("submit template layout mismatch — message tail differs");
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
payloadHex: bytesToHex(result.messageBytes),
|
|
171
|
+
wireTemplateBase64: toBase64(wireTemplate),
|
|
172
|
+
signatureOffset,
|
|
173
|
+
signatureLength: SIG_LEN,
|
|
174
|
+
signer: result.requiredSigners[0].toBase58(),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function bytesToHex(bytes) {
|
|
178
|
+
let hex = "";
|
|
179
|
+
for (const b of bytes)
|
|
180
|
+
hex += b.toString(16).padStart(2, "0");
|
|
181
|
+
return hex;
|
|
182
|
+
}
|
|
183
|
+
function toBase64(bytes) {
|
|
184
|
+
// Buffer in Node; btoa fallback in the browser.
|
|
185
|
+
if (typeof Buffer !== "undefined")
|
|
186
|
+
return Buffer.from(bytes).toString("base64");
|
|
187
|
+
let binary = "";
|
|
188
|
+
for (const b of bytes)
|
|
189
|
+
binary += String.fromCharCode(b);
|
|
190
|
+
return btoa(binary);
|
|
191
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -69,7 +69,13 @@ export interface BuildPumpfunSwapParams {
|
|
|
69
69
|
amountIn: bigint;
|
|
70
70
|
/** Minimum acceptable output (quote minus slippage), raw units. */
|
|
71
71
|
minReturn: bigint;
|
|
72
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Business order id (non-zero u128), echoed in SwapResultEvent.
|
|
74
|
+
* TENANT MODE: REQUIRED and server-authoritative — it keys the wrapper's
|
|
75
|
+
* per-(payer, order_id) replay marker, so all retries/variants of one
|
|
76
|
+
* business order MUST reuse the same id (mint it on your backend).
|
|
77
|
+
* DIRECT MODE: optional; random when omitted (no replay marker).
|
|
78
|
+
*/
|
|
73
79
|
orderId?: bigint;
|
|
74
80
|
/** A FINALIZED blockhash (gateway forwards to a different staked node). */
|
|
75
81
|
recentBlockhash: string;
|
|
@@ -79,12 +85,25 @@ export interface BuildPumpfunSwapParams {
|
|
|
79
85
|
tip?: TipParams | null;
|
|
80
86
|
computeBudget?: ComputeBudgetParams | null;
|
|
81
87
|
/**
|
|
82
|
-
* buy only: prepend create-wSOL-ATA (idempotent) + transfer +
|
|
83
|
-
* the user trades from native SOL
|
|
88
|
+
* direct buy only: prepend create-wSOL-ATA (idempotent) + transfer +
|
|
89
|
+
* syncNative so the user trades from native SOL. Default true.
|
|
84
90
|
*/
|
|
85
91
|
wrapSol?: boolean;
|
|
86
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* direct buy only: total commission bps (0Block fee) used to size the wSOL
|
|
94
|
+
* wrap — the router collects input-side fees FROM the source wSOL account
|
|
95
|
+
* AFTER the swap consumes amountIn. Excess is swept back by the post-swap
|
|
96
|
+
* close. Default 0 (no headroom).
|
|
97
|
+
*/
|
|
98
|
+
totalFeeBps?: number;
|
|
99
|
+
/** direct sell only: close the wSOL ATA so proceeds land as native SOL. Default true. */
|
|
87
100
|
unwrapWsol?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* direct sell only: close the (now empty) token ATA after the swap,
|
|
103
|
+
* refunding its rent to the user. ONLY set when selling the ENTIRE balance
|
|
104
|
+
* — any remainder reverts the whole transaction. Default false.
|
|
105
|
+
*/
|
|
106
|
+
closeTokenAccount?: boolean;
|
|
88
107
|
}
|
|
89
108
|
export interface BuildSwapResult {
|
|
90
109
|
/** The unsigned v0 transaction. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0block.io/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Client-side transaction builder for the 0Block DEX router. Builds unsigned v0 swap transactions entirely offline
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Client-side transaction builder for the 0Block DEX router. Builds unsigned v0 swap transactions entirely offline \u2014 tenant-wrapped or direct \u2014 with shared address lookup tables, gateway tips, and on-chain fee-event decoding for accounting.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"solana",
|
|
7
7
|
"dex",
|
|
@@ -44,4 +44,4 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"typescript": "^5.5.4"
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
}
|