@viwoapp/sdk 0.1.8 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,427 +1,667 @@
1
- # @viwoapp/sdk
2
-
3
- [![npm version](https://img.shields.io/npm/v/@viwoapp/sdk.svg)](https://www.npmjs.com/package/@viwoapp/sdk)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- TypeScript SDK for VCoin Protocol Integration on Solana.
7
-
8
- **Version:** 0.1.8 (Bug Fixes)
9
-
10
- ## What's New in v0.1.8 (Bug Fixes)
11
-
12
- This release addresses 4 SDK issues identified during code review:
13
-
14
- | Finding | Severity | Fix |
15
- |---------|----------|-----|
16
- | #2 | Medium | VCoin balance now correctly filters by mint address |
17
- | #5 | Medium | ViLink batch now uses deterministic nonce PDA |
18
- | #8 | High | Gasless config byte offsets corrected |
19
- | #9 | Low | Error handling improved with console warnings |
20
-
21
- ### Changes
22
-
23
- - **VCoin Mint Filter (Finding #2):** `getVCoinBalance()` now filters by VCoin mint address instead of summing all Token-2022 accounts. Set `programIds.vcoinMint` in your config.
24
- - **Gasless Config Fix (Finding #8):** All byte offsets in `gasless.getConfig()` corrected to match on-chain struct after H-02 security fix added `pending_authority`.
25
- - **ViLink Config Fix:** ViLink config byte offsets also corrected for H-02 compatibility.
26
- - **Error Logging (Finding #9):** Silent `catch { return null }` blocks replaced with `console.warn('[ViWoSDK] ...')` for easier debugging.
27
- - **Batch Nonce (Finding #5):** Added `batchNonce` to `UserActionStatsExtended` for deterministic batch PDA derivation.
28
- - **New Fields:** `GaslessConfig` now includes `feeVault`, `sscreProgram`, `sscreDeductionBps`, `maxSubsidizedPerUser`, `totalSolSpent`, `currentDay`, `daySpent`.
29
-
30
- ### Configuration Update Required
31
-
32
- ```typescript
33
- const client = new ViWoClient({
34
- connection: { endpoint: "https://api.devnet.solana.com" },
35
- wallet: walletAdapter,
36
- programIds: {
37
- // IMPORTANT: Set your VCoin mint address for accurate balance queries
38
- vcoinMint: new PublicKey("YOUR_VCOIN_MINT_ADDRESS"),
39
- },
40
- });
41
- ```
42
-
43
- ## What's New in v0.1.7
44
-
45
- - **ViLink Nonce-Based PDA:** Action PDAs now use deterministic `nonce` instead of `timestamp`
46
- - **New Field:** `actionNonce` added to `ViLinkAction` interface
47
- - **New Type:** `UserActionStatsExtended` with `actionNonce` counter
48
- - **New Method:** `getViLinkActionByNonce()` PDA helper for new derivation
49
- - **New Method:** `getNextNonce()` utility to get next nonce for action creation
50
- - **Updated Methods:** `getAction()`, `isActionValid()`, `buildExecuteTipAction()` now use nonce
51
- - **Deprecated:** `getActionByTimestamp()` - use `getAction()` with nonce instead
52
-
53
- ### Breaking Change (v0.1.7)
54
-
55
- ViLink action PDA derivation changed from timestamp to nonce:
56
- ```typescript
57
- // Old (deprecated)
58
- const action = await client.vilink.getAction(creator, timestamp);
59
-
60
- // New (v0.1.5+)
61
- const nonce = await client.vilink.getNextNonce(creator);
62
- const action = await client.vilink.getAction(creator, nonce);
63
- ```
64
-
65
- ## What's New in v0.1.4
66
-
67
- - **New Constants:** `MERKLE_PROOF_MAX_SIZE`, `MAX_EPOCH_BITMAP`, `LEGACY_SLASH_DEPRECATED`
68
- - **New Enum:** `VoteChoice` for typed governance voting (Against, For, Abstain)
69
- - **Updated Types:** `SlashRequest` (added `requestId`), `UserClaim` (bitmap storage)
70
- - **Updated Docs:** `buildVoteTransaction` - voting power now verified on-chain
71
- - **SECURITY_CONSTANTS:** Added `merkleProofMaxSize`, `maxEpochBitmap`, `votingPowerVerifiedOnChain`
72
-
73
- ## What's New in v0.1.1
74
-
75
- - Added security types for Phase 1-4 fixes
76
- - New types: `SlashRequest`, `DecryptionShare`, `PendingScoreUpdate`
77
- - All config types now support two-step authority transfer
78
- - Added `SECURITY_CONSTANTS` for timelocks and limits
79
- - Added `VALID_URI_PREFIXES` for proposal URI validation
80
- - New PDA seeds: `slashRequest`, `decryptionShare`, `pendingScore`
81
-
82
- ## Installation
83
-
84
- ```bash
85
- npm install @viwoapp/sdk
86
- # or
87
- yarn add @viwoapp/sdk
88
- ```
89
-
90
- ## Quick Start
91
-
92
- ```typescript
93
- import { ViWoClient, parseVCoin, formatVCoin, LOCK_DURATIONS } from "@viwoapp/sdk";
94
-
95
- // Initialize client
96
- const client = new ViWoClient({
97
- connection: { endpoint: "https://api.devnet.solana.com" },
98
- wallet: walletAdapter, // Your wallet adapter
99
- });
100
-
101
- // Get VCoin balance
102
- const balance = await client.getVCoinBalance();
103
- console.log("Balance:", formatVCoin(balance));
104
-
105
- // Stake VCoin
106
- const stakeTx = await client.staking.buildStakeTransaction({
107
- amount: parseVCoin("1000"),
108
- lockDuration: LOCK_DURATIONS.threeMonths,
109
- });
110
- await client.sendTransaction(stakeTx);
111
- ```
112
-
113
- ## Modules
114
-
115
- ### Core (`@viwoapp/sdk`)
116
-
117
- Connection management, utilities, and PDA derivation.
118
-
119
- ```typescript
120
- import { ViWoClient, PDAs, formatVCoin, parseVCoin } from "@viwoapp/sdk";
121
-
122
- const client = new ViWoClient({ connection, wallet });
123
-
124
- // Check connection health
125
- const health = await client.healthCheck();
126
-
127
- // Get PDAs
128
- const stakingPool = client.pdas.getStakingPool();
129
- const userStake = client.pdas.getUserStake(walletPubkey);
130
- ```
131
-
132
- ### Staking (`client.staking`)
133
-
134
- VCoin staking operations for veVCoin.
135
-
136
- ```typescript
137
- // Get staking pool info
138
- const pool = await client.staking.getPool();
139
-
140
- // Get user stake
141
- const stake = await client.staking.getUserStake();
142
- console.log("Staked:", formatVCoin(stake.stakedAmount));
143
- console.log("Tier:", client.staking.getTierName(stake.tier));
144
-
145
- // Calculate veVCoin for stake
146
- const vevcoin = client.staking.calculateVeVCoin(amount, lockDuration);
147
-
148
- // Build transactions
149
- const stakeTx = await client.staking.buildStakeTransaction({ amount, lockDuration });
150
- const unstakeTx = await client.staking.buildUnstakeTransaction();
151
- ```
152
-
153
- ### Governance (`client.governance`)
154
-
155
- Proposal creation and voting.
156
-
157
- ```typescript
158
- // Get active proposals
159
- const proposals = await client.governance.getActiveProposals();
160
-
161
- // Get proposal details
162
- const proposal = await client.governance.getProposal(proposalId);
163
- const progress = await client.governance.getProposalProgress(proposalId);
164
-
165
- // Check voting power
166
- const votingPower = await client.governance.getVotingPower();
167
-
168
- // Build transactions
169
- const voteTx = await client.governance.buildVoteTransaction(proposalId, true);
170
- ```
171
-
172
- ### Rewards (`client.rewards`)
173
-
174
- SSCRE rewards claiming.
175
-
176
- ```typescript
177
- // Get pool stats
178
- const stats = await client.rewards.getStats();
179
-
180
- // Get user claim history
181
- const claims = await client.rewards.getUserClaim();
182
-
183
- // Get unclaimed epochs
184
- const unclaimed = await client.rewards.getUnclaimedEpochs();
185
-
186
- // Build claim transaction
187
- const claimTx = await client.rewards.buildClaimTransaction({
188
- epoch,
189
- amount,
190
- merkleProof,
191
- });
192
- ```
193
-
194
- ### ViLink (`client.vilink`)
195
-
196
- Cross-dApp action deep links.
197
-
198
- ```typescript
199
- // Create tip action
200
- const tipTx = await client.vilink.buildCreateTipAction({
201
- target: recipientPubkey,
202
- amount: parseVCoin("10"),
203
- expirySeconds: 86400, // 1 day
204
- });
205
-
206
- // Generate shareable URI
207
- const uri = client.vilink.generateUri(actionId);
208
- // => viwo://action/abc123...
209
-
210
- // Generate QR code data
211
- const qrData = client.vilink.generateQRData(actionId);
212
-
213
- // Get next nonce for action creation (v0.1.5+)
214
- const nonce = await client.vilink.getNextNonce();
215
-
216
- // Get action by creator + nonce (v0.1.5+)
217
- const action = await client.vilink.getAction(creator, nonce);
218
-
219
- // Check action validity (uses nonce, not timestamp)
220
- const { valid, reason } = await client.vilink.isActionValid(creator, nonce);
221
- ```
222
-
223
- ### Gasless (`client.gasless`)
224
-
225
- Session keys and gasless transactions.
226
-
227
- ```typescript
228
- import { ACTION_SCOPES, FeeMethod } from "@viwoapp/sdk";
229
-
230
- // Create session key
231
- const sessionKeypair = Keypair.generate();
232
- const scope = ACTION_SCOPES.tip | ACTION_SCOPES.vouch;
233
-
234
- const sessionTx = await client.gasless.buildCreateSessionTransaction({
235
- sessionPubkey: sessionKeypair.publicKey,
236
- scope,
237
- durationSeconds: 24 * 3600,
238
- maxActions: 100,
239
- feeMethod: FeeMethod.VCoinDeduction,
240
- });
241
-
242
- // Check session validity
243
- const { valid } = await client.gasless.isSessionValid(user, sessionPubkey);
244
-
245
- // Revoke session
246
- const revokeTx = await client.gasless.buildRevokeSessionTransaction(sessionPubkey);
247
- ```
248
-
249
- ### Identity (`client.identity`)
250
-
251
- User identity management.
252
-
253
- ```typescript
254
- // Get identity
255
- const identity = await client.identity.getIdentity();
256
- console.log("Level:", client.identity.getVerificationLevelName(identity.verificationLevel));
257
-
258
- // Get verification requirements
259
- const reqs = client.identity.getVerificationRequirements(level);
260
- ```
261
-
262
- ### 5A Protocol (`client.fivea`)
263
-
264
- Reputation scoring.
265
-
266
- ```typescript
267
- // Get 5A score
268
- const score = await client.fivea.getScore();
269
- console.log("Composite:", client.fivea.formatScore(score.composite));
270
- console.log("Tier:", client.fivea.getScoreTier(score.composite));
271
-
272
- // Get score breakdown
273
- const breakdown = client.fivea.getScoreBreakdown(score);
274
-
275
- // Get reward multiplier
276
- const multiplier = client.fivea.getRewardMultiplier(score.composite);
277
-
278
- // Check vouch capability
279
- const { canVouch, reason } = await client.fivea.canVouchFor(target);
280
- ```
281
-
282
- ### Content (`client.content`)
283
-
284
- Content registry operations.
285
-
286
- ```typescript
287
- // Get user energy
288
- const energy = await client.content.getEnergy();
289
- const currentEnergy = client.content.calculateRegenEnergy(energy);
290
-
291
- // Check create capability
292
- const { canCreate } = await client.content.canCreateContent();
293
-
294
- // Build transactions
295
- const createTx = await client.content.buildCreateContentTransaction(contentHash);
296
- const editTx = await client.content.buildEditContentTransaction(contentId, newHash);
297
- ```
298
-
299
- ## Constants
300
-
301
- ```typescript
302
- import {
303
- PROGRAM_IDS,
304
- SEEDS,
305
- VCOIN_DECIMALS,
306
- STAKING_TIERS,
307
- LOCK_DURATIONS,
308
- SSCRE_CONSTANTS,
309
- VILINK_CONSTANTS,
310
- GASLESS_CONSTANTS,
311
- ACTION_SCOPES,
312
- FIVE_A_CONSTANTS,
313
- GOVERNANCE_CONSTANTS,
314
- CONTENT_CONSTANTS,
315
- // Security constants
316
- SECURITY_CONSTANTS,
317
- VALID_URI_PREFIXES,
318
- MERKLE_CONSTANTS,
319
- // v0.1.4 additions
320
- MERKLE_PROOF_MAX_SIZE, // 32 - prevents DoS
321
- MAX_EPOCH_BITMAP, // 1023 - max epoch with bitmap
322
- LEGACY_SLASH_DEPRECATED, // true - use propose_slash flow
323
- } from "@viwoapp/sdk";
324
-
325
- // Security constants
326
- SECURITY_CONSTANTS.authorityTransferTimelock; // 24 hours
327
- SECURITY_CONSTANTS.slashApprovalTimelock; // 48 hours
328
- SECURITY_CONSTANTS.maxFeeSlippageBps; // 500 (5%)
329
- SECURITY_CONSTANTS.oracleConsensusRequired; // 3-of-N
330
- SECURITY_CONSTANTS.circuitBreakerCooldown; // 6 hours
331
- SECURITY_CONSTANTS.merkleProofMaxSize; // 32 (v0.1.4)
332
- SECURITY_CONSTANTS.maxEpochBitmap; // 1023 (v0.1.4)
333
- SECURITY_CONSTANTS.votingPowerVerifiedOnChain; // true (v0.1.4)
334
- ```
335
-
336
- ## Types
337
-
338
- ```typescript
339
- import type {
340
- // Staking
341
- StakingPool,
342
- UserStake,
343
- StakingTier,
344
- StakeParams,
345
-
346
- // Governance
347
- Proposal,
348
- VoteRecord,
349
- ProposalStatus,
350
- VoteChoice, // v0.1.4: Against, For, Abstain
351
- GovernanceConfig,
352
- Delegation,
353
- PrivateVotingConfig,
354
- DecryptionShare, // v0.1.1: ZK voting
355
-
356
- // Rewards
357
- RewardsPoolConfig,
358
- EpochDistribution,
359
- UserClaim,
360
- ClaimRewardsParams,
361
-
362
- // ViLink
363
- ViLinkConfig,
364
- ViLinkAction, // v0.1.5: includes actionNonce
365
- ActionType,
366
- CreateActionParams,
367
- UserActionStatsExtended, // v0.1.5: includes actionNonce counter
368
-
369
- // Gasless
370
- GaslessConfig,
371
- SessionKey,
372
- FeeMethod,
373
- CreateSessionParams,
374
-
375
- // Identity
376
- Identity,
377
- IdentityConfig,
378
- VerificationLevel,
379
-
380
- // 5A
381
- FiveAScore,
382
- FiveAConfig,
383
- VouchRecord,
384
- PendingScoreUpdate, // v0.1.1: Oracle consensus
385
-
386
- // Content
387
- ContentRecord,
388
- RegistryConfig,
389
- UserEnergy,
390
- ContentState,
391
-
392
- // Security (v0.1.1)
393
- PendingAuthorityFields, // Two-step authority transfer
394
- SlashRequest, // Governance slashing
395
- SlashStatus,
396
- HookConfig, // Transfer hook config
397
- } from "@viwoapp/sdk";
398
- ```
399
-
400
- ## Utilities
401
-
402
- ```typescript
403
- import {
404
- formatVCoin,
405
- parseVCoin,
406
- getCurrentTimestamp,
407
- timestampToDate,
408
- dateToTimestamp,
409
- TransactionBuilder,
410
- } from "@viwoapp/sdk";
411
-
412
- // Format VCoin amount
413
- formatVCoin(new BN(1000000000)); // "1.000000000"
414
-
415
- // Parse VCoin string to BN
416
- parseVCoin("100.5"); // BN
417
-
418
- // Transaction builder
419
- const builder = new TransactionBuilder();
420
- builder.add(instruction1).add(instruction2);
421
- const tx = builder.build();
422
- ```
423
-
424
- ## License
425
-
426
- MIT
427
-
1
+ # @viwoapp/sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@viwoapp/sdk.svg)](https://www.npmjs.com/package/@viwoapp/sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ TypeScript SDK for VCoin Protocol Integration on Solana.
7
+
8
+ **Version:** 2.0.1 (Delegation Balance Validation & 100% Audit Completion)
9
+
10
+ ## What's New in v2.0.1
11
+
12
+ This release completes the security audit with **100% of all 68 findings resolved** and adds delegation balance validation.
13
+
14
+ ### H-NEW-03: Delegation Balance Validation
15
+
16
+ The `delegateVotes` instruction now validates the delegation amount against the delegator's actual veVCoin balance from the staking protocol:
17
+
18
+ ```typescript
19
+ // Build delegation transaction (validates balance on-chain)
20
+ const delegateTx = await client.governance.buildDelegateVotesTransaction({
21
+ delegate: delegatePubkey,
22
+ delegationType: 0, // Full delegation
23
+ categories: 0xFF, // All categories
24
+ amount: new BN(5000),
25
+ expiresAt: new BN(0),
26
+ revocable: true,
27
+ });
28
+
29
+ // Revoke delegation
30
+ const revokeTx = await client.governance.buildRevokeDelegationTransaction();
31
+
32
+ // Check existing delegation
33
+ const delegation = await client.governance.getDelegation();
34
+ ```
35
+
36
+ **On-chain changes:**
37
+ - `DelegateVotes` context now requires `config` and `userStake` accounts
38
+ - Handler validates `vevcoin_amount <= delegator's actual veVCoin balance`
39
+ - Cross-program PDA verification from staking protocol
40
+ - Empty staking accounts correctly return balance of 0
41
+
42
+ ### New SDK Features (v2.0.1)
43
+
44
+ - **`buildDelegateVotesTransaction()`**: Build delegation with on-chain balance validation
45
+ - **`buildRevokeDelegationTransaction()`**: Revoke existing delegation
46
+ - **`getDelegation()`**: Query delegation state for a user
47
+ - **`getDelegation()` PDA helper**: Derives delegation PDA from delegator pubkey
48
+ - **`getDelegateStats()` PDA helper**: Derives delegate stats PDA from delegate pubkey
49
+ - **`DelegateVotesParams`**: New type for delegation parameters
50
+
51
+ ### Audit Completion
52
+
53
+ All 68 security findings now resolved:
54
+
55
+ | Severity | Count | Status |
56
+ |----------|-------|--------|
57
+ | Critical | 12 | ✅ 100% Fixed |
58
+ | High | 8 | ✅ 100% Fixed |
59
+ | Medium | 40 | ✅ 100% Fixed |
60
+ | Low | 8 | ✅ 100% Fixed |
61
+
62
+ Key fixes in this release:
63
+ - **H-NEW-03**: Delegation amount validated against veVCoin balance
64
+ - **M-01**: Voting power precision loss fixed (scale before divide)
65
+ - **M-04**: Tier update spam prevention (TierUnchanged check)
66
+
67
+ ### Migration from v2.0.0
68
+
69
+ ```typescript
70
+ // Old: delegateVotes only needed 5 accounts
71
+ await program.methods.delegateVotes(0, 0, amount, expiresAt, true)
72
+ .accounts({
73
+ delegation, delegateStats, delegator, delegate, systemProgram,
74
+ }).rpc();
75
+
76
+ // New: delegateVotes requires config and userStake for balance validation
77
+ await program.methods.delegateVotes(0, 0, amount, expiresAt, true)
78
+ .accounts({
79
+ delegation, delegateStats, delegator, delegate,
80
+ config: govConfigPda, // NEW: governance config
81
+ userStake: userStakePda, // NEW: delegator's staking account
82
+ systemProgram,
83
+ }).rpc();
84
+ ```
85
+
86
+ ---
87
+
88
+ ## What's New in v2.0.0 (Major Release)
89
+
90
+ This is a **major release** with production-ready ZK private voting, comprehensive security audit remediation, and breaking changes across all protocol modules.
91
+
92
+ ### ZK Private Voting (Production Ready)
93
+
94
+ The governance module now supports fully encrypted, verifiable private voting:
95
+
96
+ - **Twisted ElGamal Encryption** on Ristretto255 with compressed sigma proofs
97
+ - **On-chain Vote Verification**: Validates vote proofs without revealing vote content
98
+ - **Homomorphic Tallying**: Encrypted votes accumulate without decryption
99
+ - **Threshold Decryption**: Committee-based trustless vote reveal with DLEQ proofs
100
+ - **Verifiable Results**: Anyone can verify tally correctness using cryptographic proofs
101
+
102
+ **New ZK Voting API:**
103
+
104
+ ```typescript
105
+ import { VoteChoice } from "@viwoapp/sdk";
106
+
107
+ // Create private vote with encryption
108
+ const voteTx = await client.governance.buildCastPrivateVoteTransaction({
109
+ proposalId: new BN(1),
110
+ voteChoice: VoteChoice.For,
111
+ votingPower: new BN(1000),
112
+ });
113
+
114
+ // Submit decryption share (committee members)
115
+ const decryptTx = await client.governance.buildSubmitDecryptionShareTransaction({
116
+ proposalId: new BN(1),
117
+ share: decryptionShareData,
118
+ dleqProof: dleqProofData,
119
+ });
120
+
121
+ // Aggregate revealed votes
122
+ const aggregateTx = await client.governance.buildAggregateRevealedVotesTransaction({
123
+ proposalId: new BN(1),
124
+ });
125
+ ```
126
+
127
+ **Off-chain ZK SDK:**
128
+ For vote encryption/decryption operations, use the companion Rust crate:
129
+ ```bash
130
+ cd packages/zk-voting-sdk
131
+ cargo add zk-voting-sdk
132
+ ```
133
+
134
+ ### Security Audit Remediation (14 Fixes)
135
+
136
+ All critical, high, and medium severity findings remediated across 11 programs:
137
+
138
+ | Finding | Severity | Protocol | Fix |
139
+ |---------|----------|----------|-----|
140
+ | H-02 | High | All protocols | Two-step authority transfer with 24h timelock |
141
+ | H-AUDIT-12 | High | Gasless | Per-user session limit (MAX=5) |
142
+ | H-AUDIT-13 | High | Identity | Require verification before DID changes |
143
+ | H-NEW-02 | High | SSCRE | Merkle proof size limited to 32 levels |
144
+ | C-03 | Critical | Governance | Exclude abstains from quorum calculation |
145
+ | C-05/C-06 | Critical | Multiple | Ceiling division for fee calculations |
146
+ | C-08 | Critical | 5A | Mutual vouch prevention |
147
+ | C-AUDIT-10 | Critical | Content | Monotonic engagement enforcement |
148
+ | C-AUDIT-17 | Critical | Identity | SAS attestation required |
149
+ | C-AUDIT-22 | Critical | Identity | USDC payment enforcement |
150
+ | M-02 | Medium | ViLink | Platform fee bounds (0.1%-10%) |
151
+ | M-04 | Medium | ViLink | Nonce-based deterministic PDAs |
152
+ | M-05 | Medium | Staking | TierUnchanged error for no-ops |
153
+ | M-18 | Medium | 5A | Vouch expiry (MAX_AGE=1yr) |
154
+
155
+ ### Breaking Changes
156
+
157
+ #### 1. Updated State Account Structures
158
+ All protocol state accounts now include security-related fields. Existing accounts must be migrated:
159
+
160
+ - **All Configs**: Added `pending_authority` and `transfer_initiated_at`
161
+ - **Gasless**: Added `max_sessions_per_user` to config
162
+ - **Identity**: Added `verification_required_for_did_change` flag
163
+ - **SSCRE**: Added `merkle_proof_max_size` constant
164
+ - **5A**: Added `max_vouch_age` to config
165
+
166
+ #### 2. New Governance Instructions
167
+ ```typescript
168
+ // Old: Only public voting
169
+ await client.governance.buildVoteTransaction(proposalId, true);
170
+
171
+ // New: Choose public or private voting
172
+ await client.governance.buildVoteTransaction(proposalId, VoteChoice.For); // Public
173
+ await client.governance.buildCastPrivateVoteTransaction({ ... }); // Private
174
+ ```
175
+
176
+ #### 3. Updated Types & Constants
177
+
178
+ ```typescript
179
+ // New VoteChoice enum replaces boolean
180
+ export enum VoteChoice {
181
+ Against = 0,
182
+ For = 1,
183
+ Abstain = 2,
184
+ }
185
+
186
+ // New security constants
187
+ import { SECURITY_CONSTANTS } from "@viwoapp/sdk";
188
+
189
+ SECURITY_CONSTANTS.authorityTransferTimelock; // 86400 (24h)
190
+ SECURITY_CONSTANTS.slashApprovalTimelock; // 172800 (48h)
191
+ SECURITY_CONSTANTS.merkleProofMaxSize; // 32
192
+ SECURITY_CONSTANTS.maxSessionsPerUser; // 5
193
+ SECURITY_CONSTANTS.maxVouchAge; // 31536000 (1yr)
194
+ ```
195
+
196
+ #### 4. Updated Instruction Parameters
197
+
198
+ Many instructions now require additional parameters for security validation:
199
+
200
+ ```typescript
201
+ // Gasless: Session creation now validates session limits
202
+ await client.gasless.buildCreateSessionTransaction({
203
+ sessionPubkey,
204
+ scope,
205
+ durationSeconds,
206
+ maxActions,
207
+ feeMethod,
208
+ // SDK now enforces max 5 sessions per user
209
+ });
210
+
211
+ // ViLink: Platform fee must be within bounds
212
+ await client.vilink.buildUpdateConfigTransaction({
213
+ platformFeeBps, // Must be between 10 (0.1%) and 1000 (10%)
214
+ });
215
+ ```
216
+
217
+ ### Migration Guide
218
+
219
+ **Step 1: Update Program Deployments**
220
+ All 11 programs have been redeployed with audit fixes. Update your program IDs if using custom deployments.
221
+
222
+ **Step 2: Migrate State Accounts**
223
+ Run migration scripts to add new fields to existing state accounts (contact team for migration tools).
224
+
225
+ **Step 3: Update SDK**
226
+ ```bash
227
+ npm install @viwoapp/sdk@2.0.1
228
+ ```
229
+
230
+ **Step 4: Update Code**
231
+ - Replace boolean votes with `VoteChoice` enum
232
+ - Handle new error codes (`TierUnchanged`, `MutualVouchPrevented`, etc.)
233
+ - Update type imports for new state account fields
234
+
235
+ ### New Features
236
+
237
+ - **ZK Private Voting**: Full production implementation with threshold decryption
238
+ - **Enhanced Security**: 14 audit findings remediated
239
+ - **Improved Error Handling**: New error codes for edge cases
240
+ - **Better Type Safety**: Expanded type definitions with security fields
241
+
242
+ ## What's New in v0.1.8 (Bug Fixes)
243
+
244
+ This release addresses 4 SDK issues identified during code review:
245
+
246
+ | Finding | Severity | Fix |
247
+ |---------|----------|-----|
248
+ | #2 | Medium | VCoin balance now correctly filters by mint address |
249
+ | #5 | Medium | ViLink batch now uses deterministic nonce PDA |
250
+ | #8 | High | Gasless config byte offsets corrected |
251
+ | #9 | Low | Error handling improved with console warnings |
252
+
253
+ ### Changes
254
+
255
+ - **VCoin Mint Filter (Finding #2):** `getVCoinBalance()` now filters by VCoin mint address instead of summing all Token-2022 accounts. Set `programIds.vcoinMint` in your config.
256
+ - **Gasless Config Fix (Finding #8):** All byte offsets in `gasless.getConfig()` corrected to match on-chain struct after H-02 security fix added `pending_authority`.
257
+ - **ViLink Config Fix:** ViLink config byte offsets also corrected for H-02 compatibility.
258
+ - **Error Logging (Finding #9):** Silent `catch { return null }` blocks replaced with `console.warn('[ViWoSDK] ...')` for easier debugging.
259
+ - **Batch Nonce (Finding #5):** Added `batchNonce` to `UserActionStatsExtended` for deterministic batch PDA derivation.
260
+ - **New Fields:** `GaslessConfig` now includes `feeVault`, `sscreProgram`, `sscreDeductionBps`, `maxSubsidizedPerUser`, `totalSolSpent`, `currentDay`, `daySpent`.
261
+
262
+ ### Configuration Update Required
263
+
264
+ ```typescript
265
+ const client = new ViWoClient({
266
+ connection: { endpoint: "https://api.devnet.solana.com" },
267
+ wallet: walletAdapter,
268
+ programIds: {
269
+ // IMPORTANT: Set your VCoin mint address for accurate balance queries
270
+ vcoinMint: new PublicKey("YOUR_VCOIN_MINT_ADDRESS"),
271
+ },
272
+ });
273
+ ```
274
+
275
+ ## What's New in v0.1.7
276
+
277
+ - **ViLink Nonce-Based PDA:** Action PDAs now use deterministic `nonce` instead of `timestamp`
278
+ - **New Field:** `actionNonce` added to `ViLinkAction` interface
279
+ - **New Type:** `UserActionStatsExtended` with `actionNonce` counter
280
+ - **New Method:** `getViLinkActionByNonce()` PDA helper for new derivation
281
+ - **New Method:** `getNextNonce()` utility to get next nonce for action creation
282
+ - **Updated Methods:** `getAction()`, `isActionValid()`, `buildExecuteTipAction()` now use nonce
283
+ - **Deprecated:** `getActionByTimestamp()` - use `getAction()` with nonce instead
284
+
285
+ ### Breaking Change (v0.1.7)
286
+
287
+ ViLink action PDA derivation changed from timestamp to nonce:
288
+ ```typescript
289
+ // Old (deprecated)
290
+ const action = await client.vilink.getAction(creator, timestamp);
291
+
292
+ // New (v0.1.5+)
293
+ const nonce = await client.vilink.getNextNonce(creator);
294
+ const action = await client.vilink.getAction(creator, nonce);
295
+ ```
296
+
297
+ ## What's New in v0.1.4
298
+
299
+ - **New Constants:** `MERKLE_PROOF_MAX_SIZE`, `MAX_EPOCH_BITMAP`, `LEGACY_SLASH_DEPRECATED`
300
+ - **New Enum:** `VoteChoice` for typed governance voting (Against, For, Abstain)
301
+ - **Updated Types:** `SlashRequest` (added `requestId`), `UserClaim` (bitmap storage)
302
+ - **Updated Docs:** `buildVoteTransaction` - voting power now verified on-chain
303
+ - **SECURITY_CONSTANTS:** Added `merkleProofMaxSize`, `maxEpochBitmap`, `votingPowerVerifiedOnChain`
304
+
305
+ ## What's New in v0.1.1
306
+
307
+ - Added security types for Phase 1-4 fixes
308
+ - New types: `SlashRequest`, `DecryptionShare`, `PendingScoreUpdate`
309
+ - All config types now support two-step authority transfer
310
+ - Added `SECURITY_CONSTANTS` for timelocks and limits
311
+ - Added `VALID_URI_PREFIXES` for proposal URI validation
312
+ - New PDA seeds: `slashRequest`, `decryptionShare`, `pendingScore`
313
+
314
+ ## Installation
315
+
316
+ ```bash
317
+ npm install @viwoapp/sdk
318
+ # or
319
+ yarn add @viwoapp/sdk
320
+ ```
321
+
322
+ ## Quick Start
323
+
324
+ ```typescript
325
+ import { ViWoClient, parseVCoin, formatVCoin, LOCK_DURATIONS } from "@viwoapp/sdk";
326
+
327
+ // Initialize client
328
+ const client = new ViWoClient({
329
+ connection: { endpoint: "https://api.devnet.solana.com" },
330
+ wallet: walletAdapter, // Your wallet adapter
331
+ });
332
+
333
+ // Get VCoin balance
334
+ const balance = await client.getVCoinBalance();
335
+ console.log("Balance:", formatVCoin(balance));
336
+
337
+ // Stake VCoin
338
+ const stakeTx = await client.staking.buildStakeTransaction({
339
+ amount: parseVCoin("1000"),
340
+ lockDuration: LOCK_DURATIONS.threeMonths,
341
+ });
342
+ await client.sendTransaction(stakeTx);
343
+ ```
344
+
345
+ ## Modules
346
+
347
+ ### Core (`@viwoapp/sdk`)
348
+
349
+ Connection management, utilities, and PDA derivation.
350
+
351
+ ```typescript
352
+ import { ViWoClient, PDAs, formatVCoin, parseVCoin } from "@viwoapp/sdk";
353
+
354
+ const client = new ViWoClient({ connection, wallet });
355
+
356
+ // Check connection health
357
+ const health = await client.healthCheck();
358
+
359
+ // Get PDAs
360
+ const stakingPool = client.pdas.getStakingPool();
361
+ const userStake = client.pdas.getUserStake(walletPubkey);
362
+ ```
363
+
364
+ ### Staking (`client.staking`)
365
+
366
+ VCoin staking operations for veVCoin.
367
+
368
+ ```typescript
369
+ // Get staking pool info
370
+ const pool = await client.staking.getPool();
371
+
372
+ // Get user stake
373
+ const stake = await client.staking.getUserStake();
374
+ console.log("Staked:", formatVCoin(stake.stakedAmount));
375
+ console.log("Tier:", client.staking.getTierName(stake.tier));
376
+
377
+ // Calculate veVCoin for stake
378
+ const vevcoin = client.staking.calculateVeVCoin(amount, lockDuration);
379
+
380
+ // Build transactions
381
+ const stakeTx = await client.staking.buildStakeTransaction({ amount, lockDuration });
382
+ const unstakeTx = await client.staking.buildUnstakeTransaction();
383
+ ```
384
+
385
+ ### Governance (`client.governance`)
386
+
387
+ Proposal creation and voting.
388
+
389
+ ```typescript
390
+ // Get active proposals
391
+ const proposals = await client.governance.getActiveProposals();
392
+
393
+ // Get proposal details
394
+ const proposal = await client.governance.getProposal(proposalId);
395
+ const progress = await client.governance.getProposalProgress(proposalId);
396
+
397
+ // Check voting power
398
+ const votingPower = await client.governance.getVotingPower();
399
+
400
+ // Build transactions
401
+ const voteTx = await client.governance.buildVoteTransaction(proposalId, true);
402
+
403
+ // Delegation (v2.0.1)
404
+ const delegateTx = await client.governance.buildDelegateVotesTransaction({
405
+ delegate: delegatePubkey, delegationType: 0, categories: 0xFF,
406
+ amount: new BN(1000), expiresAt: new BN(0), revocable: true,
407
+ });
408
+ const revokeTx = await client.governance.buildRevokeDelegationTransaction();
409
+ ```
410
+
411
+ ### Rewards (`client.rewards`)
412
+
413
+ SSCRE rewards claiming.
414
+
415
+ ```typescript
416
+ // Get pool stats
417
+ const stats = await client.rewards.getStats();
418
+
419
+ // Get user claim history
420
+ const claims = await client.rewards.getUserClaim();
421
+
422
+ // Get unclaimed epochs
423
+ const unclaimed = await client.rewards.getUnclaimedEpochs();
424
+
425
+ // Build claim transaction
426
+ const claimTx = await client.rewards.buildClaimTransaction({
427
+ epoch,
428
+ amount,
429
+ merkleProof,
430
+ });
431
+ ```
432
+
433
+ ### ViLink (`client.vilink`)
434
+
435
+ Cross-dApp action deep links.
436
+
437
+ ```typescript
438
+ // Create tip action
439
+ const tipTx = await client.vilink.buildCreateTipAction({
440
+ target: recipientPubkey,
441
+ amount: parseVCoin("10"),
442
+ expirySeconds: 86400, // 1 day
443
+ });
444
+
445
+ // Generate shareable URI
446
+ const uri = client.vilink.generateUri(actionId);
447
+ // => viwo://action/abc123...
448
+
449
+ // Generate QR code data
450
+ const qrData = client.vilink.generateQRData(actionId);
451
+
452
+ // Get next nonce for action creation (v0.1.5+)
453
+ const nonce = await client.vilink.getNextNonce();
454
+
455
+ // Get action by creator + nonce (v0.1.5+)
456
+ const action = await client.vilink.getAction(creator, nonce);
457
+
458
+ // Check action validity (uses nonce, not timestamp)
459
+ const { valid, reason } = await client.vilink.isActionValid(creator, nonce);
460
+ ```
461
+
462
+ ### Gasless (`client.gasless`)
463
+
464
+ Session keys and gasless transactions.
465
+
466
+ ```typescript
467
+ import { ACTION_SCOPES, FeeMethod } from "@viwoapp/sdk";
468
+
469
+ // Create session key
470
+ const sessionKeypair = Keypair.generate();
471
+ const scope = ACTION_SCOPES.tip | ACTION_SCOPES.vouch;
472
+
473
+ const sessionTx = await client.gasless.buildCreateSessionTransaction({
474
+ sessionPubkey: sessionKeypair.publicKey,
475
+ scope,
476
+ durationSeconds: 24 * 3600,
477
+ maxActions: 100,
478
+ feeMethod: FeeMethod.VCoinDeduction,
479
+ });
480
+
481
+ // Check session validity
482
+ const { valid } = await client.gasless.isSessionValid(user, sessionPubkey);
483
+
484
+ // Revoke session
485
+ const revokeTx = await client.gasless.buildRevokeSessionTransaction(sessionPubkey);
486
+ ```
487
+
488
+ ### Identity (`client.identity`)
489
+
490
+ User identity management.
491
+
492
+ ```typescript
493
+ // Get identity
494
+ const identity = await client.identity.getIdentity();
495
+ console.log("Level:", client.identity.getVerificationLevelName(identity.verificationLevel));
496
+
497
+ // Get verification requirements
498
+ const reqs = client.identity.getVerificationRequirements(level);
499
+ ```
500
+
501
+ ### 5A Protocol (`client.fivea`)
502
+
503
+ Reputation scoring.
504
+
505
+ ```typescript
506
+ // Get 5A score
507
+ const score = await client.fivea.getScore();
508
+ console.log("Composite:", client.fivea.formatScore(score.composite));
509
+ console.log("Tier:", client.fivea.getScoreTier(score.composite));
510
+
511
+ // Get score breakdown
512
+ const breakdown = client.fivea.getScoreBreakdown(score);
513
+
514
+ // Get reward multiplier
515
+ const multiplier = client.fivea.getRewardMultiplier(score.composite);
516
+
517
+ // Check vouch capability
518
+ const { canVouch, reason } = await client.fivea.canVouchFor(target);
519
+ ```
520
+
521
+ ### Content (`client.content`)
522
+
523
+ Content registry operations.
524
+
525
+ ```typescript
526
+ // Get user energy
527
+ const energy = await client.content.getEnergy();
528
+ const currentEnergy = client.content.calculateRegenEnergy(energy);
529
+
530
+ // Check create capability
531
+ const { canCreate } = await client.content.canCreateContent();
532
+
533
+ // Build transactions
534
+ const createTx = await client.content.buildCreateContentTransaction(contentHash);
535
+ const editTx = await client.content.buildEditContentTransaction(contentId, newHash);
536
+ ```
537
+
538
+ ## Constants
539
+
540
+ ```typescript
541
+ import {
542
+ PROGRAM_IDS,
543
+ SEEDS,
544
+ VCOIN_DECIMALS,
545
+ STAKING_TIERS,
546
+ LOCK_DURATIONS,
547
+ SSCRE_CONSTANTS,
548
+ VILINK_CONSTANTS,
549
+ GASLESS_CONSTANTS,
550
+ ACTION_SCOPES,
551
+ FIVE_A_CONSTANTS,
552
+ GOVERNANCE_CONSTANTS,
553
+ CONTENT_CONSTANTS,
554
+ // Security constants
555
+ SECURITY_CONSTANTS,
556
+ VALID_URI_PREFIXES,
557
+ MERKLE_CONSTANTS,
558
+ // v0.1.4 additions
559
+ MERKLE_PROOF_MAX_SIZE, // 32 - prevents DoS
560
+ MAX_EPOCH_BITMAP, // 1023 - max epoch with bitmap
561
+ LEGACY_SLASH_DEPRECATED, // true - use propose_slash flow
562
+ } from "@viwoapp/sdk";
563
+
564
+ // Security constants
565
+ SECURITY_CONSTANTS.authorityTransferTimelock; // 24 hours
566
+ SECURITY_CONSTANTS.slashApprovalTimelock; // 48 hours
567
+ SECURITY_CONSTANTS.maxFeeSlippageBps; // 500 (5%)
568
+ SECURITY_CONSTANTS.oracleConsensusRequired; // 3-of-N
569
+ SECURITY_CONSTANTS.circuitBreakerCooldown; // 6 hours
570
+ SECURITY_CONSTANTS.merkleProofMaxSize; // 32 (v0.1.4)
571
+ SECURITY_CONSTANTS.maxEpochBitmap; // 1023 (v0.1.4)
572
+ SECURITY_CONSTANTS.votingPowerVerifiedOnChain; // true (v0.1.4)
573
+ ```
574
+
575
+ ## Types
576
+
577
+ ```typescript
578
+ import type {
579
+ // Staking
580
+ StakingPool,
581
+ UserStake,
582
+ StakingTier,
583
+ StakeParams,
584
+
585
+ // Governance
586
+ Proposal,
587
+ VoteRecord,
588
+ ProposalStatus,
589
+ VoteChoice, // v0.1.4: Against, For, Abstain
590
+ GovernanceConfig,
591
+ Delegation,
592
+ DelegateVotesParams, // v2.0.1: Delegation parameters
593
+ PrivateVotingConfig,
594
+ DecryptionShare, // v0.1.1: ZK voting
595
+
596
+ // Rewards
597
+ RewardsPoolConfig,
598
+ EpochDistribution,
599
+ UserClaim,
600
+ ClaimRewardsParams,
601
+
602
+ // ViLink
603
+ ViLinkConfig,
604
+ ViLinkAction, // v0.1.5: includes actionNonce
605
+ ActionType,
606
+ CreateActionParams,
607
+ UserActionStatsExtended, // v0.1.5: includes actionNonce counter
608
+
609
+ // Gasless
610
+ GaslessConfig,
611
+ SessionKey,
612
+ FeeMethod,
613
+ CreateSessionParams,
614
+
615
+ // Identity
616
+ Identity,
617
+ IdentityConfig,
618
+ VerificationLevel,
619
+
620
+ // 5A
621
+ FiveAScore,
622
+ FiveAConfig,
623
+ VouchRecord,
624
+ PendingScoreUpdate, // v0.1.1: Oracle consensus
625
+
626
+ // Content
627
+ ContentRecord,
628
+ RegistryConfig,
629
+ UserEnergy,
630
+ ContentState,
631
+
632
+ // Security (v0.1.1)
633
+ PendingAuthorityFields, // Two-step authority transfer
634
+ SlashRequest, // Governance slashing
635
+ SlashStatus,
636
+ HookConfig, // Transfer hook config
637
+ } from "@viwoapp/sdk";
638
+ ```
639
+
640
+ ## Utilities
641
+
642
+ ```typescript
643
+ import {
644
+ formatVCoin,
645
+ parseVCoin,
646
+ getCurrentTimestamp,
647
+ timestampToDate,
648
+ dateToTimestamp,
649
+ TransactionBuilder,
650
+ } from "@viwoapp/sdk";
651
+
652
+ // Format VCoin amount
653
+ formatVCoin(new BN(1000000000)); // "1.000000000"
654
+
655
+ // Parse VCoin string to BN
656
+ parseVCoin("100.5"); // BN
657
+
658
+ // Transaction builder
659
+ const builder = new TransactionBuilder();
660
+ builder.add(instruction1).add(instruction2);
661
+ const tx = builder.build();
662
+ ```
663
+
664
+ ## License
665
+
666
+ MIT
667
+