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