@wzrd_sol/sdk 0.1.1 → 0.2.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.
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Model Selector — pick the best open-source model using live WZRD velocity data.
3
+ *
4
+ * Combines on-chain attention signals from the WZRD protocol with
5
+ * OpenRouter pricing to compute a value score for every tracked model,
6
+ * then returns a ranked list filtered by budget, task, and trend.
7
+ *
8
+ * Usage:
9
+ * import { bestModel } from '@wzrd_sol/sdk';
10
+ * const picks = await bestModel({ task: 'code', budget: 'micro' });
11
+ * console.log(picks[0].model_id);
12
+ *
13
+ * @module model-selector
14
+ */
15
+ // ── Constants ─────────────────────────────────────────────────────
16
+ const DEFAULT_WZRD_URL = 'https://api.twzrd.xyz';
17
+ const DEFAULT_OPENROUTER_URL = 'https://openrouter.ai/api/v1/models';
18
+ const DEFAULT_CACHE_TTL_MS = 300000; // 5 minutes
19
+ const EPSILON = 0.001;
20
+ /** Maximum blended price per million tokens for each budget tier. */
21
+ const BUDGET_LIMITS = {
22
+ micro: 0.20,
23
+ budget: 1.00,
24
+ mid: 5.00,
25
+ premium: Infinity,
26
+ };
27
+ /** Confidence levels ranked from lowest to highest. */
28
+ const CONFIDENCE_RANK = {
29
+ insufficient: 0,
30
+ low: 1,
31
+ medium: 2,
32
+ high: 3,
33
+ };
34
+ /** Task-specific model name patterns and their score boost multiplier. */
35
+ const TASK_BOOSTS = {
36
+ code: {
37
+ patterns: ['deepseek', 'qwen', 'codestral', 'starcoder', 'coder'],
38
+ boost: 1.3,
39
+ },
40
+ reasoning: {
41
+ patterns: ['deepseek-r', 'o1', 'o3', 'reasoning'],
42
+ boost: 1.5,
43
+ },
44
+ chat: {
45
+ patterns: ['claude', 'gpt', 'gemini', 'chat', 'llama'],
46
+ boost: 1.1,
47
+ },
48
+ };
49
+ // ── ModelSelector Class ───────────────────────────────────────────
50
+ /**
51
+ * Fetches WZRD velocity data and OpenRouter pricing, caches results,
52
+ * and scores models by value (velocity / cost).
53
+ *
54
+ * Create one instance and reuse it — the internal cache avoids redundant
55
+ * HTTP requests within the TTL window.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const selector = new ModelSelector({ wzrd_base_url: 'https://api.twzrd.xyz' });
60
+ * const picks = await selector.select({ task: 'code', budget: 'budget', limit: 3 });
61
+ * console.log(picks[0].model_id);
62
+ * ```
63
+ */
64
+ export class ModelSelector {
65
+ constructor(config = {}) {
66
+ this.cache = new Map();
67
+ this.wzrdBaseUrl = (config.wzrd_base_url ?? DEFAULT_WZRD_URL).replace(/\/+$/, '');
68
+ this.openrouterUrl = config.openrouter_url ?? DEFAULT_OPENROUTER_URL;
69
+ this.cacheTtlMs = config.cache_ttl_ms ?? DEFAULT_CACHE_TTL_MS;
70
+ }
71
+ /**
72
+ * Select the best models for a given task and budget.
73
+ *
74
+ * Fetches live data from the WZRD leaderboard, momentum signal, and
75
+ * OpenRouter catalog (all cached for 5 minutes by default), then ranks
76
+ * every OpenRouter model tracked by WZRD using:
77
+ *
78
+ * value_score = velocity_ema / (blended_price_per_m_tokens + epsilon)
79
+ *
80
+ * Results are filtered by budget tier, task relevance, minimum confidence,
81
+ * and exclusion list, then sorted by value_score descending.
82
+ *
83
+ * @param options - Filtering and ranking options.
84
+ * @returns Ranked array of model recommendations (may be empty).
85
+ */
86
+ async select(options = {}) {
87
+ const { budget = 'mid', task = 'chat', min_confidence = 'low', limit = 5, exclude = [], } = options;
88
+ // Fetch all three data sources in parallel (cached).
89
+ const [leaderboard, momentum, catalog] = await Promise.all([
90
+ this.fetchLeaderboard(),
91
+ this.fetchMomentum(),
92
+ this.fetchOpenRouterCatalog(),
93
+ ]);
94
+ // If any critical source failed, return empty (graceful degradation).
95
+ if (leaderboard === null || catalog === null) {
96
+ return [];
97
+ }
98
+ // Build lookup indices.
99
+ const orIndex = new Map();
100
+ for (const m of catalog.data) {
101
+ orIndex.set(m.id, m);
102
+ }
103
+ const momentumIndex = new Map();
104
+ if (momentum !== null) {
105
+ for (const m of momentum.models) {
106
+ momentumIndex.set(m.market_id, m);
107
+ }
108
+ }
109
+ // Filtering thresholds.
110
+ const maxPrice = BUDGET_LIMITS[budget];
111
+ const minConfidenceRank = CONFIDENCE_RANK[min_confidence];
112
+ const taskBoost = TASK_BOOSTS[task];
113
+ const excludeLower = exclude.map((e) => e.toLowerCase());
114
+ const candidates = [];
115
+ for (const market of leaderboard.markets) {
116
+ if (market.platform !== 'openrouter')
117
+ continue;
118
+ if (market.status !== 'open')
119
+ continue;
120
+ const orModel = orIndex.get(market.channel_id);
121
+ if (!orModel)
122
+ continue;
123
+ // Exclusion filter.
124
+ if (excludeLower.some((e) => market.channel_id.toLowerCase().includes(e)))
125
+ continue;
126
+ // Compute blended price per million tokens (3:1 prompt:completion weighting).
127
+ const promptPrice = parseFloat(orModel.pricing?.prompt ?? '0');
128
+ const completionPrice = parseFloat(orModel.pricing?.completion ?? '0');
129
+ const blendedPerM = ((promptPrice * 3 + completionPrice) / 4) * 1000000;
130
+ // Budget filter.
131
+ if (blendedPerM > maxPrice)
132
+ continue;
133
+ // Momentum data.
134
+ const mom = momentumIndex.get(market.market_id);
135
+ const trend = mom?.velocity_trend ?? 'insufficient_history';
136
+ const confidence = mom?.history_confidence ?? 'insufficient';
137
+ // Confidence filter.
138
+ const confidenceRank = CONFIDENCE_RANK[confidence];
139
+ if (confidenceRank < minConfidenceRank)
140
+ continue;
141
+ // Compute value score: velocity / (price + epsilon).
142
+ const velocityEma = market.velocity_ema;
143
+ const rawValueScore = velocityEma / (blendedPerM + EPSILON);
144
+ // Apply task-specific boost.
145
+ let taskMultiplier = 1.0;
146
+ if (taskBoost) {
147
+ for (const pattern of taskBoost.patterns) {
148
+ if (market.channel_id.toLowerCase().includes(pattern)) {
149
+ taskMultiplier = taskBoost.boost;
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ const valueScore = rawValueScore * taskMultiplier;
155
+ candidates.push({
156
+ model_id: market.channel_id,
157
+ provider: 'openrouter',
158
+ price_per_m_tokens: Math.round(blendedPerM * 1000) / 1000,
159
+ velocity_ema: velocityEma,
160
+ value_score: Math.round(valueScore * 1000) / 1000,
161
+ trend,
162
+ confidence,
163
+ });
164
+ }
165
+ // Sort by value_score descending.
166
+ candidates.sort((a, b) => b.value_score - a.value_score);
167
+ return candidates.slice(0, limit);
168
+ }
169
+ /**
170
+ * Invalidate the in-memory cache.
171
+ *
172
+ * Useful when you know upstream data has changed and want
173
+ * fresh results on the next `select()` call.
174
+ */
175
+ clearCache() {
176
+ this.cache.clear();
177
+ }
178
+ // ── Private Helpers ───────────────────────────────────────────
179
+ async fetchLeaderboard() {
180
+ return this.cachedFetch('wzrd:leaderboard', `${this.wzrdBaseUrl}/v1/leaderboard?limit=100`);
181
+ }
182
+ async fetchMomentum() {
183
+ return this.cachedFetch('wzrd:momentum', `${this.wzrdBaseUrl}/v1/signals/momentum`);
184
+ }
185
+ async fetchOpenRouterCatalog() {
186
+ return this.cachedFetch('openrouter:catalog', this.openrouterUrl);
187
+ }
188
+ /**
189
+ * Fetch JSON from a URL with in-memory TTL caching.
190
+ * Returns null on any error (network, HTTP status, parse failure).
191
+ */
192
+ async cachedFetch(key, url) {
193
+ const now = Date.now();
194
+ const cached = this.cache.get(key);
195
+ if (cached && cached.expires_at > now) {
196
+ return cached.data;
197
+ }
198
+ try {
199
+ const resp = await fetch(url);
200
+ if (!resp.ok) {
201
+ return null;
202
+ }
203
+ const data = (await resp.json());
204
+ this.cache.set(key, { data, expires_at: now + this.cacheTtlMs });
205
+ return data;
206
+ }
207
+ catch {
208
+ return null;
209
+ }
210
+ }
211
+ }
212
+ // ── Convenience Function ──────────────────────────────────────────
213
+ /** Shared singleton used by the convenience `bestModel()` function. */
214
+ let defaultSelector = null;
215
+ /**
216
+ * Pick the best open-source model for a task using live WZRD velocity data.
217
+ *
218
+ * This is a convenience wrapper around {@link ModelSelector.select} that
219
+ * uses a module-level singleton with default configuration. For custom
220
+ * base URLs or cache settings, instantiate {@link ModelSelector} directly.
221
+ *
222
+ * @param options - Filtering and ranking options.
223
+ * @returns Ranked array of model recommendations (may be empty if the API is unreachable).
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * import { bestModel } from '@wzrd_sol/sdk';
228
+ *
229
+ * // Cheapest model good for code
230
+ * const picks = await bestModel({ task: 'code', budget: 'micro' });
231
+ * console.log(picks[0].model_id);
232
+ *
233
+ * // Premium reasoning model, exclude specific providers
234
+ * const reasoning = await bestModel({
235
+ * task: 'reasoning',
236
+ * budget: 'premium',
237
+ * exclude: ['gpt'],
238
+ * limit: 3,
239
+ * });
240
+ * ```
241
+ */
242
+ export async function bestModel(options = {}) {
243
+ if (!defaultSelector) {
244
+ defaultSelector = new ModelSelector();
245
+ }
246
+ return defaultSelector.select(options);
247
+ }
package/dist/nav.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * NAV (Net Asset Value) helpers for vLOFI share computation.
3
+ *
4
+ * These pure functions mirror the on-chain deposit/settle math so that
5
+ * clients can preview shares received or principal returned without
6
+ * submitting a transaction.
7
+ *
8
+ * NAV BPS domain:
9
+ * - 10_000 = 1.00x (1 USDC per share, initial NAV)
10
+ * - 50_000 = 5.00x (max NAV, protocol ceiling)
11
+ * - 0 = uninitialized (pre-realloc vaults, treated as 10_000)
12
+ */
13
+ /** Structured NAV data extracted from a MarketVault. */
14
+ export interface NavInfo {
15
+ /** NAV per share in basis points (10_000 = 1.0x). Zero means uninitialized. */
16
+ navPerShareBps: bigint;
17
+ /** Slot at which NAV was last updated on-chain. */
18
+ lastNavUpdateSlot: bigint;
19
+ /** Human-readable share price in USDC terms (navPerShareBps / 10_000). */
20
+ sharePrice: number;
21
+ }
22
+ /**
23
+ * Compute the number of vLOFI shares a deposit of `amount` base units will mint.
24
+ *
25
+ * Formula (matches vault.rs deposit_market):
26
+ * shares = amount * 10_000 / nav_per_share_bps
27
+ *
28
+ * If navPerShareBps is 0 (uninitialized / pre-realloc vault), falls back to
29
+ * the default 10_000 BPS (1:1 ratio).
30
+ */
31
+ export declare function computeSharesForDeposit(amount: bigint, navPerShareBps: bigint): bigint;
32
+ /**
33
+ * Compute the USDC principal returned when settling `shares` of vLOFI.
34
+ *
35
+ * Formula (matches vault.rs settle_market):
36
+ * principal = shares * nav_per_share_bps / 10_000
37
+ *
38
+ * If navPerShareBps is 0 (uninitialized), falls back to 10_000 BPS.
39
+ */
40
+ export declare function computePrincipalForSettle(shares: bigint, navPerShareBps: bigint): bigint;
package/dist/nav.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * NAV (Net Asset Value) helpers for vLOFI share computation.
3
+ *
4
+ * These pure functions mirror the on-chain deposit/settle math so that
5
+ * clients can preview shares received or principal returned without
6
+ * submitting a transaction.
7
+ *
8
+ * NAV BPS domain:
9
+ * - 10_000 = 1.00x (1 USDC per share, initial NAV)
10
+ * - 50_000 = 5.00x (max NAV, protocol ceiling)
11
+ * - 0 = uninitialized (pre-realloc vaults, treated as 10_000)
12
+ */
13
+ const DEFAULT_NAV_BPS = 10000n;
14
+ const BPS_SCALE = 10000n;
15
+ /**
16
+ * Compute the number of vLOFI shares a deposit of `amount` base units will mint.
17
+ *
18
+ * Formula (matches vault.rs deposit_market):
19
+ * shares = amount * 10_000 / nav_per_share_bps
20
+ *
21
+ * If navPerShareBps is 0 (uninitialized / pre-realloc vault), falls back to
22
+ * the default 10_000 BPS (1:1 ratio).
23
+ */
24
+ export function computeSharesForDeposit(amount, navPerShareBps) {
25
+ const effectiveNav = navPerShareBps === 0n ? DEFAULT_NAV_BPS : navPerShareBps;
26
+ return (amount * BPS_SCALE) / effectiveNav;
27
+ }
28
+ /**
29
+ * Compute the USDC principal returned when settling `shares` of vLOFI.
30
+ *
31
+ * Formula (matches vault.rs settle_market):
32
+ * principal = shares * nav_per_share_bps / 10_000
33
+ *
34
+ * If navPerShareBps is 0 (uninitialized), falls back to 10_000 BPS.
35
+ */
36
+ export function computePrincipalForSettle(shares, navPerShareBps) {
37
+ const effectiveNav = navPerShareBps === 0n ? DEFAULT_NAV_BPS : navPerShareBps;
38
+ return (shares * effectiveNav) / BPS_SCALE;
39
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Unit tests for NAV computation helpers (computeSharesForDeposit, computePrincipalForSettle).
3
+ */
4
+ export {};
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Unit tests for NAV computation helpers (computeSharesForDeposit, computePrincipalForSettle).
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { computeSharesForDeposit, computePrincipalForSettle } from './nav.js';
6
+ // ── computeSharesForDeposit ──────────────────────────────
7
+ describe('computeSharesForDeposit', () => {
8
+ it('returns 1:1 shares at default NAV (10_000 BPS)', () => {
9
+ const shares = computeSharesForDeposit(1000000n, 10000n);
10
+ expect(shares).toBe(1000000n);
11
+ });
12
+ it('returns half shares at 2x NAV (20_000 BPS)', () => {
13
+ const shares = computeSharesForDeposit(1000000n, 20000n);
14
+ expect(shares).toBe(500000n);
15
+ });
16
+ it('handles zero NAV fallback — treats as 10_000 BPS', () => {
17
+ // zero nav fallback: uninitialized vault should behave like 1:1
18
+ const shares = computeSharesForDeposit(1000000n, 0n);
19
+ expect(shares).toBe(1000000n);
20
+ });
21
+ it('handles max NAV of 50_000 BPS (5.0x)', () => {
22
+ // max nav: 50_000 BPS ceiling
23
+ const shares = computeSharesForDeposit(5000000n, 50000n);
24
+ expect(shares).toBe(1000000n);
25
+ });
26
+ it('returns 0 shares for 0 deposit amount', () => {
27
+ const shares = computeSharesForDeposit(0n, 10000n);
28
+ expect(shares).toBe(0n);
29
+ });
30
+ it('handles large deposit without overflow', () => {
31
+ // overflow test: large amount should not throw
32
+ const amount = 1000000000000n; // 1M USDC in base units
33
+ const shares = computeSharesForDeposit(amount, 10000n);
34
+ expect(shares).toBe(amount);
35
+ });
36
+ it('truncates fractional shares (integer division)', () => {
37
+ // 3 base units at 2x NAV = 1.5 → truncates to 1
38
+ const shares = computeSharesForDeposit(3n, 20000n);
39
+ expect(shares).toBe(1n);
40
+ });
41
+ });
42
+ // ── computePrincipalForSettle ─────────────────────────────
43
+ describe('computePrincipalForSettle', () => {
44
+ it('returns 1:1 principal at default NAV (10_000 BPS)', () => {
45
+ const principal = computePrincipalForSettle(1000000n, 10000n);
46
+ expect(principal).toBe(1000000n);
47
+ });
48
+ it('returns double principal at 2x NAV (20_000 BPS)', () => {
49
+ const principal = computePrincipalForSettle(1000000n, 20000n);
50
+ expect(principal).toBe(2000000n);
51
+ });
52
+ it('handles zero NAV fallback — treats as 10_000 BPS', () => {
53
+ // zero nav fallback
54
+ const principal = computePrincipalForSettle(1000000n, 0n);
55
+ expect(principal).toBe(1000000n);
56
+ });
57
+ it('handles max NAV of 50_000 BPS (5.0x)', () => {
58
+ // max nav: 50_000 BPS ceiling
59
+ const principal = computePrincipalForSettle(1000000n, 50000n);
60
+ expect(principal).toBe(5000000n);
61
+ });
62
+ it('returns 0 principal for 0 shares', () => {
63
+ const principal = computePrincipalForSettle(0n, 10000n);
64
+ expect(principal).toBe(0n);
65
+ });
66
+ it('handles large shares without overflow', () => {
67
+ // overflow test: large shares
68
+ const shares = 1000000000000n;
69
+ const principal = computePrincipalForSettle(shares, 10000n);
70
+ expect(principal).toBe(shares);
71
+ });
72
+ });
73
+ // ── NavInfo type ─────────────────────────────────────────
74
+ describe('NavInfo type', () => {
75
+ it('can be constructed with valid fields', () => {
76
+ const info = {
77
+ navPerShareBps: 15000n,
78
+ lastNavUpdateSlot: 405000000n,
79
+ sharePrice: 1.5,
80
+ };
81
+ expect(info.navPerShareBps).toBe(15000n);
82
+ expect(info.lastNavUpdateSlot).toBe(405000000n);
83
+ expect(info.sharePrice).toBe(1.5);
84
+ });
85
+ });
86
+ // ── Round-trip deposit→settle ────────────────────────────
87
+ describe('deposit-settle round trip', () => {
88
+ it('deposit then settle at same NAV returns original amount', () => {
89
+ const amount = 1000000n;
90
+ const nav = 12500n;
91
+ const shares = computeSharesForDeposit(amount, nav);
92
+ const principal = computePrincipalForSettle(shares, nav);
93
+ // Due to integer division, principal <= amount
94
+ expect(principal).toBeLessThanOrEqual(amount);
95
+ // But should be close (within 1 base unit rounding)
96
+ expect(amount - principal).toBeLessThan(nav);
97
+ });
98
+ });
package/dist/pda.d.ts CHANGED
@@ -16,5 +16,9 @@ export declare function getGlobalRootConfigPDA(ccmMint: PublicKey, programId?: P
16
16
  export declare function getClaimStatePDA(ccmMint: PublicKey, claimer: PublicKey, programId?: PublicKey): PublicKey;
17
17
  /** Derive a ChannelConfigV2 PDA for a given mint and subject. */
18
18
  export declare function getChannelConfigV2PDA(mint: PublicKey, subject: PublicKey, programId?: PublicKey): PublicKey;
19
+ /** Derive the StreamRootConfig PDA for a given vLOFI mint. */
20
+ export declare function getStreamRootConfigPDA(vlofiMint: PublicKey, programId?: PublicKey): PublicKey;
21
+ /** Derive the per-user ClaimStateStream PDA. */
22
+ export declare function getClaimStateStreamPDA(vlofiMint: PublicKey, claimer: PublicKey, programId?: PublicKey): PublicKey;
19
23
  /** Derive an Associated Token Account address (works for both SPL and Token-2022). */
20
24
  export declare function getAta(owner: PublicKey, mint: PublicKey, tokenProgramId: PublicKey): PublicKey;
package/dist/pda.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Seeds must match programs/attention-oracle/src/constants.rs.
5
5
  */
6
6
  import { PublicKey } from '@solana/web3.js';
7
- import { PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, PROTOCOL_STATE_SEED, MARKET_VAULT_SEED, MARKET_POSITION_SEED, GLOBAL_ROOT_SEED, CLAIM_STATE_GLOBAL_SEED, CHANNEL_CONFIG_V2_SEED, } from './constants.js';
7
+ import { PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, PROTOCOL_STATE_SEED, MARKET_VAULT_SEED, MARKET_POSITION_SEED, GLOBAL_ROOT_SEED, CLAIM_STATE_GLOBAL_SEED, CHANNEL_CONFIG_V2_SEED, STREAM_ROOT_SEED, CLAIM_STATE_STREAM_SEED, } from './constants.js';
8
8
  /** Derive the singleton ProtocolState PDA. */
9
9
  export function getProtocolStatePDA(programId = PROGRAM_ID) {
10
10
  return PublicKey.findProgramAddressSync([Buffer.from(PROTOCOL_STATE_SEED)], programId)[0];
@@ -31,6 +31,15 @@ export function getClaimStatePDA(ccmMint, claimer, programId = PROGRAM_ID) {
31
31
  export function getChannelConfigV2PDA(mint, subject, programId = PROGRAM_ID) {
32
32
  return PublicKey.findProgramAddressSync([Buffer.from(CHANNEL_CONFIG_V2_SEED), mint.toBuffer(), subject.toBuffer()], programId)[0];
33
33
  }
34
+ // ── Stream (vLOFI distribution) PDA Derivation ──────────
35
+ /** Derive the StreamRootConfig PDA for a given vLOFI mint. */
36
+ export function getStreamRootConfigPDA(vlofiMint, programId = PROGRAM_ID) {
37
+ return PublicKey.findProgramAddressSync([Buffer.from(STREAM_ROOT_SEED), vlofiMint.toBuffer()], programId)[0];
38
+ }
39
+ /** Derive the per-user ClaimStateStream PDA. */
40
+ export function getClaimStateStreamPDA(vlofiMint, claimer, programId = PROGRAM_ID) {
41
+ return PublicKey.findProgramAddressSync([Buffer.from(CLAIM_STATE_STREAM_SEED), vlofiMint.toBuffer(), claimer.toBuffer()], programId)[0];
42
+ }
34
43
  /** Derive an Associated Token Account address (works for both SPL and Token-2022). */
35
44
  export function getAta(owner, mint, tokenProgramId) {
36
45
  return PublicKey.findProgramAddressSync([owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Instruction builders for the wzrd-stream vLOFI claim system.
3
+ *
4
+ * Builds publish_stream_root, claim_stream, and claim_stream_sponsored
5
+ * TransactionInstructions for the vLOFI streaming distribution pipeline.
6
+ *
7
+ * Unlike CCM global claims (Token-2022), stream claims use standard SPL
8
+ * token program for vLOFI minting.
9
+ */
10
+ import { PublicKey, TransactionInstruction } from '@solana/web3.js';
11
+ /**
12
+ * Build a `publish_stream_root` TransactionInstruction.
13
+ *
14
+ * Publishes a new merkle root for vLOFI stream distribution.
15
+ *
16
+ * Accounts (order must match PublishStreamRoot struct):
17
+ * 0. payer (signer, writable) - admin or publisher
18
+ * 1. protocol_state (readonly)
19
+ * 2. stream_root_config (writable) - PDA: seeds=[b"stream_root", vlofiMint]
20
+ * 3. vlofi_mint (readonly)
21
+ * 4. system_program (readonly)
22
+ *
23
+ * Data layout: [8 disc][8 root_seq LE][32 root][32 dataset_hash] = 80 bytes
24
+ *
25
+ * @param payer - Admin or authorized publisher (signer)
26
+ * @param vlofiMint - vLOFI mint address
27
+ * @param rootSeq - Monotonically increasing root sequence number
28
+ * @param root - 32-byte merkle root hash
29
+ * @param datasetHash - 32-byte dataset hash for auditability
30
+ * @param programId - Program ID (defaults to mainnet)
31
+ */
32
+ export declare function createPublishStreamRootIx(payer: PublicKey, vlofiMint: PublicKey, rootSeq: number | bigint, root: Uint8Array | Buffer, datasetHash: Uint8Array | Buffer, programId?: PublicKey): TransactionInstruction;
33
+ /**
34
+ * Build a `claim_stream` TransactionInstruction (self-signed).
35
+ *
36
+ * Claims vLOFI tokens from the stream distribution merkle tree.
37
+ * The claimer signs the transaction themselves.
38
+ *
39
+ * Accounts (order must match ClaimStream struct):
40
+ * 0. claimer (signer, writable)
41
+ * 1. protocol_state (readonly)
42
+ * 2. stream_root_config (readonly)
43
+ * 3. claim_state_stream (writable) - PDA: seeds=[b"claim_stream", vlofiMint, claimer]
44
+ * 4. vlofi_mint (writable) - for mint_to
45
+ * 5. claimer_vlofi_ata (writable) - ATA(claimer, vlofiMint, TOKEN_PROGRAM)
46
+ * 6. token_program (readonly) - standard SPL Token
47
+ * 7. system_program (readonly)
48
+ *
49
+ * Data layout: [8 disc][8 root_seq LE][8 cumulative_total LE][4 proof_len LE][proof_len * 32 proof_nodes]
50
+ *
51
+ * @param claimer - Wallet claiming vLOFI (signer)
52
+ * @param vlofiMint - vLOFI mint address
53
+ * @param rootSeq - Root sequence number to claim against
54
+ * @param cumulativeTotal - Cumulative vLOFI amount entitled (native units)
55
+ * @param proofHex - Hex-encoded 32-byte merkle proof sibling hashes
56
+ * @param programId - Program ID (defaults to mainnet)
57
+ * @returns Array of instructions: idempotent ATA create + claim IX
58
+ */
59
+ export declare function createClaimStreamIx(claimer: PublicKey, vlofiMint: PublicKey, rootSeq: number | bigint, cumulativeTotal: bigint | number, proofHex: string[], programId?: PublicKey): TransactionInstruction[];
60
+ /**
61
+ * Build a `claim_stream_sponsored` TransactionInstruction (gasless relay).
62
+ *
63
+ * A relayer pays for the transaction while vLOFI goes to the claimer.
64
+ * The claimer does NOT need to sign.
65
+ *
66
+ * Accounts (order must match ClaimStreamSponsored struct):
67
+ * 0. payer (signer, writable) - relayer
68
+ * 1. claimer (readonly, NOT signer)
69
+ * 2. protocol_state (readonly)
70
+ * 3. stream_root_config (readonly)
71
+ * 4. claim_state_stream (writable)
72
+ * 5. vlofi_mint (writable)
73
+ * 6. claimer_vlofi_ata (writable)
74
+ * 7. token_program (readonly)
75
+ * 8. system_program (readonly)
76
+ *
77
+ * Data layout: same as claim_stream
78
+ *
79
+ * @param payer - Relayer wallet (signer, pays fees)
80
+ * @param claimer - Wallet receiving vLOFI (NOT a signer)
81
+ * @param vlofiMint - vLOFI mint address
82
+ * @param rootSeq - Root sequence number to claim against
83
+ * @param cumulativeTotal - Cumulative vLOFI amount entitled (native units)
84
+ * @param proofHex - Hex-encoded 32-byte merkle proof sibling hashes
85
+ * @param programId - Program ID (defaults to mainnet)
86
+ * @returns Array of instructions: idempotent ATA create + sponsored claim IX
87
+ */
88
+ export declare function createClaimStreamSponsoredIx(payer: PublicKey, claimer: PublicKey, vlofiMint: PublicKey, rootSeq: number | bigint, cumulativeTotal: bigint | number, proofHex: string[], programId?: PublicKey): TransactionInstruction[];