@perena/vault-sdk 1.0.38 → 1.0.41

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.
Files changed (4) hide show
  1. package/README.md +102 -0
  2. package/dist/index.d.ts +4037 -3927
  3. package/dist/index.js +5231 -4747
  4. package/package.json +4 -2
package/README.md CHANGED
@@ -125,6 +125,101 @@ for NAV accounts backed only by a current-price API. NAV cashflows have no
125
125
  `date` or `fundingNextDay` parameter: they execute immediately at the price the
126
126
  tracker fetches during submission.
127
127
 
128
+ ## Incentive campaigns
129
+
130
+ All seven incentive instructions have exported `getTx` / `getIx` builders on
131
+ `client.tx`: `createIncentive`, `addIncentiveRecipient`, `setIncentiveLimits`,
132
+ `submitIncentive`, `cancelIncentiveProposal`, `distributeIncentive`, and
133
+ `claimIncentive`. Their
134
+ argument types are exported from `@perena/vault-sdk` alongside the builders.
135
+ Creation and enrollment take `oracle`, authorized against either of the first two
136
+ active reporting slots; `getTx` derives the vault oracle PDA. Submission also resolves
137
+ any tranche accounts. Distribution resolves registered recipients, creates canonical
138
+ share ATAs for both token programs, and requires every paid recipient to co-sign.
139
+
140
+ ```typescript
141
+ import {
142
+ getIncentiveRecipients,
143
+ getIncentiveReportRecipients,
144
+ getIncentiveTotals,
145
+ getIncentiveRecipientShareAtas,
146
+ MAX_INCENTIVE_RECIPIENTS,
147
+ } from "@perena/vault-sdk";
148
+
149
+ const [incentive] = await client.pda.deriveIncentivePda(vault, 1n);
150
+ const create = await client.tx.createIncentive.getTx({
151
+ oracle, vault, id: 1n, recipients: [recipient], maxTotalShares: 1_000_000n,
152
+ });
153
+ // Send with the oracle, then fetch the created account.
154
+ const data = await client.account.fetchIncentiveForVault(vault, 1n);
155
+ const recipients = getIncentiveRecipients(data); // registration order, bigint amounts
156
+ const reportRecipients = getIncentiveReportRecipients(data); // frozen prefix while pending
157
+ const totals = getIncentiveTotals(data); // settledShares, distributedShares, outstandingShares
158
+
159
+ // Discover IDs instead of maintaining an off-chain list.
160
+ const campaigns = await client.account.fetchAllIncentivesForVault(vault);
161
+ // Each result: { publicKey: Address, account: VaultIncentiveAccountData }.
162
+ const maybeCampaign = await client.account.fetchIncentiveNullable(incentive);
163
+ const batch = await client.account.fetchIncentives([incentive]);
164
+ // Batch preserves input order, duplicates, and nulls for missing accounts.
165
+
166
+ // Needed only for custom instruction composition; getTx derives these itself.
167
+ const recipientAtas = getIncentiveRecipientShareAtas(data, shareMint, shareTokenProgram);
168
+
169
+ // Prepare this payload once and share the SAME values with both oracle signers.
170
+ const proposal = {
171
+ vault,
172
+ incentive,
173
+ roundId: BigInt(data.roundId.toString()),
174
+ totals: reportRecipients.map(recipient => recipient.settledTotal + 100n),
175
+ expiresAt: (await client.account.fetchClockUnixTimestamp()) + 600n,
176
+ maxSurplusValue: 0n,
177
+ };
178
+ const report = await client.tx.submitIncentive.getTx({ ...proposal, oracle });
179
+ // After both reports agree and funding is reserved, the user signs when ready:
180
+ const claim = await client.tx.claimIncentive.getTx({ recipient, vault, incentive });
181
+ // Optional batch: collect signatures from every funded recipient as well as the cranker.
182
+ const payout = await client.tx.distributeIncentive.getTx({ cranker, vault, incentive });
183
+ ```
184
+
185
+ `claimIncentive` reads the signing recipient's existing batch entry and creates no
186
+ per-wallet program account. Reporting remains batched. Its payout updates the same
187
+ lifetime counter as `distributeIncentive`, so claims and batch cranks can interleave
188
+ without duplicate payment. The SDK creates only the claiming recipient's missing
189
+ ATA. Five append-only recipients share each 408-byte batch account. Oracle enrollment
190
+ preserves pending reports: new wallets join the following round. When pending,
191
+ `getIncentiveReportRecipients` excludes those new slots; when idle, it returns all
192
+ registered recipients. Persist and share the original payload for both signers.
193
+
194
+ `distributeIncentive.getTx` adds required signer metas for each outstanding recipient;
195
+ it does not collect signatures. Supply them when sending the transaction. A curator
196
+ or oracle signature cannot replace recipient consent. For custom composition,
197
+ `getIx` accepts optional `recipientSigners` (default: all `recipients`); append these
198
+ after the full ordered ATA list. The program rejects any nonzero payout without
199
+ that wallet's signature, including attempts with the old unsigned batch layout.
200
+ A PDA recipient must consent through a signed CPI from its owning program.
201
+
202
+ Creation/enrollment `getIx` calls now require `vaultOracle`; their signer argument is
203
+ `oracle`, not `curator`. Upgrade the SDK with the program. Existing funded accounts
204
+ remain valid: `proposalRecipientCount` uses former padding and the report helper
205
+ handles pending version-1 accounts. Curator cap/floor changes and cancellation
206
+ permissions are unchanged.
207
+
208
+ Incentive fetches always read fresh state. Raw decoded integers use Anchor `BN`;
209
+ the recipient and total helpers expose `bigint` without precision loss. Claims
210
+ are cumulative lifetime **atomic share amounts**: `settledTotal - distributedTotal`
211
+ is currently payable, and unfinished oracle reports are excluded. Up to
212
+ `MAX_INCENTIVE_RECIPIENTS` (five) wallets may be registered. `maxSurplusValue` and
213
+ `minSurplusReserve` use vault accounting units, rather than share units.
214
+
215
+ Use the live clock helper for deadlines; historical block timestamps can lag
216
+ execution time after validator time travel. Keep the round, expiry, surplus debit
217
+ limit and totals identical across the two oracle submissions. The program still
218
+ enforces authorization, campaign caps and available funding when agreement occurs.
219
+
220
+ For instruction semantics and the full accounting model, see
221
+ [`docs/incentives.md`](../../docs/incentives.md).
222
+
128
223
  ## Creating transactions
129
224
 
130
225
  ### The builder pattern
@@ -666,6 +761,13 @@ All builders are on `client.tx`:
666
761
  | Builder | Program instruction | Typical signer |
667
762
  | ------------------------------- | ----------------------------------------------------- | --------------------- |
668
763
  | `createVault` | `create_vault` | Curator |
764
+ | `claimIncentive` | `claim_incentive` | Recipient |
765
+ | `createIncentive` | `create_incentive` | Either reporting oracle |
766
+ | `addIncentiveRecipient` | `add_incentive_recipient` | Either reporting oracle |
767
+ | `setIncentiveLimits` | `set_incentive_limits` | Curator |
768
+ | `submitIncentive` | `submit_incentive` | First two oracle slots |
769
+ | `cancelIncentiveProposal` | `cancel_incentive_proposal` | Curator, or anyone after expiry |
770
+ | `distributeIncentive` | `distribute_incentive` | Cranker + every paid recipient |
669
771
  | `createAssetHolding` | `create_asset_holding` | HW manager |
670
772
  | `removeAssetHolding` | `remove_asset_holding` | HW manager |
671
773
  | `updateConsensusSigners` | `update_consensus_signers` | Curator |