@sage-protocol/cli 0.4.9 → 0.4.10

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.
@@ -412,6 +412,60 @@ class GovernanceManager {
412
412
  throw pfErr;
413
413
  }
414
414
 
415
+ // Check voting power vs proposal threshold (Token governance mode)
416
+ try {
417
+ const proposer = await this.signer.getAddress();
418
+
419
+ // Get proposal threshold
420
+ const threshold = await this.governor.proposalThreshold().catch(() => 0n);
421
+
422
+ // Get current clock (block number for block-based, timestamp for time-based)
423
+ let currentClock;
424
+ try {
425
+ currentClock = await this.governor.clock();
426
+ } catch {
427
+ // Fallback to block number if clock() not available
428
+ currentClock = BigInt(await this.provider.getBlockNumber());
429
+ }
430
+
431
+ // Get voting power at the previous clock tick (as required by OZ Governor)
432
+ const checkClock = currentClock > 0n ? currentClock - 1n : 0n;
433
+ let votes = 0n;
434
+ try {
435
+ votes = await this.governor.getVotes(proposer, checkClock);
436
+ } catch (e) {
437
+ // Some governors may not expose getVotes - try getPastVotes on the token
438
+ try {
439
+ const tokenAddr = await this.governor.token().catch(() => null);
440
+ if (tokenAddr && tokenAddr !== ethers.ZeroAddress) {
441
+ const token = new ethers.Contract(tokenAddr, ['function getPastVotes(address, uint256) view returns (uint256)'], this.provider);
442
+ votes = await token.getPastVotes(proposer, checkClock);
443
+ }
444
+ } catch { /* non-fatal */ }
445
+ }
446
+
447
+ console.log(`šŸ“Š Proposal threshold: ${ethers.formatEther(threshold)} votes`);
448
+ console.log(`šŸ“Š Your voting power: ${ethers.formatEther(votes)} votes`);
449
+
450
+ if (threshold > 0n && votes < threshold) {
451
+ const shortfall = threshold - votes;
452
+ throw new Error(
453
+ `\nāŒ Insufficient voting power to create proposal\n` +
454
+ ` You have: ${ethers.formatEther(votes)} votes\n` +
455
+ ` Required: ${ethers.formatEther(threshold)} votes\n` +
456
+ ` Shortfall: ${ethers.formatEther(shortfall)} votes\n\n` +
457
+ `šŸ’” To gain voting power:\n` +
458
+ ` 1. Acquire stake tokens for this SubDAO\n` +
459
+ ` 2. Delegate to yourself: sage delegate self\n` +
460
+ ` 3. Wait one block for delegation to take effect\n`
461
+ );
462
+ }
463
+ } catch (vpErr) {
464
+ if (String(vpErr.message || '').includes('Insufficient voting power')) throw vpErr;
465
+ // Non-fatal if voting power check fails (some governors may not support it)
466
+ console.log(colors.yellow('āš ļø Could not verify voting power (non-fatal)'));
467
+ }
468
+
415
469
  // Check for refundable deposit requirement (Bootstrap mode)
416
470
  let depositValue = 0n;
417
471
  try {
@@ -65,6 +65,7 @@ const COMMAND_CATALOG = {
65
65
  'list-all-subdaos',
66
66
  'wait',
67
67
  'wizard',
68
+ 'set',
68
69
  'self-delegate',
69
70
  'self-delegate-stake',
70
71
  'delegation'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-protocol/cli",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "description": "Sage Protocol CLI for managing AI prompt libraries",
5
5
  "bin": {
6
6
  "sage": "./bin/sage.js"