@viwoapp/sdk 0.1.7 → 0.1.8

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
@@ -5,7 +5,40 @@
5
5
 
6
6
  TypeScript SDK for VCoin Protocol Integration on Solana.
7
7
 
8
- **Version:** 0.1.7 (Bug Fixes)
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
+ ```
9
42
 
10
43
  ## What's New in v0.1.7
11
44
 
@@ -17,7 +50,7 @@ TypeScript SDK for VCoin Protocol Integration on Solana.
17
50
  - **Updated Methods:** `getAction()`, `isActionValid()`, `buildExecuteTipAction()` now use nonce
18
51
  - **Deprecated:** `getActionByTimestamp()` - use `getAction()` with nonce instead
19
52
 
20
- ### Breaking Change
53
+ ### Breaking Change (v0.1.7)
21
54
 
22
55
  ViLink action PDA derivation changed from timestamp to nonce:
23
56
  ```typescript
package/dist/index.d.mts CHANGED
@@ -14,6 +14,16 @@ declare const PROGRAM_IDS: {
14
14
  sscreProtocol: PublicKey;
15
15
  vilinkProtocol: PublicKey;
16
16
  gaslessProtocol: PublicKey;
17
+ /**
18
+ * VCoin Token Mint Address (Token-2022)
19
+ *
20
+ * NOTE: This is a placeholder. Override via ViWoClient config.programIds.vcoinMint
21
+ * after deploying your VCoin mint on devnet/mainnet.
22
+ *
23
+ * Finding #2 Fix: SDK now filters token accounts by mint address to prevent
24
+ * summing balances from other Token-2022 tokens.
25
+ */
26
+ vcoinMint: PublicKey;
17
27
  };
