quorum-sdk 0.1.0

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/dist/index.js ADDED
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AgentMultisig: () => AgentMultisig,
24
+ AgentMultisigError: () => AgentMultisigError,
25
+ default: () => index_default
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var AgentMultisigError = class extends Error {
29
+ constructor(message, statusCode, code) {
30
+ super(message);
31
+ this.statusCode = statusCode;
32
+ this.code = code;
33
+ this.name = "AgentMultisigError";
34
+ }
35
+ };
36
+ var AgentMultisig = class {
37
+ constructor(config) {
38
+ this.apiUrl = config.apiUrl.replace(/\/$/, "");
39
+ this.apiKey = config.apiKey;
40
+ this.timeout = config.timeout ?? 3e4;
41
+ }
42
+ async request(method, path, body) {
43
+ const url = `${this.apiUrl}${path}`;
44
+ const headers = {
45
+ "Content-Type": "application/json"
46
+ };
47
+ if (this.apiKey) {
48
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
49
+ }
50
+ const controller = new AbortController();
51
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
52
+ try {
53
+ const response = await fetch(url, {
54
+ method,
55
+ headers,
56
+ body: body ? JSON.stringify(body) : void 0,
57
+ signal: controller.signal
58
+ });
59
+ clearTimeout(timeoutId);
60
+ const data = await response.json();
61
+ if (!response.ok) {
62
+ throw new AgentMultisigError(
63
+ data.error || data.message || "Request failed",
64
+ response.status,
65
+ data.code
66
+ );
67
+ }
68
+ return data;
69
+ } catch (error) {
70
+ clearTimeout(timeoutId);
71
+ if (error instanceof AgentMultisigError) throw error;
72
+ if (error instanceof Error && error.name === "AbortError") {
73
+ throw new AgentMultisigError("Request timeout", 408, "TIMEOUT");
74
+ }
75
+ throw new AgentMultisigError(
76
+ error instanceof Error ? error.message : "Unknown error"
77
+ );
78
+ }
79
+ }
80
+ // ==================== Health ====================
81
+ async health() {
82
+ return this.request("GET", "/health");
83
+ }
84
+ // ==================== Agents ====================
85
+ /**
86
+ * Register a new agent with the coordination API.
87
+ */
88
+ async registerAgent(input) {
89
+ return this.request("POST", "/agents", input);
90
+ }
91
+ /**
92
+ * Get an agent by ID.
93
+ */
94
+ async getAgent(agentId) {
95
+ return this.request("GET", `/agents/${agentId}`);
96
+ }
97
+ /**
98
+ * List all registered agents.
99
+ */
100
+ async listAgents() {
101
+ return this.request("GET", "/agents");
102
+ }
103
+ // ==================== Multisigs ====================
104
+ /**
105
+ * Create a new multisig wallet.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const multisig = await client.createMultisig({
110
+ * name: 'AI Treasury',
111
+ * threshold: 2,
112
+ * agents: ['agent_abc', 'agent_def', 'agent_ghi'],
113
+ * network: 'mainnet'
114
+ * });
115
+ * console.log('Fund this address:', multisig.address);
116
+ * ```
117
+ */
118
+ async createMultisig(input) {
119
+ return this.request("POST", "/multisigs", input);
120
+ }
121
+ /**
122
+ * Get a multisig by ID.
123
+ */
124
+ async getMultisig(multisigId) {
125
+ return this.request("GET", `/multisigs/${multisigId}`);
126
+ }
127
+ /**
128
+ * List all multisigs.
129
+ */
130
+ async listMultisigs() {
131
+ return this.request("GET", "/multisigs");
132
+ }
133
+ /**
134
+ * Get the balance of a multisig wallet.
135
+ */
136
+ async getMultisigBalance(multisigId) {
137
+ return this.request("GET", `/multisigs/${multisigId}/balance`);
138
+ }
139
+ // ==================== Proposals ====================
140
+ /**
141
+ * Create a spend proposal for a multisig.
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const proposal = await client.createProposal({
146
+ * multisigId: 'msig_xyz',
147
+ * to: 'bc1qpzlw29z50cz7ysjpsaqggtscya3p6ggehnsp2g',
148
+ * amount: 10000 // satoshis
149
+ * });
150
+ * console.log('PSBT to sign:', proposal.psbtHex);
151
+ * ```
152
+ */
153
+ async createProposal(input) {
154
+ return this.request("POST", "/proposals", input);
155
+ }
156
+ /**
157
+ * Get a proposal by ID.
158
+ */
159
+ async getProposal(proposalId) {
160
+ return this.request("GET", `/proposals/${proposalId}`);
161
+ }
162
+ /**
163
+ * List proposals, optionally filtered by multisig.
164
+ */
165
+ async listProposals(multisigId) {
166
+ const path = multisigId ? `/proposals?multisigId=${multisigId}` : "/proposals";
167
+ return this.request("GET", path);
168
+ }
169
+ /**
170
+ * Sign a proposal with an agent's key.
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * // Agent signs the PSBT and submits signature
175
+ * const signature = await myWallet.signPsbt(proposal.psbtHex);
176
+ * await client.signProposal({
177
+ * proposalId: proposal.id,
178
+ * agentId: myAgent.id,
179
+ * signature: signature
180
+ * });
181
+ * ```
182
+ */
183
+ async signProposal(input) {
184
+ return this.request("POST", `/proposals/${input.proposalId}/sign`, {
185
+ agentId: input.agentId,
186
+ signature: input.signature
187
+ });
188
+ }
189
+ /**
190
+ * Broadcast a fully-signed proposal.
191
+ */
192
+ async broadcastProposal(proposalId) {
193
+ return this.request("POST", `/proposals/${proposalId}/broadcast`);
194
+ }
195
+ // ==================== Convenience Methods ====================
196
+ /**
197
+ * Create a multisig and register agents in one call.
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const { multisig, agents } = await client.quickSetup({
202
+ * name: 'Quick Treasury',
203
+ * threshold: 2,
204
+ * signers: [
205
+ * { name: 'Bot1', provider: 'aibtc', publicKey: '...' },
206
+ * { name: 'Bot2', provider: 'aibtc', publicKey: '...' },
207
+ * { name: 'Bot3', provider: 'aibtc', publicKey: '...' },
208
+ * ]
209
+ * });
210
+ * ```
211
+ */
212
+ async quickSetup(input) {
213
+ const agents = await Promise.all(
214
+ input.signers.map((signer) => this.registerAgent(signer))
215
+ );
216
+ const multisig = await this.createMultisig({
217
+ name: input.name,
218
+ threshold: input.threshold,
219
+ agents: agents.map((a) => a.id),
220
+ network: input.network
221
+ });
222
+ return { multisig, agents };
223
+ }
224
+ /**
225
+ * Wait for a proposal to reach a target status.
226
+ */
227
+ async waitForProposal(proposalId, targetStatus, options) {
228
+ const timeout = options?.timeoutMs ?? 3e5;
229
+ const interval = options?.pollIntervalMs ?? 5e3;
230
+ const start = Date.now();
231
+ while (Date.now() - start < timeout) {
232
+ const proposal = await this.getProposal(proposalId);
233
+ if (proposal.status === targetStatus) {
234
+ return proposal;
235
+ }
236
+ if (proposal.status === "failed") {
237
+ throw new AgentMultisigError(
238
+ "Proposal failed",
239
+ 400,
240
+ "PROPOSAL_FAILED"
241
+ );
242
+ }
243
+ await new Promise((resolve) => setTimeout(resolve, interval));
244
+ }
245
+ throw new AgentMultisigError(
246
+ `Timeout waiting for proposal to reach ${targetStatus}`,
247
+ 408,
248
+ "TIMEOUT"
249
+ );
250
+ }
251
+ };
252
+ var index_default = AgentMultisig;
253
+ // Annotate the CommonJS export names for ESM import in node:
254
+ 0 && (module.exports = {
255
+ AgentMultisig,
256
+ AgentMultisigError
257
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,231 @@
1
+ // src/index.ts
2
+ var AgentMultisigError = class extends Error {
3
+ constructor(message, statusCode, code) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.code = code;
7
+ this.name = "AgentMultisigError";
8
+ }
9
+ };
10
+ var AgentMultisig = class {
11
+ constructor(config) {
12
+ this.apiUrl = config.apiUrl.replace(/\/$/, "");
13
+ this.apiKey = config.apiKey;
14
+ this.timeout = config.timeout ?? 3e4;
15
+ }
16
+ async request(method, path, body) {
17
+ const url = `${this.apiUrl}${path}`;
18
+ const headers = {
19
+ "Content-Type": "application/json"
20
+ };
21
+ if (this.apiKey) {
22
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
23
+ }
24
+ const controller = new AbortController();
25
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
26
+ try {
27
+ const response = await fetch(url, {
28
+ method,
29
+ headers,
30
+ body: body ? JSON.stringify(body) : void 0,
31
+ signal: controller.signal
32
+ });
33
+ clearTimeout(timeoutId);
34
+ const data = await response.json();
35
+ if (!response.ok) {
36
+ throw new AgentMultisigError(
37
+ data.error || data.message || "Request failed",
38
+ response.status,
39
+ data.code
40
+ );
41
+ }
42
+ return data;
43
+ } catch (error) {
44
+ clearTimeout(timeoutId);
45
+ if (error instanceof AgentMultisigError) throw error;
46
+ if (error instanceof Error && error.name === "AbortError") {
47
+ throw new AgentMultisigError("Request timeout", 408, "TIMEOUT");
48
+ }
49
+ throw new AgentMultisigError(
50
+ error instanceof Error ? error.message : "Unknown error"
51
+ );
52
+ }
53
+ }
54
+ // ==================== Health ====================
55
+ async health() {
56
+ return this.request("GET", "/health");
57
+ }
58
+ // ==================== Agents ====================
59
+ /**
60
+ * Register a new agent with the coordination API.
61
+ */
62
+ async registerAgent(input) {
63
+ return this.request("POST", "/agents", input);
64
+ }
65
+ /**
66
+ * Get an agent by ID.
67
+ */
68
+ async getAgent(agentId) {
69
+ return this.request("GET", `/agents/${agentId}`);
70
+ }
71
+ /**
72
+ * List all registered agents.
73
+ */
74
+ async listAgents() {
75
+ return this.request("GET", "/agents");
76
+ }
77
+ // ==================== Multisigs ====================
78
+ /**
79
+ * Create a new multisig wallet.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const multisig = await client.createMultisig({
84
+ * name: 'AI Treasury',
85
+ * threshold: 2,
86
+ * agents: ['agent_abc', 'agent_def', 'agent_ghi'],
87
+ * network: 'mainnet'
88
+ * });
89
+ * console.log('Fund this address:', multisig.address);
90
+ * ```
91
+ */
92
+ async createMultisig(input) {
93
+ return this.request("POST", "/multisigs", input);
94
+ }
95
+ /**
96
+ * Get a multisig by ID.
97
+ */
98
+ async getMultisig(multisigId) {
99
+ return this.request("GET", `/multisigs/${multisigId}`);
100
+ }
101
+ /**
102
+ * List all multisigs.
103
+ */
104
+ async listMultisigs() {
105
+ return this.request("GET", "/multisigs");
106
+ }
107
+ /**
108
+ * Get the balance of a multisig wallet.
109
+ */
110
+ async getMultisigBalance(multisigId) {
111
+ return this.request("GET", `/multisigs/${multisigId}/balance`);
112
+ }
113
+ // ==================== Proposals ====================
114
+ /**
115
+ * Create a spend proposal for a multisig.
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const proposal = await client.createProposal({
120
+ * multisigId: 'msig_xyz',
121
+ * to: 'bc1qpzlw29z50cz7ysjpsaqggtscya3p6ggehnsp2g',
122
+ * amount: 10000 // satoshis
123
+ * });
124
+ * console.log('PSBT to sign:', proposal.psbtHex);
125
+ * ```
126
+ */
127
+ async createProposal(input) {
128
+ return this.request("POST", "/proposals", input);
129
+ }
130
+ /**
131
+ * Get a proposal by ID.
132
+ */
133
+ async getProposal(proposalId) {
134
+ return this.request("GET", `/proposals/${proposalId}`);
135
+ }
136
+ /**
137
+ * List proposals, optionally filtered by multisig.
138
+ */
139
+ async listProposals(multisigId) {
140
+ const path = multisigId ? `/proposals?multisigId=${multisigId}` : "/proposals";
141
+ return this.request("GET", path);
142
+ }
143
+ /**
144
+ * Sign a proposal with an agent's key.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * // Agent signs the PSBT and submits signature
149
+ * const signature = await myWallet.signPsbt(proposal.psbtHex);
150
+ * await client.signProposal({
151
+ * proposalId: proposal.id,
152
+ * agentId: myAgent.id,
153
+ * signature: signature
154
+ * });
155
+ * ```
156
+ */
157
+ async signProposal(input) {
158
+ return this.request("POST", `/proposals/${input.proposalId}/sign`, {
159
+ agentId: input.agentId,
160
+ signature: input.signature
161
+ });
162
+ }
163
+ /**
164
+ * Broadcast a fully-signed proposal.
165
+ */
166
+ async broadcastProposal(proposalId) {
167
+ return this.request("POST", `/proposals/${proposalId}/broadcast`);
168
+ }
169
+ // ==================== Convenience Methods ====================
170
+ /**
171
+ * Create a multisig and register agents in one call.
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * const { multisig, agents } = await client.quickSetup({
176
+ * name: 'Quick Treasury',
177
+ * threshold: 2,
178
+ * signers: [
179
+ * { name: 'Bot1', provider: 'aibtc', publicKey: '...' },
180
+ * { name: 'Bot2', provider: 'aibtc', publicKey: '...' },
181
+ * { name: 'Bot3', provider: 'aibtc', publicKey: '...' },
182
+ * ]
183
+ * });
184
+ * ```
185
+ */
186
+ async quickSetup(input) {
187
+ const agents = await Promise.all(
188
+ input.signers.map((signer) => this.registerAgent(signer))
189
+ );
190
+ const multisig = await this.createMultisig({
191
+ name: input.name,
192
+ threshold: input.threshold,
193
+ agents: agents.map((a) => a.id),
194
+ network: input.network
195
+ });
196
+ return { multisig, agents };
197
+ }
198
+ /**
199
+ * Wait for a proposal to reach a target status.
200
+ */
201
+ async waitForProposal(proposalId, targetStatus, options) {
202
+ const timeout = options?.timeoutMs ?? 3e5;
203
+ const interval = options?.pollIntervalMs ?? 5e3;
204
+ const start = Date.now();
205
+ while (Date.now() - start < timeout) {
206
+ const proposal = await this.getProposal(proposalId);
207
+ if (proposal.status === targetStatus) {
208
+ return proposal;
209
+ }
210
+ if (proposal.status === "failed") {
211
+ throw new AgentMultisigError(
212
+ "Proposal failed",
213
+ 400,
214
+ "PROPOSAL_FAILED"
215
+ );
216
+ }
217
+ await new Promise((resolve) => setTimeout(resolve, interval));
218
+ }
219
+ throw new AgentMultisigError(
220
+ `Timeout waiting for proposal to reach ${targetStatus}`,
221
+ 408,
222
+ "TIMEOUT"
223
+ );
224
+ }
225
+ };
226
+ var index_default = AgentMultisig;
227
+ export {
228
+ AgentMultisig,
229
+ AgentMultisigError,
230
+ index_default as default
231
+ };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "quorum-sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for Quorum - Multi-Agent Wallet Coordination",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup src/index.ts --format cjs,esm --dts",
17
+ "test": "vitest",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": ["quorum", "bitcoin", "ethereum", "solana", "multisig", "agent", "ai", "taproot", "safe", "squads"],
21
+ "author": "Aetos <aetos@agentmail.to>",
22
+ "license": "MIT",
23
+ "homepage": "https://quorumclaw.com",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/aetos53t/agent-multisig-api"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/aetos53t/agent-multisig-api/issues"
30
+ },
31
+ "devDependencies": {
32
+ "tsup": "^8.0.0",
33
+ "typescript": "^5.3.0",
34
+ "vitest": "^1.0.0"
35
+ }
36
+ }