@sage-protocol/sdk 0.0.3

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/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@sage-protocol/sdk",
3
+ "version": "0.0.3",
4
+ "description": "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "types/index.d.ts",
8
+ "type": "commonjs",
9
+ "license": "MIT",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./types/index.d.ts",
13
+ "require": "./dist/index.cjs",
14
+ "import": "./dist/index.mjs",
15
+ "default": "./dist/index.cjs"
16
+ },
17
+ "./package.json": "./package.json",
18
+ "./types/*": "./types/*"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "types",
23
+ "README.md"
24
+ ],
25
+ "sideEffects": false,
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/sage-protocol/sdk.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/sage-protocol/sdk/issues"
32
+ },
33
+ "homepage": "https://github.com/sage-protocol/sdk#readme",
34
+ "scripts": {
35
+ "build": "tsup --config tsup.config.ts",
36
+ "clean": "rm -rf dist",
37
+ "test": "yarn build && node --test \"tests/**/*.test.js\"",
38
+ "release": "yarn build && npm publish --workspace @sage-protocol/sdk"
39
+ },
40
+ "dependencies": {
41
+ "@merit-systems/echo-typescript-sdk": "^1.0.17",
42
+ "@whetstone-research/doppler-sdk": "^0.0.1-alpha.40",
43
+ "ai": "^3.2.3",
44
+ "axios": "^1.11.0",
45
+ "ethers": "^6.15.0",
46
+ "viem": "^2.33.2"
47
+ },
48
+ "devDependencies": {
49
+ "proxyquire": "^2.1.3",
50
+ "sinon": "^17.0.1",
51
+ "tsup": "^8.1.0",
52
+ "typescript": "^5.4.0"
53
+ }
54
+ }
@@ -0,0 +1,418 @@
1
+ import type { BigNumberish } from 'ethers';
2
+
3
+ export type AddressLike = string;
4
+ export type HashLike = string;
5
+
6
+ export interface ProviderLike {
7
+ getNetwork?: (...args: any[]) => Promise<any> | any;
8
+ }
9
+
10
+ export interface TransactionPayload {
11
+ to: AddressLike;
12
+ data: string;
13
+ value: bigint;
14
+ }
15
+
16
+ export interface ProposalTuple {
17
+ id: bigint;
18
+ governor: AddressLike;
19
+ targets: AddressLike[];
20
+ values: bigint[];
21
+ calldatas: string[];
22
+ description: string;
23
+ descriptionHash: string;
24
+ createdBlock: number | bigint | null;
25
+ }
26
+
27
+ export interface ProposalCacheAdapter {
28
+ load(governor: AddressLike, proposalId: bigint): Promise<ProposalTuple | null> | ProposalTuple | null;
29
+ save(governor: AddressLike, proposalId: bigint, tuple: ProposalTuple): Promise<void> | void;
30
+ }
31
+
32
+ export interface ProposalQueueResult {
33
+ receipt: any;
34
+ tuple: ProposalTuple;
35
+ viaTimelock?: boolean;
36
+ }
37
+
38
+ export interface ProposalPreflightSummary {
39
+ governor: AddressLike;
40
+ proposer: AddressLike | null;
41
+ config: {
42
+ proposalThreshold: bigint | null;
43
+ votingDelay: bigint | null;
44
+ votingPeriod: bigint | null;
45
+ proposalCooldown: bigint | null;
46
+ };
47
+ cooldown: {
48
+ remainingSeconds: number | null;
49
+ };
50
+ subdao: AddressLike | null;
51
+ governanceMode: number | null;
52
+ eligibleMember: boolean | null;
53
+ stake: {
54
+ token: AddressLike | null;
55
+ requiredWei: bigint | null;
56
+ balanceWei: bigint | null;
57
+ allowanceWei: bigint | null;
58
+ governorAuthorizedBurner: boolean | null;
59
+ };
60
+ timelock: AddressLike | null;
61
+ }
62
+
63
+ export interface TimelockRoleCheck {
64
+ contract: AddressLike;
65
+ role?: string;
66
+ hasRole?: boolean;
67
+ error?: string;
68
+ }
69
+
70
+ export interface GovernanceOperationsModule {
71
+ resolveProposalTuple(args: {
72
+ provider: ProviderLike;
73
+ governor: AddressLike;
74
+ proposalId: bigint | number | string;
75
+ refresh?: boolean;
76
+ cache?: ProposalCacheAdapter | null;
77
+ fromBlock?: number | bigint | string;
78
+ }): Promise<ProposalTuple>;
79
+ queueProposal(args: {
80
+ provider: ProviderLike;
81
+ signer: any;
82
+ governor: AddressLike;
83
+ proposalId: bigint | number | string;
84
+ timelock?: AddressLike | null;
85
+ cache?: ProposalCacheAdapter | null;
86
+ refresh?: boolean;
87
+ waitMs?: number;
88
+ }): Promise<ProposalQueueResult>;
89
+ executeProposal(args: {
90
+ provider: ProviderLike;
91
+ signer: any;
92
+ governor: AddressLike;
93
+ proposalId: bigint | number | string;
94
+ timelock?: AddressLike | null;
95
+ cache?: ProposalCacheAdapter | null;
96
+ refresh?: boolean;
97
+ waitMs?: number;
98
+ }): Promise<ProposalQueueResult>;
99
+ preflightProposal(args: {
100
+ provider: ProviderLike;
101
+ signer?: any;
102
+ governor: AddressLike;
103
+ timelock?: AddressLike | null;
104
+ subdao?: AddressLike | null;
105
+ sxxxToken?: AddressLike | null;
106
+ }): Promise<ProposalPreflightSummary>;
107
+ getProposalDetails(args: {
108
+ provider: ProviderLike;
109
+ governor: AddressLike;
110
+ proposalId: bigint | number | string;
111
+ refresh?: boolean;
112
+ cache?: ProposalCacheAdapter | null;
113
+ includeTimeline?: boolean;
114
+ }): Promise<ProposalTuple & {
115
+ stateRaw: number | null;
116
+ state: string | number | null;
117
+ snapshot: string | null;
118
+ deadline: string | null;
119
+ votes: {
120
+ against: bigint;
121
+ for: bigint;
122
+ abstain: bigint;
123
+ };
124
+ quorum: string | null;
125
+ timeline: Array<Record<string, any>>;
126
+ }>;
127
+ ensureTimelockRoles(args: {
128
+ provider: ProviderLike;
129
+ timelock: AddressLike;
130
+ registries?: AddressLike[];
131
+ }): Promise<TimelockRoleCheck[]>;
132
+ }
133
+
134
+ export interface GovernanceModule {
135
+ operations: GovernanceOperationsModule;
136
+ [key: string]: any;
137
+ }
138
+
139
+ export interface IpfsUploadResult {
140
+ cid: string;
141
+ provider: string | null;
142
+ response?: any;
143
+ }
144
+
145
+ export interface IpfsClient {
146
+ config: Record<string, any>;
147
+ hasPinataCreds(): boolean;
148
+ shouldUseWorker(): boolean;
149
+ resolveProviderOrder(preference?: string | string[]): string[];
150
+ uploadPrompt(args: {
151
+ prompt: {
152
+ name?: string;
153
+ description?: string;
154
+ content: any;
155
+ timestamp?: number;
156
+ version?: string;
157
+ files?: string[];
158
+ };
159
+ providers?: string[] | string;
160
+ provider?: string;
161
+ warm?: boolean;
162
+ gateways?: string[] | string;
163
+ }): Promise<IpfsUploadResult>;
164
+ uploadJson(payload: any, name?: string, options?: {
165
+ providers?: string[] | string;
166
+ provider?: string;
167
+ warm?: boolean;
168
+ gateways?: string[] | string;
169
+ }): Promise<IpfsUploadResult>;
170
+ uploadText(text: string, name?: string, options?: {
171
+ providers?: string[] | string;
172
+ provider?: string;
173
+ warm?: boolean;
174
+ gateways?: string[] | string;
175
+ }): Promise<IpfsUploadResult>;
176
+ downloadJson(args: { cid: string; gateways?: string[] | string; headers?: Record<string, string> }): Promise<any>;
177
+ warmGateways(cid: string, options?: { gateways?: string[] | string; timeoutMs?: number; concurrency?: number }): Promise<{ warmed: string[] }>;
178
+ buildGatewayUrls(cid: string, extra?: string[] | string): string[];
179
+ pin(args: { cids: string | string[]; warm?: boolean; gateways?: string[] | string }): Promise<any>;
180
+ generateCid(payload: any): string;
181
+ }
182
+
183
+ export interface IpfsModule {
184
+ DEFAULT_GATEWAY: string;
185
+ createClient(options?: {
186
+ provider?: string;
187
+ gateway?: string;
188
+ timeoutMs?: number;
189
+ retries?: number;
190
+ shouldWarm?: boolean;
191
+ testMode?: boolean;
192
+ pinataApiUrl?: string;
193
+ pinataApiKey?: string;
194
+ pinataSecretKey?: string;
195
+ pinataJwt?: string;
196
+ workerUploadUrl?: string;
197
+ workerUploadToken?: string;
198
+ web3Token?: string;
199
+ env?: Record<string, string | undefined>;
200
+ } & Record<string, any>): IpfsClient;
201
+ buildGatewayUrls(cid: string, gatewayBase?: string, extraGateways?: string[] | string): string[];
202
+ normalizeCidV1Base32(cid: string): string;
203
+ }
204
+
205
+ export interface ManifestLintError {
206
+ keyword: string;
207
+ instancePath: string;
208
+ message: string;
209
+ schemaPath?: string;
210
+ params?: Record<string, any>;
211
+ }
212
+
213
+ export interface ManifestLintResult {
214
+ ok: boolean;
215
+ versionOk: boolean;
216
+ missingSchema: boolean;
217
+ schemaPath: string | null;
218
+ errors: ManifestLintError[];
219
+ hints: string[];
220
+ manifestPath?: string | null;
221
+ version?: string | number | null;
222
+ }
223
+
224
+ export interface ManifestValidator {
225
+ loadSchema(): { schema: any | null; schemaPath: string | null };
226
+ lintManifest(manifest: any, options?: { enforceVersion?: boolean; manifestPath?: string | null }): ManifestLintResult;
227
+ lintManifestFile(manifestPath: string, options?: { enforceVersion?: boolean }): ManifestLintResult;
228
+ bestPracticeCheck(manifest: any, options?: { manifestPath?: string | null }): Array<Record<string, any>>;
229
+ bestPracticeCheckFile(manifestPath: string): Array<Record<string, any>>;
230
+ }
231
+
232
+ export interface LibrarySearchResult {
233
+ type: 'library' | 'prompt';
234
+ name: string;
235
+ description: string;
236
+ cid: string;
237
+ promptCount?: number;
238
+ tags?: string[];
239
+ key?: string;
240
+ }
241
+
242
+ export interface LibrarySearchResponse {
243
+ results: LibrarySearchResult[];
244
+ warnings: string[];
245
+ stats: { candidates: number; manifests: number };
246
+ }
247
+
248
+ export interface LibraryModule {
249
+ listManifests(args: { provider: ProviderLike; registry: AddressLike; offset?: number; limit?: number }): Promise<{ total: bigint; manifests: Array<{ manifestCID: string; previousCID: string; timestamp: bigint; proposer: AddressLike; promptCount: number; }> }>;
250
+ getManifestInfo(args: { provider: ProviderLike; registry: AddressLike; manifestCID: string }): Promise<{ manifestCID: string; previousCID: string; timestamp: bigint; proposer: AddressLike; promptCount: number; }>;
251
+ getLatestLibrary(args: { provider: ProviderLike; registry: AddressLike; subdao: AddressLike; libraryId?: string }): Promise<{ manifestCID: string; previousCID: string; timestamp: bigint; proposer: AddressLike; promptCount: number; } | null>;
252
+ hasScopedOwnership(args: { provider: ProviderLike; registry: AddressLike; subdao: AddressLike; manifestCID: string }): Promise<boolean>;
253
+ buildUpdateLibraryForSubDAOTx(args: { registry: AddressLike; subdao: AddressLike; manifestCID: string; promptCount?: bigint | number | string; libraryId?: string }): TransactionPayload;
254
+ searchRegistry(args: { provider: ProviderLike; registry: AddressLike; query: string; limit?: number; ipfsClient?: any; ipfsOptions?: Record<string, any>; libraryAdapter?: any; manifestFetcher?: (cid: string) => Promise<any>; }): Promise<LibrarySearchResponse>;
255
+ validation: { createManifestValidator(options?: Record<string, any>): ManifestValidator };
256
+ }
257
+
258
+ export interface TokenModule {
259
+ getBalance(args: { provider: ProviderLike; token: AddressLike; account: AddressLike }): Promise<bigint>;
260
+ getVotes(args: { provider: ProviderLike; token: AddressLike; account: AddressLike }): Promise<bigint>;
261
+ getTotalSupply(args: { provider: ProviderLike; token: AddressLike }): Promise<bigint>;
262
+ getAllowance(args: { provider: ProviderLike; token: AddressLike; owner: AddressLike; spender: AddressLike }): Promise<bigint>;
263
+ getDelegates(args: { provider: ProviderLike; token: AddressLike; account: AddressLike }): Promise<AddressLike>;
264
+ canCreateProposal(args: { provider: ProviderLike; token: AddressLike; account: AddressLike }): Promise<boolean>;
265
+ getProposalBurnMin(args: { provider: ProviderLike; token: AddressLike }): Promise<bigint>;
266
+ getTotalBurned(args: { provider: ProviderLike; token: AddressLike }): Promise<bigint>;
267
+ buildApproveTx(args: { token: AddressLike; spender: AddressLike; amount: BigNumberish }): TransactionPayload;
268
+ buildDelegateTx(args: { token: AddressLike; delegatee: AddressLike }): TransactionPayload;
269
+ buildAuthorizeBurnerTx(args: { token: AddressLike; burner: AddressLike }): TransactionPayload;
270
+ getAuthorizedBurners(args: { provider: ProviderLike; token: AddressLike; fromBlock?: number | bigint | string; toBlock?: number | bigint | string }): Promise<{
271
+ token: AddressLike;
272
+ burners: AddressLike[];
273
+ events: Array<{
274
+ type: 'authorized' | 'revoked';
275
+ burner: AddressLike;
276
+ blockNumber: number;
277
+ transactionHash: HashLike;
278
+ logIndex: number;
279
+ }>;
280
+ }>;
281
+ getBurnConstants(): {
282
+ PROPOSAL_BURN_MIN: bigint;
283
+ PROPOSAL_BURN_MAX: bigint;
284
+ SUBDAO_BURN_MIN: bigint;
285
+ SUBDAO_BURN_MAX: bigint;
286
+ FORK_BURN_MIN: bigint;
287
+ FORK_BURN_MAX: bigint;
288
+ };
289
+ }
290
+
291
+ export interface TreasuryInfo {
292
+ treasury: AddressLike;
293
+ totalReserves: bigint;
294
+ totalPOL: bigint;
295
+ totalDebt: bigint;
296
+ canonicalPool: AddressLike | null;
297
+ routerOrVault: AddressLike | null;
298
+ maxWithdrawalRate: bigint | null;
299
+ emergencyWithdrawalLimit: bigint | null;
300
+ }
301
+
302
+ export interface TreasuryModule {
303
+ getTreasuryInfo(args: { provider: ProviderLike; treasury: AddressLike }): Promise<TreasuryInfo>;
304
+ getPendingWithdrawals(args: { provider: ProviderLike; treasury: AddressLike; ids?: number[]; limit?: number }): Promise<Array<{
305
+ id: number;
306
+ token: AddressLike | null;
307
+ recipient: AddressLike | null;
308
+ amount: bigint;
309
+ value: bigint;
310
+ requester: AddressLike | null;
311
+ balanceBefore: bigint;
312
+ recipientBalanceBefore: bigint;
313
+ depositSnapshot: bigint;
314
+ isLP: boolean;
315
+ isEmergency: boolean;
316
+ }>>;
317
+ getCanonicalLiquidityPlans(args: { provider: ProviderLike; treasury: AddressLike; fromBlock?: number | bigint | string; toBlock?: number | bigint | string }): Promise<{
318
+ updates: Array<{ pool: AddressLike; routerOrVault: AddressLike; blockNumber: number; transactionHash: HashLike }>;
319
+ adds: Array<{
320
+ subdao: AddressLike;
321
+ pool: AddressLike;
322
+ sxxxToken: AddressLike;
323
+ stableToken: AddressLike;
324
+ sxxxAmount: bigint;
325
+ stableAmount: bigint;
326
+ lpRecipient: AddressLike;
327
+ blockNumber: number;
328
+ transactionHash: HashLike;
329
+ }>;
330
+ removes: Array<{
331
+ subdao: AddressLike;
332
+ pool: AddressLike;
333
+ lpToken: AddressLike;
334
+ lpAmount: bigint;
335
+ recipient: AddressLike;
336
+ blockNumber: number;
337
+ transactionHash: HashLike;
338
+ }>;
339
+ }>;
340
+ getLPContribution(args: { provider: ProviderLike; treasury: AddressLike; subdao: AddressLike; token: AddressLike }): Promise<bigint>;
341
+ }
342
+
343
+ export interface BoostModule {
344
+ getMerkleConfig(args: { provider: ProviderLike; manager: AddressLike; proposalId: number | bigint }): Promise<{
345
+ manager: AddressLike;
346
+ proposalId: number;
347
+ token: AddressLike | null;
348
+ totalAmount: bigint;
349
+ startTime: number;
350
+ endTime: number;
351
+ merkleRoot: bigint;
352
+ } | null>;
353
+ buildMerkleFundTx(args: { manager: AddressLike; proposalId: number | bigint; amount: BigNumberish }): TransactionPayload;
354
+ buildMerkleSetRootTx(args: { manager: AddressLike; proposalId: number | bigint; merkleRoot: BigNumberish }): TransactionPayload;
355
+ getDirectConfig(args: { provider: ProviderLike; manager: AddressLike; proposalId: number | bigint }): Promise<{
356
+ manager: AddressLike;
357
+ proposalId: number;
358
+ token: AddressLike | null;
359
+ perVoter: bigint;
360
+ maxVoters: bigint;
361
+ startTime: number;
362
+ endTime: number;
363
+ } | null>;
364
+ buildDirectCreateTx(args: { manager: AddressLike; proposalId: number | bigint; token: AddressLike; perVoter: BigNumberish; maxVoters: BigNumberish }): TransactionPayload;
365
+ buildDirectFundTx(args: { manager: AddressLike; proposalId: number | bigint; amount: BigNumberish }): TransactionPayload;
366
+ }
367
+
368
+ export interface PersonalModule {
369
+ buildCreatePersonalRegistryTx(args: { factory: AddressLike; policy: number }): TransactionPayload;
370
+ buildSetPriceTx(args: { marketplace: AddressLike; key: string; price: BigNumberish }): TransactionPayload;
371
+ buildBuyTx(args: {
372
+ marketplace: AddressLike;
373
+ creator: AddressLike;
374
+ key: string;
375
+ expectedPrice: BigNumberish;
376
+ deadline: BigNumberish;
377
+ }): TransactionPayload;
378
+ computeReceiptId(creator: AddressLike, key: string): bigint;
379
+ getReceiptBalance(args: {
380
+ provider: ProviderLike;
381
+ receipt: AddressLike;
382
+ holder: AddressLike;
383
+ receiptId: bigint | number | string;
384
+ }): Promise<bigint>;
385
+ }
386
+
387
+ export interface SageSDK {
388
+ version: string;
389
+ getProvider: (rpcUrl: string) => any;
390
+ abi: Record<string, any>;
391
+ governance: Record<string, any>;
392
+ subdao: Record<string, any>;
393
+ timelock: Record<string, any>;
394
+ factory: Record<string, any>;
395
+ library: LibraryModule;
396
+ prompt: Record<string, any>;
397
+ wallet: {
398
+ session: {
399
+ DEFAULT_WALLET_TYPE: string;
400
+ resolveWalletType(args?: { config?: any; env?: Record<string, any> }): string;
401
+ shouldAllowInsecurePrivateKey(env?: Record<string, any>): boolean;
402
+ persistWalletContext(args: { config: any; account: string; type: string }): boolean;
403
+ };
404
+ [key: string]: any;
405
+ };
406
+ walletTyped: Record<string, any>;
407
+ ipfs: IpfsModule;
408
+ token: TokenModule;
409
+ treasury: TreasuryModule;
410
+ boost: BoostModule;
411
+ personal: PersonalModule;
412
+ subgraph: Record<string, any>;
413
+ errors: Record<string, any>;
414
+ resolveGovernanceContext: (args: any) => Promise<any>;
415
+ }
416
+
417
+ declare const sdk: SageSDK;
418
+ export = sdk;