18
28
  declare const SEEDS: {
19
29
  vcoinConfig: string;
@@ -433,8 +443,13 @@ declare enum ActionType {
433
443
  Delegate = 6,
434
444
  Vote = 7
435
445
  }
446
+ /**
447
+ * ViLinkConfig - Updated with H-02 pending authority field
448
+ */
436
449
  interface ViLinkConfig extends PendingAuthorityFields {
437
450
  authority: PublicKey;
451
+ /** H-02: Pending authority for two-step transfer */
452
+ pendingAuthority?: PublicKey;
438
453
  vcoinMint: PublicKey;
439
454
  treasury: PublicKey;
440
455
  enabledActions: number;
@@ -442,6 +457,7 @@ interface ViLinkConfig extends PendingAuthorityFields {
442
457
  totalActionsExecuted: BN;
443
458
  totalTipVolume: BN;
444
459
  paused: boolean;
460
+ /** M-02: Platform fee in basis points, bounded 10-1000 (0.1%-10%) */
445
461
  platformFeeBps: number;
446
462
  }
447
463
  interface ViLinkAction {
@@ -472,7 +488,7 @@ interface CreateActionParams {
472
488
  */
473
489
  nonce?: BN;
474
490
  }
475
- /** M-04: User action statistics with nonce tracking */
491
+ /** M-04 + Finding #5: User action statistics with nonce tracking */
476
492
  interface UserActionStatsExtended {
477
493
  user: PublicKey;
478
494
  actionsCreated: BN;
@@ -487,22 +503,47 @@ interface UserActionStatsExtended {
487
503
  lastActionAt: BN;
488
504
  /** M-04: Next nonce to use when creating an action */
489
505
  actionNonce: BN;
506
+ /** Finding #5: Next nonce to use when creating a batch (prevents timestamp collisions) */
507
+ batchNonce: BN;
490
508
  }
491
509
  declare enum FeeMethod {
492
510
  PlatformSubsidized = 0,
493
511
  VCoinDeduction = 1,
494
512
  SSCREDeduction = 2
495
513
  }
514
+ /**
515
+ * GaslessConfig - Finding #8 Fix
516
+ *
517
+ * Updated to include all fields from on-chain GaslessConfig struct.
518
+ * Previous version was missing fields added after H-02 security fix.
519
+ */
496
520
  interface GaslessConfig extends PendingAuthorityFields {
497
521
  authority: PublicKey;
522
+ /** H-02: Pending authority for two-step transfer */
523
+ pendingAuthority?: PublicKey;
498
524
  feePayer: PublicKey;
499
525
  vcoinMint: PublicKey;
526
+ /** Fee vault for VCoin fee collection */
527
+ feeVault?: PublicKey;
528
+ /** SSCRE program for reward deduction integration */
529
+ sscreProgram?: PublicKey;
500
530
  dailySubsidyBudget: BN;
501
531
  solFeePerTx: BN;
502
532
  vcoinFeeMultiplier: BN;
533
+ /** SSCRE deduction rate in basis points */
534
+ sscreDeductionBps?: number;
535
+ /** Maximum subsidized transactions per user per day */
536
+ maxSubsidizedPerUser?: number;
503
537
  totalSubsidizedTx: BN;
538
+ /** Total SOL spent on subsidies */
539
+ totalSolSpent?: BN;
504
540
  totalVcoinCollected: BN;
505
541
  paused: boolean;
542
+ /** Current day number for daily budget reset */
543
+ currentDay?: number;
544
+ /** Today's spent budget */
545
+ daySpent?: BN;
546
+ /** L-03: Maximum fee slippage in basis points (default 500 = 5%) */
506
547
  maxSlippageBps?: number;
507
548
  }
508
549
  interface SessionKey {
@@ -856,6 +897,9 @@ declare class ViLinkClient {
856
897
  constructor(client: ViWoClient);
857
898
  /**
858
899
  * Get ViLink configuration
900
+ *
901
+ * Finding #8 (related): Corrected byte offsets to match on-chain ViLinkConfig struct.
902
+ * Added pending_authority field that was missing after H-02 security fix.
859
903
  */
860
904
  getConfig(): Promise<ViLinkConfig | null>;
861
905
  /**
@@ -977,6 +1021,10 @@ declare class GaslessClient {
977
1021
  constructor(client: ViWoClient);
978
1022
  /**
979
1023
  * Get gasless configuration
1024
+ *
1025
+ * Finding #8 Fix: Corrected byte offsets to match on-chain GaslessConfig struct.
1026
+ * Added missing fields: pendingAuthority, feeVault, sscreProgram, sscreDeductionBps,
1027
+ * maxSubsidizedPerUser, totalSolSpent, currentDay, daySpent, maxSlippageBps.
980
1028
  */
981
1029
  getConfig(): Promise<GaslessConfig | null>;
982
1030
  /**
@@ -1304,6 +1352,9 @@ declare class ViWoClient {
1304
1352
  sendTransaction(tx: Transaction): Promise<string>;
1305
1353
  /**
1306
1354
  * Get VCoin balance
1355
+ *
1356
+ * Finding #2 Fix: Now filters by VCoin mint address instead of summing all Token-2022 accounts.
1357
+ * Make sure to set programIds.vcoinMint in your ViWoClient config.
1307
1358
  */
1308
1359
  getVCoinBalance(user?: PublicKey): Promise<BN>;
1309
1360
  /**
package/dist/index.d.ts CHANGED
@@ -14,6 +14,16 @@ declare const PROGRAM_IDS: {
14
14
  sscreProtocol: PublicKey;
15
15
  vilinkProtocol: PublicKey;
16
16
  gaslessProtocol: PublicKey;
17
+ /**
18
+ * VCoin Token Mint Address (Token-2022)
19
+ *
20
+ * NOTE: This is a placeholder. Override via ViWoClient config.programIds.vcoinMint
21
+ * after deploying your VCoin mint on devnet/mainnet.
22
+ *
23
+ * Finding #2 Fix: SDK now filters token accounts by mint address to prevent
24
+ * summing balances from other Token-2022 tokens.
25
+ */
26
+ vcoinMint: PublicKey;
17
27
  };
18
28
  declare const SEEDS: {
19
29
  vcoinConfig: string;
@@ -433,8 +443,13 @@ declare enum ActionType {
433
443
  Delegate = 6,
434
444
  Vote = 7
435
445
  }
446
+ /**
447
+ * ViLinkConfig - Updated with H-02 pending authority field
448
+ */
436
449
  interface ViLinkConfig extends PendingAuthorityFields {
437
450
  authority: PublicKey;
451
+ /** H-02: Pending authority for two-step transfer */
452
+ pendingAuthority?: PublicKey;
438
453
  vcoinMint: PublicKey;
439
454
  treasury: PublicKey;
440
455
  enabledActions: number;
@@ -442,6 +457,7 @@ interface ViLinkConfig extends PendingAuthorityFields {
442
457
  totalActionsExecuted: BN;
443
458
  totalTipVolume: BN;
444
459
  paused: boolean;
460
+ /** M-02: Platform fee in basis points, bounded 10-1000 (0.1%-10%) */
445
461
  platformFeeBps: number;
446
462
  }
447
463
  interface ViLinkAction {
@@ -472,7 +488,7 @@ interface CreateActionParams {
472
488
  */
473
489
  nonce?: BN;
474
490
  }
475
- /** M-04: User action statistics with nonce tracking */
491
+ /** M-04 + Finding #5: User action statistics with nonce tracking */
476
492
  interface UserActionStatsExtended {
477
493
  user: PublicKey;
478
494
  actionsCreated: BN;
@@ -487,22 +503,47 @@ interface UserActionStatsExtended {
487
503
  lastActionAt: BN;
488
504
  /** M-04: Next nonce to use when creating an action */
489
505
  actionNonce: BN;
506
+ /** Finding #5: Next nonce to use when creating a batch (prevents timestamp collisions) */
507
+ batchNonce: BN;
490
508
  }
491
509
  declare enum FeeMethod {
492
510
  PlatformSubsidized = 0,
493
511
  VCoinDeduction = 1,
494
512
  SSCREDeduction = 2
495
513
  }
514
+ /**
515
+ * GaslessConfig - Finding #8 Fix
516
+ *
517
+ * Updated to include all fields from on-chain GaslessConfig struct.
518
+ * Previous version was missing fields added after H-02 security fix.
519
+ */
496
520
  interface GaslessConfig extends PendingAuthorityFields {
497
521
  authority: PublicKey;
522
+ /** H-02: Pending authority for two-step transfer */
523
+ pendingAuthority?: PublicKey;
498
524
  feePayer: PublicKey;
499
525
  vcoinMint: PublicKey;
526
+ /** Fee vault for VCoin fee collection */
527
+ feeVault?: PublicKey;
528
+ /** SSCRE program for reward deduction integration */
529
+ sscreProgram?: PublicKey;
500
530
  dailySubsidyBudget: BN;
501
531
  solFeePerTx: BN;
502
532
  vcoinFeeMultiplier: BN;
533
+ /** SSCRE deduction rate in basis points */
534
+ sscreDeductionBps?: number;
535
+ /** Maximum subsidized transactions per user per day */
536
+ maxSubsidizedPerUser?: number;
503
537
  totalSubsidizedTx: BN;
538
+ /** Total SOL spent on subsidies */
539
+ totalSolSpent?: BN;
504
540
  totalVcoinCollected: BN;
505
541
  paused: boolean;
542
+ /** Current day number for daily budget reset */
543
+ currentDay?: number;
544
+ /** Today's spent budget */
545
+ daySpent?: BN;
546
+ /** L-03: Maximum fee slippage in basis points (default 500 = 5%) */
506
547
  maxSlippageBps?: number;
507
548
  }
508
549
  interface SessionKey {
@@ -856,6 +897,9 @@ declare class ViLinkClient {
856
897
  constructor(client: ViWoClient);
857
898
  /**
858
899
  * Get ViLink configuration
900
+ *
901
+ * Finding #8 (related): Corrected byte offsets to match on-chain ViLinkConfig struct.
902
+ * Added pending_authority field that was missing after H-02 security fix.
859
903
  */
860
904
  getConfig(): Promise<ViLinkConfig | null>;
861
905
  /**
@@ -977,6 +1021,10 @@ declare class GaslessClient {
977
1021
  constructor(client: ViWoClient);
978
1022
  /**
979
1023
  * Get gasless configuration
1024
+ *
1025
+ * Finding #8 Fix: Corrected byte offsets to match on-chain GaslessConfig struct.
1026
+ * Added missing fields: pendingAuthority, feeVault, sscreProgram, sscreDeductionBps,
1027
+ * maxSubsidizedPerUser, totalSolSpent, currentDay, daySpent, maxSlippageBps.
980
1028
  */
981
1029
  getConfig(): Promise<GaslessConfig | null>;
982
1030
  /**
@@ -1304,6 +1352,9 @@ declare class ViWoClient {
1304
1352
  sendTransaction(tx: Transaction): Promise<string>;
1305
1353
  /**
1306
1354
  * Get VCoin balance
1355
+ *
1356
+ * Finding #2 Fix: Now filters by VCoin mint address instead of summing all Token-2022 accounts.
1357
+ * Make sure to set programIds.vcoinMint in your ViWoClient config.
1307
1358
  */
1308
1359
  getVCoinBalance(user?: PublicKey): Promise<BN>;
1309
1360
  /**
package/dist/index.js CHANGED
@@ -88,7 +88,18 @@ var PROGRAM_IDS = {
88
88
  governanceProtocol: new import_web3.PublicKey("3R256kBN9iXozjypQFRAmegBhd6HJqXWqdNG7Th78HYe"),
89
89
  sscreProtocol: new import_web3.PublicKey("6AJNcQSfoiE2UAeUDyJUBumS9SBwhAdSznoAeYpXrxXZ"),
90
90
  vilinkProtocol: new import_web3.PublicKey("CFGXTS2MueQwTYTMMTBQbRWzJtSTC2p4ZRuKPpLDmrv7"),
91
- gaslessProtocol: new import_web3.PublicKey("FcXJAjzJs8eVY2WTRFXynQBpC7WZUqKZppyp9xS6PaB3")
91
+ gaslessProtocol: new import_web3.PublicKey("FcXJAjzJs8eVY2WTRFXynQBpC7WZUqKZppyp9xS6PaB3"),
92
+ /**
93
+ * VCoin Token Mint Address (Token-2022)
94
+ *
95
+ * NOTE: This is a placeholder. Override via ViWoClient config.programIds.vcoinMint
96
+ * after deploying your VCoin mint on devnet/mainnet.
97
+ *
98
+ * Finding #2 Fix: SDK now filters token accounts by mint address to prevent
99
+ * summing balances from other Token-2022 tokens.
100
+ */
101
+ vcoinMint: new import_web3.PublicKey("11111111111111111111111111111111")
102
+ // Placeholder - override in config
92
103
  };
93
104
  var SEEDS = {
94
105
  // VCoin
@@ -1280,6 +1291,9 @@ var ViLinkClient = class {
1280
1291
  }
1281
1292
  /**
1282
1293
  * Get ViLink configuration
1294
+ *
1295
+ * Finding #8 (related): Corrected byte offsets to match on-chain ViLinkConfig struct.
1296
+ * Added pending_authority field that was missing after H-02 security fix.
1283
1297
  */
1284
1298
  async getConfig() {
1285
1299
  try {
@@ -1291,16 +1305,18 @@ var ViLinkClient = class {
1291
1305
  const data = accountInfo.data;
1292
1306
  return {
1293
1307
  authority: new import_web36.PublicKey(data.slice(8, 40)),
1294
- vcoinMint: new import_web36.PublicKey(data.slice(40, 72)),
1295
- treasury: new import_web36.PublicKey(data.slice(72, 104)),
1296
- enabledActions: data[200],
1297
- totalActionsCreated: new import_anchor5.BN(data.slice(201, 209), "le"),
1298
- totalActionsExecuted: new import_anchor5.BN(data.slice(209, 217), "le"),
1299
- totalTipVolume: new import_anchor5.BN(data.slice(217, 225), "le"),
1300
- paused: data[225] !== 0,
1301
- platformFeeBps: data.readUInt16LE(226)
1308
+ pendingAuthority: new import_web36.PublicKey(data.slice(40, 72)),
1309
+ vcoinMint: new import_web36.PublicKey(data.slice(72, 104)),
1310
+ treasury: new import_web36.PublicKey(data.slice(104, 136)),
1311
+ enabledActions: data[296],
1312
+ totalActionsCreated: new import_anchor5.BN(data.slice(297, 305), "le"),
1313
+ totalActionsExecuted: new import_anchor5.BN(data.slice(305, 313), "le"),
1314
+ totalTipVolume: new import_anchor5.BN(data.slice(313, 321), "le"),
1315
+ paused: data[321] !== 0,
1316
+ platformFeeBps: data.readUInt16LE(322)
1302
1317
  };
1303
- } catch {
1318
+ } catch (error) {
1319
+ console.warn("[ViWoSDK] vilink.getConfig failed:", error instanceof Error ? error.message : error);
1304
1320
  return null;
1305
1321
  }
1306
1322
  }
@@ -1330,7 +1346,8 @@ var ViLinkClient = class {
1330
1346
  actionNonce: nonce
1331
1347
  // M-04: Store nonce for reference
1332
1348
  };
1333
- } catch {
1349
+ } catch (error) {
1350
+ console.warn("[ViWoSDK] vilink.getAction failed:", error instanceof Error ? error.message : error);
1334
1351
  return null;
1335
1352
  }
1336
1353
  }
@@ -1364,7 +1381,8 @@ var ViLinkClient = class {
1364
1381
  vcoinSent: new import_anchor5.BN(data.slice(72, 80), "le"),
1365
1382
  vcoinReceived: new import_anchor5.BN(data.slice(80, 88), "le")
1366
1383
  };
1367
- } catch {
1384
+ } catch (error) {
1385
+ console.warn("[ViWoSDK] vilink.getUserStats failed:", error instanceof Error ? error.message : error);
1368
1386
  return null;
1369
1387
  }
1370
1388
  }
@@ -1538,6 +1556,10 @@ var GaslessClient = class {
1538
1556
  }
1539
1557
  /**
1540
1558
  * Get gasless configuration
1559
+ *
1560
+ * Finding #8 Fix: Corrected byte offsets to match on-chain GaslessConfig struct.
1561
+ * Added missing fields: pendingAuthority, feeVault, sscreProgram, sscreDeductionBps,
1562
+ * maxSubsidizedPerUser, totalSolSpent, currentDay, daySpent, maxSlippageBps.
1541
1563
  */
1542
1564
  async getConfig() {
1543
1565
  try {
@@ -1549,16 +1571,26 @@ var GaslessClient = class {
1549
1571
  const data = accountInfo.data;
1550
1572
  return {
1551
1573
  authority: new import_web37.PublicKey(data.slice(8, 40)),
1552
- feePayer: new import_web37.PublicKey(data.slice(40, 72)),
1553
- vcoinMint: new import_web37.PublicKey(data.slice(72, 104)),
1554
- dailySubsidyBudget: new import_anchor6.BN(data.slice(136, 144), "le"),
1555
- solFeePerTx: new import_anchor6.BN(data.slice(144, 152), "le"),
1556
- vcoinFeeMultiplier: new import_anchor6.BN(data.slice(152, 160), "le"),
1557
- totalSubsidizedTx: new import_anchor6.BN(data.slice(168, 176), "le"),
1558
- totalVcoinCollected: new import_anchor6.BN(data.slice(184, 192), "le"),
1559
- paused: data[192] !== 0
1574
+ pendingAuthority: new import_web37.PublicKey(data.slice(40, 72)),
1575
+ feePayer: new import_web37.PublicKey(data.slice(72, 104)),
1576
+ vcoinMint: new import_web37.PublicKey(data.slice(104, 136)),
1577
+ feeVault: new import_web37.PublicKey(data.slice(136, 168)),
1578
+ sscreProgram: new import_web37.PublicKey(data.slice(168, 200)),
1579
+ dailySubsidyBudget: new import_anchor6.BN(data.slice(200, 208), "le"),
1580
+ solFeePerTx: new import_anchor6.BN(data.slice(208, 216), "le"),
1581
+ vcoinFeeMultiplier: new import_anchor6.BN(data.slice(216, 224), "le"),
1582
+ sscreDeductionBps: data.readUInt16LE(224),
1583
+ maxSubsidizedPerUser: data.readUInt32LE(226),
1584
+ totalSubsidizedTx: new import_anchor6.BN(data.slice(230, 238), "le"),
1585
+ totalSolSpent: new import_anchor6.BN(data.slice(238, 246), "le"),
1586
+ totalVcoinCollected: new import_anchor6.BN(data.slice(246, 254), "le"),
1587
+ paused: data[254] !== 0,
1588
+ currentDay: data.readUInt32LE(255),
1589
+ daySpent: new import_anchor6.BN(data.slice(259, 267), "le"),
1590
+ maxSlippageBps: data.readUInt16LE(267)
1560
1591
  };
1561
- } catch {
1592
+ } catch (error) {
1593
+ console.warn("[ViWoSDK] gasless.getConfig failed:", error instanceof Error ? error.message : error);
1562
1594
  return null;
1563
1595
  }
1564
1596
  }
@@ -1586,7 +1618,8 @@ var GaslessClient = class {
1586
1618
  isRevoked: data[114] !== 0,
1587
1619
  feeMethod: data[123]
1588
1620
  };
1589
- } catch {
1621
+ } catch (error) {
1622
+ console.warn("[ViWoSDK] gasless.getSessionKey failed:", error instanceof Error ? error.message : error);
1590
1623
  return null;
1591
1624
  }
1592
1625
  }
@@ -1613,7 +1646,8 @@ var GaslessClient = class {
1613
1646
  sessionsCreated: data.readUInt32LE(72),
1614
1647
  activeSession: new import_web37.PublicKey(data.slice(76, 108))
1615
1648
  };
1616
- } catch {
1649
+ } catch (error) {
1650
+ console.warn("[ViWoSDK] gasless.getUserStats failed:", error instanceof Error ? error.message : error);
1617
1651
  return null;
1618
1652
  }
1619
1653
  }
@@ -2388,6 +2422,9 @@ var ViWoClient = class {
2388
2422
  }
2389
2423
  /**
2390
2424
  * Get VCoin balance
2425
+ *
2426
+ * Finding #2 Fix: Now filters by VCoin mint address instead of summing all Token-2022 accounts.
2427
+ * Make sure to set programIds.vcoinMint in your ViWoClient config.
2391
2428
  */
2392
2429
  async getVCoinBalance(user) {
2393
2430
  const target = user || this.publicKey;
@@ -2397,7 +2434,7 @@ var ViWoClient = class {
2397
2434
  try {
2398
2435
  const tokenAccounts = await this.connection.connection.getTokenAccountsByOwner(
2399
2436
  target,
2400
- { programId: import_spl_token.TOKEN_2022_PROGRAM_ID }
2437
+ { mint: this.programIds.vcoinMint, programId: import_spl_token.TOKEN_2022_PROGRAM_ID }
2401
2438
  );
2402
2439
  let balance = new import_anchor10.BN(0);
2403
2440
  for (const { account } of tokenAccounts.value) {
@@ -2406,7 +2443,8 @@ var ViWoClient = class {
2406
2443
  balance = balance.add(new import_anchor10.BN(amount, "le"));
2407
2444
  }
2408
2445
  return balance;
2409
- } catch {
2446
+ } catch (error) {
2447
+ console.warn("[ViWoSDK] getVCoinBalance failed:", error instanceof Error ? error.message : error);
2410
2448
  return new import_anchor10.BN(0);
2411
2449
  }
2412
2450
  }
@@ -2421,7 +2459,8 @@ var ViWoClient = class {
2421
2459
  try {
2422
2460
  const stakeData = await this.staking.getUserStake(target);
2423
2461
  return stakeData?.vevcoinBalance || new import_anchor10.BN(0);
2424
- } catch {
2462
+ } catch (error) {
2463
+ console.warn("[ViWoSDK] getVeVCoinBalance failed:", error instanceof Error ? error.message : error);
2425
2464
  return new import_anchor10.BN(0);
2426
2465
  }
2427
2466
  }
@@ -2436,7 +2475,8 @@ var ViWoClient = class {
2436
2475
  ]);
2437
2476
  const blockTime = await this.connection.getBlockTime();
2438
2477
  return { connected, slot, blockTime };
2439
- } catch {
2478
+ } catch (error) {
2479
+ console.warn("[ViWoSDK] healthCheck failed:", error instanceof Error ? error.message : error);
2440
2480
  return { connected: false, slot: null, blockTime: null };
2441
2481
  }
2442
2482
  }
package/dist/index.mjs CHANGED
@@ -19,7 +19,18 @@ var PROGRAM_IDS = {
19
19
  governanceProtocol: new PublicKey("3R256kBN9iXozjypQFRAmegBhd6HJqXWqdNG7Th78HYe"),
20
20
  sscreProtocol: new PublicKey("6AJNcQSfoiE2UAeUDyJUBumS9SBwhAdSznoAeYpXrxXZ"),
21
21
  vilinkProtocol: new PublicKey("CFGXTS2MueQwTYTMMTBQbRWzJtSTC2p4ZRuKPpLDmrv7"),
22
- gaslessProtocol: new PublicKey("FcXJAjzJs8eVY2WTRFXynQBpC7WZUqKZppyp9xS6PaB3")
22
+ gaslessProtocol: new PublicKey("FcXJAjzJs8eVY2WTRFXynQBpC7WZUqKZppyp9xS6PaB3"),
23
+ /**
24
+ * VCoin Token Mint Address (Token-2022)
25
+ *
26
+ * NOTE: This is a placeholder. Override via ViWoClient config.programIds.vcoinMint
27
+ * after deploying your VCoin mint on devnet/mainnet.
28
+ *
29
+ * Finding #2 Fix: SDK now filters token accounts by mint address to prevent
30
+ * summing balances from other Token-2022 tokens.
31
+ */
32
+ vcoinMint: new PublicKey("11111111111111111111111111111111")
33
+ // Placeholder - override in config
23
34
  };
24
35
  var SEEDS = {
25
36
  // VCoin
@@ -1211,6 +1222,9 @@ var ViLinkClient = class {
1211
1222
  }
1212
1223
  /**
1213
1224
  * Get ViLink configuration
1225
+ *
1226
+ * Finding #8 (related): Corrected byte offsets to match on-chain ViLinkConfig struct.
1227
+ * Added pending_authority field that was missing after H-02 security fix.
1214
1228
  */
1215
1229
  async getConfig() {
1216
1230
  try {
@@ -1222,16 +1236,18 @@ var ViLinkClient = class {
1222
1236
  const data = accountInfo.data;
1223
1237
  return {
1224
1238
  authority: new PublicKey6(data.slice(8, 40)),
1225
- vcoinMint: new PublicKey6(data.slice(40, 72)),
1226
- treasury: new PublicKey6(data.slice(72, 104)),
1227
- enabledActions: data[200],
1228
- totalActionsCreated: new BN5(data.slice(201, 209), "le"),
1229
- totalActionsExecuted: new BN5(data.slice(209, 217), "le"),
1230
- totalTipVolume: new BN5(data.slice(217, 225), "le"),
1231
- paused: data[225] !== 0,
1232
- platformFeeBps: data.readUInt16LE(226)
1239
+ pendingAuthority: new PublicKey6(data.slice(40, 72)),
1240
+ vcoinMint: new PublicKey6(data.slice(72, 104)),
1241
+ treasury: new PublicKey6(data.slice(104, 136)),
1242
+ enabledActions: data[296],
1243
+ totalActionsCreated: new BN5(data.slice(297, 305), "le"),
1244
+ totalActionsExecuted: new BN5(data.slice(305, 313), "le"),
1245
+ totalTipVolume: new BN5(data.slice(313, 321), "le"),
1246
+ paused: data[321] !== 0,
1247
+ platformFeeBps: data.readUInt16LE(322)
1233
1248
  };
1234
- } catch {
1249
+ } catch (error) {
1250
+ console.warn("[ViWoSDK] vilink.getConfig failed:", error instanceof Error ? error.message : error);
1235
1251
  return null;
1236
1252
  }
1237
1253
  }
@@ -1261,7 +1277,8 @@ var ViLinkClient = class {
1261
1277
  actionNonce: nonce
1262
1278
  // M-04: Store nonce for reference
1263
1279
  };
1264
- } catch {
1280
+ } catch (error) {
1281
+ console.warn("[ViWoSDK] vilink.getAction failed:", error instanceof Error ? error.message : error);
1265
1282
  return null;
1266
1283
  }
1267
1284
  }
@@ -1295,7 +1312,8 @@ var ViLinkClient = class {
1295
1312
  vcoinSent: new BN5(data.slice(72, 80), "le"),
1296
1313
  vcoinReceived: new BN5(data.slice(80, 88), "le")
1297
1314
  };
1298
- } catch {
1315
+ } catch (error) {
1316
+ console.warn("[ViWoSDK] vilink.getUserStats failed:", error instanceof Error ? error.message : error);
1299
1317
  return null;
1300
1318
  }
1301
1319
  }
@@ -1469,6 +1487,10 @@ var GaslessClient = class {
1469
1487
  }
1470
1488
  /**
1471
1489
  * Get gasless configuration
1490
+ *
1491
+ * Finding #8 Fix: Corrected byte offsets to match on-chain GaslessConfig struct.
1492
+ * Added missing fields: pendingAuthority, feeVault, sscreProgram, sscreDeductionBps,
1493
+ * maxSubsidizedPerUser, totalSolSpent, currentDay, daySpent, maxSlippageBps.
1472
1494
  */
1473
1495
  async getConfig() {
1474
1496
  try {
@@ -1480,16 +1502,26 @@ var GaslessClient = class {
1480
1502
  const data = accountInfo.data;
1481
1503
  return {
1482
1504
  authority: new PublicKey7(data.slice(8, 40)),
1483
- feePayer: new PublicKey7(data.slice(40, 72)),
1484
- vcoinMint: new PublicKey7(data.slice(72, 104)),
1485
- dailySubsidyBudget: new BN6(data.slice(136, 144), "le"),
1486
- solFeePerTx: new BN6(data.slice(144, 152), "le"),
1487
- vcoinFeeMultiplier: new BN6(data.slice(152, 160), "le"),
1488
- totalSubsidizedTx: new BN6(data.slice(168, 176), "le"),
1489
- totalVcoinCollected: new BN6(data.slice(184, 192), "le"),
1490
- paused: data[192] !== 0
1505
+ pendingAuthority: new PublicKey7(data.slice(40, 72)),
1506
+ feePayer: new PublicKey7(data.slice(72, 104)),
1507
+ vcoinMint: new PublicKey7(data.slice(104, 136)),
1508
+ feeVault: new PublicKey7(data.slice(136, 168)),
1509
+ sscreProgram: new PublicKey7(data.slice(168, 200)),
1510
+ dailySubsidyBudget: new BN6(data.slice(200, 208), "le"),
1511
+ solFeePerTx: new BN6(data.slice(208, 216), "le"),
1512
+ vcoinFeeMultiplier: new BN6(data.slice(216, 224), "le"),
1513
+ sscreDeductionBps: data.readUInt16LE(224),
1514
+ maxSubsidizedPerUser: data.readUInt32LE(226),
1515
+ totalSubsidizedTx: new BN6(data.slice(230, 238), "le"),
1516
+ totalSolSpent: new BN6(data.slice(238, 246), "le"),
1517
+ totalVcoinCollected: new BN6(data.slice(246, 254), "le"),
1518
+ paused: data[254] !== 0,
1519
+ currentDay: data.readUInt32LE(255),
1520
+ daySpent: new BN6(data.slice(259, 267), "le"),
1521
+ maxSlippageBps: data.readUInt16LE(267)
1491
1522
  };
1492
- } catch {
1523
+ } catch (error) {
1524
+ console.warn("[ViWoSDK] gasless.getConfig failed:", error instanceof Error ? error.message : error);
1493
1525
  return null;
1494
1526
  }
1495
1527
  }
@@ -1517,7 +1549,8 @@ var GaslessClient = class {
1517
1549
  isRevoked: data[114] !== 0,
1518
1550
  feeMethod: data[123]
1519
1551
  };
1520
- } catch {
1552
+ } catch (error) {
1553
+ console.warn("[ViWoSDK] gasless.getSessionKey failed:", error instanceof Error ? error.message : error);
1521
1554
  return null;
1522
1555
  }
1523
1556
  }
@@ -1544,7 +1577,8 @@ var GaslessClient = class {
1544
1577
  sessionsCreated: data.readUInt32LE(72),
1545
1578
  activeSession: new PublicKey7(data.slice(76, 108))
1546
1579
  };
1547
- } catch {
1580
+ } catch (error) {
1581
+ console.warn("[ViWoSDK] gasless.getUserStats failed:", error instanceof Error ? error.message : error);
1548
1582
  return null;
1549
1583
  }
