@sage-protocol/sdk 0.1.18 → 0.1.21

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
@@ -62,6 +62,7 @@ Module Overview
62
62
  | `timelock` | Min delay, queued operation inspection, schedule/cancel builders | Safe workflows, monitoring |
63
63
  | `factory` | Config reads, template enumeration, SubDAO create/fork builders | Launch tooling, analytics |
64
64
  | `library` | Manifest listings & scoped ownership checks | Prompt library browsers |
65
+ | `lineage` | Library fork ancestry, per-library fork fees | Fork tracking, royalty analytics |
65
66
  | `prompt` | Prompt metadata, fork counts, usage counters | UI prompt catalogues, agent prompt selection |
66
67
  | `ipfs` | Upload helpers + discovery/governance worker APIs | CLI sandbox, dashboards, worker automation |
67
68
  | `subdao` | Discovery, staking helpers, per-user stats | SubDAO directories, onboarding |
@@ -371,6 +372,8 @@ Important
371
372
  Deprecations
372
373
  ------------
373
374
  - `resolveGovernanceContext` is still exported for compatibility but now logs a deprecation warning. Use the richer `governance` + `subdao` helpers instead.
375
+ - **Prompt-level forking** is deprecated. On-chain prompt forking via `SubDAO.forkPrompt()` and `SubDAO.forkPromptWithStable()` is no longer supported. Use `forked_from` metadata in prompt frontmatter instead. Library-level forks (entire SubDAOs) remain fully supported via the factory.
376
+ - **Prompt fork fees** (stable fee configuration for prompt forks) have been removed. Per-library SXXX fork fees are now the standard model for monetizing library forks. See the `lineage` module documentation above.
374
377
 
375
378
  Next Phases
376
379
  -----------
@@ -649,6 +652,100 @@ const profileCid = 'bafy...'; // CID of dao-profile.json on IPFS
649
652
  const { to, data, value } = sdk.subdao.buildSetProfileCidTx({ subdao: res.subdao, profileCid });
650
653
  // Example: schedule via timelock or propose via Governor, depending on your governance mode
