@wzrd_sol/sdk 0.1.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/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # @wzrd/sdk
2
+
3
+ TypeScript SDK for the Liquid Attention Protocol on Solana.
4
+
5
+ Builds `deposit_market`, `settle_market`, and `claim_global` transaction instructions that wallets sign directly — no server signing needed.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @wzrd/sdk @solana/web3.js
11
+ ```
12
+
13
+ ## Example Scripts
14
+
15
+ From the repo root:
16
+
17
+ ```bash
18
+ npm run build --workspace=sdk
19
+ npm run typecheck:examples --workspace=sdk
20
+ ```
21
+
22
+ Runnable examples:
23
+
24
+ - `npm run example:deposit --workspace=sdk`
25
+ - `npm run example:claim --workspace=sdk`
26
+
27
+ Both examples expect:
28
+
29
+ - `SOLANA_RPC_URL`
30
+ - `WZRD_KEYPAIR_PATH`
31
+
32
+ The deposit example also expects:
33
+
34
+ - `WZRD_MARKET_ID`
35
+ - `WZRD_DEPOSIT_USDC`
36
+
37
+ ## Quick Reference
38
+
39
+ ### PDA Derivation
40
+
41
+ ```typescript
42
+ import {
43
+ getProtocolStatePDA,
44
+ getMarketVaultPDA,
45
+ getUserPositionPDA,
46
+ getGlobalRootConfigPDA,
47
+ getClaimStatePDA,
48
+ PROGRAM_ID,
49
+ } from '@wzrd/sdk';
50
+
51
+ const protocolState = getProtocolStatePDA();
52
+ const marketVault = getMarketVaultPDA(protocolState, 6); // market ID 6
53
+ const position = getUserPositionPDA(marketVault, walletPubkey);
54
+ ```
55
+
56
+ ### Deposit USDC → Receive vLOFI
57
+
58
+ ```typescript
59
+ import { Connection, Keypair, VersionedTransaction, TransactionMessage } from '@solana/web3.js';
60
+ import { createDepositMarketIx } from '@wzrd/sdk';
61
+
62
+ const connection = new Connection('https://api.mainnet-beta.solana.com');
63
+ const wallet = Keypair.fromSecretKey(/* your key */);
64
+
65
+ // Build instructions for a 1 USDC deposit into market 6
66
+ const ixs = await createDepositMarketIx(connection, wallet.publicKey, 6, 1_000_000n);
67
+
68
+ const { blockhash } = await connection.getLatestBlockhash();
69
+ const message = new TransactionMessage({
70
+ payerKey: wallet.publicKey,
71
+ recentBlockhash: blockhash,
72
+ instructions: ixs,
73
+ }).compileToV0Message();
74
+
75
+ const tx = new VersionedTransaction(message);
76
+ tx.sign([wallet]);
77
+ const sig = await connection.sendTransaction(tx);
78
+ console.log('Deposit tx:', sig);
79
+ ```
80
+
81
+ ### Claim CCM via Merkle Proof
82
+
83
+ ```typescript
84
+ import { createClaimGlobalIx } from '@wzrd/sdk';
85
+
86
+ // Fetch proof from the server API
87
+ const res = await fetch(`https://api.twzrd.xyz/v1/claims/${wallet.publicKey.toBase58()}`);
88
+ const { root_seq, cumulative_total, proof } = await res.json();
89
+
90
+ const ixs = await createClaimGlobalIx(
91
+ connection,
92
+ wallet.publicKey,
93
+ root_seq,
94
+ BigInt(cumulative_total),
95
+ proof, // hex-encoded [u8; 32] nodes
96
+ );
97
+
98
+ // Build, sign, send as above
99
+ ```
100
+
101
+ ### Settle a Matured Position
102
+
103
+ ```typescript
104
+ import { createSettleMarketIx } from '@wzrd/sdk';
105
+
106
+ const ixs = await createSettleMarketIx(connection, wallet.publicKey, 6);
107
+ // Build, sign, send as above
108
+ ```
109
+
110
+ ### Read On-Chain State
111
+
112
+ ```typescript
113
+ import { fetchMarketVault, fetchOnChainPosition, fetchTokenBalance } from '@wzrd/sdk';
114
+
115
+ const vault = await fetchMarketVault(connection, 6);
116
+ console.log('Total deposited:', vault?.totalDeposited);
117
+
118
+ const pos = await fetchOnChainPosition(connection, wallet.publicKey, 6);
119
+ console.log('My deposit:', pos?.depositedAmount, 'Multiplier:', pos?.attentionMultiplierBps);
120
+ ```
121
+
122
+ ## Exports
123
+
124
+ ### Constants
125
+
126
+ | Export | Description |
127
+ |--------|-------------|
128
+ | `PROGRAM_ID` | Mainnet program ID (`GnGz...`) |
129
+ | `DEVNET_PROGRAM_ID` | Devnet program ID (`GmGX...`) |
130
+ | `TOKEN_PROGRAM_ID` | SPL Token program |
131
+ | `TOKEN_2022_PROGRAM_ID` | Token-2022 program (CCM uses this) |
132
+
133
+ ### PDA Derivation
134
+
135
+ | Function | Seeds |
136
+ |----------|-------|
137
+ | `getProtocolStatePDA()` | `["protocol_state"]` |
138
+ | `getMarketVaultPDA(protocolState, marketId)` | `["market_vault", protocolState, marketId]` |
139
+ | `getUserPositionPDA(marketVault, user)` | `["market_position", marketVault, user]` |
140
+ | `getGlobalRootConfigPDA(ccmMint)` | `["global_root", ccmMint]` |
141
+ | `getClaimStatePDA(ccmMint, claimer)` | `["claim_global", ccmMint, claimer]` |
142
+
143
+ ### Instruction Builders
144
+
145
+ | Function | On-chain instruction |
146
+ |----------|---------------------|
147
+ | `createDepositMarketIx(conn, user, marketId, amount)` | `deposit_market` |
148
+ | `createSettleMarketIx(conn, user, marketId)` | `settle_market` |
149
+ | `createClaimGlobalIx(conn, claimer, rootSeq, total, proof)` | `claim_global` |
150
+ | `createInitializeMarketVaultIx(admin, marketId, ...)` | `initialize_market_vault` |
151
+
152
+ ### Account Parsers
153
+
154
+ | Function | Account type |
155
+ |----------|-------------|
156
+ | `parseMarketVault(data)` | `MarketVault` |
157
+ | `parseProtocolState(data)` | `ProtocolState` |
158
+ | `parseUserMarketPosition(data)` | `UserMarketPosition` |
159
+ | `fetchMarketVault(conn, marketId)` | Fetch + parse |
160
+ | `fetchOnChainPosition(conn, user, marketId)` | Fetch + parse |
161
+ | `fetchTokenBalance(conn, ata)` | Raw token balance |
162
+
163
+ ## Key Addresses
164
+
165
+ | Asset | Mint | Token Program |
166
+ |-------|------|---------------|
167
+ | USDC | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | SPL Token |
168
+ | vLOFI | `E9Kt33axpCy3ve2PCY9BSrbPhcR9wdDsWQECAahzw2dS` | SPL Token |
169
+ | CCM | `Dxk8mAb3C7AM8JN6tAJfVuSja5yidhZM5sEKW3SRX2BM` | Token-2022 |
@@ -0,0 +1,60 @@
1
+ /**
2
+ * On-chain account deserialization for the Liquid Attention Protocol.
3
+ *
4
+ * Layouts must match the Anchor account structs defined in
5
+ * programs/attention-oracle/src/state/*.rs.
6
+ */
7
+ import { Connection, PublicKey } from '@solana/web3.js';
8
+ export interface MarketVaultData {
9
+ bump: number;
10
+ depositMint: PublicKey;
11
+ vlofiMint: PublicKey;
12
+ vaultAta: PublicKey;
13
+ }
14
+ export interface MarketVaultFull extends MarketVaultData {
15
+ marketId: number;
16
+ totalDeposited: bigint;
17
+ totalShares: bigint;
18
+ }
19
+ export interface ProtocolStateData {
20
+ isInitialized: boolean;
21
+ version: number;
22
+ admin: PublicKey;
23
+ publisher: PublicKey;
24
+ treasury: PublicKey;
25
+ oracleAuthority: PublicKey;
26
+ /** CCM (reward) mint address */
27
+ mint: PublicKey;
28
+ /** USDC (or deposit token) mint address — added for market vault init discovery */
29
+ depositMint?: PublicKey;
30
+ paused: boolean;
31
+ requireReceipt: boolean;
32
+ bump: number;
33
+ }
34
+ export interface OnChainPosition {
35
+ user: PublicKey;
36
+ marketVault: PublicKey;
37
+ depositedAmount: bigint;
38
+ sharesMinted: bigint;
39
+ attentionMultiplierBps: bigint;
40
+ settled: boolean;
41
+ entrySlot: bigint;
42
+ }
43
+ /** Parse a MarketVault account's core fields (skip Anchor discriminator). */
44
+ export declare function parseMarketVault(data: Buffer): MarketVaultData;
45
+ /**
46
+ * Parse a ProtocolState account (matches `ProtocolState` struct in state/protocol.rs).
47
+ *
48
+ * Layout after 8-byte Anchor discriminator:
49
+ * is_initialized(1) + version(1) + admin(32) + publisher(32)
50
+ * + treasury(32) + oracle_authority(32) + mint(32) + paused(1) + require_receipt(1) + bump(1)
51
+ */
52
+ export declare function parseProtocolState(data: Buffer): ProtocolStateData;
53
+ /** Parse a UserMarketPosition account. Returns null if data is too short. */
54
+ export declare function parseUserMarketPosition(data: Buffer): OnChainPosition | null;
55
+ /** Fetch a user's position for a specific market directly from chain. */
56
+ export declare function fetchOnChainPosition(connection: Connection, user: PublicKey, marketId: number, programId?: PublicKey): Promise<OnChainPosition | null>;
57
+ /** Fetch the full MarketVault data from chain. */
58
+ export declare function fetchMarketVault(connection: Connection, marketId: number, programId?: PublicKey): Promise<MarketVaultFull | null>;
59
+ /** Read a token account balance from chain. */
60
+ export declare function fetchTokenBalance(connection: Connection, tokenAccount: PublicKey): Promise<bigint>;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * On-chain account deserialization for the Liquid Attention Protocol.
3
+ *
4
+ * Layouts must match the Anchor account structs defined in
5
+ * programs/attention-oracle/src/state/*.rs.
6
+ */
7
+ import { PublicKey } from '@solana/web3.js';
8
+ import { getProtocolStatePDA, getMarketVaultPDA, getUserPositionPDA } from './pda';
9
+ // ── Parsers ────────────────────────────────────────────
10
+ /** Parse a MarketVault account's core fields (skip Anchor discriminator). */
11
+ export function parseMarketVault(data) {
12
+ const d = data.subarray(8);
13
+ return {
14
+ bump: d[0],
15
+ // market_id at offset 1 (8 bytes) — skip
16
+ depositMint: new PublicKey(d.subarray(9, 41)),
17
+ vlofiMint: new PublicKey(d.subarray(41, 73)),
18
+ vaultAta: new PublicKey(d.subarray(73, 105)),
19
+ };
20
+ }
21
+ /**
22
+ * Parse a ProtocolState account (matches `ProtocolState` struct in state/protocol.rs).
23
+ *
24
+ * Layout after 8-byte Anchor discriminator:
25
+ * is_initialized(1) + version(1) + admin(32) + publisher(32)
26
+ * + treasury(32) + oracle_authority(32) + mint(32) + paused(1) + require_receipt(1) + bump(1)
27
+ */
28
+ export function parseProtocolState(data) {
29
+ const d = data.subarray(8);
30
+ return {
31
+ isInitialized: d[0] !== 0,
32
+ version: d[1],
33
+ admin: new PublicKey(d.subarray(2, 34)),
34
+ publisher: new PublicKey(d.subarray(34, 66)),
35
+ treasury: new PublicKey(d.subarray(66, 98)),
36
+ oracleAuthority: new PublicKey(d.subarray(98, 130)),
37
+ mint: new PublicKey(d.subarray(130, 162)),
38
+ paused: d[162] !== 0,
39
+ requireReceipt: d[163] !== 0,
40
+ bump: d[164],
41
+ };
42
+ }
43
+ /** Parse a UserMarketPosition account. Returns null if data is too short. */
44
+ export function parseUserMarketPosition(data) {
45
+ if (data.length < 106)
46
+ return null;
47
+ const d = data.subarray(8); // skip Anchor discriminator
48
+ return {
49
+ user: new PublicKey(d.subarray(1, 33)),
50
+ marketVault: new PublicKey(d.subarray(33, 65)),
51
+ depositedAmount: d.readBigUInt64LE(65),
52
+ sharesMinted: d.readBigUInt64LE(73),
53
+ attentionMultiplierBps: d.readBigUInt64LE(81),
54
+ settled: d[89] !== 0,
55
+ entrySlot: d.readBigUInt64LE(90),
56
+ };
57
+ }
58
+ // ── Fetch Helpers ──────────────────────────────────────
59
+ /** Fetch a user's position for a specific market directly from chain. */
60
+ export async function fetchOnChainPosition(connection, user, marketId, programId) {
61
+ const protocolState = getProtocolStatePDA(programId);
62
+ const marketVault = getMarketVaultPDA(protocolState, marketId, programId);
63
+ const positionPda = getUserPositionPDA(marketVault, user, programId);
64
+ const info = await connection.getAccountInfo(positionPda);
65
+ if (!info)
66
+ return null;
67
+ return parseUserMarketPosition(Buffer.from(info.data));
68
+ }
69
+ /** Fetch the full MarketVault data from chain. */
70
+ export async function fetchMarketVault(connection, marketId, programId) {
71
+ const protocolState = getProtocolStatePDA(programId);
72
+ const marketVault = getMarketVaultPDA(protocolState, marketId, programId);
73
+ const info = await connection.getAccountInfo(marketVault);
74
+ if (!info)
75
+ return null;
76
+ const d = Buffer.from(info.data).subarray(8);
77
+ return {
78
+ bump: d[0],
79
+ depositMint: new PublicKey(d.subarray(9, 41)),
80
+ vlofiMint: new PublicKey(d.subarray(41, 73)),
81
+ vaultAta: new PublicKey(d.subarray(73, 105)),
82
+ marketId,
83
+ totalDeposited: d.readBigUInt64LE(105),
84
+ totalShares: d.readBigUInt64LE(113),
85
+ };
86
+ }
87
+ /** Read a token account balance from chain. */
88
+ export async function fetchTokenBalance(connection, tokenAccount) {
89
+ const info = await connection.getAccountInfo(tokenAccount);
90
+ if (!info || info.data.length < 72)
91
+ return 0n;
92
+ return Buffer.from(info.data.subarray(64, 72)).readBigUInt64LE(0);
93
+ }
@@ -0,0 +1,16 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ /** Devnet program ID (matches declare_id! in lib.rs) */
3
+ export declare const DEVNET_PROGRAM_ID: PublicKey;
4
+ /** Mainnet program ID */
5
+ export declare const MAINNET_PROGRAM_ID: PublicKey;
6
+ /** Default program ID — mainnet */
7
+ export declare const PROGRAM_ID: PublicKey;
8
+ export declare const TOKEN_PROGRAM_ID: PublicKey;
9
+ export declare const TOKEN_2022_PROGRAM_ID: PublicKey;
10
+ export declare const ASSOCIATED_TOKEN_PROGRAM_ID: PublicKey;
11
+ export declare const PROTOCOL_STATE_SEED = "protocol_state";
12
+ export declare const MARKET_VAULT_SEED = "market_vault";
13
+ export declare const MARKET_POSITION_SEED = "market_position";
14
+ export declare const GLOBAL_ROOT_SEED = "global_root";
15
+ export declare const CLAIM_STATE_GLOBAL_SEED = "claim_global";
16
+ export declare const CHANNEL_CONFIG_V2_SEED = "channel_cfg_v2";
@@ -0,0 +1,19 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ // ── Program IDs ────────────────────────────────────────
3
+ /** Devnet program ID (matches declare_id! in lib.rs) */
4
+ export const DEVNET_PROGRAM_ID = new PublicKey('GmGXXNjLhxKdEfCqnYgW2tev4DewPvgUXzhsVfm677VW');
5
+ /** Mainnet program ID */
6
+ export const MAINNET_PROGRAM_ID = new PublicKey('GnGzNdsQMxMpJfMeqnkGPsvHm8kwaDidiKjNU2dCVZop');
7
+ /** Default program ID — mainnet */
8
+ export const PROGRAM_ID = MAINNET_PROGRAM_ID;
9
+ // ── Token Program IDs ──────────────────────────────────
10
+ export const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
11
+ export const TOKEN_2022_PROGRAM_ID = new PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
12
+ export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
13
+ // ── PDA Seeds (must match programs/attention-oracle/src/constants.rs) ──
14
+ export const PROTOCOL_STATE_SEED = 'protocol_state';
15
+ export const MARKET_VAULT_SEED = 'market_vault';
16
+ export const MARKET_POSITION_SEED = 'market_position';
17
+ export const GLOBAL_ROOT_SEED = 'global_root';
18
+ export const CLAIM_STATE_GLOBAL_SEED = 'claim_global';
19
+ export const CHANNEL_CONFIG_V2_SEED = 'channel_cfg_v2';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @wzrd/sdk — TypeScript SDK for the Liquid Attention Protocol.
3
+ *
4
+ * PDA derivation, instruction builders, and account parsers for
5
+ * deposit_market, settle_market, and claim_global.
6
+ */
7
+ export declare const VERSION = "0.1.0";
8
+ export { PROGRAM_ID, DEVNET_PROGRAM_ID, MAINNET_PROGRAM_ID, TOKEN_PROGRAM_ID, TOKEN_2022_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';
9
+ export { getProtocolStatePDA, getMarketVaultPDA, getUserPositionPDA, getGlobalRootConfigPDA, getClaimStatePDA, getChannelConfigV2PDA, getAta, } from './pda';
10
+ export type { MarketVaultData, MarketVaultFull, ProtocolStateData, OnChainPosition, } from './accounts';
11
+ export { parseMarketVault, parseProtocolState, parseUserMarketPosition, fetchOnChainPosition, fetchMarketVault, fetchTokenBalance, } from './accounts';
12
+ export { anchorDisc, createAtaIdempotentIx, createDepositMarketIx, createSettleMarketIx, createInitializeMarketVaultIx, createClaimGlobalIx, createChannelConfigV2Ix, } from './instructions';
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @wzrd/sdk — TypeScript SDK for the Liquid Attention Protocol.
3
+ *
4
+ * PDA derivation, instruction builders, and account parsers for
5
+ * deposit_market, settle_market, and claim_global.
6
+ */
7
+ export const VERSION = '0.1.0';
8
+ // ── Constants ──────────────────────────────────────────
9
+ export { PROGRAM_ID, DEVNET_PROGRAM_ID, MAINNET_PROGRAM_ID, TOKEN_PROGRAM_ID, TOKEN_2022_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';
10
+ // ── PDA Derivation ─────────────────────────────────────
11
+ export { getProtocolStatePDA, getMarketVaultPDA, getUserPositionPDA, getGlobalRootConfigPDA, getClaimStatePDA, getChannelConfigV2PDA, getAta, } from './pda';
12
+ export { parseMarketVault, parseProtocolState, parseUserMarketPosition, fetchOnChainPosition, fetchMarketVault, fetchTokenBalance, } from './accounts';
13
+ // ── Instruction Builders ───────────────────────────────
14
+ export { anchorDisc, createAtaIdempotentIx, createDepositMarketIx, createSettleMarketIx, createInitializeMarketVaultIx, createClaimGlobalIx, createChannelConfigV2Ix, } from './instructions';
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Instruction builders for the Liquid Attention Protocol.
3
+ *
4
+ * Builds deposit_market, settle_market, and claim_global TransactionInstructions
5
+ * that the wallet adapter signs directly — no server signing needed.
6
+ */
7
+ import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';
8
+ /**
9
+ * Anchor instruction discriminator: first 8 bytes of SHA-256("global:<name>").
10
+ * Works in both browser (WebCrypto) and Node.js (crypto module) environments.
11
+ */
12
+ export declare function anchorDisc(name: string): Promise<Buffer>;
13
+ /** Build a CreateIdempotent ATA instruction (instruction index 1). Never fails if ATA exists. */
14
+ export declare function createAtaIdempotentIx(payer: PublicKey, ata: PublicKey, owner: PublicKey, mint: PublicKey, tokenProgramId?: PublicKey): TransactionInstruction;
15
+ /**
16
+ * Build a `deposit_market` TransactionInstruction.
17
+ *
18
+ * Accounts (order must match DepositMarket struct in vault.rs):
19
+ * 0. user (signer, writable)
20
+ * 1. protocol_state (readonly)
21
+ * 2. market_vault (writable)
22
+ * 3. user_market_position (writable)
23
+ * 4. user_usdc_ata (writable)
24
+ * 5. vault_usdc_ata (writable)
25
+ * 6. vlofi_mint (writable)
26
+ * 7. user_vlofi_ata (writable)
27
+ * 8. token_program (readonly)
28
+ * 9. token_2022_program (readonly)
29
+ * 10. system_program (readonly)
30
+ *
31
+ * @returns Array of instructions: idempotent ATA creates + the deposit IX.
32
+ */
33
+ export declare function createDepositMarketIx(connection: Connection, user: PublicKey, marketId: number,
34
+ /** USDC amount in native units (6 decimals, e.g., 1_000_000 = 1 USDC) */
35
+ amount: bigint | number, programId?: PublicKey): Promise<TransactionInstruction[]>;
36
+ /**
37
+ * Build a `settle_market` TransactionInstruction.
38
+ *
39
+ * Accounts (order must match SettleMarket struct in vault.rs):
40
+ * 0. user (signer, writable)
41
+ * 1. protocol_state (readonly)
42
+ * 2. market_vault (writable)
43
+ * 3. user_market_position (writable)
44
+ * 4. vlofi_mint (writable)
45
+ * 5. user_vlofi_ata (writable)
46
+ * 6. vault_usdc_ata (writable)
47
+ * 7. user_usdc_ata (writable)
48
+ * 8. ccm_mint (writable)
49
+ * 9. user_ccm_ata (writable)
50
+ * 10. token_program (readonly) — legacy SPL (USDC)
51
+ * 11. token_2022_program (readonly) — vLOFI burn
52
+ * 12. ccm_token_program (readonly) — CCM mint (Token-2022 on mainnet)
53
+ *
54
+ * @returns Array of instructions: idempotent ATA create for CCM + the settle IX.
55
+ */
56
+ export declare function createSettleMarketIx(connection: Connection, user: PublicKey, marketId: number, programId?: PublicKey): Promise<TransactionInstruction[]>;
57
+ /**
58
+ * Build an `initialize_market_vault` TransactionInstruction.
59
+ *
60
+ * Accounts (order must match InitializeMarketVault struct in vault.rs):
61
+ * 0. admin (signer, writable)
62
+ * 1. protocol_state (readonly)
63
+ * 2. market_vault (writable, init)
64
+ * 3. deposit_mint (readonly) — USDC
65
+ * 4. vlofi_mint (readonly) — Token-2022
66
+ * 5. vault_ata (readonly) — Pre-created ATA owned by vault PDA
67
+ * 6. system_program (readonly)
68
+ */
69
+ export declare function createInitializeMarketVaultIx(admin: PublicKey, marketId: number, depositMint: PublicKey, vlofiMint: PublicKey, programId?: PublicKey): Promise<TransactionInstruction>;
70
+ /**
71
+ * Build a `claim_global` TransactionInstruction.
72
+ *
73
+ * Accounts (must match ClaimGlobal struct in global.rs):
74
+ * 0. claimer (signer, writable)
75
+ * 1. protocol_state (writable)
76
+ * 2. global_root_config (readonly)
77
+ * 3. claim_state (writable, init_if_needed)
78
+ * 4. mint (readonly) — CCM Token-2022 mint
79
+ * 5. treasury_ata (writable)
80
+ * 6. claimer_ata (writable, init_if_needed)
81
+ * 7. token_program (readonly) — Token-2022
82
+ * 8. associated_token_program (readonly)
83
+ * 9. system_program (readonly)
84
+ *
85
+ * @returns Array of instructions: idempotent ATA create for claimer CCM + the claim IX.
86
+ */
87
+ export declare function createClaimGlobalIx(connection: Connection, claimer: PublicKey, rootSeq: number, cumulativeTotal: bigint | number,
88
+ /** Hex-encoded 32-byte sibling hashes from the claims API */
89
+ proofHex: string[], programId?: PublicKey): Promise<TransactionInstruction[]>;
90
+ /**
91
+ * Build a `create_channel_config_v2` TransactionInstruction.
92
+ *
93
+ * Accounts (order must match CreateChannelConfigV2 struct in admin.rs):
94
+ * 0. admin (signer, writable)
95
+ * 1. protocol_state (readonly)
96
+ * 2. channel_config (writable, init)
97
+ * 3. system_program (readonly)
98
+ *
99
+ * Args (Borsh-serialized):
100
+ * subject: Pubkey (32 bytes)
101
+ * authority: Pubkey (32 bytes)
102
+ * creator_wallet: Pubkey (32 bytes)
103
+ * creator_fee_bps: u16 (2 bytes LE)
104
+ */
105
+ export declare function createChannelConfigV2Ix(admin: PublicKey,
106
+ /** CCM mint pubkey (from ProtocolState.mint) */
107
+ mint: PublicKey, subject: PublicKey, authority: PublicKey, creatorWallet: PublicKey, creatorFeeBps: number, programId?: PublicKey): Promise<TransactionInstruction>;
@@ -0,0 +1,332 @@
1
+ /**
2
+ * Instruction builders for the Liquid Attention Protocol.
3
+ *
4
+ * Builds deposit_market, settle_market, and claim_global TransactionInstructions
5
+ * that the wallet adapter signs directly — no server signing needed.
6
+ */
7
+ import { SystemProgram, TransactionInstruction, } from '@solana/web3.js';
8
+ import { PROGRAM_ID, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, } from './constants';
9
+ import { getProtocolStatePDA, getMarketVaultPDA, getUserPositionPDA, getGlobalRootConfigPDA, getClaimStatePDA, getChannelConfigV2PDA, getAta, } from './pda';
10
+ import { parseMarketVault, parseProtocolState } from './accounts';
11
+ // ── Helpers ────────────────────────────────────────────
12
+ /**
13
+ * Anchor instruction discriminator: first 8 bytes of SHA-256("global:<name>").
14
+ * Works in both browser (WebCrypto) and Node.js (crypto module) environments.
15
+ */
16
+ export async function anchorDisc(name) {
17
+ const preimage = `global:${name}`;
18
+ // Node.js path — use built-in crypto module
19
+ if (typeof globalThis.process !== 'undefined') {
20
+ const { createHash } = await import('crypto');
21
+ const hash = createHash('sha256').update(preimage).digest();
22
+ return Buffer.from(hash.subarray(0, 8));
23
+ }
24
+ // Browser path — WebCrypto
25
+ const encoded = new TextEncoder().encode(preimage);
26
+ const hash = await crypto.subtle.digest('SHA-256', encoded.buffer);
27
+ return Buffer.from(new Uint8Array(hash).slice(0, 8));
28
+ }
29
+ /** Build a CreateIdempotent ATA instruction (instruction index 1). Never fails if ATA exists. */
30
+ export function createAtaIdempotentIx(payer, ata, owner, mint, tokenProgramId = TOKEN_PROGRAM_ID) {
31
+ return new TransactionInstruction({
32
+ programId: ASSOCIATED_TOKEN_PROGRAM_ID,
33
+ keys: [
34
+ { pubkey: payer, isSigner: true, isWritable: true },
35
+ { pubkey: ata, isSigner: false, isWritable: true },
36
+ { pubkey: owner, isSigner: false, isWritable: false },
37
+ { pubkey: mint, isSigner: false, isWritable: false },
38
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
39
+ { pubkey: tokenProgramId, isSigner: false, isWritable: false },
40
+ ],
41
+ data: Buffer.from([1]), // CreateIdempotent
42
+ });
43
+ }
44
+ // ── Instruction Builders ───────────────────────────────
45
+ /**
46
+ * Build a `deposit_market` TransactionInstruction.
47
+ *
48
+ * Accounts (order must match DepositMarket struct in vault.rs):
49
+ * 0. user (signer, writable)
50
+ * 1. protocol_state (readonly)
51
+ * 2. market_vault (writable)
52
+ * 3. user_market_position (writable)
53
+ * 4. user_usdc_ata (writable)
54
+ * 5. vault_usdc_ata (writable)
55
+ * 6. vlofi_mint (writable)
56
+ * 7. user_vlofi_ata (writable)
57
+ * 8. token_program (readonly)
58
+ * 9. token_2022_program (readonly)
59
+ * 10. system_program (readonly)
60
+ *
61
+ * @returns Array of instructions: idempotent ATA creates + the deposit IX.
62
+ */
63
+ export async function createDepositMarketIx(connection, user, marketId,
64
+ /** USDC amount in native units (6 decimals, e.g., 1_000_000 = 1 USDC) */
65
+ amount, programId = PROGRAM_ID) {
66
+ const protocolState = getProtocolStatePDA(programId);
67
+ const marketVault = getMarketVaultPDA(protocolState, marketId, programId);
68
+ const userPosition = getUserPositionPDA(marketVault, user, programId);
69
+ // Fetch vault to discover mints
70
+ const vaultInfo = await connection.getAccountInfo(marketVault);
71
+ if (!vaultInfo)
72
+ throw new Error(`MarketVault not found for market ${marketId}`);
73
+ const vault = parseMarketVault(Buffer.from(vaultInfo.data));
74
+ const userUsdcAta = getAta(user, vault.depositMint, TOKEN_PROGRAM_ID);
75
+ const userVlofiAta = getAta(user, vault.vlofiMint, TOKEN_PROGRAM_ID);
76
+ // Prepend idempotent ATA creation for USDC and vLOFI (no-ops if they exist)
77
+ const ixs = [
78
+ createAtaIdempotentIx(user, userUsdcAta, user, vault.depositMint, TOKEN_PROGRAM_ID),
79
+ createAtaIdempotentIx(user, userVlofiAta, user, vault.vlofiMint, TOKEN_PROGRAM_ID),
80
+ ];
81
+ // Instruction data: [8 disc][8 market_id LE][8 amount LE]
82
+ const disc = await anchorDisc('deposit_market');
83
+ const data = Buffer.alloc(24);
84
+ disc.copy(data, 0);
85
+ data.writeBigUInt64LE(BigInt(marketId), 8);
86
+ data.writeBigUInt64LE(BigInt(amount), 16);
87
+ ixs.push(new TransactionInstruction({
88
+ programId,
89
+ keys: [
90
+ { pubkey: user, isSigner: true, isWritable: true },
91
+ { pubkey: protocolState, isSigner: false, isWritable: false },
92
+ { pubkey: marketVault, isSigner: false, isWritable: true },
93
+ { pubkey: userPosition, isSigner: false, isWritable: true },
94
+ { pubkey: userUsdcAta, isSigner: false, isWritable: true },
95
+ { pubkey: vault.vaultAta, isSigner: false, isWritable: true },
96
+ { pubkey: vault.vlofiMint, isSigner: false, isWritable: true },
97
+ { pubkey: userVlofiAta, isSigner: false, isWritable: true },
98
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
99
+ { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
100
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
101
+ ],
102
+ data,
103
+ }));
104
+ return ixs;
105
+ }
106
+ /**
107
+ * Build a `settle_market` TransactionInstruction.
108
+ *
109
+ * Accounts (order must match SettleMarket struct in vault.rs):
110
+ * 0. user (signer, writable)
111
+ * 1. protocol_state (readonly)
112
+ * 2. market_vault (writable)
113
+ * 3. user_market_position (writable)
114
+ * 4. vlofi_mint (writable)
115
+ * 5. user_vlofi_ata (writable)
116
+ * 6. vault_usdc_ata (writable)
117
+ * 7. user_usdc_ata (writable)
118
+ * 8. ccm_mint (writable)
119
+ * 9. user_ccm_ata (writable)
120
+ * 10. token_program (readonly) — legacy SPL (USDC)
121
+ * 11. token_2022_program (readonly) — vLOFI burn
122
+ * 12. ccm_token_program (readonly) — CCM mint (Token-2022 on mainnet)
123
+ *
124
+ * @returns Array of instructions: idempotent ATA create for CCM + the settle IX.
125
+ */
126
+ export async function createSettleMarketIx(connection, user, marketId, programId = PROGRAM_ID) {
127
+ const protocolState = getProtocolStatePDA(programId);
128
+ const marketVault = getMarketVaultPDA(protocolState, marketId, programId);
129
+ const userPosition = getUserPositionPDA(marketVault, user, programId);
130
+ // Fetch vault to discover mints
131
+ const vaultInfo = await connection.getAccountInfo(marketVault);
132
+ if (!vaultInfo)
133
+ throw new Error(`MarketVault not found for market ${marketId}`);
134
+ const vault = parseMarketVault(Buffer.from(vaultInfo.data));
135
+ // Fetch protocol state to discover CCM mint
136
+ const protocolInfo = await connection.getAccountInfo(protocolState);
137
+ if (!protocolInfo)
138
+ throw new Error('ProtocolState not found');
139
+ const protocol = parseProtocolState(Buffer.from(protocolInfo.data));
140
+ // Detect CCM mint's token program (Token-2022 on mainnet, legacy SPL on devnet)
141
+ const ccmMintInfo = await connection.getAccountInfo(protocol.mint);
142
+ if (!ccmMintInfo)
143
+ throw new Error('CCM mint account not found');
144
+ const ccmTokenProgram = ccmMintInfo.owner;
145
+ const userVlofiAta = getAta(user, vault.vlofiMint, TOKEN_PROGRAM_ID);
146
+ const userUsdcAta = getAta(user, vault.depositMint, TOKEN_PROGRAM_ID);
147
+ const userCcmAta = getAta(user, protocol.mint, ccmTokenProgram);
148
+ // Prepend idempotent ATA creation for CCM (no-op if exists)
149
+ const ixs = [
150
+ createAtaIdempotentIx(user, userCcmAta, user, protocol.mint, ccmTokenProgram),
151
+ ];
152
+ // Instruction data: [8 disc][8 market_id LE]
153
+ const disc = await anchorDisc('settle_market');
154
+ const data = Buffer.alloc(16);
155
+ disc.copy(data, 0);
156
+ data.writeBigUInt64LE(BigInt(marketId), 8);
157
+ ixs.push(new TransactionInstruction({
158
+ programId,
159
+ keys: [
160
+ { pubkey: user, isSigner: true, isWritable: true },
161
+ { pubkey: protocolState, isSigner: false, isWritable: false },
162
+ { pubkey: marketVault, isSigner: false, isWritable: true },
163
+ { pubkey: userPosition, isSigner: false, isWritable: true },
164
+ { pubkey: vault.vlofiMint, isSigner: false, isWritable: true },
165
+ { pubkey: userVlofiAta, isSigner: false, isWritable: true },
166
+ { pubkey: vault.vaultAta, isSigner: false, isWritable: true },
167
+ { pubkey: userUsdcAta, isSigner: false, isWritable: true },
168
+ { pubkey: protocol.mint, isSigner: false, isWritable: true },
169
+ { pubkey: userCcmAta, isSigner: false, isWritable: true },
170
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
171
+ { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
172
+ { pubkey: ccmTokenProgram, isSigner: false, isWritable: false },
173
+ ],
174
+ data,
175
+ }));
176
+ return ixs;
177
+ }
178
+ /**
179
+ * Build an `initialize_market_vault` TransactionInstruction.
180
+ *
181
+ * Accounts (order must match InitializeMarketVault struct in vault.rs):
182
+ * 0. admin (signer, writable)
183
+ * 1. protocol_state (readonly)
184
+ * 2. market_vault (writable, init)
185
+ * 3. deposit_mint (readonly) — USDC
186
+ * 4. vlofi_mint (readonly) — Token-2022
187
+ * 5. vault_ata (readonly) — Pre-created ATA owned by vault PDA
188
+ * 6. system_program (readonly)
189
+ */
190
+ export async function createInitializeMarketVaultIx(admin, marketId, depositMint, vlofiMint, programId = PROGRAM_ID) {
191
+ const protocolState = getProtocolStatePDA(programId);
192
+ const marketVault = getMarketVaultPDA(protocolState, marketId, programId);
193
+ // The vault's USDC ATA must be pre-created and owned by the vault PDA
194
+ const vaultAta = getAta(marketVault, depositMint, TOKEN_PROGRAM_ID);
195
+ // Instruction data: [8 disc][8 market_id LE]
196
+ const disc = await anchorDisc('initialize_market_vault');
197
+ const data = Buffer.alloc(16);
198
+ disc.copy(data, 0);
199
+ data.writeBigUInt64LE(BigInt(marketId), 8);
200
+ return new TransactionInstruction({
201
+ programId,
202
+ keys: [
203
+ { pubkey: admin, isSigner: true, isWritable: true },
204
+ { pubkey: protocolState, isSigner: false, isWritable: false },
205
+ { pubkey: marketVault, isSigner: false, isWritable: true },
206
+ { pubkey: depositMint, isSigner: false, isWritable: false },
207
+ { pubkey: vlofiMint, isSigner: false, isWritable: false },
208
+ { pubkey: vaultAta, isSigner: false, isWritable: false },
209
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
210
+ ],
211
+ data,
212
+ });
213
+ }
214
+ /**
215
+ * Build a `claim_global` TransactionInstruction.
216
+ *
217
+ * Accounts (must match ClaimGlobal struct in global.rs):
218
+ * 0. claimer (signer, writable)
219
+ * 1. protocol_state (writable)
220
+ * 2. global_root_config (readonly)
221
+ * 3. claim_state (writable, init_if_needed)
222
+ * 4. mint (readonly) — CCM Token-2022 mint
223
+ * 5. treasury_ata (writable)
224
+ * 6. claimer_ata (writable, init_if_needed)
225
+ * 7. token_program (readonly) — Token-2022
226
+ * 8. associated_token_program (readonly)
227
+ * 9. system_program (readonly)
228
+ *
229
+ * @returns Array of instructions: idempotent ATA create for claimer CCM + the claim IX.
230
+ */
231
+ export async function createClaimGlobalIx(connection, claimer, rootSeq, cumulativeTotal,
232
+ /** Hex-encoded 32-byte sibling hashes from the claims API */
233
+ proofHex, programId = PROGRAM_ID) {
234
+ const protocolState = getProtocolStatePDA(programId);
235
+ // Fetch protocol state to discover CCM mint
236
+ const protocolInfo = await connection.getAccountInfo(protocolState);
237
+ if (!protocolInfo)
238
+ throw new Error('ProtocolState not found');
239
+ const protocol = parseProtocolState(Buffer.from(protocolInfo.data));
240
+ const ccmMint = protocol.mint;
241
+ // Derive PDAs
242
+ const globalRootConfig = getGlobalRootConfigPDA(ccmMint, programId);
243
+ const claimState = getClaimStatePDA(ccmMint, claimer, programId);
244
+ // ATAs — Token-2022 for CCM
245
+ const treasuryAta = getAta(protocolState, ccmMint, TOKEN_2022_PROGRAM_ID);
246
+ const claimerAta = getAta(claimer, ccmMint, TOKEN_2022_PROGRAM_ID);
247
+ // Prepend idempotent ATA creation for claimer's CCM account
248
+ const ixs = [
249
+ createAtaIdempotentIx(claimer, claimerAta, claimer, ccmMint, TOKEN_2022_PROGRAM_ID),
250
+ ];
251
+ // Decode hex proof to bytes
252
+ const proofBytes = proofHex.map((h) => Buffer.from(h, 'hex'));
253
+ // Instruction data: [8 disc][8 root_seq LE][8 cumulative_total LE][4 proof_len LE][N * 32 proof]
254
+ const disc = await anchorDisc('claim_global');
255
+ const dataLen = 8 + 8 + 8 + 4 + proofBytes.length * 32;
256
+ const data = Buffer.alloc(dataLen);
257
+ let offset = 0;
258
+ disc.copy(data, offset);
259
+ offset += 8;
260
+ data.writeBigUInt64LE(BigInt(rootSeq), offset);
261
+ offset += 8;
262
+ data.writeBigUInt64LE(BigInt(cumulativeTotal), offset);
263
+ offset += 8;
264
+ data.writeUInt32LE(proofBytes.length, offset);
265
+ offset += 4;
266
+ for (const node of proofBytes) {
267
+ node.copy(data, offset);
268
+ offset += 32;
269
+ }
270
+ ixs.push(new TransactionInstruction({
271
+ programId,
272
+ keys: [
273
+ { pubkey: claimer, isSigner: true, isWritable: true },
274
+ { pubkey: protocolState, isSigner: false, isWritable: true },
275
+ { pubkey: globalRootConfig, isSigner: false, isWritable: false },
276
+ { pubkey: claimState, isSigner: false, isWritable: true },
277
+ { pubkey: ccmMint, isSigner: false, isWritable: false },
278
+ { pubkey: treasuryAta, isSigner: false, isWritable: true },
279
+ { pubkey: claimerAta, isSigner: false, isWritable: true },
280
+ { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
281
+ { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
282
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
283
+ ],
284
+ data,
285
+ }));
286
+ return ixs;
287
+ }
288
+ // ── Admin Instruction Builders ────────────────────────
289
+ /**
290
+ * Build a `create_channel_config_v2` TransactionInstruction.
291
+ *
292
+ * Accounts (order must match CreateChannelConfigV2 struct in admin.rs):
293
+ * 0. admin (signer, writable)
294
+ * 1. protocol_state (readonly)
295
+ * 2. channel_config (writable, init)
296
+ * 3. system_program (readonly)
297
+ *
298
+ * Args (Borsh-serialized):
299
+ * subject: Pubkey (32 bytes)
300
+ * authority: Pubkey (32 bytes)
301
+ * creator_wallet: Pubkey (32 bytes)
302
+ * creator_fee_bps: u16 (2 bytes LE)
303
+ */
304
+ export async function createChannelConfigV2Ix(admin,
305
+ /** CCM mint pubkey (from ProtocolState.mint) */
306
+ mint, subject, authority, creatorWallet, creatorFeeBps, programId = PROGRAM_ID) {
307
+ const protocolState = getProtocolStatePDA(programId);
308
+ const channelConfig = getChannelConfigV2PDA(mint, subject, programId);
309
+ // Instruction data: [8 disc][32 subject][32 authority][32 creator_wallet][2 fee_bps LE]
310
+ const disc = await anchorDisc('create_channel_config_v2');
311
+ const data = Buffer.alloc(8 + 32 + 32 + 32 + 2);
312
+ let offset = 0;
313
+ disc.copy(data, offset);
314
+ offset += 8;
315
+ subject.toBuffer().copy(data, offset);
316
+ offset += 32;
317
+ authority.toBuffer().copy(data, offset);
318
+ offset += 32;
319
+ creatorWallet.toBuffer().copy(data, offset);
320
+ offset += 32;
321
+ data.writeUInt16LE(creatorFeeBps, offset);
322
+ return new TransactionInstruction({
323
+ programId,
324
+ keys: [
325
+ { pubkey: admin, isSigner: true, isWritable: true },
326
+ { pubkey: protocolState, isSigner: false, isWritable: false },
327
+ { pubkey: channelConfig, isSigner: false, isWritable: true },
328
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
329
+ ],
330
+ data,
331
+ });
332
+ }
package/dist/pda.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * PDA derivation helpers for the Liquid Attention Protocol.
3
+ *
4
+ * Seeds must match programs/attention-oracle/src/constants.rs.
5
+ */
6
+ import { PublicKey } from '@solana/web3.js';
7
+ /** Derive the singleton ProtocolState PDA. */
8
+ export declare function getProtocolStatePDA(programId?: PublicKey): PublicKey;
9
+ /** Derive a MarketVault PDA for a given market ID. */
10
+ export declare function getMarketVaultPDA(protocolState: PublicKey, marketId: number, programId?: PublicKey): PublicKey;
11
+ /** Derive a UserMarketPosition PDA. */
12
+ export declare function getUserPositionPDA(marketVault: PublicKey, user: PublicKey, programId?: PublicKey): PublicKey;
13
+ /** Derive the GlobalRootConfig PDA for a given CCM mint. */
14
+ export declare function getGlobalRootConfigPDA(ccmMint: PublicKey, programId?: PublicKey): PublicKey;
15
+ /** Derive the per-user ClaimStateGlobal PDA. */
16
+ export declare function getClaimStatePDA(ccmMint: PublicKey, claimer: PublicKey, programId?: PublicKey): PublicKey;
17
+ /** Derive a ChannelConfigV2 PDA for a given mint and subject. */
18
+ export declare function getChannelConfigV2PDA(mint: PublicKey, subject: PublicKey, programId?: PublicKey): PublicKey;
19
+ /** Derive an Associated Token Account address (works for both SPL and Token-2022). */
20
+ export declare function getAta(owner: PublicKey, mint: PublicKey, tokenProgramId: PublicKey): PublicKey;
package/dist/pda.js ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * PDA derivation helpers for the Liquid Attention Protocol.
3
+ *
4
+ * Seeds must match programs/attention-oracle/src/constants.rs.
5
+ */
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';
8
+ /** Derive the singleton ProtocolState PDA. */
9
+ export function getProtocolStatePDA(programId = PROGRAM_ID) {
10
+ return PublicKey.findProgramAddressSync([Buffer.from(PROTOCOL_STATE_SEED)], programId)[0];
11
+ }
12
+ /** Derive a MarketVault PDA for a given market ID. */
13
+ export function getMarketVaultPDA(protocolState, marketId, programId = PROGRAM_ID) {
14
+ const idBuf = Buffer.alloc(8);
15
+ idBuf.writeBigUInt64LE(BigInt(marketId));
16
+ return PublicKey.findProgramAddressSync([Buffer.from(MARKET_VAULT_SEED), protocolState.toBuffer(), idBuf], programId)[0];
17
+ }
18
+ /** Derive a UserMarketPosition PDA. */
19
+ export function getUserPositionPDA(marketVault, user, programId = PROGRAM_ID) {
20
+ return PublicKey.findProgramAddressSync([Buffer.from(MARKET_POSITION_SEED), marketVault.toBuffer(), user.toBuffer()], programId)[0];
21
+ }
22
+ /** Derive the GlobalRootConfig PDA for a given CCM mint. */
23
+ export function getGlobalRootConfigPDA(ccmMint, programId = PROGRAM_ID) {
24
+ return PublicKey.findProgramAddressSync([Buffer.from(GLOBAL_ROOT_SEED), ccmMint.toBuffer()], programId)[0];
25
+ }
26
+ /** Derive the per-user ClaimStateGlobal PDA. */
27
+ export function getClaimStatePDA(ccmMint, claimer, programId = PROGRAM_ID) {
28
+ return PublicKey.findProgramAddressSync([Buffer.from(CLAIM_STATE_GLOBAL_SEED), ccmMint.toBuffer(), claimer.toBuffer()], programId)[0];
29
+ }
30
+ /** Derive a ChannelConfigV2 PDA for a given mint and subject. */
31
+ export function getChannelConfigV2PDA(mint, subject, programId = PROGRAM_ID) {
32
+ return PublicKey.findProgramAddressSync([Buffer.from(CHANNEL_CONFIG_V2_SEED), mint.toBuffer(), subject.toBuffer()], programId)[0];
33
+ }
34
+ /** Derive an Associated Token Account address (works for both SPL and Token-2022). */
35
+ export function getAta(owner, mint, tokenProgramId) {
36
+ return PublicKey.findProgramAddressSync([owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
37
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@wzrd_sol/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for the WZRD Liquid Attention Protocol — deposit, settle, claim on Solana",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "prepublishOnly": "tsc",
20
+ "dev": "tsc --watch",
21
+ "example:deposit": "tsx examples/deposit.ts",
22
+ "example:claim": "tsx examples/claim.ts",
23
+ "typecheck:examples": "tsc -p tsconfig.examples.json"
24
+ },
25
+ "keywords": [
26
+ "solana",
27
+ "attention",
28
+ "defi",
29
+ "sdk",
30
+ "wzrd",
31
+ "vlofi",
32
+ "ccm",
33
+ "anchor"
34
+ ],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/twzrd-sol/wzrd-final",
39
+ "directory": "sdk"
40
+ },
41
+ "homepage": "https://twzrd.xyz",
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "peerDependencies": {
46
+ "@solana/web3.js": "^1.90.0"
47
+ },
48
+ "devDependencies": {
49
+ "@solana/web3.js": "^1.95.0",
50
+ "typescript": "^5.5.0"
51
+ }
52
+ }