1550
1584
  }
@@ -2319,6 +2353,9 @@ var ViWoClient = class {
2319
2353
  }
2320
2354
  /**
2321
2355
  * Get VCoin balance
2356
+ *
2357
+ * Finding #2 Fix: Now filters by VCoin mint address instead of summing all Token-2022 accounts.
2358
+ * Make sure to set programIds.vcoinMint in your ViWoClient config.
2322
2359
  */
2323
2360
  async getVCoinBalance(user) {
2324
2361
  const target = user || this.publicKey;
@@ -2328,7 +2365,7 @@ var ViWoClient = class {
2328
2365
  try {
2329
2366
  const tokenAccounts = await this.connection.connection.getTokenAccountsByOwner(
2330
2367
  target,
2331
- { programId: TOKEN_2022_PROGRAM_ID }
2368
+ { mint: this.programIds.vcoinMint, programId: TOKEN_2022_PROGRAM_ID }
2332
2369
  );
2333
2370
  let balance = new BN10(0);
2334
2371
  for (const { account } of tokenAccounts.value) {
@@ -2337,7 +2374,8 @@ var ViWoClient = class {
2337
2374
  balance = balance.add(new BN10(amount, "le"));
2338
2375
  }
2339
2376
  return balance;
2340
- } catch {
2377
+ } catch (error) {
2378
+ console.warn("[ViWoSDK] getVCoinBalance failed:", error instanceof Error ? error.message : error);
2341
2379
  return new BN10(0);
2342
2380
  }
2343
2381
  }
@@ -2352,7 +2390,8 @@ var ViWoClient = class {
2352
2390
  try {
2353
2391
  const stakeData = await this.staking.getUserStake(target);
2354
2392
  return stakeData?.vevcoinBalance || new BN10(0);
2355
- } catch {
2393
+ } catch (error) {
2394
+ console.warn("[ViWoSDK] getVeVCoinBalance failed:", error instanceof Error ? error.message : error);
2356
2395
  return new BN10(0);
2357
2396
  }
2358
2397
  }
@@ -2367,7 +2406,8 @@ var ViWoClient = class {
2367
2406
  ]);
2368
2407
  const blockTime = await this.connection.getBlockTime();
2369
2408
  return { connected, slot, blockTime };
2370
- } catch {
2409
+ } catch (error) {
2410
+ console.warn("[ViWoSDK] healthCheck failed:", error instanceof Error ? error.message : error);
2371
2411
  return { connected: false, slot: null, blockTime: null };
2372
2412
  }
2373
2413
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viwoapp/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "ViWoApp SDK - TypeScript SDK for VCoin Protocol Integration",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -80,4 +80,3 @@
80
80
  }
81
81
  }
82
82
  }
83
-