@ritkey/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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mmorgsmorgan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # @ritkey/sdk
2
+
3
+ TypeScript SDK for Ritkey — the MPC wallet service for AI agents on Ritual Chain.
4
+
5
+ ```bash
6
+ npm install @ritkey/sdk
7
+ ```
8
+
9
+ Zero runtime dependencies. Works in Node 18+ and modern browsers / edge runtimes (Cloudflare Workers, Vercel, Deno).
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { RitkeyClient } from '@ritkey/sdk';
15
+
16
+ const client = new RitkeyClient({
17
+ baseUrl: 'https://ritkey.example.com',
18
+ apiKey: process.env.RITKEY_API_KEY,
19
+ });
20
+
21
+ // Create a wallet (Shamir 2-of-3 threshold). Save the shards — shown once.
22
+ const wallet = await client.wallets.create({ label: 'agent-7' });
23
+ console.log(wallet.address);
24
+ console.log('agent shard:', wallet.agentShard);
25
+ console.log('backup shard:', wallet.backupShard);
26
+
27
+ // Sign + broadcast a transaction.
28
+ const tx = await client.wallets.send({
29
+ walletId: wallet.walletId,
30
+ agentShard: wallet.agentShard,
31
+ to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
32
+ value: '0.01',
33
+ });
34
+ console.log(tx.hash, tx.explorer);
35
+ ```
36
+
37
+ ## Webhooks
38
+
39
+ Register a webhook to receive real-time events. Save the `secret` — Ritkey shows it only once.
40
+
41
+ ```ts
42
+ const hook = await client.webhooks.create({
43
+ url: 'https://yourapp.com/ritkey-hook',
44
+ events: ['tx.sent', 'wallet.funded', 'key.exported'],
45
+ label: 'production',
46
+ });
47
+
48
+ // Save somewhere safe:
49
+ // hook.id, hook.secret
50
+
51
+ // Fire a test delivery to verify connectivity:
52
+ await client.webhooks.test(hook.id);
53
+ ```
54
+
55
+ ### Verify deliveries on your receiver
56
+
57
+ In your webhook handler, use `verifyWebhook` to check the HMAC signature and parse the event.
58
+
59
+ **IMPORTANT**: pass the EXACT raw bytes Ritkey sent. If your framework JSON-parses before you see the body, the HMAC will mismatch. Use a raw body reader on the webhook route.
60
+
61
+ ```ts
62
+ import express from 'express';
63
+ import { verifyWebhook, isEvent } from '@ritkey/sdk';
64
+
65
+ const app = express();
66
+
67
+ app.post(
68
+ '/ritkey-hook',
69
+ express.raw({ type: 'application/json' }), // raw bytes
70
+ (req, res) => {
71
+ const result = verifyWebhook(
72
+ req.body, // Buffer
73
+ req.headers['ritkey-signature'],
74
+ process.env.RITKEY_WEBHOOK_SECRET
75
+ );
76
+
77
+ if (!result.ok) {
78
+ return res.status(401).send(result.reason);
79
+ }
80
+
81
+ // Type-narrow on the event type:
82
+ if (isEvent(result.event, 'tx.sent')) {
83
+ console.log('tx hash:', result.event.data.hash);
84
+ } else if (isEvent(result.event, 'key.exported')) {
85
+ console.log('SECURITY: key exported for', result.event.data.address);
86
+ }
87
+
88
+ // Always 200 quickly — Ritkey retries on non-2xx.
89
+ res.status(200).end();
90
+ }
91
+ );
92
+ ```
93
+
94
+ The verifier:
95
+ - Validates HMAC-SHA256 over `<timestamp>.<rawBody>` using your secret
96
+ - Rejects timestamps outside a 5-minute tolerance window (replay protection)
97
+ - Uses `timingSafeEqual` (no early-exit / timing leaks)
98
+ - Returns a typed event object on success
99
+
100
+ ### Idempotency
101
+
102
+ Deliveries can repeat if your endpoint times out but actually succeeded. Use `Ritkey-Event-Id` as the dedup key:
103
+
104
+ ```ts
105
+ const eventId = req.headers['ritkey-event-id'];
106
+ if (await alreadyProcessed(eventId)) {
107
+ return res.status(200).end();
108
+ }
109
+ ```
110
+
111
+ ## Events (polling)
112
+
113
+ For environments where running a public HTTPS endpoint is impractical (CLIs, scripts, local dev), use the polling client:
114
+
115
+ ```ts
116
+ const stop = client.events.subscribe({
117
+ types: ['tx.sent', 'wallet.funded'],
118
+ intervalMs: 3000,
119
+ onEvent: (event) => {
120
+ console.log(event.type, event.data);
121
+ },
122
+ onError: (err) => console.error(err),
123
+ });
124
+
125
+ // Later:
126
+ stop();
127
+ ```
128
+
129
+ Polling burns more API quota than webhooks. Use webhooks for production.
130
+
131
+ ## Import an existing wallet
132
+
133
+ Bring your MetaMask / Rabby / hardware-wallet key under Ritkey management:
134
+
135
+ ```ts
136
+ const wallet = await client.wallets.import_({
137
+ privateKey: '0x562f22a32039901eac...',
138
+ label: 'imported-from-metamask',
139
+ });
140
+
141
+ // Same address as MetaMask, now manageable through Ritkey.
142
+ console.log(wallet.address);
143
+ ```
144
+
145
+ ## Export a key
146
+
147
+ If you need full self-custody (back to MetaMask, hardware wallet, etc.):
148
+
149
+ ```ts
150
+ const { privateKey, status } = await client.wallets.exportKey({
151
+ walletId: wallet.walletId,
152
+ agentShard: wallet.agentShard,
153
+ });
154
+
155
+ console.log('private key for MetaMask import:', privateKey);
156
+ console.log('wallet status:', status); // 'archived'
157
+ ```
158
+
159
+ After export, the wallet is **archived** in Ritkey. `/send`, `/sign`, `/deposit-ritual`, and a re-export all return 403. Sweep funds to a fresh wallet if you want to keep using Ritkey.
160
+
161
+ ## Errors
162
+
163
+ Every error from the SDK is a `RitkeyError` with `status`, `code`, and the parsed response body:
164
+
165
+ ```ts
166
+ import { RitkeyClient, RitkeyError } from '@ritkey/sdk';
167
+
168
+ try {
169
+ await client.wallets.get('nope');
170
+ } catch (err) {
171
+ if (err instanceof RitkeyError) {
172
+ console.log(err.status); // 404
173
+ console.log(err.code); // optional error code from the server
174
+ console.log(err.body); // full server response body
175
+ }
176
+ }
177
+ ```
178
+
179
+ ## Reference
180
+
181
+ ### Construction
182
+
183
+ ```ts
184
+ new RitkeyClient({
185
+ baseUrl: string; // required, no trailing slash needed
186
+ apiKey?: string; // required unless server is in OPEN_MODE
187
+ fetch?: typeof fetch; // override (e.g. for Cloudflare Workers)
188
+ timeoutMs?: number; // per-request timeout, default 30000
189
+ });
190
+ ```
191
+
192
+ ### Wallets
193
+
194
+ | Method | HTTP |
195
+ |---|---|
196
+ | `client.wallets.create(input?)` | `POST /wallets` |
197
+ | `client.wallets.import_(input)` | `POST /wallets/import` |
198
+ | `client.wallets.list()` | `GET /wallets` |
199
+ | `client.wallets.me()` | `GET /wallets/me` |
200
+ | `client.wallets.get(id)` | `GET /wallets/:id` |
201
+ | `client.wallets.balance(id)` | `GET /wallets/:id/balance` |
202
+ | `client.wallets.send(input)` | `POST /wallets/:id/send` |
203
+ | `client.wallets.sign(input)` | `POST /wallets/:id/sign` |
204
+ | `client.wallets.fund(id)` | `POST /wallets/:id/fund` |
205
+ | `client.wallets.exportKey(input)` | `POST /wallets/:id/export-key` |
206
+ | `client.wallets.sweepAndArchive(input)` | `POST /wallets/:id/sweep-and-archive` |
207
+ | `client.wallets.freeze(id)` | `POST /wallets/:id/freeze` |
208
+ | `client.wallets.unfreeze(id)` | `POST /wallets/:id/unfreeze` |
209
+
210
+ ### Webhooks
211
+
212
+ | Method | HTTP |
213
+ |---|---|
214
+ | `client.webhooks.create(input)` | `POST /webhooks` |
215
+ | `client.webhooks.list()` | `GET /webhooks` |
216
+ | `client.webhooks.listEventTypes()` | `GET /webhooks/events` |
217
+ | `client.webhooks.get(id)` | `GET /webhooks/:id` |
218
+ | `client.webhooks.update(id, patch)` | `PATCH /webhooks/:id` |
219
+ | `client.webhooks.delete(id)` | `DELETE /webhooks/:id` |
220
+ | `client.webhooks.test(id)` | `POST /webhooks/:id/test` |
221
+ | `client.webhooks.listDeliveries(id)` | `GET /webhooks/:id/deliveries` |
222
+
223
+ ### Events
224
+
225
+ | Method | Behaviour |
226
+ |---|---|
227
+ | `client.events.list(opts?)` | One-shot fetch of recent events. |
228
+ | `client.events.subscribe(opts)` | Polls `/events`, calls `onEvent` per new event. Returns a stop function. |
229
+
230
+ ### Verification helper
231
+
232
+ | Function | Use |
233
+ |---|---|
234
+ | `verifyWebhook(rawBody, sigHeader, secret, opts?)` | Verify a webhook delivery on your receiver. Returns `{ ok, event } \| { ok: false, reason }`. |
235
+ | `isEvent(event, type)` | Type-narrowing helper for verified events. |
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Alert rule management.
3
+ *
4
+ * POST /wallets/:id/alerts create({ walletId, kind, config, ... })
5
+ * GET /wallets/:id/alerts listForWallet(walletId)
6
+ * GET /alerts list()
7
+ * GET /alerts/:id get(id)
8
+ * PATCH /alerts/:id update(id, patch)
9
+ * DELETE /alerts/:id delete(id)
10
+ */
11
+ import type { HttpTransport } from '../transport.js';
12
+ import type { AlertRule, CreateAlertRuleInput, UpdateAlertRuleInput } from '../types.js';
13
+ export declare class AlertsClient {
14
+ private readonly http;
15
+ constructor(http: HttpTransport);
16
+ create(input: CreateAlertRuleInput): Promise<AlertRule>;
17
+ listForWallet(walletId: string): Promise<{
18
+ rules: AlertRule[];
19
+ count: number;
20
+ }>;
21
+ list(): Promise<{
22
+ rules: AlertRule[];
23
+ count: number;
24
+ }>;
25
+ get(ruleId: string): Promise<AlertRule>;
26
+ update(ruleId: string, patch: UpdateAlertRuleInput): Promise<AlertRule>;
27
+ delete(ruleId: string): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=alerts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/client/alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAE1C,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC;IASvD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAO/E,IAAI,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAItD,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIvC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC;IAQvE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG5C"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Alert rule management.
3
+ *
4
+ * POST /wallets/:id/alerts create({ walletId, kind, config, ... })
5
+ * GET /wallets/:id/alerts listForWallet(walletId)
6
+ * GET /alerts list()
7
+ * GET /alerts/:id get(id)
8
+ * PATCH /alerts/:id update(id, patch)
9
+ * DELETE /alerts/:id delete(id)
10
+ */
11
+ export class AlertsClient {
12
+ http;
13
+ constructor(http) {
14
+ this.http = http;
15
+ }
16
+ async create(input) {
17
+ const { walletId, ...body } = input;
18
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/alerts`, body);
19
+ }
20
+ async listForWallet(walletId) {
21
+ return this.http.request('GET', `/wallets/${encodeURIComponent(walletId)}/alerts`);
22
+ }
23
+ async list() {
24
+ return this.http.request('GET', '/alerts');
25
+ }
26
+ async get(ruleId) {
27
+ return this.http.request('GET', `/alerts/${encodeURIComponent(ruleId)}`);
28
+ }
29
+ async update(ruleId, patch) {
30
+ return this.http.request('PATCH', `/alerts/${encodeURIComponent(ruleId)}`, patch);
31
+ }
32
+ async delete(ruleId) {
33
+ await this.http.request('DELETE', `/alerts/${encodeURIComponent(ruleId)}`);
34
+ }
35
+ }
36
+ //# sourceMappingURL=alerts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alerts.js","sourceRoot":"","sources":["../../src/client/alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,IAAmB;QAAnB,SAAI,GAAJ,IAAI,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,MAAM,CAAC,KAA2B;QACtC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CACtB,MAAM,EACN,YAAY,kBAAkB,CAAC,QAAQ,CAAC,SAAS,EACjD,IAAI,CACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CACtB,KAAK,EACL,YAAY,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAClD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAwC,KAAK,EAAE,SAAS,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAc;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAY,KAAK,EAAE,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,KAA2B;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CACtB,OAAO,EACP,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,EACvC,KAAK,CACN,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAO,QAAQ,EAAE,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Top-level RitkeyClient.
3
+ *
4
+ * Glues the transport to per-resource clients. Apps should construct one
5
+ * client and reuse it.
6
+ *
7
+ * const client = new RitkeyClient({
8
+ * baseUrl: 'https://ritkey.example.com',
9
+ * apiKey: process.env.RITKEY_API_KEY,
10
+ * });
11
+ *
12
+ * const wallet = await client.wallets.create({ label: 'agent-7' });
13
+ * const hook = await client.webhooks.create({ url: 'https://app/hook' });
14
+ * const stop = client.events.subscribe({ onEvent: (e) => log(e) });
15
+ */
16
+ import { WalletsClient } from './wallets.js';
17
+ import { WebhooksClient } from './webhooks.js';
18
+ import { AlertsClient } from './alerts.js';
19
+ import { EventsClient } from '../events/poller.js';
20
+ import type { RitkeyClientConfig } from '../types.js';
21
+ export declare class RitkeyClient {
22
+ /** Wallet operations. */
23
+ readonly wallets: WalletsClient;
24
+ /** Webhook subscription management. */
25
+ readonly webhooks: WebhooksClient;
26
+ /** Alert rule management. */
27
+ readonly alerts: AlertsClient;
28
+ /** Event polling. */
29
+ readonly events: EventsClient;
30
+ constructor(config: RitkeyClientConfig);
31
+ }
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,qBAAa,YAAY;IACvB,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,qBAAqB;IACrB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;gBAElB,MAAM,EAAE,kBAAkB;CAOvC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Top-level RitkeyClient.
3
+ *
4
+ * Glues the transport to per-resource clients. Apps should construct one
5
+ * client and reuse it.
6
+ *
7
+ * const client = new RitkeyClient({
8
+ * baseUrl: 'https://ritkey.example.com',
9
+ * apiKey: process.env.RITKEY_API_KEY,
10
+ * });
11
+ *
12
+ * const wallet = await client.wallets.create({ label: 'agent-7' });
13
+ * const hook = await client.webhooks.create({ url: 'https://app/hook' });
14
+ * const stop = client.events.subscribe({ onEvent: (e) => log(e) });
15
+ */
16
+ import { HttpTransport } from '../transport.js';
17
+ import { WalletsClient } from './wallets.js';
18
+ import { WebhooksClient } from './webhooks.js';
19
+ import { AlertsClient } from './alerts.js';
20
+ import { EventsClient } from '../events/poller.js';
21
+ export class RitkeyClient {
22
+ /** Wallet operations. */
23
+ wallets;
24
+ /** Webhook subscription management. */
25
+ webhooks;
26
+ /** Alert rule management. */
27
+ alerts;
28
+ /** Event polling. */
29
+ events;
30
+ constructor(config) {
31
+ const http = new HttpTransport(config);
32
+ this.wallets = new WalletsClient(http);
33
+ this.webhooks = new WebhooksClient(http);
34
+ this.alerts = new AlertsClient(http);
35
+ this.events = new EventsClient(http);
36
+ }
37
+ }
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,OAAO,YAAY;IACvB,yBAAyB;IAChB,OAAO,CAAgB;IAChC,uCAAuC;IAC9B,QAAQ,CAAiB;IAClC,6BAA6B;IACpB,MAAM,CAAe;IAC9B,qBAAqB;IACZ,MAAM,CAAe;IAE9B,YAAY,MAA0B;QACpC,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Wallet operations.
3
+ *
4
+ * Maps directly to the @ritkey/service HTTP API:
5
+ *
6
+ * POST /wallets create()
7
+ * POST /wallets/import import_()
8
+ * GET /wallets list()
9
+ * GET /wallets/me me()
10
+ * GET /wallets/:id get(id)
11
+ * GET /wallets/:id/balance balance(id)
12
+ * POST /wallets/:id/send send(...)
13
+ * POST /wallets/:id/sign sign(...)
14
+ * POST /wallets/:id/fund fund(id)
15
+ * POST /wallets/:id/export-key exportKey(...)
16
+ * POST /wallets/:id/sweep-and-archive sweepAndArchive(...)
17
+ * POST /wallets/:id/freeze freeze(id)
18
+ * POST /wallets/:id/unfreeze unfreeze(id)
19
+ */
20
+ import type { HttpTransport } from '../transport.js';
21
+ import type { CreatedWallet, Wallet, BalanceResponse, SendTransactionInput, SignMessageInput, ExportKeyInput, SweepInput, SentTransaction, ExportedKey } from '../types.js';
22
+ export declare class WalletsClient {
23
+ private readonly http;
24
+ constructor(http: HttpTransport);
25
+ /**
26
+ * Create a new threshold (Shamir 2-of-3) wallet.
27
+ *
28
+ * The response includes the agentShard and backupShard ONCE. The SDK
29
+ * passes them through verbatim — your application is responsible for
30
+ * storing them safely.
31
+ */
32
+ create(input?: {
33
+ label?: string;
34
+ }): Promise<CreatedWallet>;
35
+ /**
36
+ * Import an existing private key (e.g. from MetaMask / Rabby) into Ritkey.
37
+ *
38
+ * The key is split into 2-of-3 Shamir shares. Server keeps share 1, you
39
+ * receive shares 2 and 3.
40
+ */
41
+ import_(input: {
42
+ privateKey: string;
43
+ label?: string;
44
+ }): Promise<CreatedWallet>;
45
+ list(): Promise<{
46
+ wallets: Wallet[];
47
+ count: number;
48
+ }>;
49
+ /** GET /wallets/me — returns the wallet bound to the current API key. */
50
+ me(): Promise<Wallet>;
51
+ get(walletId: string): Promise<Wallet>;
52
+ balance(walletId: string): Promise<BalanceResponse>;
53
+ /**
54
+ * Sign and broadcast a transaction.
55
+ *
56
+ * The agentShard is sent over the wire to the server, which combines it
57
+ * with its server shard to reconstruct the private key (in Rust, briefly,
58
+ * zeroized after signing). See SECURITY-MODEL.md for the exact trust model.
59
+ */
60
+ send(input: SendTransactionInput): Promise<SentTransaction>;
61
+ sign(input: SignMessageInput): Promise<{
62
+ signature: string;
63
+ address: string;
64
+ }>;
65
+ fund(walletId: string): Promise<{
66
+ hash: string;
67
+ from: string;
68
+ to: string;
69
+ amount: string;
70
+ explorer: string;
71
+ }>;
72
+ /**
73
+ * Export the private key. ⚠️ After a successful export the wallet is
74
+ * archived and can no longer be used through Ritkey. Save the privateKey
75
+ * (and consider sweeping funds to a fresh wallet).
76
+ */
77
+ exportKey(input: ExportKeyInput): Promise<ExportedKey>;
78
+ sweepAndArchive(input: SweepInput): Promise<{
79
+ status: 'archived';
80
+ walletId: string;
81
+ swept: boolean;
82
+ sweepTxHash: string | null;
83
+ sweepTo: string;
84
+ apiKeyGrantReleased: boolean;
85
+ }>;
86
+ freeze(walletId: string): Promise<{
87
+ status: 'frozen';
88
+ walletId: string;
89
+ }>;
90
+ unfreeze(walletId: string): Promise<{
91
+ status: 'active';
92
+ walletId: string;
93
+ }>;
94
+ }
95
+ //# sourceMappingURL=wallets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallets.d.ts","sourceRoot":"","sources":["../../src/client/wallets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EACV,aAAa,EACb,MAAM,EACN,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,eAAe,EACf,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAEhD;;;;;;OAMG;IACG,MAAM,CAAC,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAIhE;;;;;OAKG;IACG,OAAO,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAI9E,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3D,yEAAyE;IACnE,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC;IAIrB,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAItC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAOzD;;;;;;OAMG;IACG,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IAS3D,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAS9E,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QACpC,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IAIF;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAStD,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC;QAChD,MAAM,EAAE,UAAU,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,OAAO,CAAC;QACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IASI,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAOzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAMlF"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Wallet operations.
3
+ *
4
+ * Maps directly to the @ritkey/service HTTP API:
5
+ *
6
+ * POST /wallets create()
7
+ * POST /wallets/import import_()
8
+ * GET /wallets list()
9
+ * GET /wallets/me me()
10
+ * GET /wallets/:id get(id)
11
+ * GET /wallets/:id/balance balance(id)
12
+ * POST /wallets/:id/send send(...)
13
+ * POST /wallets/:id/sign sign(...)
14
+ * POST /wallets/:id/fund fund(id)
15
+ * POST /wallets/:id/export-key exportKey(...)
16
+ * POST /wallets/:id/sweep-and-archive sweepAndArchive(...)
17
+ * POST /wallets/:id/freeze freeze(id)
18
+ * POST /wallets/:id/unfreeze unfreeze(id)
19
+ */
20
+ export class WalletsClient {
21
+ http;
22
+ constructor(http) {
23
+ this.http = http;
24
+ }
25
+ /**
26
+ * Create a new threshold (Shamir 2-of-3) wallet.
27
+ *
28
+ * The response includes the agentShard and backupShard ONCE. The SDK
29
+ * passes them through verbatim — your application is responsible for
30
+ * storing them safely.
31
+ */
32
+ async create(input) {
33
+ return this.http.request('POST', '/wallets', input ?? {});
34
+ }
35
+ /**
36
+ * Import an existing private key (e.g. from MetaMask / Rabby) into Ritkey.
37
+ *
38
+ * The key is split into 2-of-3 Shamir shares. Server keeps share 1, you
39
+ * receive shares 2 and 3.
40
+ */
41
+ async import_(input) {
42
+ return this.http.request('POST', '/wallets/import', input);
43
+ }
44
+ async list() {
45
+ return this.http.request('GET', '/wallets');
46
+ }
47
+ /** GET /wallets/me — returns the wallet bound to the current API key. */
48
+ async me() {
49
+ return this.http.request('GET', '/wallets/me');
50
+ }
51
+ async get(walletId) {
52
+ return this.http.request('GET', `/wallets/${encodeURIComponent(walletId)}`);
53
+ }
54
+ async balance(walletId) {
55
+ return this.http.request('GET', `/wallets/${encodeURIComponent(walletId)}/balance`);
56
+ }
57
+ /**
58
+ * Sign and broadcast a transaction.
59
+ *
60
+ * The agentShard is sent over the wire to the server, which combines it
61
+ * with its server shard to reconstruct the private key (in Rust, briefly,
62
+ * zeroized after signing). See SECURITY-MODEL.md for the exact trust model.
63
+ */
64
+ async send(input) {
65
+ const { walletId, ...body } = input;
66
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/send`, body);
67
+ }
68
+ async sign(input) {
69
+ const { walletId, ...body } = input;
70
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/sign`, body);
71
+ }
72
+ async fund(walletId) {
73
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/fund`);
74
+ }
75
+ /**
76
+ * Export the private key. ⚠️ After a successful export the wallet is
77
+ * archived and can no longer be used through Ritkey. Save the privateKey
78
+ * (and consider sweeping funds to a fresh wallet).
79
+ */
80
+ async exportKey(input) {
81
+ const { walletId, ...rest } = input;
82
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/export-key`, { ...rest, confirm: true });
83
+ }
84
+ async sweepAndArchive(input) {
85
+ const { walletId, ...body } = input;
86
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/sweep-and-archive`, body);
87
+ }
88
+ async freeze(walletId) {
89
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/freeze`);
90
+ }
91
+ async unfreeze(walletId) {
92
+ return this.http.request('POST', `/wallets/${encodeURIComponent(walletId)}/unfreeze`);
93
+ }
94
+ }
95
+ //# sourceMappingURL=wallets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallets.js","sourceRoot":"","sources":["../../src/client/wallets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Webhook subscription management.
3
+ *
4
+ * POST /webhooks create()
5
+ * GET /webhooks list()
6
+ * GET /webhooks/events listEventTypes()
7
+ * GET /webhooks/:id get(id)
8
+ * PATCH /webhooks/:id update(id, ...)
9
+ * DELETE /webhooks/:id delete(id)
10
+ * POST /webhooks/:id/test test(id)
11
+ * GET /webhooks/:id/deliveries listDeliveries(id)
12
+ */
13
+ import type { HttpTransport } from '../transport.js';
14
+ import type { CreatedWebhook, WebhookSubscription, CreateWebhookInput, UpdateWebhookInput, DeliveryLogEntry, EventType } from '../types.js';
15
+ export declare class WebhooksClient {
16
+ private readonly http;
17
+ constructor(http: HttpTransport);
18
+ /** Create a new webhook subscription. Response includes `secret` — save it. */
19
+ create(input: CreateWebhookInput): Promise<CreatedWebhook>;
20
+ list(): Promise<{
21
+ subscriptions: WebhookSubscription[];
22
+ count: number;
23
+ }>;
24
+ listEventTypes(): Promise<{
25
+ eventTypes: EventType[];
26
+ wildcard: '*';
27
+ description: string;
28
+ }>;
29
+ get(subscriptionId: string): Promise<WebhookSubscription>;
30
+ update(subscriptionId: string, patch: UpdateWebhookInput): Promise<WebhookSubscription>;
31
+ delete(subscriptionId: string): Promise<void>;
32
+ /**
33
+ * Fire a `webhook.test` event to this subscription only.
34
+ * Useful for verifying connectivity and HMAC verification on your receiver.
35
+ */
36
+ test(subscriptionId: string): Promise<{
37
+ message: string;
38
+ eventId: string;
39
+ }>;
40
+ listDeliveries(subscriptionId: string, opts?: {
41
+ limit?: number;
42
+ }): Promise<{
43
+ deliveries: DeliveryLogEntry[];
44
+ count: number;
45
+ }>;
46
+ }
47
+ //# sourceMappingURL=webhooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/client/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAEhD,+EAA+E;IACzE,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IAI1D,IAAI,IAAI,OAAO,CAAC;QAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAOxE,cAAc,IAAI,OAAO,CAAC;QAC9B,UAAU,EAAE,SAAS,EAAE,CAAC;QACxB,QAAQ,EAAE,GAAG,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IAII,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAOzD,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC;IAQzB,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD;;;OAGG;IACG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAO3E,cAAc,CAClB,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GACxB,OAAO,CAAC;QAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAO9D"}