651
654
  ```
655
+
656
+ # Library Lineage and Fork Fees
657
+
658
+ The `lineage` module provides helpers for tracking library fork relationships and per-library SXXX fork fees.
659
+
660
+ ## Fork Ancestry
661
+
662
+ Libraries can be forked from other libraries. The `lineage` module tracks this ancestry:
663
+
664
+ ```js
665
+ import sdk from '@sage-protocol/sdk';
666
+
667
+ const provider = sdk.getProvider({ rpcUrl: process.env.RPC_URL });
668
+ const registry = '0xLibraryRegistry';
669
+ const subdao = '0xSubDAO';
670
+
671
+ // Check if a library was forked from another
672
+ const isFork = await sdk.lineage.isFork({ provider, registry, subdao });
673
+ // → true if this library has a parent
674
+
675
+ // Get the parent library (null if original)
676
+ const parent = await sdk.lineage.getParentLibrary({ provider, registry, subdao });
677
+ // → '0xParentSubDAO' or null
678
+
679
+ // Get full ancestry chain from root to current
680
+ const chain = await sdk.lineage.getLineageChain({ provider, registry, subdao });
681
+ // → { chain: ['0xRoot', '0xChild', '0xGrandchild'], depth: 2, root: '0xRoot' }
682
+ ```
683
+
684
+ ## Per-Library Fork Fees
685
+
686
+ Library owners can set an SXXX fee for forking their library. This fee is paid by the forker to the parent library's treasury when creating a forked SubDAO.
687
+
688
+ ```js
689
+ // Get the SXXX fork fee for a library (0n = free fork)
690
+ const fee = await sdk.lineage.getLibraryForkFee({ provider, registry, subdao });
691
+ // → 1000000000000000000n (1 SXXX in wei)
692
+
693
+ // Get comprehensive library info including fork fee
694
+ const info = await sdk.lineage.getLibraryInfo({ provider, registry, subdao });
695
+ // → {
696
+ // parentDAO: '0xParent' | null,
697
+ // forkFee: 1000000000000000000n,
698
+ // manifestCID: 'Qm...',
699
+ // version: '1.0.0'
700
+ // }
701
+ ```
702
+
703
+ ## Setting Fork Fees (via Governance)
704
+
705
+ Fork fees can only be set by the library's timelock. This is typically done through a governance proposal:
706
+
707
+ ```js
708
+ import { ethers } from 'ethers';
709
+
710
+ // Build the setLibraryForkFee transaction (for use in a proposal)
711
+ const registryIface = new ethers.Interface([
712
+ 'function setLibraryForkFee(address dao, uint256 fee)'
713
+ ]);
714
+
715
+ const feeInWei = ethers.parseUnits('10', 18); // 10 SXXX
716
+ const calldata = registryIface.encodeFunctionData('setLibraryForkFee', [subdao, feeInWei]);
717
+
718
+ // Include in a governance proposal
719
+ const proposeTx = sdk.governance.buildProposeTx({
720
+ governor,
721
+ targets: [registry],
722
+ values: [0n],
723
+ calldatas: [calldata],
724
+ descriptionOrHash: 'Set library fork fee to 10 SXXX'
725
+ });
726
+ ```
727
+
728
+ ## Fork Fee Flow
729
+
730
+ When a SubDAO is forked via the factory:
731
+
732
+ 1. Factory reads the parent library's fork fee from LibraryRegistry
733
+ 2. If fee > 0, SXXX is transferred from forker to parent's treasury
734
+ 3. `LibraryForkFeePaid(parentDAO, forker, amount)` event is emitted
735
+ 4. Fork proceeds with standard SubDAO creation
736
+
737
+ Note: Forkers must approve SXXX to the factory before forking a library with a fee set.
738
+
739
+ ## Deprecation: Prompt-Level Forks
740
+
741
+ On-chain prompt forking is deprecated. Prompt forks are now tracked via metadata only:
742
+
743
+ 1. Add `forked_from: <original-cid>` to your prompt frontmatter
744
+ 2. Upload the new prompt to IPFS
745
+ 3. Register via governance proposal
746
+
747
+ Library-level forks (entire SubDAOs) continue to work and are tracked via `LibraryRegistry.registerForkedDAO()`.
748
+
652
749
  # Governance Adapter (OpenZeppelin)
653
750
 
654
751
  Normalize proposals/timelines across OZ governors with a compact adapter, inspired by Boardroom’s pattern.
@@ -14,7 +14,7 @@ var require_package = __commonJS({
14
14
  "package.json"(exports, module) {
15
15
  module.exports = {
16
16
  name: "@sage-protocol/sdk",
17
- version: "0.1.18",
17
+ version: "0.1.21",
18
18
  description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
19
19
  main: "dist/index.cjs",
20
20
  module: "dist/index.mjs",
@@ -130,7 +130,6 @@ var require_abi = __commonJS({
130
130
  "function stableCreationFee() view returns (uint256)",
131
131
  "function stableFeeReceiver() view returns (address)",
132
132
  "function stableCreationEnabled() view returns (bool)",
133
- "function stablePromptForkFee() view returns (uint256)",
134
133
  "function stableForkFee() view returns (uint256)",
135
134
  // Core factory reads
136
135
  "function timelockMinDelay() view returns (uint256)",
@@ -172,13 +171,18 @@ var require_abi = __commonJS({
172
171
  "function maxCreationBurn() view returns (uint256)"
173
172
  ];
174
173
  var LibraryRegistry = [
175
- "function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
174
+ "function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version, address forkedFromDAO, uint256 sxxxForkFee)",
176
175
  "function daoTimelock(address) view returns (address)",
177
- "function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
176
+ "function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version, address forkedFromDAO, uint256 sxxxForkFee))",
177
+ "function getLibraryForkFee(address dao) view returns (uint256)",
178
+ "function setLibraryForkFee(address dao, uint256 fee)",
178
179
  "function updateLibrary(address dao, string manifestCID, string version)",
179
180
  "function registerDAO(address dao, address timelock)",
181
+ "function registerForkedDAO(address childDAO, address childTimelock, address parentDAO, string manifestCID, string version)",
180
182
  "event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
181
- "event DAORegistered(address indexed dao, address indexed timelock)"
183
+ "event DAORegistered(address indexed dao, address indexed timelock)",
184
+ "event LibraryForked(address indexed parentDAO, address indexed childDAO)",
185
+ "event LibraryForkFeeUpdated(address indexed dao, uint256 fee)"
182
186
  ];
183
187
  var PromptRegistry = [
184
188
  "function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
@@ -1383,7 +1387,6 @@ var require_ipfs = __commonJS({
1383
1387
  headers["X-Wallet-Address"] = auth.address;
1384
1388
  headers["X-Wallet-Signature"] = auth.signature;
1385
1389
  headers["X-Wallet-Nonce"] = auth.nonce;
1386
- headers["X-Wallet-Message"] = auth.message;
1387
1390
  }
1388
1391
  return { headers, auth };
1389
1392
  }
@@ -1404,8 +1407,7 @@ var require_ipfs = __commonJS({
1404
1407
  ...extraHeaders,
1405
1408
  "X-Wallet-Address": auth.address,
1406
1409
  "X-Wallet-Signature": auth.signature,
1407
- "X-Wallet-Nonce": auth.nonce,
1408
- "X-Wallet-Message": auth.message
1410
+ "X-Wallet-Nonce": auth.nonce
1409
1411
  };
1410
1412
  return { headers, auth };
1411
1413
  }
@@ -1790,8 +1792,7 @@ var require_ipfs = __commonJS({
1790
1792
  "Content-Type": "application/json",
1791
1793
  "X-Wallet-Address": address,
1792
1794
  "X-Wallet-Signature": signature,
1793
- "X-Wallet-Nonce": nonce,
1794
- "X-Wallet-Message": message
1795
+ "X-Wallet-Nonce": nonce
1795
1796
  };
1796
1797
  let verified = false;
1797
1798
  try {