@soltracer/nft-staking 0.3.1 → 0.4.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/INTEGRATION.md CHANGED
@@ -131,7 +131,7 @@ const ix = await client.createStakePool(
131
131
  rewardMint: mintPubkey,
132
132
  baseRate: 100,
133
133
  rateInterval: 86400,
134
- traitBonusMode: 0,
134
+ traitBonusEnabled: false,
135
135
  quantityThresholds: [],
136
136
  },
137
137
  [{ lockDuration: 30 * 86400, rewardRate: 150, earlyUnstakePenaltyBps: 500, claimOnlyAtEnd: false }],
@@ -196,10 +196,29 @@ const fund = await client.fundRewardVault(poolId, amount, { rewardMint: mintPk }
196
196
 
197
197
  ### Close Pool
198
198
 
199
+ Permanently deletes the pool account and refunds rent to the project authority. This is a hard delete — the account
200
+ ceases to exist on-chain. The on-chain guard requires **all four** of the following before it will close:
201
+
202
+ 1. `is_active == false` — flip it off first via `updateStakePool({ isActive: false })`.
203
+ 2. `total_staked == 0` — every staker must have unstaked.
204
+ 3. `total_obligation_pending == 0` — every staker must have claimed (settled inside the ix via `pool_settle`).
205
+ 4. Token-reward pools only: the reward vault ATA must hold zero — drain via `withdrawRewardVault(poolId, amount)`.
206
+
199
207
  ```ts
208
+ // Step 1 — deactivate so no new stakes can land while you wind down.
209
+ await client.updateStakePool(poolId, { isActive: false })
210
+
211
+ // Step 2 — (off-chain) wait for or coordinate all unstakes + claims.
212
+ // Optionally drain leftover rewards back to the project treasury:
213
+ await client.withdrawRewardVault(poolId, remainingBalance)
214
+
215
+ // Step 3 — permanent close. The SDK auto-resolves the reward vault for token pools.
200
216
  const ix = await client.closeStakePool(poolId)
201
217
  ```
202
218
 
219
+ If any precondition fails the program returns `PoolStillActive`, `PoolHasActiveStakes`,
220
+ `PoolHasOutstandingObligations`, or `VaultNotEmpty` so you can surface the exact blocker in the admin UI.
221
+
203
222
  ### Secondary Rewards Management
204
223
 
205
224
  ```ts
@@ -269,117 +288,155 @@ Early-unstake penalties apply on exit when configured.
269
288
 
270
289
  ### Trait Bonus Claims
271
290
 
272
- `RewardConfig.traitBonusMode` controls how a signed `traitBonusRate` is interpreted:
291
+ `RewardConfig.traitBonusEnabled` is a single boolean. When `false`, claims that include a non-zero `traitBonusRate`
292
+ are rejected on-chain. When `true`, the pool accepts a signed `u64` `traitBonusRate` and **adds it directly** to the
293
+ staker's effective rate for the accrual window. There are no modes, no on-chain multipliers, no per-claim cross-NFT
294
+ math — the chain only ever sees one absolute number.
295
+
296
+ All bonus aggregation (per-trait lookups, per-NFT multipliers, caps, edge cases) lives off-chain in the trait-authority
297
+ server. The server is the only party that can produce a signature the pool will accept, so reward rules are fully
298
+ enforced even though the chain knows nothing about traits.
273
299
 
274
- - `0` / `None`: trait bonus proofs are disabled; nonzero `traitBonusRate` is rejected.
275
- - `1` / `FixedExtra`: `traitBonusRate` is a raw extra reward rate per interval, added temporarily for the claim accrual
276
- window.
277
- - `2` / `BaseMultiplier`: `traitBonusRate` is bonus basis points over the staker's current base effective rate. `10_000`
278
- means +100%, so total accrual for that window is 2x base.
300
+ #### Why per-NFT (not per-staker) multipliers
279
301
 
280
- #### Aggregating per-trait bonuses
302
+ If you want rare NFTs to earn more, multiply the rare NFT's **own** bonus contribution and leave every other staked
303
+ NFT's contribution alone. A staker-wide multiplier (e.g. "Mythic NFT = 2× everything") cross-contaminates: every plain
304
+ NFT they own also doubles its rewards inside the same claim window. The SDK's `computeTraitBonusRate` helper applies
305
+ `multiplierBps` per NFT and sums the results, so one NFT's multiplier can never inflate another's reward.
281
306
 
282
- The on-chain instruction accepts a **single** `u64` `traitBonusRate` per claim — it has no notion of per-trait or
283
- per-NFT granularity, and it cannot read NFT metadata. Aggregation lives entirely off-chain in the trait-authority
284
- server. The intended flow:
307
+ #### Backend flow
285
308
 
286
- 1. **Client request.** The wallet calls your API with `{ wallet, poolId, mints }` (the mints it wants to claim against).
309
+ 1. **Client request.** The wallet calls your API with `{ wallet, poolId, mints }`.
287
310
  2. **Ownership / stake validation.** The API resolves the wallet's active stake entries
288
- (`client.fetchStakeEntriesByOwner(poolId, wallet)`) and **drops** any mint not present — never trust the client's
311
+ (`client.fetchStakeEntriesByOwner(wallet, poolId)`) and **drops** any mint not present — never trust the client's
289
312
  list. Anything that survives is provably staked by `wallet` in `pool`.
290
313
  3. **Trait resolution.** For each surviving mint, fetch its trait list from your own source of truth (collection JSON,
291
314
  Metaplex on-chain metadata, indexer, internal DB). The chain stores no trait data.
292
- 4. **Catalog lookup.** Each `(traitType, value)` pair is checked against your project's bonus catalog. Traits without
293
- an entry contribute nothing.
294
- 5. **Mode-aware sum.** Bonuses are summed according to the pool's `rewardConfig.traitBonusMode`:
295
- - `FixedExtra`: catalog uses `fixedExtra` (raw reward per `rateInterval`); each matched trait adds its value.
296
- - `BaseMultiplier`: catalog uses `bonusBps` (10_000 = +100%); each matched trait adds its BPS to a single boost that
297
- scales the staker's current `effective_rate` for the accrual window.
298
- 6. **Sign and return.** Sign the resulting `u64` with the pool's `traitAuthority` keypair; return signature + rate to
299
- the client.
300
-
301
- The SDK ships `computeTraitBonusRate` for steps 4–5 (mode-aware aggregation only) and `prepareTraitProof` for the full
302
- pipeline (steps 2–5 plus the 80-byte signable message). Pick whichever fits how much of the flow your stack already
303
- owns.
315
+ 4. **Catalog lookup.** Each `(traitType, value)` pair is checked against your project's bonus catalog. Each match
316
+ adds its `bonus` (absolute raw reward units per `rateInterval`) to that NFT's running total.
317
+ 5. **Per-NFT multiplier (optional).** If the NFT carries a project-defined `multiplierBps`, multiply its bonus sum by
318
+ `multiplierBps / 10_000`. The multiplier never escapes that NFT.
319
+ 6. **Aggregate.** Sum every NFT's post-multiplier bonus into one `u64` that is the `traitBonusRate`.
320
+ 7. **Sign and return.** Sign the 80-byte message with the pool's `traitAuthority` keypair (or the global stake-config
321
+ authority); return `{ signature, traitBonusRate }` to the client.
322
+
323
+ `computeTraitBonusRate` performs steps 4–6 in one call; `prepareTraitProof` performs steps 2–6 plus the signable
324
+ message (step 7's payload). Pick whichever fits how much of the flow your stack already owns.
304
325
 
305
326
  #### Managing the bonus catalog (any DB)
306
327
 
307
- The admin UI (Trait Bonuses card) writes a row per `(projectId, poolId, traitType, traitValue)` to your DB. Sample
308
- Prisma schema used by the reference app:
328
+ The catalog is keyed by **NFT collection mint**, not by pool id. The same set of trait bonuses applies to every
329
+ pool that stakes a given collection — if you run a 30-day and a 90-day pool over the same NFTs, they share one
330
+ catalog and you only manage it in one place. (Pools toggle whether the bonus is *used* via
331
+ `rewardConfig.traitBonusEnabled` and supply the signing authority; the bonus values themselves live with the
332
+ collection.)
333
+
334
+ Each row stores one absolute `bonus` amount in raw reward units per `rateInterval`. Sample Prisma schema:
309
335
 
310
336
  ```prisma
311
337
  model TraitBonusConfig {
312
- id String @id @default(cuid())
313
- projectId String @map("project_id")
314
- poolId Int @map("pool_id")
315
- traitType String @map("trait_type") @db.VarChar(64)
316
- traitValue String @map("trait_value") @db.VarChar(64)
317
- bonusAmount Int @map("bonus_amount") // bonusBps (mode 2) or fixedExtra (mode 1)
318
- imageUrl String? @map("image_url")
319
- createdAt DateTime @default(now())
320
- updatedAt DateTime @updatedAt
321
-
322
- @@unique([projectId, poolId, traitType, traitValue])
338
+ id String @id @default(cuid())
339
+ projectId String @map("project_id")
340
+ collectionMint String @map("collection_mint") @db.VarChar(44) // base58 pubkey
341
+ traitType String @map("trait_type") @db.VarChar(64)
342
+ traitValue String @map("trait_value") @db.VarChar(64)
343
+ bonus BigInt @map("bonus") // raw reward units per rateInterval
344
+ imageUrl String? @map("image_url")
345
+ createdAt DateTime @default(now())
346
+ updatedAt DateTime @updatedAt
347
+
348
+ @@unique([collectionMint, traitType, traitValue])
349
+ @@index([projectId])
323
350
  @@map("trait_bonus_configs")
324
351
  }
325
352
  ```
326
353
 
327
- You can model this however you like — Drizzle, raw Postgres, Mongo, KV, Firestore, an in-memory map for testing. The
328
- SDK only needs a `TraitBonusStore` adapter:
354
+ Model it however you like — Drizzle, raw Postgres, Mongo, KV, Firestore, an in-memory map for testing. The SDK only
355
+ needs a `TraitBonusStore` adapter that resolves a collection mint to its catalog rows:
329
356
 
330
357
  ```ts
331
358
  import type { TraitBonusStore } from "@soltracer/nft-staking"
332
359
 
333
360
  // Prisma example
334
361
  export const prismaTraitBonusStore: TraitBonusStore = {
335
- async list({ poolId, projectId }) {
336
- const rows = await prisma.traitBonusConfig.findMany({
337
- where: { poolId, ...(projectId ? { projectId: String(projectId) } : {}) },
338
- })
362
+ async listForCollection(collectionMint) {
363
+ const rows = await prisma.traitBonusConfig.findMany({ where: { collectionMint } })
339
364
  return rows.map((r) => ({
340
365
  traitType: r.traitType,
341
366
  value: r.traitValue,
342
- // Pool in BaseMultiplier mode? use bonusBps. FixedExtra? use fixedExtra.
343
- bonusBps: r.bonusAmount,
367
+ bonus: BigInt(r.bonus),
344
368
  }))
345
369
  },
346
370
  }
347
371
 
348
372
  // Drizzle example (drop-in replacement)
349
373
  export const drizzleTraitBonusStore: TraitBonusStore = {
350
- async list({ poolId, projectId }) {
374
+ async listForCollection(collectionMint) {
351
375
  const rows = await db
352
376
  .select()
353
377
  .from(traitBonusConfig)
354
- .where(and(eq(traitBonusConfig.poolId, poolId), projectId ? eq(traitBonusConfig.projectId, String(projectId)) : undefined))
355
- return rows.map((r) => ({ traitType: r.traitType, value: r.traitValue, bonusBps: r.bonusAmount }))
378
+ .where(eq(traitBonusConfig.collectionMint, collectionMint))
379
+ return rows.map((r) => ({ traitType: r.traitType, value: r.traitValue, bonus: BigInt(r.bonus) }))
356
380
  },
357
381
  }
358
382
 
359
- // In-memory (for tests / examples)
360
- export function makeMemoryStore(seed: TraitBonusCatalogEntry[]): TraitBonusStore {
361
- return { async list() { return seed } }
383
+ // Firebase / Firestore example
384
+ // Collection layout: traitBonusConfigs/{autoId} with fields
385
+ // { projectId: string, collectionMint: string, traitType: string, traitValue: string, bonus: string }
386
+ // `bonus` is stored as a decimal string so values > 2^53 survive JSON round-trips.
387
+ import { collection, getDocs, query, where } from "firebase/firestore"
388
+ import { db as firestore } from "./firebase" // your initialised Firestore instance
389
+
390
+ export const firestoreTraitBonusStore: TraitBonusStore = {
391
+ async listForCollection(collectionMint) {
392
+ const snap = await getDocs(
393
+ query(collection(firestore, "traitBonusConfigs"), where("collectionMint", "==", collectionMint)),
394
+ )
395
+ return snap.docs.map((d) => {
396
+ const r = d.data() as { traitType: string; traitValue: string; bonus: string }
397
+ return { traitType: r.traitType, value: r.traitValue, bonus: BigInt(r.bonus) }
398
+ })
399
+ },
362
400
  }
401
+
402
+ // Realtime Database variant (admin SDK)
403
+ // /traitBonusConfigs/{collectionMint}/{autoId} = { traitType, traitValue, bonus }
404
+ import { getDatabase } from "firebase-admin/database"
405
+
406
+ export const firebaseRtdbTraitBonusStore: TraitBonusStore = {
407
+ async listForCollection(collectionMint) {
408
+ const snap = await getDatabase().ref(`traitBonusConfigs/${collectionMint}`).get()
409
+ const val = (snap.val() ?? {}) as Record<string, { traitType: string; traitValue: string; bonus: string }>
410
+ return Object.values(val).map((r) => ({
411
+ traitType: r.traitType,
412
+ value: r.traitValue,
413
+ bonus: BigInt(r.bonus),
414
+ }))
415
+ },
416
+ }
417
+
418
+ // In-memory (for tests / examples)
419
+ import { InMemoryTraitBonusStore } from "@soltracer/nft-staking"
420
+ const memStore = InMemoryTraitBonusStore.from({
421
+ // key by collection mint (base58)
422
+ "5XyZ...AaBb": [{ traitType: "Rarity", value: "Mythic", bonus: 1_000_000n }],
423
+ })
363
424
  ```
364
425
 
365
426
  Recommended CRUD endpoints (the reference app exposes these as tRPC; HTTP/GraphQL works identically):
366
427
 
367
428
  | Operation | Inputs | Behavior |
368
429
  | --- | --- | --- |
369
- | `list` | `{ projectId, poolId }` | Returns all catalog rows for the pool. Used by the admin UI and by `TraitBonusStore.list`. |
370
- | `create` | `{ projectId, poolId, traitType, traitValue, bonusAmount, imageUrl? }` | Inserts one row. |
371
- | `update` | `{ id, bonusAmount?, imageUrl? }` | Updates a single row. |
430
+ | `list` | `{ projectId, collectionMint }` | Returns all catalog rows for the collection. |
431
+ | `create` | `{ projectId, collectionMint, traitType, traitValue, bonus, imageUrl? }` | Inserts one row. |
432
+ | `update` | `{ id, bonus?, imageUrl? }` | Updates a single row. |
372
433
  | `delete` | `{ id }` | Deletes a row. |
373
- | `upsert` (bulk) | `{ projectId, poolId, bonuses: [...] }` | Idempotent bulk replace via the unique `(projectId, poolId, traitType, traitValue)` index. |
434
+ | `upsert` (bulk) | `{ projectId, collectionMint, bonuses: [...] }` | Idempotent bulk replace via the unique `(collectionMint, traitType, traitValue)` index. |
374
435
 
375
- Treat all five as admin-only. Gate them behind a project-authority check (e.g. signed-message session for the
376
- project's `authority` wallet) so non-admins can't rewrite reward rules.
436
+ Treat all five as admin-only. Gate them behind a project-authority check so non-admins can't rewrite reward rules.
377
437
 
378
438
  #### Full backend flow with `prepareTraitProof`
379
439
 
380
- `prepareTraitProof` wires together ownership validation, trait resolution, the store, and the 80-byte message into a
381
- single async call. You only supply the four pieces that depend on your infrastructure:
382
-
383
440
  ```ts
384
441
  import {
385
442
  prepareTraitProof,
@@ -388,50 +445,56 @@ import {
388
445
  } from "@soltracer/nft-staking"
389
446
  import nacl from "tweetnacl"
390
447
 
391
- // One-time wiring:
392
- const traitBonusStore = prismaTraitBonusStore // from §"Managing the bonus catalog"
448
+ const traitBonusStore = prismaTraitBonusStore
393
449
  const resolveTraits: NftTraitResolver = async (mint) => {
394
- // Your trait source: Metaplex metadata, indexer, internal DB, collection JSON, etc.
395
450
  const nft = await metadataIndex.getByMint(mint)
396
- return nft.attributes.map((a) => ({ traitType: a.trait_type, value: a.value }))
451
+ return {
452
+ traits: nft.attributes.map((a) => ({ traitType: a.trait_type, value: a.value })),
453
+ // Optional — only set for NFTs that earn a per-NFT multiplier (e.g. 1-of-1s).
454
+ // Affects ONLY this NFT's own bonus sum. 10_000 = 1x, 20_000 = 2x.
455
+ multiplierBps: nft.rarityTier === "mythic" ? 20_000 : undefined,
456
+ }
397
457
  }
398
- const validateOwnership = ownershipFromClient(client) // or your own stake-state index
458
+ const isStakedBy = ownershipFromClient(client) // verifies via fetchStakeEntriesByOwner
399
459
 
400
460
  // ── POST /api/staking/trait-proof
401
- async function handleProofRequest(req: { wallet: PublicKey; projectId: string; poolId: number; mints: string[] }) {
461
+ async function handleProofRequest(req: { wallet: PublicKey; poolId: number; mints: string[] }) {
402
462
  const pool = await client.fetchStakePool(undefined, req.poolId)
403
463
  const staker = await client.fetchStakerAccount(req.poolId, req.wallet)
404
464
 
405
- const prepared = await prepareTraitProof({
406
- pool: { address: pool.address, rewardConfig: pool.rewardConfig },
407
- projectId: req.projectId,
408
- poolId: req.poolId,
465
+ const { message, traitBonusRate, perNft, rejectedMints } = await prepareTraitProof({
466
+ pool: pool.address,
409
467
  wallet: req.wallet,
410
- requestedMints: req.mints,
468
+ totalClaimed: staker.totalClaimed,
469
+ poolId: req.poolId,
470
+ // Catalog is keyed by collection mint — read it straight off the pool so
471
+ // every pool over the same collection shares one set of trait bonuses.
472
+ collectionMint: pool.collectionMint.toBase58(),
473
+ mints: req.mints,
411
474
  store: traitBonusStore,
412
475
  resolveTraits,
413
- validateOwnership,
414
- totalClaimed: staker.totalClaimed,
476
+ isStakedBy,
415
477
  })
416
478
 
417
- const signature = nacl.sign.detached(prepared.message, traitAuthority.secretKey)
479
+ const signature = nacl.sign.detached(message, traitAuthority.secretKey)
418
480
 
419
481
  return {
420
- traitBonusRate: prepared.traitBonusRate.toString(),
482
+ traitBonusRate: traitBonusRate.toString(),
421
483
  signature: Buffer.from(signature).toString("base64"),
422
484
  traitAuthority: traitAuthority.publicKey.toBase58(),
423
- validatedMints: prepared.validatedMints,
424
- rejectedMints: prepared.rejectedMints,
425
- perNft: prepared.perNft, // [{ mint, bonus, matchedTraits }] — display in the claim UI
485
+ perNft: perNft.map((p) => ({ mint: p.mint, bonus: p.bonus.toString() })),
486
+ rejectedMints,
426
487
  }
427
488
  }
428
489
  ```
429
490
 
430
- Client side, pass the returned `signature` and `traitBonusRate` (as `BN`) into `client.claimRewards(poolId, { traitBonusRate, fee })`
491
+ Client side, pass the returned `signature` and `traitBonusRate` into `client.claimRewards(poolId, { traitBonusRate, fee })`
431
492
  and prepend the `Ed25519Program.createInstructionWithPublicKey({ publicKey: traitAuthority, message, signature })`
432
493
  instruction to the same transaction.
433
494
 
434
- The original lower-level helpers remain available if you want to compose the pipeline yourself:
495
+ #### Composing the pipeline manually
496
+
497
+ If you already own ownership validation or trait resolution, use the lower-level helpers directly:
435
498
 
436
499
  ```ts
437
500
  import {
@@ -442,74 +505,82 @@ import {
442
505
  } from "@soltracer/nft-staking"
443
506
  import nacl from "tweetnacl"
444
507
 
445
- // ── Server: POST /claim/trait-proof body: { wallet, poolId, mints }
446
508
  async function buildProof(req: { wallet: PublicKey; poolId: number; mints: string[] }) {
447
509
  // 2. Validate ownership / current stake state.
448
- const entries = await client.fetchStakeEntriesByOwner(req.poolId, req.wallet)
510
+ const entries = await client.fetchStakeEntriesByOwner(req.wallet, req.poolId)
449
511
  const stakedSet = new Set(entries.map((e) => e.nftMint.toBase58()))
450
512
  const ownedMints = req.mints.filter((m) => stakedSet.has(m))
451
513
 
452
- // 3. Resolve traits from your collection catalog.
514
+ // 3. Resolve traits + optional per-NFT multiplier.
453
515
  const nfts: NftTraitInput[] = await Promise.all(
454
- ownedMints.map(async (mint) => ({
455
- mint,
456
- traits: await catalog.getTraits(mint), // [{ traitType, value }, ..]
457
- })),
516
+ ownedMints.map(async (mint) => {
517
+ const meta = await catalog.getMint(mint)
518
+ return {
519
+ mint,
520
+ traits: meta.traits, // [{ traitType, value }, ..]
521
+ multiplierBps: meta.multiplierBps, // optional, per-NFT only
522
+ }
523
+ }),
458
524
  )
459
525
 
460
- // 4 + 5. Mode-aware aggregation against the project's bonus catalog.
461
- const pool = await client.fetchStakePool(undefined, req.poolId)
526
+ // 4–6. Per-NFT lookup optional per-NFT multiply → global sum.
462
527
  const bonusCatalog: TraitBonusCatalogEntry[] = [
463
- { traitType: "Background", value: "Mythic", bonusBps: 2500 }, // +25%
464
- { traitType: "Eyes", value: "Laser", bonusBps: 1000 }, // +10%
465
- { traitType: "Head", value: "Gold Crown", bonusBps: 500 }, // +5%
528
+ { traitType: "Background", value: "Mythic", bonus: 25_000_000n },
529
+ { traitType: "Eyes", value: "Laser", bonus: 10_000_000n },
530
+ { traitType: "Head", value: "Gold Crown", bonus: 5_000_000n },
466
531
  ]
467
532
  const { traitBonusRate, perNft } = computeTraitBonusRate({
468
- traitBonusMode: pool.rewardConfig.traitBonusMode as 0 | 1 | 2,
469
533
  catalog: bonusCatalog,
470
534
  nfts,
471
535
  })
472
536
 
473
- // 6. Sign the aggregated rate.
474
- const stakerAccount = await client.fetchStakerAccount(req.poolId, req.wallet)
537
+ // 7. Sign the aggregated rate.
538
+ const staker = await client.fetchStakerAccount(req.poolId, req.wallet)
539
+ const pool = await client.fetchStakePool(undefined, req.poolId)
475
540
  const message = buildTraitProofMessage({
476
541
  pool: pool.address,
477
542
  wallet: req.wallet,
478
543
  traitBonusRate,
479
- totalClaimed: stakerAccount.totalClaimed,
544
+ totalClaimed: staker.totalClaimed,
480
545
  })
481
546
  const signature = nacl.sign.detached(message, traitAuthority.secretKey)
482
547
  return { traitBonusRate: traitBonusRate.toString(), signature, perNft }
483
548
  }
484
549
  ```
485
550
 
486
- > ⚠️ Re-run the entire pipeline on every claim. The staked set, NFT traits, and the staker's `totalClaimed` nonce can
487
- > all change between claims; a stale proof is rejected on-chain.
551
+ > ⚠️ Re-run the entire pipeline on every claim. The staked set, NFT traits, and `staker.totalClaimed` can all change
552
+ > between claims; a stale proof is rejected on-chain.
488
553
 
489
- Examples per mode:
554
+ #### Per-NFT multiplier example
490
555
 
491
- | Mode | Catalog field | What 1 matched trait contributes | Final `traitBonusRate` |
492
- | --- | --- | --- | --- |
493
- | `FixedExtra` | `fixedExtra: 100` | +100 reward tokens per `rateInterval` | Sum across every matched trait on every validated NFT. |
494
- | `BaseMultiplier` | `bonusBps: 500` | +5% over the staker's current effective rate | Sum across every matched trait on every validated NFT. `10_000` 2x base for that claim window. |
556
+ Catalog row: `{ traitType: "Rarity", value: "Mythic", bonus: 1_000_000n }`.
557
+ Staker has two staked NFTs:
558
+
559
+ | NFT | Traits matched | Pre-multiplier sum | `multiplierBps` | Post-multiplier sum |
560
+ | ---- | -------------- | ------------------ | --------------- | ------------------- |
561
+ | A | Rarity = Mythic | 1_000_000n | 20_000 (2×) | 2_000_000n |
562
+ | B | (none) | 0n | (n/a) | 0n |
563
+
564
+ `traitBonusRate = 2_000_000n + 0n = 2_000_000n`. The mythic multiplier doubles A's contribution; B is unaffected.
565
+ Compare to the old `BaseMultiplier` model, which would have doubled the rewards from B as well — that bug is why the
566
+ on-chain enum was replaced with a boolean.
495
567
 
496
- Trait proof messages bind the pool, wallet, signed rate, and the staker account's strictly-monotonic `totalClaimed`
497
- counter. A new proof is required after every successful claim because `totalClaimed` advances.
568
+ #### Trait proof message format
498
569
 
499
- Use the SDK's `buildTraitProofMessage` helper to assemble the exact 80-byte payload the on-chain verifier rebuilds
500
- (`pool wallet rate u64 LE ‖ totalClaimed u64 LE`):
570
+ The Ed25519 verifier rebuilds an 80-byte payload: `pool wallet traitBonusRate u64 LE totalClaimed u64 LE`. Use
571
+ `buildTraitProofMessage` to construct it identically.
501
572
 
502
573
  ```ts
503
574
  import nacl from "tweetnacl"
504
575
  import { Ed25519Program, Transaction } from "@solana/web3.js"
505
576
  import { buildTraitProofMessage } from "@soltracer/nft-staking"
506
577
 
507
- const stakerAccount = await client.fetchStakerAccount(poolId, wallet)
578
+ const staker = await client.fetchStakerAccount(poolId, wallet)
508
579
  const message = buildTraitProofMessage({
509
580
  pool,
510
581
  wallet,
511
- traitBonusRate, // BN
512
- totalClaimed: stakerAccount.totalClaimed,
582
+ traitBonusRate,
583
+ totalClaimed: staker.totalClaimed,
513
584
  })
514
585
  const signature = nacl.sign.detached(message, traitAuthority.secretKey)
515
586
  const ed25519Ix = Ed25519Program.createInstructionWithPublicKey({
@@ -522,7 +593,27 @@ await provider.sendAndConfirm(new Transaction().add(ed25519Ix, claimIx))
522
593
  ```
523
594
 
524
595
  The Ed25519 verifier instruction MUST be in the same transaction as `claimRewards` and the signing pubkey MUST match
525
- `pool.traitAuthority` (or the global trait authority if configured).
596
+ `pool.traitAuthority` (or the global `stakeConfig.authority` if the pool has no override). The pool also rejects any
597
+ non-zero `traitBonusRate` when `rewardConfig.traitBonusEnabled` is `false`.
598
+
599
+ #### Trait authority scope — per-project, not platform-global
600
+
601
+ There is **no platform-wide trait authority**. The on-chain hierarchy is:
602
+
603
+ | Account | Field | Scope | How to set |
604
+ | --- | --- | --- | --- |
605
+ | `StakePool` | `traitAuthority` | **Per pool** (overrides the project default when non-zero) | `updateStakePool(poolId, { traitAuthority: <pubkey> })` |
606
+ | `StakeConfig` | `authority` | **Per project** (used as fallback when `pool.traitAuthority == Pubkey::default()`) | Set when the project's `StakeConfig` is initialised; rotated via your project-management flow. |
607
+
608
+ In practice each project has its own `StakeConfig` PDA — the same wallet that authorises pool admin actions also acts
609
+ as the default trait signer for that project. To use a separate, dedicated trait-signing wallet (recommended so you
610
+ can rotate it without touching the admin key), call `updateStakePool` with `traitAuthority` set to the dedicated
611
+ keypair's pubkey. Pass `Pubkey::default()` (32 zero bytes) to clear the override and fall back to
612
+ `stakeConfig.authority`.
613
+
614
+ Because the authority is scoped to one project's pools, multi-project deployments must run one signing service (or one
615
+ keypair) **per project**. Do not share a single signer across projects unless you also re-use the same `StakeConfig`
616
+ authority across them.
526
617
 
527
618
  ### Merkle Gate Proofs
528
619
 
package/dist/client.d.ts CHANGED
@@ -217,7 +217,7 @@ export declare class NftStakingClient {
217
217
  rewardMint: PkInput;
218
218
  baseRate: number;
219
219
  rateInterval: number;
220
- traitBonusMode: number;
220
+ traitBonusEnabled: boolean;
221
221
  quantityThresholds: QuantityBonusInput[];
222
222
  }, lockConfigs: {
223
223
  lockDuration: number;
@@ -236,7 +236,7 @@ export declare class NftStakingClient {
236
236
  rewardMint: PkInput;
237
237
  baseRate: number;
238
238
  rateInterval: number;
239
- traitBonusMode: number;
239
+ traitBonusEnabled: boolean;
240
240
  quantityThresholds: QuantityBonusInput[];
241
241
  } | null;
242
242
  lockConfigs?: {
@@ -267,6 +267,19 @@ export declare class NftStakingClient {
267
267
  destinationTokenAccount?: PkInput;
268
268
  projectId?: number;
269
269
  }): Promise<TransactionInstruction>;
270
+ /**
271
+ * Permanently close (delete) a stake pool. The pool account is closed and
272
+ * rent is refunded to `authority`. The on-chain handler requires:
273
+ *
274
+ * - `is_active == false` — call `updateStakePool({ isActive: false })` first.
275
+ * - `total_staked == 0` — every NFT must be unstaked.
276
+ * - `total_obligation_pending == 0` — every staker must have claimed.
277
+ * - For token-reward pools, the `reward_vault` ATA must hold zero —
278
+ * drain via `withdrawRewardVault` before closing.
279
+ *
280
+ * The reward vault and its token program are auto-resolved from the pool
281
+ * for token-reward pools. Points/SOL pools pass `null` automatically.
282
+ */
270
283
  closeStakePool(poolId: number, projectId?: number): Promise<TransactionInstruction>;
271
284
  /** Stake a legacy/pNFT. Auto-resolves stakingMode from pool. */
272
285
  stakeNft(poolId: number, nftMint: PkInput, opts?: {
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -731,7 +731,7 @@ export class NftStakingClient {
731
731
  rewardMint: _rewardMint,
732
732
  baseRate: new BN(Math.round(rewardConfig.baseRate * multiplier)),
733
733
  rateInterval: new BN(rewardConfig.rateInterval),
734
- traitBonusMode: rewardConfig.traitBonusMode,
734
+ traitBonusEnabled: rewardConfig.traitBonusEnabled,
735
735
  quantityThresholds: rewardConfig.quantityThresholds.map(normalizeQuantityBonus),
736
736
  };
737
737
  const rawLockConfigs = lockConfigs.map((lc) => ({
@@ -790,7 +790,7 @@ export class NftStakingClient {
790
790
  rewardMint: _rMint,
791
791
  baseRate: new BN(Math.round(rewardConfig.baseRate * multiplier)),
792
792
  rateInterval: new BN(rewardConfig.rateInterval),
793
- traitBonusMode: rewardConfig.traitBonusMode,
793
+ traitBonusEnabled: rewardConfig.traitBonusEnabled,
794
794
  quantityThresholds: rewardConfig.quantityThresholds.map(normalizeQuantityBonus),
795
795
  };
796
796
  }
@@ -884,18 +884,42 @@ export class NftStakingClient {
884
884
  })
885
885
  .instruction();
886
886
  }
887
+ /**
888
+ * Permanently close (delete) a stake pool. The pool account is closed and
889
+ * rent is refunded to `authority`. The on-chain handler requires:
890
+ *
891
+ * - `is_active == false` — call `updateStakePool({ isActive: false })` first.
892
+ * - `total_staked == 0` — every NFT must be unstaked.
893
+ * - `total_obligation_pending == 0` — every staker must have claimed.
894
+ * - For token-reward pools, the `reward_vault` ATA must hold zero —
895
+ * drain via `withdrawRewardVault` before closing.
896
+ *
897
+ * The reward vault and its token program are auto-resolved from the pool
898
+ * for token-reward pools. Points/SOL pools pass `null` automatically.
899
+ */
887
900
  async closeStakePool(poolId, projectId) {
888
901
  const pid = this.resolveProjectId(projectId);
889
902
  const [poolPda] = getStakePoolPda(pid, poolId);
890
903
  const [project] = getProjectPda(pid);
904
+ // Token-reward pools must pass the (empty) reward vault so the program
905
+ // can assert it. Points pools omit it.
906
+ const pool = await this.fetchStakePool(pid, poolId);
907
+ let rewardVault = null;
908
+ let tokenProgram = null;
909
+ if (pool && pool.rewardConfig.rewardType === 0 /* Token */) {
910
+ const rewardMint = toPk(pool.rewardConfig.rewardMint);
911
+ tokenProgram = await this.resolveTokenProgram(rewardMint);
912
+ const [poolAuthority] = getPoolAuthorityPda(pid, poolId);
913
+ rewardVault = getAta(poolAuthority, rewardMint, tokenProgram);
914
+ }
891
915
  return this.program.methods
892
916
  .closeStakePool(new BN(pid), new BN(poolId))
893
917
  .accountsStrict({
894
918
  pool: poolPda,
895
919
  project,
896
920
  projectManagementProgram: PROJECT_MANAGEMENT_PROGRAM_ID,
897
- rewardVault: null,
898
- tokenProgram: null,
921
+ rewardVault,
922
+ tokenProgram,
899
923
  authority: this.provider.wallet.publicKey,
900
924
  })
901
925
  .instruction();