@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/README.md
CHANGED
|
@@ -3,10 +3,17 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@0block.io/sdk)
|
|
4
4
|
[](https://www.npmjs.com/package/@0block.io/sdk)
|
|
5
5
|
|
|
6
|
-
**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
**The SDK for 0Block's two products — independent, composable:**
|
|
7
|
+
|
|
8
|
+
| Product | What it does | Needs the other? |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| **DEX Smart Router** | Build swap transactions on-chain-routed across 60+ venues — through your tenant wrapper (your fee applies) or directly (0Block fee only) | No — submit through any RPC |
|
|
11
|
+
| **Landing Service** | Land **any** fully-signed Solana transaction: tip-gated submission forwarded to staked infrastructure and current/next leader TPUs | No — accepts any transaction |
|
|
12
|
+
|
|
13
|
+
Used together they form a complete trade pipeline: build with the router SDK,
|
|
14
|
+
sign externally, land through the service.
|
|
15
|
+
|
|
16
|
+
**Router highlights:**
|
|
10
17
|
|
|
11
18
|
- **Zero network calls at trade time.** Market context, lookup tables, and a
|
|
12
19
|
blockhash are resolved once server-side and streamed; the client assembles
|
|
@@ -14,6 +21,8 @@ accounting.
|
|
|
14
21
|
- **One signature.** The end user is the only required signer, in both modes.
|
|
15
22
|
- **Fees are on-chain, not inputs.** Tenant and platform commissions are read
|
|
16
23
|
and enforced by the programs; the SDK never accepts a fee parameter.
|
|
24
|
+
- **SOL-native UX, program-managed.** In tenant mode the wrapper wraps/unwraps
|
|
25
|
+
and cleans up token accounts on-chain — clients never touch wSOL.
|
|
17
26
|
- **External-signer native.** Returns the exact message bytes to sign, for
|
|
18
27
|
wallets, signing services, or HSMs — no `Keypair` ever touches the SDK.
|
|
19
28
|
|
|
@@ -117,6 +126,36 @@ const events = decodeSwapResultEvents(tx.meta.logMessages);
|
|
|
117
126
|
// items: [{ kind: "platform" | "tenant", bps, amount, tenantProgram }] } }]
|
|
118
127
|
```
|
|
119
128
|
|
|
129
|
+
## Landing Service (standalone)
|
|
130
|
+
|
|
131
|
+
Land any transaction — router-built or otherwise. Three rules: include the
|
|
132
|
+
tip (a plain transfer to an allowlisted account, kept as a **static** message
|
|
133
|
+
key, never behind a lookup table), use a **finalized** blockhash, and confirm
|
|
134
|
+
by **polling** (no websocket).
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { createLandingClient, withLandingTip } from "@0block.io/sdk";
|
|
138
|
+
|
|
139
|
+
// Any instructions at all — no router required:
|
|
140
|
+
const ixs = withLandingTip(myInstructions, payer, {
|
|
141
|
+
account: tipAccount, // allowlisted tip account
|
|
142
|
+
lamports: 1_000_000n, // ≥ the service minimum
|
|
143
|
+
});
|
|
144
|
+
// ...compile with a FINALIZED blockhash, sign...
|
|
145
|
+
|
|
146
|
+
const landing = createLandingClient({
|
|
147
|
+
url: "https://<landing-endpoint>",
|
|
148
|
+
apiKey: process.env.ZEROBLOCK_API_KEY,
|
|
149
|
+
});
|
|
150
|
+
const { signature, slot } = await landing.submitAndConfirm(wireBytes, readConnection, {
|
|
151
|
+
lastValidBlockHeight,
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Router-built transactions already carry the tip when you pass `tip` to
|
|
156
|
+
`buildPumpfunSwapTransaction` — hand their signed wire bytes straight to
|
|
157
|
+
`landing.sendTransaction`.
|
|
158
|
+
|
|
120
159
|
## API overview
|
|
121
160
|
|
|
122
161
|
| Runs | Function | Purpose |
|
|
@@ -135,6 +174,13 @@ exported as well.
|
|
|
135
174
|
|
|
136
175
|
## Operational notes
|
|
137
176
|
|
|
177
|
+
- **Order ids are server-authoritative in tenant mode.** The wrapper enforces
|
|
178
|
+
an exactly-once replay gate keyed by `(payer, order_id)`: a duplicate order
|
|
179
|
+
id fails at account creation and the whole swap reverts. Mint `orderId` on
|
|
180
|
+
your backend (non-zero u128, one per business order — reuse it across
|
|
181
|
+
retries) and pass it to `buildPumpfunSwapTransaction`; the SDK refuses to
|
|
182
|
+
build tenant swaps without one. Direct mode has no marker; a random id is
|
|
183
|
+
generated when omitted.
|
|
138
184
|
- **Tenant mode prerequisites.** Your wrapper must be the build in which the
|
|
139
185
|
`wrapper_config` PDA signs the router CPI, and the router's
|
|
140
186
|
`TenantConfig.tenant_authority` must equal that PDA
|
package/dist/constants.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare const FEE_MINT_ALLOWLIST: readonly string[];
|
|
|
20
20
|
export declare const PUMPFUN_PROGRAM_ID: web3.PublicKey;
|
|
21
21
|
export declare const PUMPFUN_FEE_PROGRAM_ID: web3.PublicKey;
|
|
22
22
|
export declare const SEED_WRAPPER_CONFIG: Uint8Array<ArrayBuffer>;
|
|
23
|
+
export declare const SEED_ORDER_MARKER: Uint8Array<ArrayBuffer>;
|
|
23
24
|
export declare const SEED_ROUTER_GLOBAL_CONFIG: Uint8Array<ArrayBuffer>;
|
|
24
25
|
export declare const SEED_ROUTER_TENANT: Uint8Array<ArrayBuffer>;
|
|
25
26
|
export declare const SEED_PUMPFUN_GLOBAL: Uint8Array<ArrayBuffer>;
|
package/dist/constants.js
CHANGED
|
@@ -29,6 +29,7 @@ export const PUMPFUN_PROGRAM_ID = new web3.PublicKey("6EF8rrecthR5Dkzon8Nwu78hRv
|
|
|
29
29
|
export const PUMPFUN_FEE_PROGRAM_ID = new web3.PublicKey("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
|
|
30
30
|
const te = new TextEncoder();
|
|
31
31
|
export const SEED_WRAPPER_CONFIG = te.encode("tenant_wrapper_config");
|
|
32
|
+
export const SEED_ORDER_MARKER = te.encode("order");
|
|
32
33
|
export const SEED_ROUTER_GLOBAL_CONFIG = te.encode("config");
|
|
33
34
|
export const SEED_ROUTER_TENANT = te.encode("tenant");
|
|
34
35
|
export const SEED_PUMPFUN_GLOBAL = te.encode("global");
|
|
@@ -74,6 +74,7 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
74
74
|
}];
|
|
75
75
|
}, {
|
|
76
76
|
readonly name: "swap";
|
|
77
|
+
readonly docs: readonly ["Tenant swap with a hard, exactly-once-SUCCESS replay gate (R-6 / H1).", "", "The `order_marker` account is created with Anchor `init` (NOT", "`init_if_needed`) ATOMICALLY in this same instruction, BEFORE the router", "CPI runs. A second instruction with the same `(payer, order_id)` fails at", "`create_account` (\"account already in use\") and reverts the WHOLE", "instruction — including the router CPI — so a duplicate business order can", "never execute (and never pays fees) twice.", "", "INVARIANTS (off-chain encoder MUST uphold):", "- `order_id` is SERVER-AUTHORITATIVE. It is minted by the backend per", "business order and is NEVER a client-supplied value. A client that could", "choose `order_id` could grief a victim only inside its own `payer`", "namespace (see namespacing note below), but a server-authoritative id", "also guarantees that all per-gate provider-variants (0block / Jito /", "Helius / ...) of ONE business order reuse the SAME `(payer, order_id)`,", "so at most one variant can ever succeed.", "- On land-but-revert (the tx is included on-chain but the instruction", "reverts for any reason), the `init` is rolled back: the marker does NOT", "persist, the `order_id` is reclaimable, and the order may be retried with", "a FRESH durable nonce. (Durable-nonce dedup is at-most-one-LAND; this", "marker is exactly-once-SUCCESS — complementary, not redundant.)"];
|
|
77
78
|
readonly discriminator: readonly [248, 198, 158, 145, 225, 117, 135, 200];
|
|
78
79
|
readonly accounts: readonly [{
|
|
79
80
|
readonly name: "payer";
|
|
@@ -88,17 +89,33 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
88
89
|
readonly value: readonly [116, 101, 110, 97, 110, 116, 95, 119, 114, 97, 112, 112, 101, 114, 95, 99, 111, 110, 102, 105, 103];
|
|
89
90
|
}];
|
|
90
91
|
};
|
|
92
|
+
}, {
|
|
93
|
+
readonly name: "order_marker";
|
|
94
|
+
readonly docs: readonly ["Per-order replay marker (R-6 / H1). `init` (NOT `init_if_needed`) makes a", "duplicate `(payer, order_id)` fail at `create_account` → the whole", "instruction (router CPI included) reverts.", "", "Namespaced by `payer` for griefing isolation: a third party can only ever", "init markers inside its OWN payer namespace, so it cannot pre-burn another", "user's `order_id`.", "", "ALTERNATIVE NAMESPACING: keying by `tenant_authority` instead of `payer`", "would dedup per business tenant (so the same logical order is unique across", "all of a tenant's relayer payers). We choose `payer` here because the RAX", "flow has one user-payer per order and `payer`-namespacing gives the", "strongest third-party griefing isolation; revisit if a single business", "order can legitimately arrive under multiple distinct payers."];
|
|
95
|
+
readonly writable: true;
|
|
96
|
+
readonly pda: {
|
|
97
|
+
readonly seeds: readonly [{
|
|
98
|
+
readonly kind: "const";
|
|
99
|
+
readonly value: readonly [111, 114, 100, 101, 114];
|
|
100
|
+
}, {
|
|
101
|
+
readonly kind: "account";
|
|
102
|
+
readonly path: "payer";
|
|
103
|
+
}, {
|
|
104
|
+
readonly kind: "arg";
|
|
105
|
+
readonly path: "order_id";
|
|
106
|
+
}];
|
|
107
|
+
};
|
|
91
108
|
}, {
|
|
92
109
|
readonly name: "router_program";
|
|
93
110
|
readonly docs: readonly ["Router program (hard-checked by address)"];
|
|
94
111
|
readonly address: "zeroRxfemoQCz6JT7RyShjuuRCN7VZof1WSekfXhmEn";
|
|
95
112
|
}, {
|
|
96
113
|
readonly name: "source_token_account";
|
|
97
|
-
readonly docs: readonly ["SOURCE token account (authority = payer)"];
|
|
114
|
+
readonly docs: readonly ["SOURCE token account (authority = payer).", "buys (Anchor deserializes typed accounts before the handler runs, which", "would reject a not-yet-existing ATA). The router CPI re-validates", "`token::mint = source_mint, token::authority = payer` on this account."];
|
|
98
115
|
readonly writable: true;
|
|
99
116
|
}, {
|
|
100
117
|
readonly name: "destination_token_account";
|
|
101
|
-
readonly docs: readonly ["DESTINATION token account (receives the swap output)"];
|
|
118
|
+
readonly docs: readonly ["DESTINATION token account (receives the swap output).", "M2: authority must be `payer` so output cannot be routed to an arbitrary", "same-mint account — enforced by the ROUTER's account constraints."];
|
|
102
119
|
readonly writable: true;
|
|
103
120
|
}, {
|
|
104
121
|
readonly name: "source_mint";
|
|
@@ -106,10 +123,10 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
106
123
|
readonly name: "destination_mint";
|
|
107
124
|
}, {
|
|
108
125
|
readonly name: "global_cfg";
|
|
109
|
-
readonly docs: readonly ["Global config (router PDA)"];
|
|
126
|
+
readonly docs: readonly ["Global config (router PDA; owner/discriminator checked here, PDA seeds", "re-validated by the router). Typed so the wrapper can read the 0Block", "fee bps for exact wSOL fee-headroom sizing."];
|
|
110
127
|
}, {
|
|
111
128
|
readonly name: "tenant_cfg";
|
|
112
|
-
readonly docs: readonly ["Tenant config (router PDA)"];
|
|
129
|
+
readonly docs: readonly ["Tenant config (router PDA; owner/discriminator checked here, PDA seeds", "re-validated by the router)."];
|
|
113
130
|
}, {
|
|
114
131
|
readonly name: "zeroblock_sol_vault";
|
|
115
132
|
readonly docs: readonly ["0BLOCK fee authority (owns 0BLOCK fee token accounts)"];
|
|
@@ -138,7 +155,7 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
138
155
|
readonly address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
139
156
|
}, {
|
|
140
157
|
readonly name: "system_program";
|
|
141
|
-
readonly optional:
|
|
158
|
+
readonly docs: readonly ["REQUIRED (was optional): the `order_marker` `init` needs the System", "program, and it is also forwarded to the router for fee-ATA creation."];
|
|
142
159
|
readonly address: "11111111111111111111111111111111";
|
|
143
160
|
}, {
|
|
144
161
|
readonly name: "ix_sysvar";
|
|
@@ -158,6 +175,15 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
158
175
|
}];
|
|
159
176
|
}];
|
|
160
177
|
readonly accounts: readonly [{
|
|
178
|
+
readonly name: "GlobalConfig";
|
|
179
|
+
readonly discriminator: readonly [149, 8, 156, 202, 160, 252, 176, 217];
|
|
180
|
+
}, {
|
|
181
|
+
readonly name: "OrderMarker";
|
|
182
|
+
readonly discriminator: readonly [221, 221, 169, 152, 245, 69, 110, 108];
|
|
183
|
+
}, {
|
|
184
|
+
readonly name: "TenantConfig";
|
|
185
|
+
readonly discriminator: readonly [195, 252, 97, 104, 160, 30, 231, 112];
|
|
186
|
+
}, {
|
|
161
187
|
readonly name: "TenantWrapperConfig";
|
|
162
188
|
readonly discriminator: readonly [221, 67, 69, 41, 128, 45, 34, 31];
|
|
163
189
|
}];
|
|
@@ -169,6 +195,26 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
169
195
|
readonly code: 6001;
|
|
170
196
|
readonly name: "InvalidAdmin";
|
|
171
197
|
readonly msg: "Admin cannot be the default pubkey";
|
|
198
|
+
}, {
|
|
199
|
+
readonly code: 6002;
|
|
200
|
+
readonly name: "ZeroOrderId";
|
|
201
|
+
readonly msg: "order_id must be non-zero";
|
|
202
|
+
}, {
|
|
203
|
+
readonly code: 6003;
|
|
204
|
+
readonly name: "MissingTokenProgram";
|
|
205
|
+
readonly msg: "token program account is required for native-SOL handling";
|
|
206
|
+
}, {
|
|
207
|
+
readonly code: 6004;
|
|
208
|
+
readonly name: "MissingAssociatedTokenProgram";
|
|
209
|
+
readonly msg: "associated token program account is required for native-SOL handling";
|
|
210
|
+
}, {
|
|
211
|
+
readonly code: 6005;
|
|
212
|
+
readonly name: "AmountOverflow";
|
|
213
|
+
readonly msg: "amount_in plus fees overflows u64";
|
|
214
|
+
}, {
|
|
215
|
+
readonly code: 6006;
|
|
216
|
+
readonly name: "InvalidTokenAccount";
|
|
217
|
+
readonly msg: "account is not a valid SPL token account";
|
|
172
218
|
}];
|
|
173
219
|
readonly types: readonly [{
|
|
174
220
|
readonly name: "Dex";
|
|
@@ -307,6 +353,81 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
307
353
|
readonly name: "SolRfq";
|
|
308
354
|
}];
|
|
309
355
|
};
|
|
356
|
+
}, {
|
|
357
|
+
readonly name: "GlobalConfig";
|
|
358
|
+
readonly serialization: "bytemuckunsafe";
|
|
359
|
+
readonly repr: {
|
|
360
|
+
readonly kind: "c";
|
|
361
|
+
};
|
|
362
|
+
readonly type: {
|
|
363
|
+
readonly kind: "struct";
|
|
364
|
+
readonly fields: readonly [{
|
|
365
|
+
readonly name: "bump";
|
|
366
|
+
readonly docs: readonly ["PDA bump"];
|
|
367
|
+
readonly type: "u8";
|
|
368
|
+
}, {
|
|
369
|
+
readonly name: "admin";
|
|
370
|
+
readonly docs: readonly ["Program admin (controls global/tenant settings)"];
|
|
371
|
+
readonly type: "pubkey";
|
|
372
|
+
}, {
|
|
373
|
+
readonly name: "zeroblock_fee_bps";
|
|
374
|
+
readonly docs: readonly ["0BLOCK platform fee default (bps out of 10_000)"];
|
|
375
|
+
readonly type: "u16";
|
|
376
|
+
}, {
|
|
377
|
+
readonly name: "zeroblock_fee_vault";
|
|
378
|
+
readonly docs: readonly ["Fee authority that owns 0BLOCK fee token accounts"];
|
|
379
|
+
readonly type: "pubkey";
|
|
380
|
+
}, {
|
|
381
|
+
readonly name: "paused";
|
|
382
|
+
readonly docs: readonly ["A2 (remediation-2026-07-02): global instant-halt switch. `0` = not", "paused (default; matches the zeroed tail of every already-deployed", "account), `1` = paused. Plain `u8` rather than `bool` — zero_copy/Pod", "requires every byte pattern to be valid, which `bool` does not", "guarantee. Use `is_paused()`/`set_paused()`, never the raw field."];
|
|
383
|
+
readonly type: "u8";
|
|
384
|
+
}, {
|
|
385
|
+
readonly name: "spl_token_swap_allowlist";
|
|
386
|
+
readonly docs: readonly ["A1 (remediation-2026-07-02): admin-provisioned CPI-target allowlist", "for the `SplTokenSwap` (Dex=0) adapter — the router invokes", "`swap_accounts.dex_program_id` with the `0block_sa` PDA as signer on", "hop ≥ 1, so an unconstrained target is a confused-deputy sweep of any", "PDA-held funds. Unlike the other ~60 adapters this venue has no", "single hardcoded upstream program id (multiple live forks share the", "same instruction interface), so the allowed set is admin-configured", "instead of a compile-time const. Unset slots are `Pubkey::default()`", "and never match; an all-default allowlist rejects every CPI (fail", "closed) until an admin provisions it via `set_spl_token_swap_allowlist`", "(see `// TODO(remediation-2026-07-02):` in `adapters/spl_token_swap.rs`", "— provisioning real venue ids is a deploy-config/operator action, out", "of scope for this remediation pass, same as the plan's other", "\"provisioning\" items)."];
|
|
387
|
+
readonly type: {
|
|
388
|
+
readonly array: readonly ["pubkey", 2];
|
|
389
|
+
};
|
|
390
|
+
}, {
|
|
391
|
+
readonly name: "stable_swap_allowlist";
|
|
392
|
+
readonly docs: readonly ["A1 (remediation-2026-07-02): same contract as", "`spl_token_swap_allowlist`, for the `StableSwap` (Dex=1) adapter."];
|
|
393
|
+
readonly type: {
|
|
394
|
+
readonly array: readonly ["pubkey", 2];
|
|
395
|
+
};
|
|
396
|
+
}, {
|
|
397
|
+
readonly name: "padding";
|
|
398
|
+
readonly docs: readonly ["Reserved to keep struct size stable for future upgrades. Shrunk from", "the original 160 bytes by exactly the width of the fields above (see", "`REMAINING_PADDING_BYTES`) so total account size is unchanged."];
|
|
399
|
+
readonly type: {
|
|
400
|
+
readonly array: readonly ["u8", 31];
|
|
401
|
+
};
|
|
402
|
+
}];
|
|
403
|
+
};
|
|
404
|
+
}, {
|
|
405
|
+
readonly name: "OrderMarker";
|
|
406
|
+
readonly docs: readonly ["Per-order replay marker (R-6 / H1). Audit-only fields — the account's", "EXISTENCE under seeds `[b\"order\", payer, order_id_le]` IS the dedup signal."];
|
|
407
|
+
readonly type: {
|
|
408
|
+
readonly kind: "struct";
|
|
409
|
+
readonly fields: readonly [{
|
|
410
|
+
readonly name: "order_id";
|
|
411
|
+
readonly docs: readonly ["The server-authoritative business order id this marker pins."];
|
|
412
|
+
readonly type: "u128";
|
|
413
|
+
}, {
|
|
414
|
+
readonly name: "authority";
|
|
415
|
+
readonly docs: readonly ["The payer namespace this marker was created under (== `payer`)."];
|
|
416
|
+
readonly type: "pubkey";
|
|
417
|
+
}, {
|
|
418
|
+
readonly name: "slot";
|
|
419
|
+
readonly docs: readonly ["Slot at creation (forensics only)."];
|
|
420
|
+
readonly type: "u64";
|
|
421
|
+
}, {
|
|
422
|
+
readonly name: "unix_timestamp";
|
|
423
|
+
readonly docs: readonly ["Unix timestamp at creation (forensics only)."];
|
|
424
|
+
readonly type: "i64";
|
|
425
|
+
}, {
|
|
426
|
+
readonly name: "bump";
|
|
427
|
+
readonly docs: readonly ["PDA bump."];
|
|
428
|
+
readonly type: "u8";
|
|
429
|
+
}];
|
|
430
|
+
};
|
|
310
431
|
}, {
|
|
311
432
|
readonly name: "Route";
|
|
312
433
|
readonly type: {
|
|
@@ -395,6 +516,46 @@ export declare const TENANT_WRAPPER_IDL: {
|
|
|
395
516
|
};
|
|
396
517
|
}];
|
|
397
518
|
};
|
|
519
|
+
}, {
|
|
520
|
+
readonly name: "TenantConfig";
|
|
521
|
+
readonly docs: readonly ["----------------------------------------------------------------------------", "TenantConfig (+ strict wrapper enforcement)", "----------------------------------------------------------------------------"];
|
|
522
|
+
readonly type: {
|
|
523
|
+
readonly kind: "struct";
|
|
524
|
+
readonly fields: readonly [{
|
|
525
|
+
readonly name: "bump";
|
|
526
|
+
readonly type: "u8";
|
|
527
|
+
}, {
|
|
528
|
+
readonly name: "tenant_authority";
|
|
529
|
+
readonly docs: readonly ["Signer (EOA or PDA) authorized to act for this tenant"];
|
|
530
|
+
readonly type: "pubkey";
|
|
531
|
+
}, {
|
|
532
|
+
readonly name: "tenant_wrapper_program";
|
|
533
|
+
readonly docs: readonly ["Wrapper program id used to validate tenant-mode calls."];
|
|
534
|
+
readonly type: "pubkey";
|
|
535
|
+
}, {
|
|
536
|
+
readonly name: "zeroblock_fee_bps";
|
|
537
|
+
readonly docs: readonly ["0BLOCK fee (bps out of 10_000) for this tenant. Use 0 to fall back to global default."];
|
|
538
|
+
readonly type: "u16";
|
|
539
|
+
}, {
|
|
540
|
+
readonly name: "tenant_fee_vault";
|
|
541
|
+
readonly docs: readonly ["Fee authority that owns tenant fee token accounts"];
|
|
542
|
+
readonly type: "pubkey";
|
|
543
|
+
}, {
|
|
544
|
+
readonly name: "whitelisted";
|
|
545
|
+
readonly docs: readonly ["Whether this tenant is active/whitelisted"];
|
|
546
|
+
readonly type: "bool";
|
|
547
|
+
}, {
|
|
548
|
+
readonly name: "max_total_fee_bps";
|
|
549
|
+
readonly docs: readonly ["Optional per-tenant cap: (tenant_fee_bps + zeroblock_fee_bps) must be <= this if > 0.", "tenant_fee_bps is supplied per swap."];
|
|
550
|
+
readonly type: "u16";
|
|
551
|
+
}, {
|
|
552
|
+
readonly name: "_reserved";
|
|
553
|
+
readonly docs: readonly ["Reserved for upgrades (fixed size)"];
|
|
554
|
+
readonly type: {
|
|
555
|
+
readonly array: readonly ["u8", 64];
|
|
556
|
+
};
|
|
557
|
+
}];
|
|
558
|
+
};
|
|
398
559
|
}, {
|
|
399
560
|
readonly name: "TenantWrapperConfig";
|
|
400
561
|
readonly type: {
|