@gabox-labs/sdk 0.2.0 → 0.7.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/CHANGELOG.md +310 -0
- package/README.md +173 -438
- package/dist/{gaboxV2-CV2XltqC.js → gabox-DGTCh34U.js} +575 -1584
- package/dist/gabox-DGTCh34U.js.map +1 -0
- package/dist/generated/index.d.ts +384 -752
- package/dist/generated/index.js +116 -338
- package/dist/generated/index.js.map +1 -1
- package/dist/index-C4at2cZ_.d.ts +1184 -0
- package/dist/index.d.ts +474 -432
- package/dist/index.js +1186 -1374
- package/dist/index.js.map +1 -1
- package/dist/raydium/index.d.ts +2 -0
- package/dist/raydium/index.js +2 -0
- package/dist/raydium-CU-tZzIk.js +3282 -0
- package/dist/raydium-CU-tZzIk.js.map +1 -0
- package/llms.txt +7 -3
- package/package.json +11 -16
- package/skills/gabox-sdk/SKILL.md +57 -146
- package/skills/gabox-sdk/references/api.md +155 -145
- package/dist/gaboxV2-CV2XltqC.js.map +0 -1
- package/dist/index-BxvSkzCO.d.ts +0 -471
- package/dist/pump/index.d.ts +0 -2
- package/dist/pump/index.js +0 -2
- package/dist/pump-D0K_0uiC.js +0 -1531
- package/dist/pump-D0K_0uiC.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gabox-labs/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "The Solana Kit SDK for gabox
|
|
5
|
+
"description": "The Solana Kit SDK for gabox: generated instruction builders, PDAs, Raydium LaunchLab and CPMM venue accounts, and the pack flow.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
"solana",
|
|
17
17
|
"solana-kit",
|
|
18
18
|
"gabox",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"raydium",
|
|
20
|
+
"launchlab",
|
|
21
|
+
"cpmm",
|
|
21
22
|
"anchor"
|
|
22
23
|
],
|
|
23
24
|
"engines": {
|
|
@@ -40,10 +41,10 @@
|
|
|
40
41
|
"import": "./dist/generated/index.js",
|
|
41
42
|
"default": "./dist/generated/index.js"
|
|
42
43
|
},
|
|
43
|
-
"./
|
|
44
|
-
"types": "./dist/
|
|
45
|
-
"import": "./dist/
|
|
46
|
-
"default": "./dist/
|
|
44
|
+
"./raydium": {
|
|
45
|
+
"types": "./dist/raydium/index.d.ts",
|
|
46
|
+
"import": "./dist/raydium/index.js",
|
|
47
|
+
"default": "./dist/raydium/index.js"
|
|
47
48
|
},
|
|
48
49
|
"./package.json": "./package.json"
|
|
49
50
|
},
|
|
@@ -68,15 +69,9 @@
|
|
|
68
69
|
"prepublishOnly": "npm run typecheck && npm test && npm run check:surface && npm run build && npm run check:package"
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
71
|
-
"@pump-fun/pump-sdk": "1.36.0",
|
|
72
|
-
"@pump-fun/pump-swap-sdk": "1.19.0",
|
|
73
72
|
"@solana-program/system": "^0.13.0",
|
|
74
73
|
"@solana-program/token": "^0.15.0",
|
|
75
|
-
"@solana/program-client-core": "^7.0.0"
|
|
76
|
-
"@solana/spl-token": "^0.4.15",
|
|
77
|
-
"@solana/web3.js": "^1.99.0",
|
|
78
|
-
"bn.js": "^5.2.5",
|
|
79
|
-
"buffer": "^6.0.3"
|
|
74
|
+
"@solana/program-client-core": "^7.0.0"
|
|
80
75
|
},
|
|
81
76
|
"peerDependencies": {
|
|
82
77
|
"@solana/kit": "^7.0.0"
|
|
@@ -86,7 +81,7 @@
|
|
|
86
81
|
"@codama/nodes-from-anchor": "^1.5.3",
|
|
87
82
|
"@codama/renderers-js": "^2.3.1",
|
|
88
83
|
"@solana/kit": "^7.0.0",
|
|
89
|
-
"@
|
|
84
|
+
"@solana/web3.js": "^1.99.0",
|
|
90
85
|
"@types/node": "^24.3.0",
|
|
91
86
|
"codama": "^1.10.0",
|
|
92
87
|
"publint": "0.3.24",
|
|
@@ -1,164 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gabox-sdk
|
|
3
|
-
description: Integrate
|
|
3
|
+
description: Integrate Gabox machines on Solana with @gabox-labs/sdk and @solana/kit. Use for Gabox pools, packs, Raydium LaunchLab and CPMM venues, draws, prizes, creator fees, and SDK integration.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Gabox SDK
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function and type: `references/api.md`.
|
|
8
|
+
Gabox binds a prize machine to a brand-new Raydium LaunchLab coin. The coin trades on its LaunchLab
|
|
9
|
+
curve until it raises the pinned amount, then Raydium migrates it into a Raydium CPMM pool. Gabox
|
|
10
|
+
delivers awards and closes draw accounts itself; there is no Ready, claim or sell-prize flow, and no
|
|
11
|
+
referral program.
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
Use only devnet clients today. Pass `GaboxClient` first to every chain function; all amounts are
|
|
14
|
+
`bigint`.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ESM only. Node 24+. `@solana/kit` is a peer dependency. The program is on **devnet only** today.
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
import { createClient } from '@gabox-labs/sdk';
|
|
24
|
-
const gabox = createClient({ cluster: 'devnet' }); // public devnet RPC
|
|
25
|
-
const gabox = createClient({ cluster: 'devnet', url: RPC }); // your provider; wsUrl follows
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Pass `gabox` as the first argument to every SDK function. `cluster` is required and the URL must
|
|
29
|
-
agree with it: a devnet client refuses a URL without `devnet` in it. This throws at
|
|
30
|
-
`createClient`, before any request.
|
|
16
|
+
Gabox charges no fee at all. Every price the SDK shows already includes Raydium's own fees: on the
|
|
17
|
+
curve, 0.5% to the Gabox platform wallet and 0.5% to the coin creator plus Raydium's trade fee; after
|
|
18
|
+
graduation, the CPMM pool fee and the pool creator fee.
|
|
31
19
|
|
|
32
|
-
|
|
20
|
+
A machine is priced in one quote asset, fixed when the pool is created. It defaults to wrapped SOL,
|
|
21
|
+
and any quote Raydium enabled on LaunchLab works; `raydium.fetchQuoteConfig(client, mint)` says
|
|
22
|
+
whether a mint is one of them, and `raydium.isQuoteSupported` is the boolean version. The quote may
|
|
23
|
+
be classic SPL Token or Token-2022; the coin is always classic SPL Token.
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- **Address derivation is async.** `await poolAddress(mint)`, `await drawAddress(pool, seq)`.
|
|
41
|
-
- **Low-level `generated.*` functions take `gabox.rpc`**, not the client.
|
|
42
|
-
- **Keep the surface kit-only.** Do not import `@solana/web3.js` to talk to this SDK.
|
|
43
|
-
|
|
44
|
-
## Flow 1: price and buy a pack
|
|
25
|
+
Buyers pay in SOL either way. On a WSOL pool every builder wraps the SOL its trade needs and closes
|
|
26
|
+
the WSOL account afterwards, so the wallet spends and receives plain SOL; that close also unwraps any
|
|
27
|
+
WSOL the wallet already held. On any other pool a route provider swaps SOL into the quote token **in
|
|
28
|
+
the same transaction** as the Gabox instruction, and back after a sale. `createClient` gives mainnet
|
|
29
|
+
`jupiterRoute()`; devnet has no router, so pass `route: raydiumCpmmRoute(pool)` with a CPMM pool for
|
|
30
|
+
the SOL pair. `payWith: 'quote'` and `receive: 'quote'` skip the swap.
|
|
45
31
|
|
|
46
32
|
```ts
|
|
47
|
-
import { buyPack,
|
|
33
|
+
import { buyPack, createClient, getOffer } from '@gabox-labs/sdk';
|
|
48
34
|
|
|
35
|
+
const gabox = createClient({ cluster: 'devnet' });
|
|
49
36
|
const offer = await getOffer(gabox, mint, { user: purchaser.address });
|
|
50
|
-
// offer.quoteLamports the pack price now (venue fees included)
|
|
51
|
-
// offer.prizes [{ amount, tickets }], amounts in tokens, already capped by inventory
|
|
52
|
-
// offer.maximum top prize; offer.isSeeded === false means the cap is biting: warn the user
|
|
53
|
-
|
|
54
|
-
const pool = await fetchPoolByMint(gabox, mint);
|
|
55
|
-
const seq = pool!.nextSeq; // pin the draw
|
|
56
|
-
const maxQuoteIn = (offer.quoteLamports * 102n) / 100n; // 2% slippage
|
|
57
37
|
const message = await buyPack(gabox, {
|
|
58
38
|
mint,
|
|
59
|
-
purchaser,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
maxTotalDebit: maxQuoteIn + share(maxQuoteIn, 200n) + 20_000_000n,
|
|
64
|
-
});
|
|
65
|
-
// ...sign and send...
|
|
66
|
-
const draw = await drawAddress(offer.pool, seq);
|
|
67
|
-
const resolved = await watchDraw(gabox, draw, { signal: AbortSignal.timeout(180_000) });
|
|
68
|
-
// resolved.amount = tokens won, already in the purchaser's associated token account
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
The three limits the buyer signs:
|
|
72
|
-
|
|
73
|
-
| limit | caps | set it to |
|
|
74
|
-
| --------------- | -------------------------------------------------------------------- | -------------------------------------- |
|
|
75
|
-
| `maxQuoteIn` | the venue price in lamports | `quoteLamports` + your slippage |
|
|
76
|
-
| `minMaximum` | the top prize in tokens; fails if inventory dropped | `offer.maximum` |
|
|
77
|
-
| `maxTotalDebit` | price + creator fee + protocol fee + randomness fee (both fees ≈ 1%) | `maxQuoteIn + share(maxQuoteIn, 200n) + margin` |
|
|
78
|
-
|
|
79
|
-
`maxTotalDebit` excludes rent and the transaction fee. Add ~0.02 SOL of margin. Always pass `seq`
|
|
80
|
-
so a retry after a stale blockhash cannot buy a second pack.
|
|
81
|
-
|
|
82
|
-
## Flow 2: keep or sell
|
|
83
|
-
|
|
84
|
-
Keeping needs no transaction. Selling routes through the SDK:
|
|
85
|
-
|
|
86
|
-
```ts
|
|
87
|
-
import { pump, sellTokens } from '@gabox-labs/sdk';
|
|
88
|
-
const gross = await pump.sellQuote(gabox, mint, amount, { user: seller.address });
|
|
89
|
-
const message = await sellTokens(gabox, {
|
|
90
|
-
mint, seller, amount,
|
|
91
|
-
minQuoteOutput: (gross * 95n) / 100n, // must be > 0
|
|
39
|
+
purchaser,
|
|
40
|
+
maxQuoteIn: (offer.quoteAmount * 102n) / 100n,
|
|
41
|
+
minMaximum: (offer.maximum * 98n) / 100n,
|
|
42
|
+
maxNativeDebit: 100_000_000n,
|
|
92
43
|
});
|
|
93
44
|
```
|
|
94
45
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
`
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Retry: 300 slots after the last attempt, 3 attempts total. Expire: after 216,000 slots (~1 day),
|
|
128
|
-
only while the draw is `Pending`; it pays the **smallest** prize, not a refund. A `Ready` draw must
|
|
129
|
-
go through normal delivery. Show `slotsUntilRetry` / `slotsUntilExpiry` as a countdown.
|
|
130
|
-
|
|
131
|
-
## Referrals
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
await bindReferrer(gabox, referee, referrerAddress); // referee signs, permanent
|
|
135
|
-
await buyPack(gabox, { ...input, referrer: referrerAddress }); // or bind + buy in one tx
|
|
136
|
-
await claimReferral(gabox, referrer, poolAddress); // referrer collects
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
The referrer earns 1% of the creator's fee per pack. The buyer pays nothing extra.
|
|
140
|
-
|
|
141
|
-
## Reading state
|
|
142
|
-
|
|
143
|
-
`fetchPoolByMint`, `fetchPoolInventory`, `fetchDraw`, `listPools`, `listDraws({ pool?, purchaser? })`,
|
|
144
|
-
`fetchEvents(gabox, signature)`. `list*` uses `getProgramAccounts`: cache it. Events:
|
|
145
|
-
`PoolCreated`, `PackBought`, `DrawResolved`, `TokensSold`, `PrizesFunded`, `RandomnessRetried`.
|
|
146
|
-
|
|
147
|
-
## Errors
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
import { generated } from '@gabox-labs/sdk';
|
|
151
|
-
if (generated.isGaboxV2Error(error, message, generated.GABOX_V2_ERROR__SLIPPAGE_EXCEEDED)) { /* widen maxQuoteIn */ }
|
|
152
|
-
if (generated.isGaboxV2Error(error, message)) console.log(generated.getGaboxV2ErrorMessage(error.context.code));
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Common: `SlippageExceeded`, `PrizeCapChanged` (refresh the offer), `RetryTooSoon`,
|
|
156
|
-
`RetryUnavailable`, `NotExpired`, `NotPending`, `InvalidReferral`, `ZeroAmount`.
|
|
157
|
-
|
|
158
|
-
## Do not
|
|
159
|
-
|
|
160
|
-
- Do not guess the draw address: derive it with `drawAddress(pool, seq)` from the `seq` you pinned.
|
|
161
|
-
- Do not set `minQuoteOutput` or `maxQuoteIn` to `0n`. The program rejects them.
|
|
162
|
-
- Do not call `getOffer` once and reuse it for minutes. Prices move with the coin.
|
|
163
|
-
- Do not point a `'devnet'` client at any other URL. Use `cluster: 'localnet'` for a test validator.
|
|
164
|
-
- Do not run against mainnet. The program is not deployed there.
|
|
46
|
+
`offer.quoteAmount` is the exact venue price for one pack, in the pool's quote token;
|
|
47
|
+
`offer.solAmount` is the same price in lamports, with `offer.quoteDecimals` and `offer.quoteSymbol`
|
|
48
|
+
for showing it. `maxQuoteIn` is the slippage cap in the quote token, and the amount put in the
|
|
49
|
+
buyer's quote account first. `maxNativeDebit` is a separate cap on the lamports the handler watches:
|
|
50
|
+
the VRF request and any venue account rent.
|
|
51
|
+
|
|
52
|
+
For creation use `createMachine` with `name`, `symbol`, `uri`, `maxSeedQuoteIn` and
|
|
53
|
+
`maxSeedNativeDebit`. Metaplex limits the three strings to 32, 10 and 200 UTF-8 bytes. Add
|
|
54
|
+
`quote: { mint }` and `raise` for a machine priced in another token: `raise` is
|
|
55
|
+
`total_quote_fund_raising` in that token's base units, and a WSOL pool uses the raise the program
|
|
56
|
+
pins instead. Everything else about the launch is pinned. It buys a mandatory seed: enough for a 3x
|
|
57
|
+
top prize on the first pack, or the table's full top prize when that pays less than 3x. A table's
|
|
58
|
+
top tier can be at most 20x. Pass `extraSeedTokens` to buy more seed in the same trade, and read
|
|
59
|
+
`seedCostEstimate` for the mandatory, extra and total amounts plus the exact cost.
|
|
60
|
+
|
|
61
|
+
`raydium.resolveVenue(client, { mint, user })` says which venue is live. It throws while a coin is
|
|
62
|
+
migrating, which on devnet lasts under a minute. A migrated CPMM pool can sit at any address, so the
|
|
63
|
+
SDK proves it from its own data and reads its fee tier, vaults and oracle out of the pool account.
|
|
64
|
+
|
|
65
|
+
Creators collect their share with `raydium.claimCreatorFee(client, { creator, quoteMint })`, which
|
|
66
|
+
sweeps every coin they launched against that quote, and
|
|
67
|
+
`raydium.collectCreatorFee(client, { mint, creator })` for one graduated coin.
|
|
68
|
+
`raydium.fetchCreatorFees` reads both, per quote asset.
|
|
69
|
+
|
|
70
|
+
`buyPack` keeps a per-wallet `WalletActivity` account (`fetchWalletActivity(client, wallet)`, `null`
|
|
71
|
+
before a wallet's first purchase); it resolves the account itself.
|
|
72
|
+
|
|
73
|
+
Use `fetchEvents` and `findResolvedDraw` for final delivery, and `retryDraw` or `expireDraw` for
|
|
74
|
+
permissionless recovery. `fundPrizes` moves coins a funder already holds into the irrevocable prize
|
|
75
|
+
vault. See `references/api.md` and the package README for complete signatures.
|
|
@@ -1,148 +1,158 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Client
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
| --- | --- | --- |
|
|
11
|
-
| `createClient` | `(config: ClientConfig) => GaboxClient` | the init step. Throws if the URL contradicts the cluster |
|
|
12
|
-
| `ClientConfig` | `{ cluster: Cluster; url?: string; wsUrl?: string; addressLookupTables?: AddressesByLookupTableAddress }` | `cluster` is required |
|
|
13
|
-
| `GaboxClient` | `{ cluster; url; wsUrl; rpc: GaboxRpc; rpcSubscriptions: GaboxRpcSubscriptions; addressLookupTables }` | a plain object; spread to replace `rpc` |
|
|
14
|
-
| `Cluster` | `'devnet' \| 'mainnet-beta' \| 'localnet'` | |
|
|
15
|
-
| `CLUSTER_ENDPOINTS` | `Record<Cluster, { url; wsUrl }>` | the defaults |
|
|
16
|
-
| `clusterNamedBy` | `(url: string) => Cluster \| 'testnet' \| null` | substring check |
|
|
17
|
-
| `assertClusterUrl` | `(cluster: Cluster, url: string) => void` | the guard, exported for scripts |
|
|
18
|
-
| `websocketUrlFor` | `(url: string) => string` | `https`→`wss`, `http`→`ws` |
|
|
19
|
-
| `defaultAddressLookupTables` | `(cluster: Cluster) => AddressesByLookupTableAddress` | devnet's shared table; `{}` elsewhere |
|
|
20
|
-
| `GaboxRpc`, `GaboxRpcSubscriptions` | kit `Rpc<SolanaRpcApi>`, `RpcSubscriptions<SolanaRpcSubscriptionsApi>` | |
|
|
21
|
-
|
|
22
|
-
## Offers and prices (`src/offer.ts`)
|
|
23
|
-
|
|
24
|
-
| function | signature | notes |
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| `getOffer` | `(client, mint: Address, options?: { user?: Address; venue?: VenueKind }) => Promise<PackOffer>` | two reads: pool + vault, then the venue. Throws if the mint has no machine |
|
|
27
|
-
| `offerFromState` | `(inventory: PoolInventory, venue: VenueKind, quoteLamports: bigint) => PackOffer` | pure |
|
|
28
|
-
| `seedShortfall` | `(offer: PackOffer) => bigint` | tokens that would uncap the top prize |
|
|
29
|
-
|
|
30
|
-
`PackOffer` fields: `mint`, `pool`, `packTokens`, `quoteLamports`, `feeBps`, `feeLamports`,
|
|
31
|
-
`protocolLamports`, `seedLamports`, `seedTokens`, `venue`, `prizes: Prize[]`, `maximum`, `minimum`,
|
|
32
|
-
`uncapped`, `inventory`, `reserved`, `free`, `isFirstPack`, `isSeeded`, `maxMultiplierBps`,
|
|
33
|
-
`averageMultiplierBps`.
|
|
34
|
-
|
|
35
|
-
## Transaction builders (`src/tx/`, `src/referral.ts`)
|
|
36
|
-
|
|
37
|
-
| function | input | signers |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| `createMachine` | `{ creator; mintKeypair; name; symbol; uri; feeBps: number; tiers?: readonly Tier[]; maxSeedLamports: bigint; feeRecipientIndex?; buybackRecipientIndex? }` | creator, mintKeypair |
|
|
40
|
-
| `seedCostEstimate` | `(client, tiers?: readonly Tier[]) => Promise<{ tiers: readonly Tier[]; seedTokens: bigint; lamports: bigint }>` | read only |
|
|
41
|
-
| `buyPack` | `{ mint; purchaser; maxQuoteIn: bigint; minMaximum: bigint; maxTotalDebit: bigint; seq?: bigint; venue?; wrapLamports?; cashback?; referrer?: Address }` | purchaser |
|
|
42
|
-
| `sellTokens` | `{ mint; seller; amount: bigint; minQuoteOutput: bigint; venue? }` | seller |
|
|
43
|
-
| `fundPrizes` | `{ mint; funder; amount: bigint; source?: Address }` | funder |
|
|
44
|
-
| `fundPrizesWithBuy` | `{ mint; funder; tokens: bigint; maxQuoteIn: bigint; venue?; wrapLamports? }` | funder |
|
|
45
|
-
| `retryDraw` | `{ payer; pool; draw; maxVrfDebit: bigint }` | payer (anyone) |
|
|
46
|
-
| `expireDraw` | `{ payer; pool; draw }` | payer (anyone); only for an expired `Pending` draw |
|
|
47
|
-
| `bindReferrer` | `(client, referee: TransactionSigner, referrer: Address, options?) ` | referee |
|
|
48
|
-
| `claimReferral` | `(client, referrer: TransactionSigner, pool: Address, options?)` | referrer |
|
|
49
|
-
| `claimPrize`, `sellPrize`, `quoteSellPrize` | legacy draws only (created before automatic delivery) | purchaser |
|
|
50
|
-
| `buildMessage` | `(client, feePayer, instructions: Instruction[], options: BuildOptions)` | assemble your own |
|
|
51
|
-
|
|
52
|
-
Every input also accepts `BuildOptions`: `computeUnitLimit?: number`, `computeUnitPrice?: number | bigint`
|
|
53
|
-
(micro-lamports per unit), `addressLookupTables?`.
|
|
54
|
-
|
|
55
|
-
`drawAvailability(client, draw) => Promise<DrawAvailability | null>` returns
|
|
56
|
-
`{ status, attempts, slotsUntilRetry, slotsUntilExpiry, canRetry, canExpire }`.
|
|
57
|
-
|
|
58
|
-
## Readers (`src/accounts.ts`, `src/events.ts`)
|
|
59
|
-
|
|
60
|
-
| function | returns |
|
|
1
|
+
# Gabox SDK API
|
|
2
|
+
|
|
3
|
+
All chain-touching functions take `client: GaboxClient` first. Addresses use `Address`; all token
|
|
4
|
+
amounts use base-unit `bigint`. Every venue is Raydium: LaunchLab before a coin graduates, Raydium
|
|
5
|
+
CPMM after. Both settle in the pool's own quote asset, which defaults to wrapped SOL.
|
|
6
|
+
|
|
7
|
+
## Client and reads
|
|
8
|
+
|
|
9
|
+
| Function | Result |
|
|
61
10
|
| --- | --- |
|
|
11
|
+
| `createClient({ cluster: 'devnet', ... })` | `GaboxClient` |
|
|
62
12
|
| `fetchPoolByMint(client, mint)` | `Pool \| null` |
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
`
|
|
85
|
-
`
|
|
86
|
-
|
|
87
|
-
`
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
`
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
13
|
+
| `fetchPoolInventory(client, mint)` | pool, vault inventory, reservations, free inventory |
|
|
14
|
+
| `getOffer(client, mint, options?)` | current `PackOffer` |
|
|
15
|
+
| `listPools(client)` / `listDrawsByPurchaser(client, wallet)` | current account scans |
|
|
16
|
+
| `fetchWalletActivity(client, wallet)` | `WalletActivity \| null`, a buyer's lifetime `packsBought`/`nativeSpent` |
|
|
17
|
+
|
|
18
|
+
`Pool` records `creator`, `mint`, `vault`, `quoteMint`, `packTokens`, `seedQuoteAmount`, `tiers`,
|
|
19
|
+
`nextSeq`, `reserved`, `quoteConfig` (LaunchLab's global config for the quote) and
|
|
20
|
+
`quoteTokenProgram` (classic SPL Token or Token-2022). It stores no base token program, because the
|
|
21
|
+
coin is always classic SPL Token, and no fee, because Gabox charges none.
|
|
22
|
+
|
|
23
|
+
`PackOffer` gives `quoteAmount` (the whole pack price in the quote token, the venue's fees
|
|
24
|
+
included), `quoteMint`, `quoteDecimals`, `quoteSymbol`, `solAmount` (the same price in lamports
|
|
25
|
+
through the route provider, or `null`), `venue` (`'launchlab'` or `'cpmm'`), the frozen prize table,
|
|
26
|
+
`maximum`, `minimum`, `uncapped`, the inventory numbers and `isSeeded`.
|
|
27
|
+
|
|
28
|
+
## Builders
|
|
29
|
+
|
|
30
|
+
Each returns a kit transaction message. Nothing here signs or sends.
|
|
31
|
+
|
|
32
|
+
| Function | Input highlights |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `createMachine` | `name`, `symbol`, `uri`, `tiers?`, `quote?`, `raise?`, `payWith?`, `maxSeedQuoteIn`, `maxSeedNativeDebit`, `extraSeedTokens?` |
|
|
35
|
+
| `buyPack` | `maxQuoteIn`, `minMaximum`, `maxNativeDebit`, `payWith?`, `venue?`, `seq?` |
|
|
36
|
+
| `fundPrizes` | donate coins the funder already holds into the prize vault |
|
|
37
|
+
| `sellTokens` | `amount`, `minQuoteOutput`, `maxNativeDebit`, `receive?`, `venue?` |
|
|
38
|
+
| `retryDraw` / `expireDraw` | permissionless recovery |
|
|
39
|
+
| `raydium.claimCreatorFee` | `creator`, `quoteMint?`; sweeps every coin that wallet launched against that quote |
|
|
40
|
+
| `raydium.collectCreatorFee` | `mint`, `creator`; one graduated coin's CPMM creator fee |
|
|
41
|
+
|
|
42
|
+
On a WSOL pool every builder wraps the SOL its trade needs into the wallet's WSOL account and closes
|
|
43
|
+
that account afterwards, so the wallet spends and receives plain SOL. Closing unwraps any WSOL the
|
|
44
|
+
wallet already held.
|
|
45
|
+
|
|
46
|
+
On any other pool the wallet's quote account is created if missing, and `payWith: 'sol'` (the
|
|
47
|
+
default) prepends a swap that turns SOL into the quote token. `receive: 'sol'` appends the reverse
|
|
48
|
+
after a sale. `payWith: 'quote'` and `receive: 'quote'` skip the swap. The swap and the Gabox
|
|
49
|
+
instruction always share one transaction.
|
|
50
|
+
|
|
51
|
+
`createMachine` builds one transaction with LaunchLab's `initialize_v2` first and `initialize_pool`
|
|
52
|
+
second. The mint keypair and the creator both sign. It buys a mandatory seed,
|
|
53
|
+
`seedTokens(PACK_TOKENS, tiers)`: enough for a 3x top prize on the first pack, or the table's full
|
|
54
|
+
top prize when that pays less than 3x. A table's top tier can be at most 20x. `extraSeedTokens`
|
|
55
|
+
(default `0n`) adds more in the same trade. `seedCostEstimate` returns `seedTokens`,
|
|
56
|
+
`extraSeedTokens`, `totalSeedTokens` and the exact `quoteAmount` a fresh curve would charge.
|
|
57
|
+
|
|
58
|
+
`buyPack` also resolves a per-wallet `WalletActivity` account (`findActivityPda({ purchaser })` or
|
|
59
|
+
`activityAddress(wallet)`); callers do not pass it. It does not create the purchaser's coin account
|
|
60
|
+
either: the program declares it `init_if_needed`, so Anchor does that and the purchaser pays its rent
|
|
61
|
+
once.
|
|
62
|
+
|
|
63
|
+
`maxQuoteIn` and `maxSeedQuoteIn` are venue slippage caps in the quote token, and each is also the
|
|
64
|
+
amount put in the wallet's quote account before the trade. `maxNativeDebit` and
|
|
65
|
+
`maxSeedNativeDebit` are separate lamport caps for what the handler watches: venue account rent, and
|
|
66
|
+
the VRF request on a pack buy.
|
|
67
|
+
|
|
68
|
+
`createMachine` takes `quote: { mint }` and `raise`. The quote defaults to wrapped SOL, whose raise
|
|
69
|
+
the program pins per cluster; any other quote needs a `raise` in its own base units, at or above
|
|
70
|
+
`min_quote_fund_raising` in its config. `seedCostEstimate(client, tiers?, { extraSeedTokens?,
|
|
71
|
+
quote?, raise? })` reports the seed cost in the quote token, its decimals and symbol, the raise, and
|
|
72
|
+
`solAmount` through the route provider.
|
|
73
|
+
|
|
74
|
+
## The venue
|
|
75
|
+
|
|
76
|
+
| Function | Result |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `raydium.resolveVenue(client, { mint, user, venue? })` | `ResolvedVenue`: `kind`, `program`, `poolState`, `status`, `creator`, `ammConfig`, `remainingCurveBase`, `buyAccounts`, `sellAccounts`, `quoteBuy`, `quoteSell` |
|
|
79
|
+
| `raydium.curveQuote(client, mint, tokens)` | the buy price, for a display |
|
|
80
|
+
| `raydium.sellQuote(client, mint, tokens)` | the sale proceeds |
|
|
81
|
+
| `raydium.newCurveBuyCost(client, tokens, { quoteConfig, raise })` | what a buy costs on a curve that does not exist yet |
|
|
82
|
+
| `raydium.findCpmmPool(client, { mint, creator, cpswapConfig, quoteMint? })` | the migrated CPMM pool, proved from its own data |
|
|
83
|
+
| `raydium.fetchCurveSettings(client, quoteConfig)` | the fee rates, the migrate fee and the CPMM fee tier, read from chain |
|
|
84
|
+
| `raydium.fetchCreatorFees(client, { creator, mint?, quoteMint? })` | `{ quoteMint, curveQuote, cpmmQuote, cpmmTokens }` |
|
|
85
|
+
| `raydium.fetchQuoteConfig(client, mint)` | LaunchLab's global config for a quote, or `null` |
|
|
86
|
+
| `raydium.isQuoteSupported(client, mint)` | can a machine be priced in this mint? |
|
|
87
|
+
| `raydium.fetchQuoteAsset(client, mint)` | the config, token program, decimals, symbol and minimum raise |
|
|
88
|
+
| `raydium.quoteAccountFor(user, quoteMint, quoteTokenProgram)` | the account both venues settle in |
|
|
89
|
+
| `raydium.wsolAccountFor(user)` | the same, for a WSOL pool |
|
|
90
|
+
|
|
91
|
+
`resolveVenue` takes an optional `quote: { mint, config, tokenProgram }`. Left out, it reads the
|
|
92
|
+
Gabox pool for it, so a caller that already holds a `Pool` saves a round trip by passing it.
|
|
93
|
+
|
|
94
|
+
`resolveVenue` follows the LaunchLab pool's `status`: `0` routes to the curve, `2` to the CPMM pool,
|
|
95
|
+
and `1` throws because the coin is migrating right now. A migrated CPMM pool does not have to sit at
|
|
96
|
+
a derived address, so it proves itself from its own data, and its fee tier, its two vaults and its
|
|
97
|
+
oracle are read out of the pool account. The program checks the same things.
|
|
98
|
+
|
|
99
|
+
`quoteBuy` on the curve throws when the amount is larger than the curve has left to sell. That is not
|
|
100
|
+
a price failure: the program requires an exact one-pack delta, so such a buy cannot succeed until the
|
|
101
|
+
coin graduates.
|
|
102
|
+
|
|
103
|
+
## Math and low-level builders
|
|
104
|
+
|
|
105
|
+
`raydium.curve` exports exact bigint ports of Raydium's own math: `curveBuyExactOut`,
|
|
106
|
+
`curveBuyExactIn`, `curveSellExactIn`, `initialCurve`, `cpmmSwapBaseOutput`, `cpmmSwapBaseInput`, and
|
|
107
|
+
the `ceilDivRate` / `preFeeAmount` helpers they are built from. Every rounding step matches
|
|
108
|
+
Raydium's.
|
|
109
|
+
|
|
110
|
+
`raydium.getLaunchInstruction(input, ids)` builds LaunchLab's `initialize_v2` with the pinned launch
|
|
111
|
+
shape. `raydium.getCurveBuyExactInInstruction(client, input, ids?)` builds a plain curve buy that
|
|
112
|
+
Gabox never makes itself; the devnet end-to-end test uses it to buy a curve out and force graduation.
|
|
113
|
+
|
|
114
|
+
`initialize_pool`'s `venue` account has no generated default, because LaunchLab has a different
|
|
115
|
+
address on each cluster and a default would be wrong on one of them. Every builder here passes it
|
|
116
|
+
from `raydiumIds(client.cluster)`; a caller using the generated builder directly has to do the same.
|
|
117
|
+
|
|
118
|
+
`raydiumIds(cluster)` gives one cluster's Raydium deployment. Mainnet and devnet run different
|
|
119
|
+
programs and PDAs, and a WSOL launch raises 3 SOL on devnet where mainnet raises 85. `localnet` uses
|
|
120
|
+
the mainnet set, which is what the program's default build pins.
|
|
121
|
+
|
|
122
|
+
## Routes
|
|
123
|
+
|
|
124
|
+
A route provider swaps SOL into a pool's quote token, and back. `createClient` gives mainnet
|
|
125
|
+
`jupiterRoute()` and every other cluster `null`; pass `route` to override, or `null` to switch the
|
|
126
|
+
swap leg off.
|
|
127
|
+
|
|
128
|
+
| Function | Result |
|
|
125
129
|
| --- | --- |
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
133
|
-
`
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
130
|
+
| `jupiterRoute({ url?, slippageBps? })` | a `RouteProvider` over Jupiter's swap API, for mainnet |
|
|
131
|
+
| `raydiumCpmmRoute(poolAddress)` | a `RouteProvider` over one Raydium CPMM pool, for devnet |
|
|
132
|
+
| `routeQuoteIn(client, provider, { quoteMint, amount, user })` | a swap that buys at least `amount`, exact-out first |
|
|
133
|
+
| `routeQuoteOut(client, provider, { quoteMint, amount, user })` | a swap that turns `amount` into SOL |
|
|
134
|
+
| `solPriceOf(client, quoteMint, amount)` | the exact-out SOL cost of `amount`, or `null` |
|
|
135
|
+
| `assertRouteIsSafe(route, { forbidden, settlesIn })` | refuse a route that touches Gabox state or settles elsewhere |
|
|
136
|
+
|
|
137
|
+
A `Route` is `{ instructions, lookupTables, inAmount, outAmount, mode, computeUnits }`. `mode` is
|
|
138
|
+
`'exactOut'` or `'exactIn'`: the amounts are bounds, so an exact-out route states the most it spends
|
|
139
|
+
and an exact-in route the least it pays out.
|
|
140
|
+
|
|
141
|
+
`computeUnits` is what the swap costs on top of the Gabox instruction, because the two share one
|
|
142
|
+
budget. A builder adds it to its own limit and caps the total at `MAX_COMPUTE_UNIT_LIMIT`; an
|
|
143
|
+
explicit `computeUnitLimit` still wins. Jupiter returns the number with the route, falling back to
|
|
144
|
+
`JUPITER_DEFAULT_COMPUTE_UNITS` when its response carries none; `raydiumCpmmRoute` uses
|
|
145
|
+
`CPMM_ROUTE_COMPUTE_UNITS`, measured on devnet, which holds because it is always one pool. Jupiter answers `NO_ROUTES_FOUND` for exact-out whenever the best route
|
|
146
|
+
has more than one hop, which is why `routeQuoteIn` falls back to exact-in and leaves the change in
|
|
147
|
+
the buyer's quote account.
|
|
148
|
+
|
|
149
|
+
## Events
|
|
150
|
+
|
|
151
|
+
`decodeEvents` and `fetchEvents` return only `PoolCreated`, `PrizesFunded`, `PackBought`,
|
|
152
|
+
`RandomnessRetried`, `DrawResolved` and `TokensSold`. None carries a Gabox fee field any more.
|
|
153
|
+
`PackBought` reports `quoteMint`, `quoteDebit` (what the venue charged, in that token),
|
|
154
|
+
`nativeDebit` (venue account rent), `vrfNativeDebit` and `totalNativeDebit`.
|
|
155
|
+
|
|
156
|
+
Delivery closes a draw atomically; use `findResolvedDraw` rather than a Ready or claim flow. It
|
|
157
|
+
searches a bounded recent signature history, so production indexers should persist `DrawResolved`
|
|
158
|
+
events as the authoritative history.
|