@sage-protocol/sdk 0.1.14 → 0.1.16
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 +9 -2
- package/dist/browser/index.mjs +8 -7
- package/dist/index.cjs +100 -67
- package/dist/index.mjs +100 -67
- package/dist/node/index.cjs +100 -67
- package/dist/node/index.mjs +100 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,8 +32,9 @@ const subdaos = await sdk.subdao.discoverSubDAOs({
|
|
|
32
32
|
fromBlock: 0,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
// Fetch governance metadata for a SubDAO
|
|
36
|
-
const info = await sdk.
|
|
35
|
+
// Fetch governance + profile metadata for a SubDAO
|
|
36
|
+
const info = await sdk.subdao.getSubDAOInfo({ provider, subdao: subdaos[0].subdao });
|
|
37
|
+
// info.profileCID points at an IPFS JSON profile/playbook document (name, description, avatar, social links, etc.)
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
**CommonJS usage**
|
|
@@ -641,6 +642,12 @@ await sdk.subdao.makeOperator({ signer, subdao: res.subdao, operator: '0xSafeOrE
|
|
|
641
642
|
|
|
642
643
|
// Ensure SXXX approval for factory burn if needed
|
|
643
644
|
await sdk.subdao.ensureSxxxBurnAllowance({ signer, sxxx: SXXX, spender: FACTORY, amount: 1500n * 10n**18n });
|
|
645
|
+
|
|
646
|
+
// (Optional) Build a setProfileCid tx for newer SubDAO implementations that expose setProfileCid(string)
|
|
647
|
+
// Use this in a Governor/Timelock proposal or Safe Transaction Builder, not as a direct EOA call.
|
|
648
|
+
const profileCid = 'bafy...'; // CID of dao-profile.json on IPFS
|
|
649
|
+
const { to, data, value } = sdk.subdao.buildSetProfileCidTx({ subdao: res.subdao, profileCid });
|
|
650
|
+
// Example: schedule via timelock or propose via Governor, depending on your governance mode
|
|
644
651
|
```
|
|
645
652
|
# Governance Adapter (OpenZeppelin)
|
|
646
653
|
|
package/dist/browser/index.mjs
CHANGED
|
@@ -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.
|
|
17
|
+
version: "0.1.16",
|
|
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",
|
|
@@ -172,12 +172,13 @@ var require_abi = __commonJS({
|
|
|
172
172
|
"function maxCreationBurn() view returns (uint256)"
|
|
173
173
|
];
|
|
174
174
|
var LibraryRegistry = [
|
|
175
|
-
"function
|
|
176
|
-
"function
|
|
177
|
-
"function
|
|
178
|
-
"function
|
|
179
|
-
"function
|
|
180
|
-
"
|
|
175
|
+
"function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
|
|
176
|
+
"function daoTimelock(address) view returns (address)",
|
|
177
|
+
"function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
|
|
178
|
+
"function updateLibrary(address dao, string manifestCID, string version)",
|
|
179
|
+
"function registerDAO(address dao, address timelock)",
|
|
180
|
+
"event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
|
|
181
|
+
"event DAORegistered(address indexed dao, address indexed timelock)"
|
|
181
182
|
];
|
|
182
183
|
var PromptRegistry = [
|
|
183
184
|
"function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
|
package/dist/index.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports2, module2) {
|
|
15
15
|
module2.exports = {
|
|
16
16
|
name: "@sage-protocol/sdk",
|
|
17
|
-
version: "0.1.
|
|
17
|
+
version: "0.1.16",
|
|
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",
|
|
@@ -172,12 +172,13 @@ var require_abi = __commonJS({
|
|
|
172
172
|
"function maxCreationBurn() view returns (uint256)"
|
|
173
173
|
];
|
|
174
174
|
var LibraryRegistry = [
|
|
175
|
-
"function
|
|
176
|
-
"function
|
|
177
|
-
"function
|
|
178
|
-
"function
|
|
179
|
-
"function
|
|
180
|
-
"
|
|
175
|
+
"function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
|
|
176
|
+
"function daoTimelock(address) view returns (address)",
|
|
177
|
+
"function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
|
|
178
|
+
"function updateLibrary(address dao, string manifestCID, string version)",
|
|
179
|
+
"function registerDAO(address dao, address timelock)",
|
|
180
|
+
"event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
|
|
181
|
+
"event DAORegistered(address indexed dao, address indexed timelock)"
|
|
181
182
|
];
|
|
182
183
|
var PromptRegistry = [
|
|
183
184
|
"function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
|
|
@@ -1231,15 +1232,35 @@ var require_ipfs = __commonJS({
|
|
|
1231
1232
|
if (metadata) {
|
|
1232
1233
|
formData.append("pinataMetadata", JSON.stringify(metadata));
|
|
1233
1234
|
}
|
|
1234
|
-
const
|
|
1235
|
+
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1236
|
+
const sendWithAuthMode = async (mode) => {
|
|
1237
|
+
const headers = { ...formData.getHeaders() };
|
|
1238
|
+
if (mode === "jwt") {
|
|
1239
|
+
headers.Authorization = `Bearer ${config.pinata.jwt}`;
|
|
1240
|
+
} else {
|
|
1241
|
+
headers.pinata_api_key = config.pinata.apiKey;
|
|
1242
|
+
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1243
|
+
}
|
|
1244
|
+
return axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1245
|
+
};
|
|
1246
|
+
let response;
|
|
1247
|
+
let lastError;
|
|
1235
1248
|
if (config.pinata.jwt) {
|
|
1236
|
-
|
|
1249
|
+
try {
|
|
1250
|
+
response = await sendWithAuthMode("jwt");
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
lastError = error;
|
|
1253
|
+
const status = error?.response?.status;
|
|
1254
|
+
const reason = error?.response?.data?.error?.reason || "";
|
|
1255
|
+
const isInvalidJwt = status === 401 && typeof reason === "string" && reason.toUpperCase().includes("INVALID_CREDENTIALS");
|
|
1256
|
+
if (!config.pinata.apiKey || !config.pinata.secretKey || !isInvalidJwt) {
|
|
1257
|
+
throw error;
|
|
1258
|
+
}
|
|
1259
|
+
response = await sendWithAuthMode("keys");
|
|
1260
|
+
}
|
|
1237
1261
|
} else {
|
|
1238
|
-
|
|
1239
|
-
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1262
|
+
response = await sendWithAuthMode("keys");
|
|
1240
1263
|
}
|
|
1241
|
-
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1242
|
-
const response = await axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1243
1264
|
const cid = response?.data?.IpfsHash || response?.data?.cid || response?.data?.Hash;
|
|
1244
1265
|
if (!cid) {
|
|
1245
1266
|
throw new Error("Pinata upload did not return IpfsHash");
|
|
@@ -1875,7 +1896,7 @@ var require_validation = __commonJS({
|
|
|
1875
1896
|
schemaPath: null,
|
|
1876
1897
|
errors: [{ keyword: "schema", instancePath: "/", message: "manifest schema not found" }],
|
|
1877
1898
|
hints: [
|
|
1878
|
-
'Ensure docs/schemas/manifest.schema.json exists (run "sage
|
|
1899
|
+
'Ensure docs/schemas/manifest.schema.json exists (run "sage project scaffold" to regenerate)'
|
|
1879
1900
|
],
|
|
1880
1901
|
manifestPath
|
|
1881
1902
|
};
|
|
@@ -2016,93 +2037,95 @@ var require_library = __commonJS({
|
|
|
2016
2037
|
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
2017
2038
|
}
|
|
2018
2039
|
}
|
|
2019
|
-
async function listManifests({ provider, registry, offset = 0, limit = 50 }) {
|
|
2040
|
+
async function listManifests({ provider, registry, factoryAddress, offset = 0, limit = 50 }) {
|
|
2020
2041
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2021
|
-
|
|
2022
|
-
const
|
|
2023
|
-
const
|
|
2042
|
+
if (!factoryAddress) throw new SageSDKError(CODES.INVALID_ARGS, "factoryAddress required for V4 listing");
|
|
2043
|
+
const factory2 = new Contract(factoryAddress, ABI.FactoryRead, provider);
|
|
2044
|
+
const totalSubDAOs = await factory2.getSubDAOCount();
|
|
2024
2045
|
const manifests = [];
|
|
2025
|
-
|
|
2026
|
-
|
|
2046
|
+
const start = Number(offset);
|
|
2047
|
+
const end = Math.min(start + Number(limit), Number(totalSubDAOs));
|
|
2048
|
+
for (let i = start; i < end; i++) {
|
|
2049
|
+
const subdao2 = await factory2.subDaos(i);
|
|
2050
|
+
const info = await getLatestLibrary({ provider, registry, subdao: subdao2 });
|
|
2051
|
+
if (info && info.manifestCID) {
|
|
2052
|
+
manifests.push(info);
|
|
2053
|
+
}
|
|
2027
2054
|
}
|
|
2028
|
-
return { total: BigInt(
|
|
2055
|
+
return { total: BigInt(totalSubDAOs), manifests };
|
|
2029
2056
|
}
|
|
2030
|
-
async function
|
|
2057
|
+
async function getLibraryInfo({ provider, registry, subdao: subdao2 }) {
|
|
2031
2058
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2032
|
-
if (!
|
|
2059
|
+
if (!subdao2) throw new SageSDKError(CODES.INVALID_ARGS, "subdao required");
|
|
2033
2060
|
const addr = normalise(registry, "registry");
|
|
2061
|
+
const dao = normalise(subdao2, "subdao");
|
|
2034
2062
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2035
|
-
const
|
|
2063
|
+
const info = await contract.getLibrary(dao);
|
|
2036
2064
|
return {
|
|
2037
|
-
manifestCID,
|
|
2038
|
-
previousCID,
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2065
|
+
manifestCID: info.manifestCID,
|
|
2066
|
+
previousCID: "",
|
|
2067
|
+
// Not tracked on-chain in V4 (history is in events/subgraph)
|
|
2068
|
+
timestamp: BigInt(info.lastUpdated.toString()),
|
|
2069
|
+
proposer: getAddress(info.lastUpdater),
|
|
2070
|
+
promptCount: 0,
|
|
2071
|
+
// Not tracked on-chain in V4
|
|
2072
|
+
version: info.version
|
|
2042
2073
|
};
|
|
2043
2074
|
}
|
|
2075
|
+
async function getManifestInfo({ provider, registry, manifestCID }) {
|
|
2076
|
+
throw new SageSDKError(CODES.UNSUPPORTED_OPERATION, "getManifestInfo(cid) is not supported in V4. Use getLibraryInfo(subdao).");
|
|
2077
|
+
}
|
|
2044
2078
|
function _computeLibraryKey(subdao2, libraryId) {
|
|
2045
|
-
|
|
2046
|
-
const encoded = coder.encode(["address", "string"], [getAddress(subdao2), String(libraryId)]);
|
|
2047
|
-
return keccak256(encoded);
|
|
2079
|
+
return getAddress(subdao2);
|
|
2048
2080
|
}
|
|
2049
|
-
async function getLatestLibrary({ provider, registry, subdao: subdao2
|
|
2050
|
-
|
|
2051
|
-
const addr = normalise(registry, "registry");
|
|
2052
|
-
const sub = normalise(subdao2, "subdao");
|
|
2053
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2054
|
-
const key = _computeLibraryKey(sub, libraryId);
|
|
2055
|
-
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
2056
|
-
if (!latestCID || latestCID.length === 0) return null;
|
|
2057
|
-
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
2058
|
-
return info;
|
|
2081
|
+
async function getLatestLibrary({ provider, registry, subdao: subdao2 }) {
|
|
2082
|
+
return getLibraryInfo({ provider, registry, subdao: subdao2 });
|
|
2059
2083
|
}
|
|
2060
|
-
async function getBeforeAfterForUpdate({ provider, registry, subdao: subdao2,
|
|
2084
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao: subdao2, newCid }) {
|
|
2061
2085
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2062
|
-
const
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2086
|
+
const info = await getLatestLibrary({ provider, registry, subdao: subdao2 });
|
|
2087
|
+
return {
|
|
2088
|
+
previousCID: info ? info.manifestCID : null,
|
|
2089
|
+
newCID: String(newCid),
|
|
2090
|
+
version: info ? info.version : "0.0.0"
|
|
2091
|
+
};
|
|
2068
2092
|
}
|
|
2069
2093
|
async function hasScopedOwnership({ provider, registry, subdao: subdao2, manifestCID }) {
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
const sub = normalise(subdao2, "subdao");
|
|
2073
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2074
|
-
return contract.hasScopedOwnership(sub, manifestCID);
|
|
2094
|
+
const info = await getLatestLibrary({ provider, registry, subdao: subdao2 });
|
|
2095
|
+
return info && info.manifestCID === manifestCID;
|
|
2075
2096
|
}
|
|
2076
|
-
function
|
|
2097
|
+
function buildUpdateLibraryTx({ registry, subdao: subdao2, manifestCID, version = "1.0.0" }) {
|
|
2077
2098
|
const to = normalise(registry, "registry");
|
|
2078
2099
|
if (!manifestCID) throw new SageSDKError(CODES.INVALID_ARGS, "manifestCID required");
|
|
2079
|
-
const iface = new Interface(["function
|
|
2080
|
-
const data = iface.encodeFunctionData("
|
|
2100
|
+
const iface = new Interface(["function updateLibrary(address,string,string)"]);
|
|
2101
|
+
const data = iface.encodeFunctionData("updateLibrary", [
|
|
2081
2102
|
normalise(subdao2, "subdao"),
|
|
2082
|
-
String(libraryId || "main"),
|
|
2083
2103
|
String(manifestCID),
|
|
2084
|
-
|
|
2104
|
+
String(version)
|
|
2085
2105
|
]);
|
|
2086
2106
|
return { to, data, value: 0n };
|
|
2087
2107
|
}
|
|
2108
|
+
var buildUpdateLibraryForSubDAOTx = buildUpdateLibraryTx;
|
|
2088
2109
|
module2.exports = {
|
|
2089
2110
|
listManifests,
|
|
2090
2111
|
getManifestInfo,
|
|
2112
|
+
getLibraryInfo,
|
|
2091
2113
|
getLatestLibrary,
|
|
2092
2114
|
hasScopedOwnership,
|
|
2115
|
+
buildUpdateLibraryTx,
|
|
2093
2116
|
buildUpdateLibraryForSubDAOTx,
|
|
2094
2117
|
_computeLibraryKey,
|
|
2095
2118
|
getBeforeAfterForUpdate,
|
|
2096
2119
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
2097
2120
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock: timelock2, subdao: subdao2 }) {
|
|
2098
2121
|
const to = normalise(registry, "registry");
|
|
2099
|
-
const iface = new Interface(["function
|
|
2100
|
-
const data = iface.encodeFunctionData("
|
|
2122
|
+
const iface = new Interface(["function registerDAO(address,address)"]);
|
|
2123
|
+
const data = iface.encodeFunctionData("registerDAO", [normalise(subdao2, "subdao"), normalise(timelock2, "timelock")]);
|
|
2101
2124
|
return { to, data, value: 0n };
|
|
2102
2125
|
},
|
|
2103
2126
|
searchRegistry,
|
|
2104
2127
|
validation,
|
|
2105
|
-
/** Simulate
|
|
2128
|
+
/** Simulate as timelock */
|
|
2106
2129
|
simulateAsTimelock: async function simulateAsTimelock({ provider, registry, to, data, timelock: timelock2 }) {
|
|
2107
2130
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2108
2131
|
const reg = normalise(registry, "registry");
|
|
@@ -2115,10 +2138,9 @@ var require_library = __commonJS({
|
|
|
2115
2138
|
return { ok: false, error: { type: "Revert", message: String(err && err.message || err) } };
|
|
2116
2139
|
}
|
|
2117
2140
|
},
|
|
2118
|
-
|
|
2119
|
-
executionReadiness: async function executionReadiness({ provider, registry, timelock: timelock2, subdao: subdao2, libraryId = "main", manifestCID = "", promptCount = 0 }) {
|
|
2141
|
+
executionReadiness: async function executionReadiness({ provider, registry, timelock: timelock2, subdao: subdao2, manifestCID = "", version = "1.0.0" }) {
|
|
2120
2142
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2121
|
-
const payload =
|
|
2143
|
+
const payload = buildUpdateLibraryTx({ registry, subdao: subdao2, manifestCID, version });
|
|
2122
2144
|
const sim = await this.simulateAsTimelock({ provider, registry, to: payload.to, data: payload.data, timelock: timelock2 });
|
|
2123
2145
|
const out = { ok: !!sim.ok, error: sim.ok ? null : sim.error?.message || "revert", missingRole: null };
|
|
2124
2146
|
return out;
|
|
@@ -2931,7 +2953,9 @@ var require_subdao = __commonJS({
|
|
|
2931
2953
|
}
|
|
2932
2954
|
var SubDAOInterface = new Interface([
|
|
2933
2955
|
"function stake(uint256)",
|
|
2934
|
-
"function unstake(uint256)"
|
|
2956
|
+
"function unstake(uint256)",
|
|
2957
|
+
// Optional on newer SubDAO implementations; provided for tx building only.
|
|
2958
|
+
"function setProfileCid(string)"
|
|
2935
2959
|
]);
|
|
2936
2960
|
function buildStakeTx({ subdao: subdao2, amount }) {
|
|
2937
2961
|
const addr = normalise(subdao2, "subdao");
|
|
@@ -2943,12 +2967,21 @@ var require_subdao = __commonJS({
|
|
|
2943
2967
|
const data = SubDAOInterface.encodeFunctionData("unstake", [BigInt(amount)]);
|
|
2944
2968
|
return { to: addr, data, value: 0n };
|
|
2945
2969
|
}
|
|
2970
|
+
function buildSetProfileCidTx({ subdao: subdao2, profileCid }) {
|
|
2971
|
+
const addr = normalise(subdao2, "subdao");
|
|
2972
|
+
if (!profileCid || typeof profileCid !== "string" || !profileCid.trim()) {
|
|
2973
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "profileCid (CID string) required");
|
|
2974
|
+
}
|
|
2975
|
+
const data = SubDAOInterface.encodeFunctionData("setProfileCid", [String(profileCid)]);
|
|
2976
|
+
return { to: addr, data, value: 0n };
|
|
2977
|
+
}
|
|
2946
2978
|
module2.exports = {
|
|
2947
2979
|
discoverSubDAOs,
|
|
2948
2980
|
getSubDAOInfo,
|
|
2949
2981
|
getSubDAOUserStats,
|
|
2950
2982
|
buildStakeTx,
|
|
2951
|
-
buildUnstakeTx
|
|
2983
|
+
buildUnstakeTx,
|
|
2984
|
+
buildSetProfileCidTx
|
|
2952
2985
|
};
|
|
2953
2986
|
async function ensureSxxxBurnAllowance({ signer, sxxx, owner, spender, amount }) {
|
|
2954
2987
|
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var require_package = __commonJS({
|
|
|
20
20
|
"package.json"(exports2, module2) {
|
|
21
21
|
module2.exports = {
|
|
22
22
|
name: "@sage-protocol/sdk",
|
|
23
|
-
version: "0.1.
|
|
23
|
+
version: "0.1.16",
|
|
24
24
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
25
25
|
main: "dist/index.cjs",
|
|
26
26
|
module: "dist/index.mjs",
|
|
@@ -178,12 +178,13 @@ var require_abi = __commonJS({
|
|
|
178
178
|
"function maxCreationBurn() view returns (uint256)"
|
|
179
179
|
];
|
|
180
180
|
var LibraryRegistry = [
|
|
181
|
-
"function
|
|
182
|
-
"function
|
|
183
|
-
"function
|
|
184
|
-
"function
|
|
185
|
-
"function
|
|
186
|
-
"
|
|
181
|
+
"function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
|
|
182
|
+
"function daoTimelock(address) view returns (address)",
|
|
183
|
+
"function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
|
|
184
|
+
"function updateLibrary(address dao, string manifestCID, string version)",
|
|
185
|
+
"function registerDAO(address dao, address timelock)",
|
|
186
|
+
"event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
|
|
187
|
+
"event DAORegistered(address indexed dao, address indexed timelock)"
|
|
187
188
|
];
|
|
188
189
|
var PromptRegistry = [
|
|
189
190
|
"function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
|
|
@@ -1237,15 +1238,35 @@ var require_ipfs = __commonJS({
|
|
|
1237
1238
|
if (metadata) {
|
|
1238
1239
|
formData.append("pinataMetadata", JSON.stringify(metadata));
|
|
1239
1240
|
}
|
|
1240
|
-
const
|
|
1241
|
+
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1242
|
+
const sendWithAuthMode = async (mode) => {
|
|
1243
|
+
const headers = { ...formData.getHeaders() };
|
|
1244
|
+
if (mode === "jwt") {
|
|
1245
|
+
headers.Authorization = `Bearer ${config.pinata.jwt}`;
|
|
1246
|
+
} else {
|
|
1247
|
+
headers.pinata_api_key = config.pinata.apiKey;
|
|
1248
|
+
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1249
|
+
}
|
|
1250
|
+
return axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1251
|
+
};
|
|
1252
|
+
let response;
|
|
1253
|
+
let lastError;
|
|
1241
1254
|
if (config.pinata.jwt) {
|
|
1242
|
-
|
|
1255
|
+
try {
|
|
1256
|
+
response = await sendWithAuthMode("jwt");
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
lastError = error;
|
|
1259
|
+
const status = error?.response?.status;
|
|
1260
|
+
const reason = error?.response?.data?.error?.reason || "";
|
|
1261
|
+
const isInvalidJwt = status === 401 && typeof reason === "string" && reason.toUpperCase().includes("INVALID_CREDENTIALS");
|
|
1262
|
+
if (!config.pinata.apiKey || !config.pinata.secretKey || !isInvalidJwt) {
|
|
1263
|
+
throw error;
|
|
1264
|
+
}
|
|
1265
|
+
response = await sendWithAuthMode("keys");
|
|
1266
|
+
}
|
|
1243
1267
|
} else {
|
|
1244
|
-
|
|
1245
|
-
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1268
|
+
response = await sendWithAuthMode("keys");
|
|
1246
1269
|
}
|
|
1247
|
-
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1248
|
-
const response = await axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1249
1270
|
const cid = response?.data?.IpfsHash || response?.data?.cid || response?.data?.Hash;
|
|
1250
1271
|
if (!cid) {
|
|
1251
1272
|
throw new Error("Pinata upload did not return IpfsHash");
|
|
@@ -1881,7 +1902,7 @@ var require_validation = __commonJS({
|
|
|
1881
1902
|
schemaPath: null,
|
|
1882
1903
|
errors: [{ keyword: "schema", instancePath: "/", message: "manifest schema not found" }],
|
|
1883
1904
|
hints: [
|
|
1884
|
-
'Ensure docs/schemas/manifest.schema.json exists (run "sage
|
|
1905
|
+
'Ensure docs/schemas/manifest.schema.json exists (run "sage project scaffold" to regenerate)'
|
|
1885
1906
|
],
|
|
1886
1907
|
manifestPath
|
|
1887
1908
|
};
|
|
@@ -2022,93 +2043,95 @@ var require_library = __commonJS({
|
|
|
2022
2043
|
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
2023
2044
|
}
|
|
2024
2045
|
}
|
|
2025
|
-
async function listManifests({ provider, registry, offset = 0, limit = 50 }) {
|
|
2046
|
+
async function listManifests({ provider, registry, factoryAddress, offset = 0, limit = 50 }) {
|
|
2026
2047
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2027
|
-
|
|
2028
|
-
const
|
|
2029
|
-
const
|
|
2048
|
+
if (!factoryAddress) throw new SageSDKError(CODES.INVALID_ARGS, "factoryAddress required for V4 listing");
|
|
2049
|
+
const factory = new Contract(factoryAddress, ABI.FactoryRead, provider);
|
|
2050
|
+
const totalSubDAOs = await factory.getSubDAOCount();
|
|
2030
2051
|
const manifests = [];
|
|
2031
|
-
|
|
2032
|
-
|
|
2052
|
+
const start = Number(offset);
|
|
2053
|
+
const end = Math.min(start + Number(limit), Number(totalSubDAOs));
|
|
2054
|
+
for (let i = start; i < end; i++) {
|
|
2055
|
+
const subdao = await factory.subDaos(i);
|
|
2056
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2057
|
+
if (info && info.manifestCID) {
|
|
2058
|
+
manifests.push(info);
|
|
2059
|
+
}
|
|
2033
2060
|
}
|
|
2034
|
-
return { total: BigInt(
|
|
2061
|
+
return { total: BigInt(totalSubDAOs), manifests };
|
|
2035
2062
|
}
|
|
2036
|
-
async function
|
|
2063
|
+
async function getLibraryInfo({ provider, registry, subdao }) {
|
|
2037
2064
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2038
|
-
if (!
|
|
2065
|
+
if (!subdao) throw new SageSDKError(CODES.INVALID_ARGS, "subdao required");
|
|
2039
2066
|
const addr = normalise(registry, "registry");
|
|
2067
|
+
const dao = normalise(subdao, "subdao");
|
|
2040
2068
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2041
|
-
const
|
|
2069
|
+
const info = await contract.getLibrary(dao);
|
|
2042
2070
|
return {
|
|
2043
|
-
manifestCID,
|
|
2044
|
-
previousCID,
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2071
|
+
manifestCID: info.manifestCID,
|
|
2072
|
+
previousCID: "",
|
|
2073
|
+
// Not tracked on-chain in V4 (history is in events/subgraph)
|
|
2074
|
+
timestamp: BigInt(info.lastUpdated.toString()),
|
|
2075
|
+
proposer: getAddress(info.lastUpdater),
|
|
2076
|
+
promptCount: 0,
|
|
2077
|
+
// Not tracked on-chain in V4
|
|
2078
|
+
version: info.version
|
|
2048
2079
|
};
|
|
2049
2080
|
}
|
|
2081
|
+
async function getManifestInfo({ provider, registry, manifestCID }) {
|
|
2082
|
+
throw new SageSDKError(CODES.UNSUPPORTED_OPERATION, "getManifestInfo(cid) is not supported in V4. Use getLibraryInfo(subdao).");
|
|
2083
|
+
}
|
|
2050
2084
|
function _computeLibraryKey(subdao, libraryId) {
|
|
2051
|
-
|
|
2052
|
-
const encoded = coder.encode(["address", "string"], [getAddress(subdao), String(libraryId)]);
|
|
2053
|
-
return keccak256(encoded);
|
|
2085
|
+
return getAddress(subdao);
|
|
2054
2086
|
}
|
|
2055
|
-
async function getLatestLibrary({ provider, registry, subdao
|
|
2056
|
-
|
|
2057
|
-
const addr = normalise(registry, "registry");
|
|
2058
|
-
const sub = normalise(subdao, "subdao");
|
|
2059
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2060
|
-
const key = _computeLibraryKey(sub, libraryId);
|
|
2061
|
-
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
2062
|
-
if (!latestCID || latestCID.length === 0) return null;
|
|
2063
|
-
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
2064
|
-
return info;
|
|
2087
|
+
async function getLatestLibrary({ provider, registry, subdao }) {
|
|
2088
|
+
return getLibraryInfo({ provider, registry, subdao });
|
|
2065
2089
|
}
|
|
2066
|
-
async function getBeforeAfterForUpdate({ provider, registry, subdao,
|
|
2090
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao, newCid }) {
|
|
2067
2091
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2092
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2093
|
+
return {
|
|
2094
|
+
previousCID: info ? info.manifestCID : null,
|
|
2095
|
+
newCID: String(newCid),
|
|
2096
|
+
version: info ? info.version : "0.0.0"
|
|
2097
|
+
};
|
|
2074
2098
|
}
|
|
2075
2099
|
async function hasScopedOwnership({ provider, registry, subdao, manifestCID }) {
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
const sub = normalise(subdao, "subdao");
|
|
2079
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2080
|
-
return contract.hasScopedOwnership(sub, manifestCID);
|
|
2100
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2101
|
+
return info && info.manifestCID === manifestCID;
|
|
2081
2102
|
}
|
|
2082
|
-
function
|
|
2103
|
+
function buildUpdateLibraryTx({ registry, subdao, manifestCID, version = "1.0.0" }) {
|
|
2083
2104
|
const to = normalise(registry, "registry");
|
|
2084
2105
|
if (!manifestCID) throw new SageSDKError(CODES.INVALID_ARGS, "manifestCID required");
|
|
2085
|
-
const iface = new Interface(["function
|
|
2086
|
-
const data = iface.encodeFunctionData("
|
|
2106
|
+
const iface = new Interface(["function updateLibrary(address,string,string)"]);
|
|
2107
|
+
const data = iface.encodeFunctionData("updateLibrary", [
|
|
2087
2108
|
normalise(subdao, "subdao"),
|
|
2088
|
-
String(libraryId || "main"),
|
|
2089
2109
|
String(manifestCID),
|
|
2090
|
-
|
|
2110
|
+
String(version)
|
|
2091
2111
|
]);
|
|
2092
2112
|
return { to, data, value: 0n };
|
|
2093
2113
|
}
|
|
2114
|
+
var buildUpdateLibraryForSubDAOTx = buildUpdateLibraryTx;
|
|
2094
2115
|
module2.exports = {
|
|
2095
2116
|
listManifests,
|
|
2096
2117
|
getManifestInfo,
|
|
2118
|
+
getLibraryInfo,
|
|
2097
2119
|
getLatestLibrary,
|
|
2098
2120
|
hasScopedOwnership,
|
|
2121
|
+
buildUpdateLibraryTx,
|
|
2099
2122
|
buildUpdateLibraryForSubDAOTx,
|
|
2100
2123
|
_computeLibraryKey,
|
|
2101
2124
|
getBeforeAfterForUpdate,
|
|
2102
2125
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
2103
2126
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock, subdao }) {
|
|
2104
2127
|
const to = normalise(registry, "registry");
|
|
2105
|
-
const iface = new Interface(["function
|
|
2106
|
-
const data = iface.encodeFunctionData("
|
|
2128
|
+
const iface = new Interface(["function registerDAO(address,address)"]);
|
|
2129
|
+
const data = iface.encodeFunctionData("registerDAO", [normalise(subdao, "subdao"), normalise(timelock, "timelock")]);
|
|
2107
2130
|
return { to, data, value: 0n };
|
|
2108
2131
|
},
|
|
2109
2132
|
searchRegistry,
|
|
2110
2133
|
validation,
|
|
2111
|
-
/** Simulate
|
|
2134
|
+
/** Simulate as timelock */
|
|
2112
2135
|
simulateAsTimelock: async function simulateAsTimelock({ provider, registry, to, data, timelock }) {
|
|
2113
2136
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2114
2137
|
const reg = normalise(registry, "registry");
|
|
@@ -2121,10 +2144,9 @@ var require_library = __commonJS({
|
|
|
2121
2144
|
return { ok: false, error: { type: "Revert", message: String(err && err.message || err) } };
|
|
2122
2145
|
}
|
|
2123
2146
|
},
|
|
2124
|
-
|
|
2125
|
-
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, libraryId = "main", manifestCID = "", promptCount = 0 }) {
|
|
2147
|
+
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, manifestCID = "", version = "1.0.0" }) {
|
|
2126
2148
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2127
|
-
const payload =
|
|
2149
|
+
const payload = buildUpdateLibraryTx({ registry, subdao, manifestCID, version });
|
|
2128
2150
|
const sim = await this.simulateAsTimelock({ provider, registry, to: payload.to, data: payload.data, timelock });
|
|
2129
2151
|
const out = { ok: !!sim.ok, error: sim.ok ? null : sim.error?.message || "revert", missingRole: null };
|
|
2130
2152
|
return out;
|
|
@@ -2937,7 +2959,9 @@ var require_subdao = __commonJS({
|
|
|
2937
2959
|
}
|
|
2938
2960
|
var SubDAOInterface = new Interface([
|
|
2939
2961
|
"function stake(uint256)",
|
|
2940
|
-
"function unstake(uint256)"
|
|
2962
|
+
"function unstake(uint256)",
|
|
2963
|
+
// Optional on newer SubDAO implementations; provided for tx building only.
|
|
2964
|
+
"function setProfileCid(string)"
|
|
2941
2965
|
]);
|
|
2942
2966
|
function buildStakeTx({ subdao, amount }) {
|
|
2943
2967
|
const addr = normalise(subdao, "subdao");
|
|
@@ -2949,12 +2973,21 @@ var require_subdao = __commonJS({
|
|
|
2949
2973
|
const data = SubDAOInterface.encodeFunctionData("unstake", [BigInt(amount)]);
|
|
2950
2974
|
return { to: addr, data, value: 0n };
|
|
2951
2975
|
}
|
|
2976
|
+
function buildSetProfileCidTx({ subdao, profileCid }) {
|
|
2977
|
+
const addr = normalise(subdao, "subdao");
|
|
2978
|
+
if (!profileCid || typeof profileCid !== "string" || !profileCid.trim()) {
|
|
2979
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "profileCid (CID string) required");
|
|
2980
|
+
}
|
|
2981
|
+
const data = SubDAOInterface.encodeFunctionData("setProfileCid", [String(profileCid)]);
|
|
2982
|
+
return { to: addr, data, value: 0n };
|
|
2983
|
+
}
|
|
2952
2984
|
module2.exports = {
|
|
2953
2985
|
discoverSubDAOs,
|
|
2954
2986
|
getSubDAOInfo,
|
|
2955
2987
|
getSubDAOUserStats,
|
|
2956
2988
|
buildStakeTx,
|
|
2957
|
-
buildUnstakeTx
|
|
2989
|
+
buildUnstakeTx,
|
|
2990
|
+
buildSetProfileCidTx
|
|
2958
2991
|
};
|
|
2959
2992
|
async function ensureSxxxBurnAllowance({ signer, sxxx, owner, spender, amount }) {
|
|
2960
2993
|
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
package/dist/node/index.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports2, module2) {
|
|
15
15
|
module2.exports = {
|
|
16
16
|
name: "@sage-protocol/sdk",
|
|
17
|
-
version: "0.1.
|
|
17
|
+
version: "0.1.16",
|
|
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",
|
|
@@ -172,12 +172,13 @@ var require_abi = __commonJS({
|
|
|
172
172
|
"function maxCreationBurn() view returns (uint256)"
|
|
173
173
|
];
|
|
174
174
|
var LibraryRegistry = [
|
|
175
|
-
"function
|
|
176
|
-
"function
|
|
177
|
-
"function
|
|
178
|
-
"function
|
|
179
|
-
"function
|
|
180
|
-
"
|
|
175
|
+
"function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
|
|
176
|
+
"function daoTimelock(address) view returns (address)",
|
|
177
|
+
"function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
|
|
178
|
+
"function updateLibrary(address dao, string manifestCID, string version)",
|
|
179
|
+
"function registerDAO(address dao, address timelock)",
|
|
180
|
+
"event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
|
|
181
|
+
"event DAORegistered(address indexed dao, address indexed timelock)"
|
|
181
182
|
];
|
|
182
183
|
var PromptRegistry = [
|
|
183
184
|
"function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
|
|
@@ -1231,15 +1232,35 @@ var require_ipfs = __commonJS({
|
|
|
1231
1232
|
if (metadata) {
|
|
1232
1233
|
formData.append("pinataMetadata", JSON.stringify(metadata));
|
|
1233
1234
|
}
|
|
1234
|
-
const
|
|
1235
|
+
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1236
|
+
const sendWithAuthMode = async (mode) => {
|
|
1237
|
+
const headers = { ...formData.getHeaders() };
|
|
1238
|
+
if (mode === "jwt") {
|
|
1239
|
+
headers.Authorization = `Bearer ${config.pinata.jwt}`;
|
|
1240
|
+
} else {
|
|
1241
|
+
headers.pinata_api_key = config.pinata.apiKey;
|
|
1242
|
+
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1243
|
+
}
|
|
1244
|
+
return axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1245
|
+
};
|
|
1246
|
+
let response;
|
|
1247
|
+
let lastError;
|
|
1235
1248
|
if (config.pinata.jwt) {
|
|
1236
|
-
|
|
1249
|
+
try {
|
|
1250
|
+
response = await sendWithAuthMode("jwt");
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
lastError = error;
|
|
1253
|
+
const status = error?.response?.status;
|
|
1254
|
+
const reason = error?.response?.data?.error?.reason || "";
|
|
1255
|
+
const isInvalidJwt = status === 401 && typeof reason === "string" && reason.toUpperCase().includes("INVALID_CREDENTIALS");
|
|
1256
|
+
if (!config.pinata.apiKey || !config.pinata.secretKey || !isInvalidJwt) {
|
|
1257
|
+
throw error;
|
|
1258
|
+
}
|
|
1259
|
+
response = await sendWithAuthMode("keys");
|
|
1260
|
+
}
|
|
1237
1261
|
} else {
|
|
1238
|
-
|
|
1239
|
-
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1262
|
+
response = await sendWithAuthMode("keys");
|
|
1240
1263
|
}
|
|
1241
|
-
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1242
|
-
const response = await axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1243
1264
|
const cid = response?.data?.IpfsHash || response?.data?.cid || response?.data?.Hash;
|
|
1244
1265
|
if (!cid) {
|
|
1245
1266
|
throw new Error("Pinata upload did not return IpfsHash");
|
|
@@ -1875,7 +1896,7 @@ var require_validation = __commonJS({
|
|
|
1875
1896
|
schemaPath: null,
|
|
1876
1897
|
errors: [{ keyword: "schema", instancePath: "/", message: "manifest schema not found" }],
|
|
1877
1898
|
hints: [
|
|
1878
|
-
'Ensure docs/schemas/manifest.schema.json exists (run "sage
|
|
1899
|
+
'Ensure docs/schemas/manifest.schema.json exists (run "sage project scaffold" to regenerate)'
|
|
1879
1900
|
],
|
|
1880
1901
|
manifestPath
|
|
1881
1902
|
};
|
|
@@ -2016,93 +2037,95 @@ var require_library = __commonJS({
|
|
|
2016
2037
|
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
2017
2038
|
}
|
|
2018
2039
|
}
|
|
2019
|
-
async function listManifests({ provider, registry, offset = 0, limit = 50 }) {
|
|
2040
|
+
async function listManifests({ provider, registry, factoryAddress, offset = 0, limit = 50 }) {
|
|
2020
2041
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2021
|
-
|
|
2022
|
-
const
|
|
2023
|
-
const
|
|
2042
|
+
if (!factoryAddress) throw new SageSDKError(CODES.INVALID_ARGS, "factoryAddress required for V4 listing");
|
|
2043
|
+
const factory = new Contract(factoryAddress, ABI.FactoryRead, provider);
|
|
2044
|
+
const totalSubDAOs = await factory.getSubDAOCount();
|
|
2024
2045
|
const manifests = [];
|
|
2025
|
-
|
|
2026
|
-
|
|
2046
|
+
const start = Number(offset);
|
|
2047
|
+
const end = Math.min(start + Number(limit), Number(totalSubDAOs));
|
|
2048
|
+
for (let i = start; i < end; i++) {
|
|
2049
|
+
const subdao = await factory.subDaos(i);
|
|
2050
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2051
|
+
if (info && info.manifestCID) {
|
|
2052
|
+
manifests.push(info);
|
|
2053
|
+
}
|
|
2027
2054
|
}
|
|
2028
|
-
return { total: BigInt(
|
|
2055
|
+
return { total: BigInt(totalSubDAOs), manifests };
|
|
2029
2056
|
}
|
|
2030
|
-
async function
|
|
2057
|
+
async function getLibraryInfo({ provider, registry, subdao }) {
|
|
2031
2058
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2032
|
-
if (!
|
|
2059
|
+
if (!subdao) throw new SageSDKError(CODES.INVALID_ARGS, "subdao required");
|
|
2033
2060
|
const addr = normalise(registry, "registry");
|
|
2061
|
+
const dao = normalise(subdao, "subdao");
|
|
2034
2062
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2035
|
-
const
|
|
2063
|
+
const info = await contract.getLibrary(dao);
|
|
2036
2064
|
return {
|
|
2037
|
-
manifestCID,
|
|
2038
|
-
previousCID,
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2065
|
+
manifestCID: info.manifestCID,
|
|
2066
|
+
previousCID: "",
|
|
2067
|
+
// Not tracked on-chain in V4 (history is in events/subgraph)
|
|
2068
|
+
timestamp: BigInt(info.lastUpdated.toString()),
|
|
2069
|
+
proposer: getAddress(info.lastUpdater),
|
|
2070
|
+
promptCount: 0,
|
|
2071
|
+
// Not tracked on-chain in V4
|
|
2072
|
+
version: info.version
|
|
2042
2073
|
};
|
|
2043
2074
|
}
|
|
2075
|
+
async function getManifestInfo({ provider, registry, manifestCID }) {
|
|
2076
|
+
throw new SageSDKError(CODES.UNSUPPORTED_OPERATION, "getManifestInfo(cid) is not supported in V4. Use getLibraryInfo(subdao).");
|
|
2077
|
+
}
|
|
2044
2078
|
function _computeLibraryKey(subdao, libraryId) {
|
|
2045
|
-
|
|
2046
|
-
const encoded = coder.encode(["address", "string"], [getAddress(subdao), String(libraryId)]);
|
|
2047
|
-
return keccak256(encoded);
|
|
2079
|
+
return getAddress(subdao);
|
|
2048
2080
|
}
|
|
2049
|
-
async function getLatestLibrary({ provider, registry, subdao
|
|
2050
|
-
|
|
2051
|
-
const addr = normalise(registry, "registry");
|
|
2052
|
-
const sub = normalise(subdao, "subdao");
|
|
2053
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2054
|
-
const key = _computeLibraryKey(sub, libraryId);
|
|
2055
|
-
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
2056
|
-
if (!latestCID || latestCID.length === 0) return null;
|
|
2057
|
-
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
2058
|
-
return info;
|
|
2081
|
+
async function getLatestLibrary({ provider, registry, subdao }) {
|
|
2082
|
+
return getLibraryInfo({ provider, registry, subdao });
|
|
2059
2083
|
}
|
|
2060
|
-
async function getBeforeAfterForUpdate({ provider, registry, subdao,
|
|
2084
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao, newCid }) {
|
|
2061
2085
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2062
|
-
const
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2086
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2087
|
+
return {
|
|
2088
|
+
previousCID: info ? info.manifestCID : null,
|
|
2089
|
+
newCID: String(newCid),
|
|
2090
|
+
version: info ? info.version : "0.0.0"
|
|
2091
|
+
};
|
|
2068
2092
|
}
|
|
2069
2093
|
async function hasScopedOwnership({ provider, registry, subdao, manifestCID }) {
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
const sub = normalise(subdao, "subdao");
|
|
2073
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2074
|
-
return contract.hasScopedOwnership(sub, manifestCID);
|
|
2094
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2095
|
+
return info && info.manifestCID === manifestCID;
|
|
2075
2096
|
}
|
|
2076
|
-
function
|
|
2097
|
+
function buildUpdateLibraryTx({ registry, subdao, manifestCID, version = "1.0.0" }) {
|
|
2077
2098
|
const to = normalise(registry, "registry");
|
|
2078
2099
|
if (!manifestCID) throw new SageSDKError(CODES.INVALID_ARGS, "manifestCID required");
|
|
2079
|
-
const iface = new Interface(["function
|
|
2080
|
-
const data = iface.encodeFunctionData("
|
|
2100
|
+
const iface = new Interface(["function updateLibrary(address,string,string)"]);
|
|
2101
|
+
const data = iface.encodeFunctionData("updateLibrary", [
|
|
2081
2102
|
normalise(subdao, "subdao"),
|
|
2082
|
-
String(libraryId || "main"),
|
|
2083
2103
|
String(manifestCID),
|
|
2084
|
-
|
|
2104
|
+
String(version)
|
|
2085
2105
|
]);
|
|
2086
2106
|
return { to, data, value: 0n };
|
|
2087
2107
|
}
|
|
2108
|
+
var buildUpdateLibraryForSubDAOTx = buildUpdateLibraryTx;
|
|
2088
2109
|
module2.exports = {
|
|
2089
2110
|
listManifests,
|
|
2090
2111
|
getManifestInfo,
|
|
2112
|
+
getLibraryInfo,
|
|
2091
2113
|
getLatestLibrary,
|
|
2092
2114
|
hasScopedOwnership,
|
|
2115
|
+
buildUpdateLibraryTx,
|
|
2093
2116
|
buildUpdateLibraryForSubDAOTx,
|
|
2094
2117
|
_computeLibraryKey,
|
|
2095
2118
|
getBeforeAfterForUpdate,
|
|
2096
2119
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
2097
2120
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock, subdao }) {
|
|
2098
2121
|
const to = normalise(registry, "registry");
|
|
2099
|
-
const iface = new Interface(["function
|
|
2100
|
-
const data = iface.encodeFunctionData("
|
|
2122
|
+
const iface = new Interface(["function registerDAO(address,address)"]);
|
|
2123
|
+
const data = iface.encodeFunctionData("registerDAO", [normalise(subdao, "subdao"), normalise(timelock, "timelock")]);
|
|
2101
2124
|
return { to, data, value: 0n };
|
|
2102
2125
|
},
|
|
2103
2126
|
searchRegistry,
|
|
2104
2127
|
validation,
|
|
2105
|
-
/** Simulate
|
|
2128
|
+
/** Simulate as timelock */
|
|
2106
2129
|
simulateAsTimelock: async function simulateAsTimelock({ provider, registry, to, data, timelock }) {
|
|
2107
2130
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2108
2131
|
const reg = normalise(registry, "registry");
|
|
@@ -2115,10 +2138,9 @@ var require_library = __commonJS({
|
|
|
2115
2138
|
return { ok: false, error: { type: "Revert", message: String(err && err.message || err) } };
|
|
2116
2139
|
}
|
|
2117
2140
|
},
|
|
2118
|
-
|
|
2119
|
-
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, libraryId = "main", manifestCID = "", promptCount = 0 }) {
|
|
2141
|
+
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, manifestCID = "", version = "1.0.0" }) {
|
|
2120
2142
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2121
|
-
const payload =
|
|
2143
|
+
const payload = buildUpdateLibraryTx({ registry, subdao, manifestCID, version });
|
|
2122
2144
|
const sim = await this.simulateAsTimelock({ provider, registry, to: payload.to, data: payload.data, timelock });
|
|
2123
2145
|
const out = { ok: !!sim.ok, error: sim.ok ? null : sim.error?.message || "revert", missingRole: null };
|
|
2124
2146
|
return out;
|
|
@@ -2931,7 +2953,9 @@ var require_subdao = __commonJS({
|
|
|
2931
2953
|
}
|
|
2932
2954
|
var SubDAOInterface = new Interface([
|
|
2933
2955
|
"function stake(uint256)",
|
|
2934
|
-
"function unstake(uint256)"
|
|
2956
|
+
"function unstake(uint256)",
|
|
2957
|
+
// Optional on newer SubDAO implementations; provided for tx building only.
|
|
2958
|
+
"function setProfileCid(string)"
|
|
2935
2959
|
]);
|
|
2936
2960
|
function buildStakeTx({ subdao, amount }) {
|
|
2937
2961
|
const addr = normalise(subdao, "subdao");
|
|
@@ -2943,12 +2967,21 @@ var require_subdao = __commonJS({
|
|
|
2943
2967
|
const data = SubDAOInterface.encodeFunctionData("unstake", [BigInt(amount)]);
|
|
2944
2968
|
return { to: addr, data, value: 0n };
|
|
2945
2969
|
}
|
|
2970
|
+
function buildSetProfileCidTx({ subdao, profileCid }) {
|
|
2971
|
+
const addr = normalise(subdao, "subdao");
|
|
2972
|
+
if (!profileCid || typeof profileCid !== "string" || !profileCid.trim()) {
|
|
2973
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "profileCid (CID string) required");
|
|
2974
|
+
}
|
|
2975
|
+
const data = SubDAOInterface.encodeFunctionData("setProfileCid", [String(profileCid)]);
|
|
2976
|
+
return { to: addr, data, value: 0n };
|
|
2977
|
+
}
|
|
2946
2978
|
module2.exports = {
|
|
2947
2979
|
discoverSubDAOs,
|
|
2948
2980
|
getSubDAOInfo,
|
|
2949
2981
|
getSubDAOUserStats,
|
|
2950
2982
|
buildStakeTx,
|
|
2951
|
-
buildUnstakeTx
|
|
2983
|
+
buildUnstakeTx,
|
|
2984
|
+
buildSetProfileCidTx
|
|
2952
2985
|
};
|
|
2953
2986
|
async function ensureSxxxBurnAllowance({ signer, sxxx, owner, spender, amount }) {
|
|
2954
2987
|
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
package/dist/node/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var require_package = __commonJS({
|
|
|
20
20
|
"package.json"(exports2, module2) {
|
|
21
21
|
module2.exports = {
|
|
22
22
|
name: "@sage-protocol/sdk",
|
|
23
|
-
version: "0.1.
|
|
23
|
+
version: "0.1.16",
|
|
24
24
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
25
25
|
main: "dist/index.cjs",
|
|
26
26
|
module: "dist/index.mjs",
|
|
@@ -178,12 +178,13 @@ var require_abi = __commonJS({
|
|
|
178
178
|
"function maxCreationBurn() view returns (uint256)"
|
|
179
179
|
];
|
|
180
180
|
var LibraryRegistry = [
|
|
181
|
-
"function
|
|
182
|
-
"function
|
|
183
|
-
"function
|
|
184
|
-
"function
|
|
185
|
-
"function
|
|
186
|
-
"
|
|
181
|
+
"function libraryByDAO(address) view returns (string manifestCID, address lastUpdater, uint256 lastUpdated, string version)",
|
|
182
|
+
"function daoTimelock(address) view returns (address)",
|
|
183
|
+
"function getLibrary(address) view returns (tuple(string manifestCID, address lastUpdater, uint256 lastUpdated, string version))",
|
|
184
|
+
"function updateLibrary(address dao, string manifestCID, string version)",
|
|
185
|
+
"function registerDAO(address dao, address timelock)",
|
|
186
|
+
"event LibraryUpdated(address indexed dao, string manifestCID, address indexed timelock, string version)",
|
|
187
|
+
"event DAORegistered(address indexed dao, address indexed timelock)"
|
|
187
188
|
];
|
|
188
189
|
var PromptRegistry = [
|
|
189
190
|
"function prompts(string key) view returns (string cid, uint256 version, uint256 timestamp, address author, string forkedFromCID, address originalAuthor, bool isFork, uint256 forkDepth)",
|
|
@@ -1237,15 +1238,35 @@ var require_ipfs = __commonJS({
|
|
|
1237
1238
|
if (metadata) {
|
|
1238
1239
|
formData.append("pinataMetadata", JSON.stringify(metadata));
|
|
1239
1240
|
}
|
|
1240
|
-
const
|
|
1241
|
+
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1242
|
+
const sendWithAuthMode = async (mode) => {
|
|
1243
|
+
const headers = { ...formData.getHeaders() };
|
|
1244
|
+
if (mode === "jwt") {
|
|
1245
|
+
headers.Authorization = `Bearer ${config.pinata.jwt}`;
|
|
1246
|
+
} else {
|
|
1247
|
+
headers.pinata_api_key = config.pinata.apiKey;
|
|
1248
|
+
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1249
|
+
}
|
|
1250
|
+
return axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1251
|
+
};
|
|
1252
|
+
let response;
|
|
1253
|
+
let lastError;
|
|
1241
1254
|
if (config.pinata.jwt) {
|
|
1242
|
-
|
|
1255
|
+
try {
|
|
1256
|
+
response = await sendWithAuthMode("jwt");
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
lastError = error;
|
|
1259
|
+
const status = error?.response?.status;
|
|
1260
|
+
const reason = error?.response?.data?.error?.reason || "";
|
|
1261
|
+
const isInvalidJwt = status === 401 && typeof reason === "string" && reason.toUpperCase().includes("INVALID_CREDENTIALS");
|
|
1262
|
+
if (!config.pinata.apiKey || !config.pinata.secretKey || !isInvalidJwt) {
|
|
1263
|
+
throw error;
|
|
1264
|
+
}
|
|
1265
|
+
response = await sendWithAuthMode("keys");
|
|
1266
|
+
}
|
|
1243
1267
|
} else {
|
|
1244
|
-
|
|
1245
|
-
headers.pinata_secret_api_key = config.pinata.secretKey;
|
|
1268
|
+
response = await sendWithAuthMode("keys");
|
|
1246
1269
|
}
|
|
1247
|
-
const endpoint = `${config.pinata.apiUrl}/pinning/pinFileToIPFS`;
|
|
1248
|
-
const response = await axiosInstance.post(endpoint, formData, { headers, timeout: config.timeoutMs });
|
|
1249
1270
|
const cid = response?.data?.IpfsHash || response?.data?.cid || response?.data?.Hash;
|
|
1250
1271
|
if (!cid) {
|
|
1251
1272
|
throw new Error("Pinata upload did not return IpfsHash");
|
|
@@ -1881,7 +1902,7 @@ var require_validation = __commonJS({
|
|
|
1881
1902
|
schemaPath: null,
|
|
1882
1903
|
errors: [{ keyword: "schema", instancePath: "/", message: "manifest schema not found" }],
|
|
1883
1904
|
hints: [
|
|
1884
|
-
'Ensure docs/schemas/manifest.schema.json exists (run "sage
|
|
1905
|
+
'Ensure docs/schemas/manifest.schema.json exists (run "sage project scaffold" to regenerate)'
|
|
1885
1906
|
],
|
|
1886
1907
|
manifestPath
|
|
1887
1908
|
};
|
|
@@ -2022,93 +2043,95 @@ var require_library = __commonJS({
|
|
|
2022
2043
|
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
2023
2044
|
}
|
|
2024
2045
|
}
|
|
2025
|
-
async function listManifests({ provider, registry, offset = 0, limit = 50 }) {
|
|
2046
|
+
async function listManifests({ provider, registry, factoryAddress, offset = 0, limit = 50 }) {
|
|
2026
2047
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2027
|
-
|
|
2028
|
-
const
|
|
2029
|
-
const
|
|
2048
|
+
if (!factoryAddress) throw new SageSDKError(CODES.INVALID_ARGS, "factoryAddress required for V4 listing");
|
|
2049
|
+
const factory = new Contract(factoryAddress, ABI.FactoryRead, provider);
|
|
2050
|
+
const totalSubDAOs = await factory.getSubDAOCount();
|
|
2030
2051
|
const manifests = [];
|
|
2031
|
-
|
|
2032
|
-
|
|
2052
|
+
const start = Number(offset);
|
|
2053
|
+
const end = Math.min(start + Number(limit), Number(totalSubDAOs));
|
|
2054
|
+
for (let i = start; i < end; i++) {
|
|
2055
|
+
const subdao = await factory.subDaos(i);
|
|
2056
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2057
|
+
if (info && info.manifestCID) {
|
|
2058
|
+
manifests.push(info);
|
|
2059
|
+
}
|
|
2033
2060
|
}
|
|
2034
|
-
return { total: BigInt(
|
|
2061
|
+
return { total: BigInt(totalSubDAOs), manifests };
|
|
2035
2062
|
}
|
|
2036
|
-
async function
|
|
2063
|
+
async function getLibraryInfo({ provider, registry, subdao }) {
|
|
2037
2064
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2038
|
-
if (!
|
|
2065
|
+
if (!subdao) throw new SageSDKError(CODES.INVALID_ARGS, "subdao required");
|
|
2039
2066
|
const addr = normalise(registry, "registry");
|
|
2067
|
+
const dao = normalise(subdao, "subdao");
|
|
2040
2068
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2041
|
-
const
|
|
2069
|
+
const info = await contract.getLibrary(dao);
|
|
2042
2070
|
return {
|
|
2043
|
-
manifestCID,
|
|
2044
|
-
previousCID,
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2071
|
+
manifestCID: info.manifestCID,
|
|
2072
|
+
previousCID: "",
|
|
2073
|
+
// Not tracked on-chain in V4 (history is in events/subgraph)
|
|
2074
|
+
timestamp: BigInt(info.lastUpdated.toString()),
|
|
2075
|
+
proposer: getAddress(info.lastUpdater),
|
|
2076
|
+
promptCount: 0,
|
|
2077
|
+
// Not tracked on-chain in V4
|
|
2078
|
+
version: info.version
|
|
2048
2079
|
};
|
|
2049
2080
|
}
|
|
2081
|
+
async function getManifestInfo({ provider, registry, manifestCID }) {
|
|
2082
|
+
throw new SageSDKError(CODES.UNSUPPORTED_OPERATION, "getManifestInfo(cid) is not supported in V4. Use getLibraryInfo(subdao).");
|
|
2083
|
+
}
|
|
2050
2084
|
function _computeLibraryKey(subdao, libraryId) {
|
|
2051
|
-
|
|
2052
|
-
const encoded = coder.encode(["address", "string"], [getAddress(subdao), String(libraryId)]);
|
|
2053
|
-
return keccak256(encoded);
|
|
2085
|
+
return getAddress(subdao);
|
|
2054
2086
|
}
|
|
2055
|
-
async function getLatestLibrary({ provider, registry, subdao
|
|
2056
|
-
|
|
2057
|
-
const addr = normalise(registry, "registry");
|
|
2058
|
-
const sub = normalise(subdao, "subdao");
|
|
2059
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2060
|
-
const key = _computeLibraryKey(sub, libraryId);
|
|
2061
|
-
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
2062
|
-
if (!latestCID || latestCID.length === 0) return null;
|
|
2063
|
-
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
2064
|
-
return info;
|
|
2087
|
+
async function getLatestLibrary({ provider, registry, subdao }) {
|
|
2088
|
+
return getLibraryInfo({ provider, registry, subdao });
|
|
2065
2089
|
}
|
|
2066
|
-
async function getBeforeAfterForUpdate({ provider, registry, subdao,
|
|
2090
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao, newCid }) {
|
|
2067
2091
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2092
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2093
|
+
return {
|
|
2094
|
+
previousCID: info ? info.manifestCID : null,
|
|
2095
|
+
newCID: String(newCid),
|
|
2096
|
+
version: info ? info.version : "0.0.0"
|
|
2097
|
+
};
|
|
2074
2098
|
}
|
|
2075
2099
|
async function hasScopedOwnership({ provider, registry, subdao, manifestCID }) {
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
const sub = normalise(subdao, "subdao");
|
|
2079
|
-
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
2080
|
-
return contract.hasScopedOwnership(sub, manifestCID);
|
|
2100
|
+
const info = await getLatestLibrary({ provider, registry, subdao });
|
|
2101
|
+
return info && info.manifestCID === manifestCID;
|
|
2081
2102
|
}
|
|
2082
|
-
function
|
|
2103
|
+
function buildUpdateLibraryTx({ registry, subdao, manifestCID, version = "1.0.0" }) {
|
|
2083
2104
|
const to = normalise(registry, "registry");
|
|
2084
2105
|
if (!manifestCID) throw new SageSDKError(CODES.INVALID_ARGS, "manifestCID required");
|
|
2085
|
-
const iface = new Interface(["function
|
|
2086
|
-
const data = iface.encodeFunctionData("
|
|
2106
|
+
const iface = new Interface(["function updateLibrary(address,string,string)"]);
|
|
2107
|
+
const data = iface.encodeFunctionData("updateLibrary", [
|
|
2087
2108
|
normalise(subdao, "subdao"),
|
|
2088
|
-
String(libraryId || "main"),
|
|
2089
2109
|
String(manifestCID),
|
|
2090
|
-
|
|
2110
|
+
String(version)
|
|
2091
2111
|
]);
|
|
2092
2112
|
return { to, data, value: 0n };
|
|
2093
2113
|
}
|
|
2114
|
+
var buildUpdateLibraryForSubDAOTx = buildUpdateLibraryTx;
|
|
2094
2115
|
module2.exports = {
|
|
2095
2116
|
listManifests,
|
|
2096
2117
|
getManifestInfo,
|
|
2118
|
+
getLibraryInfo,
|
|
2097
2119
|
getLatestLibrary,
|
|
2098
2120
|
hasScopedOwnership,
|
|
2121
|
+
buildUpdateLibraryTx,
|
|
2099
2122
|
buildUpdateLibraryForSubDAOTx,
|
|
2100
2123
|
_computeLibraryKey,
|
|
2101
2124
|
getBeforeAfterForUpdate,
|
|
2102
2125
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
2103
2126
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock, subdao }) {
|
|
2104
2127
|
const to = normalise(registry, "registry");
|
|
2105
|
-
const iface = new Interface(["function
|
|
2106
|
-
const data = iface.encodeFunctionData("
|
|
2128
|
+
const iface = new Interface(["function registerDAO(address,address)"]);
|
|
2129
|
+
const data = iface.encodeFunctionData("registerDAO", [normalise(subdao, "subdao"), normalise(timelock, "timelock")]);
|
|
2107
2130
|
return { to, data, value: 0n };
|
|
2108
2131
|
},
|
|
2109
2132
|
searchRegistry,
|
|
2110
2133
|
validation,
|
|
2111
|
-
/** Simulate
|
|
2134
|
+
/** Simulate as timelock */
|
|
2112
2135
|
simulateAsTimelock: async function simulateAsTimelock({ provider, registry, to, data, timelock }) {
|
|
2113
2136
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2114
2137
|
const reg = normalise(registry, "registry");
|
|
@@ -2121,10 +2144,9 @@ var require_library = __commonJS({
|
|
|
2121
2144
|
return { ok: false, error: { type: "Revert", message: String(err && err.message || err) } };
|
|
2122
2145
|
}
|
|
2123
2146
|
},
|
|
2124
|
-
|
|
2125
|
-
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, libraryId = "main", manifestCID = "", promptCount = 0 }) {
|
|
2147
|
+
executionReadiness: async function executionReadiness({ provider, registry, timelock, subdao, manifestCID = "", version = "1.0.0" }) {
|
|
2126
2148
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2127
|
-
const payload =
|
|
2149
|
+
const payload = buildUpdateLibraryTx({ registry, subdao, manifestCID, version });
|
|
2128
2150
|
const sim = await this.simulateAsTimelock({ provider, registry, to: payload.to, data: payload.data, timelock });
|
|
2129
2151
|
const out = { ok: !!sim.ok, error: sim.ok ? null : sim.error?.message || "revert", missingRole: null };
|
|
2130
2152
|
return out;
|
|
@@ -2937,7 +2959,9 @@ var require_subdao = __commonJS({
|
|
|
2937
2959
|
}
|
|
2938
2960
|
var SubDAOInterface = new Interface([
|
|
2939
2961
|
"function stake(uint256)",
|
|
2940
|
-
"function unstake(uint256)"
|
|
2962
|
+
"function unstake(uint256)",
|
|
2963
|
+
// Optional on newer SubDAO implementations; provided for tx building only.
|
|
2964
|
+
"function setProfileCid(string)"
|
|
2941
2965
|
]);
|
|
2942
2966
|
function buildStakeTx({ subdao, amount }) {
|
|
2943
2967
|
const addr = normalise(subdao, "subdao");
|
|
@@ -2949,12 +2973,21 @@ var require_subdao = __commonJS({
|
|
|
2949
2973
|
const data = SubDAOInterface.encodeFunctionData("unstake", [BigInt(amount)]);
|
|
2950
2974
|
return { to: addr, data, value: 0n };
|
|
2951
2975
|
}
|
|
2976
|
+
function buildSetProfileCidTx({ subdao, profileCid }) {
|
|
2977
|
+
const addr = normalise(subdao, "subdao");
|
|
2978
|
+
if (!profileCid || typeof profileCid !== "string" || !profileCid.trim()) {
|
|
2979
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "profileCid (CID string) required");
|
|
2980
|
+
}
|
|
2981
|
+
const data = SubDAOInterface.encodeFunctionData("setProfileCid", [String(profileCid)]);
|
|
2982
|
+
return { to: addr, data, value: 0n };
|
|
2983
|
+
}
|
|
2952
2984
|
module2.exports = {
|
|
2953
2985
|
discoverSubDAOs,
|
|
2954
2986
|
getSubDAOInfo,
|
|
2955
2987
|
getSubDAOUserStats,
|
|
2956
2988
|
buildStakeTx,
|
|
2957
|
-
buildUnstakeTx
|
|
2989
|
+
buildUnstakeTx,
|
|
2990
|
+
buildSetProfileCidTx
|
|
2958
2991
|
};
|
|
2959
2992
|
async function ensureSxxxBurnAllowance({ signer, sxxx, owner, spender, amount }) {
|
|
2960
2993
|
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
package/package.json
CHANGED