@gabox-labs/sdk 0.8.0 → 0.9.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/CHANGELOG.md +48 -0
- package/README.md +63 -22
- package/dist/{gabox-DGTCh34U.js → gabox-CuyJYmrS.js} +669 -309
- package/dist/gabox-CuyJYmrS.js.map +1 -0
- package/dist/generated/index.d.ts +458 -92
- package/dist/generated/index.js +214 -54
- package/dist/generated/index.js.map +1 -1
- package/dist/index.d.ts +222 -31
- package/dist/index.js +182 -40
- package/dist/index.js.map +1 -1
- package/dist/raydium/index.js +1 -1
- package/dist/{raydium-DIF1WOvI.js → raydium-BZT4-i79.js} +231 -53
- package/dist/raydium-BZT4-i79.js.map +1 -0
- package/llms.txt +4 -0
- package/package.json +1 -1
- package/skills/gabox-sdk/SKILL.md +21 -13
- package/skills/gabox-sdk/references/api.md +42 -18
- package/dist/gabox-DGTCh34U.js.map +0 -1
- package/dist/raydium-DIF1WOvI.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,54 @@
|
|
|
3
3
|
All notable changes to `@gabox-labs/sdk`. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
4
4
|
and the project uses [Semantic Versioning](https://semver.org/) with the `0.x` rule from `CONTRIBUTING.md`.
|
|
5
5
|
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.9.1] - 2026-09-19
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- `DEFAULT_TIERS` is now Common 80% at 0.5126x, Rare 15% at 2x, Epic 4% at 3.5x, Mythic 1% at
|
|
13
|
+
10x. The average payout stays 9,499 bps and the mandatory seed stays 2 packs. Every win at least
|
|
14
|
+
doubles the pack, and the top tier halves so one hit pays 1% of the supply instead of 2%. Pools
|
|
15
|
+
created before this release keep the table they were created with.
|
|
16
|
+
|
|
17
|
+
## [0.9.0] - 2026-09-19
|
|
18
|
+
|
|
19
|
+
**Breaking.** The program now sells packs in purchases of one to five, and pays a prize it cannot
|
|
20
|
+
deliver into an owed balance instead of failing. Every earlier devnet pool is abandoned by this
|
|
21
|
+
program version, so nothing this release reads existed before its deploy.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `buyPacks(client, { count, nonce?, maxQuoteIn, minFirstMaximum, maxNativeDebit, ... })` opens
|
|
26
|
+
`count` packs (1 to `MAX_BATCH_SIZE`, which is 5) in one venue trade with one draw and one
|
|
27
|
+
randomness request. It returns `{ message, draw, nonce, seqStart, count }`. `buyPack` stays as
|
|
28
|
+
the one-pack form with `minMaximum`, and returns the same shape.
|
|
29
|
+
- `getOffer(client, mint, { count })` prices the whole purchase and adds `count`, `perPackCaps`
|
|
30
|
+
(the worst-case top prize of each pack), `batchReserved` and `freeSnapshot`.
|
|
31
|
+
- `settle`, `settleDraw` and `ticketFor` reproduce a purchase's settlement from the oracle's
|
|
32
|
+
randomness, the way the program does it. `reserveFor`, `settleWith`, `perPackCaps`,
|
|
33
|
+
`chooseIndex`, `uncappedAmounts` and `minTier` are the pure parts.
|
|
34
|
+
- `claimPrize` and `claimPrizeTo` pay an owed prize; `fetchOwedDraws` lists what a wallet is owed;
|
|
35
|
+
`drawAvailability` reports `settled`, `owed`, `canDeliver` and `canClaim`.
|
|
36
|
+
- `randomNonce`, and `drawAddress(pool, purchaser, nonce)`.
|
|
37
|
+
- Events `PacksBought` and `PrizeClaimed`. `DrawResolved` carries `draw`, `seqStart`, `count`,
|
|
38
|
+
`total`, `paid` and one `results` entry per pack. `RandomnessRetried` names the draw.
|
|
39
|
+
- `CLAIM_PRIZE_COMPUTE_UNITS`.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- `drawAddress` takes the purchaser and a nonce; the pool's sequence counter is no longer in the
|
|
44
|
+
address. `findResolvedDraw` matches the event's own `draw` field.
|
|
45
|
+
- `Draw` has a new layout and discriminator: a snapshot of the tiers, the pack size and the free
|
|
46
|
+
inventory, plus `settled`, `randomness`, `timedOut` and `owed`. `Pool` has a new discriminator.
|
|
47
|
+
- `expireDraw` refuses a settled draw before sending; the program pays every pack of an expired
|
|
48
|
+
purchase its smallest tier.
|
|
49
|
+
|
|
50
|
+
### Removed
|
|
51
|
+
|
|
52
|
+
- `PackBought`; `PacksBought` replaces it.
|
|
53
|
+
|
|
6
54
|
## [0.8.0] - 2026-09-19
|
|
7
55
|
|
|
8
56
|
The platform's own fees, so the app can show them and claim them.
|
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ const client = createClient({
|
|
|
61
61
|
});
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
`payWith: 'quote'` on `
|
|
64
|
+
`payWith: 'quote'` on `buyPacks` skips the swap and spends the token the wallet already holds.
|
|
65
65
|
`receive: 'quote'` does the same for a sale. A WSOL pool ignores both: its quote token is SOL.
|
|
66
66
|
|
|
67
67
|
The swap has to fit in the same 1,232-byte transaction as the buy. When it does not, the builder
|
|
@@ -123,7 +123,7 @@ const message = await createMachine(client, {
|
|
|
123
123
|
|
|
124
124
|
**The creator pays the seed, in the machine's own quote token.** There is no swap here: a machine
|
|
125
125
|
quoted in USDC needs the creator to hold at least `maxSeedQuoteIn` of USDC before this transaction
|
|
126
|
-
runs. Only a buyer arrives holding SOL alone, so only `
|
|
126
|
+
runs. Only a buyer arrives holding SOL alone, so only `buyPacks` and `sellTokens` swap.
|
|
127
127
|
|
|
128
128
|
`raise` is how much the curve must take in before the coin graduates, in the quote's own base units.
|
|
129
129
|
A WSOL pool has it pinned by the program — 85 SOL on mainnet, 3 SOL on devnet — so leave it out
|
|
@@ -145,28 +145,47 @@ can add more with `extraSeedTokens` (default `0n`), which the program adds to th
|
|
|
145
145
|
at most 20x; seed beyond what a 20x prize needs stays in the vault as backup for the draws after a
|
|
146
146
|
top-tier hit.
|
|
147
147
|
|
|
148
|
-
## Buy
|
|
148
|
+
## Buy packs
|
|
149
149
|
|
|
150
150
|
```ts
|
|
151
|
-
const offer = await getOffer(client, mint, { user: purchaser.address });
|
|
152
|
-
const message = await
|
|
151
|
+
const offer = await getOffer(client, mint, { user: purchaser.address, count: 3 });
|
|
152
|
+
const { message, draw, nonce } = await buyPacks(client, {
|
|
153
153
|
mint,
|
|
154
154
|
purchaser,
|
|
155
|
+
count: 3,
|
|
155
156
|
maxQuoteIn: (offer.quoteAmount * 102n) / 100n,
|
|
156
|
-
|
|
157
|
+
minFirstMaximum: (offer.maximum * 98n) / 100n,
|
|
157
158
|
maxNativeDebit: 100_000_000n,
|
|
158
159
|
});
|
|
159
160
|
```
|
|
160
161
|
|
|
161
|
-
`
|
|
162
|
-
|
|
163
|
-
`
|
|
164
|
-
|
|
162
|
+
One purchase opens `count` packs, 1 to `MAX_BATCH_SIZE` (5): one venue trade for all of them, one
|
|
163
|
+
draw, one randomness request. `buyPack` is the same with `count: 1` and `minMaximum` in place of
|
|
164
|
+
`minFirstMaximum`. Both return the message, the draw's address and its nonce, so the caller can
|
|
165
|
+
watch the draw without deriving anything.
|
|
166
|
+
|
|
167
|
+
`offer.quoteAmount` is the exact price the venue will charge for the whole purchase right now, fees
|
|
168
|
+
included, in the pool's quote token. The curve math is a port of Raydium's own, not an estimate, so
|
|
169
|
+
the `PacksBought` event reports the same number unless somebody trades in between. `offer.solAmount`
|
|
170
|
+
is the same price in lamports through the route provider, with `offer.quoteDecimals` and
|
|
165
171
|
`offer.quoteSymbol` for showing it.
|
|
166
172
|
|
|
167
|
-
`
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
`offer.prizes` and `offer.maximum` are the first pack's table, capped by the vault as it is now. The
|
|
174
|
+
later packs settle in order: each one is capped at what the vault can pay after the packs before
|
|
175
|
+
it, counting the purchase's own tokens as they arrive. `offer.perPackCaps` is the worst case per
|
|
176
|
+
pack, the top prize it keeps if every earlier pack won its own; on a thin vault the later entries
|
|
177
|
+
fall towards one pack, and a screen should show that next to the first table.
|
|
178
|
+
|
|
179
|
+
The draw's address is `["draw", pool, purchaser, nonce]`. The builder draws a random nonce unless
|
|
180
|
+
you pass one, so purchases from several buyers, or several from one buyer sent together, never
|
|
181
|
+
collide. A nonce still in use fails at the program; a nonce whose draw already closed opens a new
|
|
182
|
+
purchase, so never reuse the nonce of a purchase that may have landed.
|
|
183
|
+
|
|
184
|
+
`maxQuoteIn` is the slippage cap for the whole purchase, in the quote token, and the amount put in
|
|
185
|
+
the buyer's quote account before the buy. `minFirstMaximum` is the floor on the first pack's top
|
|
186
|
+
prize; refresh the offer when `PrizeCapChanged` refuses it. `maxNativeDebit` is separate: it caps
|
|
187
|
+
the lamports the handler watches, which are the VRF request and any venue account rent. Gabox adds
|
|
188
|
+
nothing to any of them.
|
|
170
189
|
|
|
171
190
|
## Sell
|
|
172
191
|
|
|
@@ -245,18 +264,35 @@ that LP and pays both sides of the pair into the owner's accounts, closing the W
|
|
|
245
264
|
|
|
246
265
|
## Wallet activity
|
|
247
266
|
|
|
248
|
-
`
|
|
267
|
+
`buyPacks` keeps a `WalletActivity` account per buyer, at the PDA `findActivityPda({ purchaser })`
|
|
249
268
|
(also `activityAddress(wallet)`). It tracks `packsBought` and `nativeSpent` across every pool.
|
|
250
269
|
`nativeSpent` is what the venue charged in WSOL, which is SOL; Gabox's own rent, the VRF fee and a
|
|
251
|
-
pack bought in any other quote token are not counted. The buyer pays its rent once, on the first
|
|
252
|
-
|
|
253
|
-
first purchase.
|
|
270
|
+
pack bought in any other quote token are not counted. The buyer pays its rent once, on the first
|
|
271
|
+
purchase, and `buyPacks` resolves the account itself. Read it with
|
|
272
|
+
`fetchWalletActivity(client, wallet)`, which returns `null` before a wallet's first purchase.
|
|
254
273
|
|
|
255
274
|
## Draws
|
|
256
275
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
276
|
+
The oracle's callback settles every pack of a purchase from one randomness and pays the total into
|
|
277
|
+
the purchaser's coin account, then closes the draw and returns its rent. `findResolvedDraw(client,
|
|
278
|
+
draw)` finds that `DrawResolved` event: `total`, one `results` entry per pack with its tier and
|
|
279
|
+
amount, the `randomness`, and `paid`.
|
|
280
|
+
|
|
281
|
+
`paid: false` means the callback could not use the purchaser's coin account, because it was
|
|
282
|
+
missing, closed, or no longer the purchaser's. The outcome is still fixed: the draw stays open with
|
|
283
|
+
`settled: true` and the total in `owed`, and nothing can reopen it. `claimPrize(client, { payer,
|
|
284
|
+
draw })` pays it to the purchaser's ATA, creating the account if needed, and anyone may send it.
|
|
285
|
+
`claimPrizeTo(client, { purchaser, draw, destination })` is the purchaser's own way out when they
|
|
286
|
+
changed their ATA's owner: it pays any coin account they own. `fetchOwedDraws(client, purchaser)`
|
|
287
|
+
lists what a wallet is still owed. This path exists so that a buyer cannot make the callback fail,
|
|
288
|
+
read its randomness, and try again; honest buyers never see it.
|
|
289
|
+
|
|
290
|
+
Anyone can check what a purchase won. `settle({ tiers, packTokens, freeSnapshot, count, pool,
|
|
291
|
+
seqStart, randomness })` recomputes every pack's result the way the program does, and
|
|
292
|
+
`settleDraw(draw)` does it from an owed draw's account alone. `drawAvailability(client, draw)` says
|
|
293
|
+
what can still happen to a draw. A stalled draw uses `retryDraw`, and `expireDraw` fixes it at every
|
|
294
|
+
pack's smallest tier after `TIMEOUT_SLOTS`. Existing base tokens can be donated irrevocably with
|
|
295
|
+
`fundPrizes`.
|
|
260
296
|
|
|
261
297
|
## Errors
|
|
262
298
|
|
|
@@ -266,8 +302,13 @@ The generated client decodes the program's own errors by name. The ones a client
|
|
|
266
302
|
| --- | --- |
|
|
267
303
|
| `InvalidVenue` | The account list did not match. Resolve the venue again and rebuild. |
|
|
268
304
|
| `SlippageExceeded` | The price moved past `maxQuoteIn`, or a cost went past `maxNativeDebit`. |
|
|
269
|
-
| `PrizeCapChanged` | The top prize fell below `
|
|
270
|
-
| `IncorrectTokenDelta` | The venue did not deliver exactly
|
|
305
|
+
| `PrizeCapChanged` | The first pack's top prize fell below `minFirstMaximum`. Refresh the offer. |
|
|
306
|
+
| `IncorrectTokenDelta` | The venue did not deliver exactly `count` packs. Usually a curve with fewer whole packs left; buy fewer or wait for graduation. |
|
|
307
|
+
| `TooManyPacks` / `ZeroAmount` | `count` is above `MAX_BATCH_SIZE` or zero. The builder refuses these before sending. |
|
|
308
|
+
| `DrawAlreadySettled` | A retry, an expiry or a second callback reached a draw whose outcome is fixed. Nothing to do. |
|
|
309
|
+
| `DrawNotSettled` | A claim on a draw that is still pending. Wait for the callback. |
|
|
310
|
+
| `DrawExpired` | A callback arrived after the deadline; only `expireDraw` remains. |
|
|
311
|
+
| `WrongDestination` | `claimPrizeTo` was given an account that is not the purchaser's, or not for this coin. |
|
|
271
312
|
| `InvalidLaunch` | The LaunchLab create instruction was missing or did not match the pinned shape. |
|
|
272
313
|
| `InvalidQuote` | The quote mint is not one Raydium enabled, or its Token-2022 profile is one the program refuses. |
|
|
273
314
|
|