@1sat/wallet-server 0.0.29 → 0.0.32
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/createHostServer.d.ts +44 -0
- package/dist/createHostServer.d.ts.map +1 -0
- package/dist/createHostServer.js +205 -0
- package/dist/createHostServer.js.map +1 -0
- package/dist/createWalletServer.d.ts +15 -1
- package/dist/createWalletServer.d.ts.map +1 -1
- package/dist/createWalletServer.js +29 -6
- package/dist/createWalletServer.js.map +1 -1
- package/dist/hosting/client.d.ts +33 -0
- package/dist/hosting/client.d.ts.map +1 -0
- package/dist/hosting/client.js +45 -0
- package/dist/hosting/client.js.map +1 -0
- package/dist/hosting/routes.d.ts +27 -0
- package/dist/hosting/routes.d.ts.map +1 -0
- package/dist/hosting/routes.js +239 -0
- package/dist/hosting/routes.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/openapi/fragments.d.ts +20 -0
- package/dist/openapi/fragments.d.ts.map +1 -0
- package/dist/openapi/fragments.js +399 -0
- package/dist/openapi/fragments.js.map +1 -0
- package/dist/openapi/index.d.ts +25 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +82 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/paymail/destination.d.ts +14 -0
- package/dist/paymail/destination.d.ts.map +1 -0
- package/dist/paymail/destination.js +48 -0
- package/dist/paymail/destination.js.map +1 -0
- package/dist/paymail/entitlement.d.ts +15 -0
- package/dist/paymail/entitlement.d.ts.map +1 -0
- package/dist/paymail/entitlement.js +30 -0
- package/dist/paymail/entitlement.js.map +1 -0
- package/dist/paymail/messagebox.d.ts +25 -0
- package/dist/paymail/messagebox.d.ts.map +1 -0
- package/dist/paymail/messagebox.js +55 -0
- package/dist/paymail/messagebox.js.map +1 -0
- package/dist/paymail/pending.d.ts +19 -0
- package/dist/paymail/pending.d.ts.map +1 -0
- package/dist/paymail/pending.js +90 -0
- package/dist/paymail/pending.js.map +1 -0
- package/dist/paymail/resolve.d.ts +12 -0
- package/dist/paymail/resolve.d.ts.map +1 -0
- package/dist/paymail/resolve.js +72 -0
- package/dist/paymail/resolve.js.map +1 -0
- package/dist/paymail/routes.d.ts +8 -0
- package/dist/paymail/routes.d.ts.map +1 -0
- package/dist/paymail/routes.js +152 -0
- package/dist/paymail/routes.js.map +1 -0
- package/dist/paymail/types.d.ts +48 -0
- package/dist/paymail/types.d.ts.map +1 -0
- package/dist/paymail/types.js +2 -0
- package/dist/paymail/types.js.map +1 -0
- package/package.json +61 -57
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-surface OpenAPI path fragments. Each surface contributes its canonical
|
|
3
|
+
* paths only — legacy root-mounted messagebox aliases are intentionally
|
|
4
|
+
* undocumented. The assembler merges fragments for enabled surfaces.
|
|
5
|
+
*/
|
|
6
|
+
/** Tag metadata rendered as section headings + intros on the docs page. */
|
|
7
|
+
export const TAG_DOCS = [
|
|
8
|
+
{
|
|
9
|
+
name: 'auth',
|
|
10
|
+
'x-displayName': 'Authentication',
|
|
11
|
+
description: 'BRC-103/104 mutual authentication. Complete one handshake here and the resulting peer session authenticates you on every authed endpoint below — storage, account, hosting, and messagebox.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'storage',
|
|
15
|
+
'x-displayName': 'Wallet storage',
|
|
16
|
+
description: 'Remote storage for BRC-100 wallets. A wallet-toolbox client connects here to persist and sync its outputs, actions, and certificates.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'account',
|
|
20
|
+
'x-displayName': 'Storage account (billing)',
|
|
21
|
+
description: 'Metered billing for the wallet storage surface above: every identity gets a free byte baseline, and additional capacity is purchased in fixed-size chunks for a block-window term. Unrelated to paymail/messagebox hosting, which has its own flat-rate subscription below.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'hosting',
|
|
25
|
+
'x-displayName': 'Paymail + messagebox hosting',
|
|
26
|
+
description: 'Flat-rate subscription that covers both paymail hosting and messagebox delivery for an identity. While the subscription is active, this server answers paymail lookups for your alias and stores inbound messages for you. Billed separately from the storage account above.',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'paymail',
|
|
30
|
+
'x-displayName': 'Paymail (bsvalias)',
|
|
31
|
+
description: 'Public bsvalias surface for receiving payments at alias@domain. Endpoints beyond capability discovery are resolved from the capability document. When hosting is enabled, aliases resolve only for identities with an active hosting subscription.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'messagebox',
|
|
35
|
+
'x-displayName': 'Messagebox',
|
|
36
|
+
description: 'Store-and-forward message delivery between identity keys, with live WebSocket delivery to connected recipients. When hosting is enabled, recipients must hold an active hosting subscription.',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
const brc104 = [{ brc104: [] }];
|
|
40
|
+
const errorSchema = {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
status: { type: 'string', example: 'error' },
|
|
44
|
+
code: { type: 'string' },
|
|
45
|
+
description: { type: 'string' },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const paymentRequiredResponse = {
|
|
49
|
+
description: 'Payment required (BRC-41). Retry the request with an `x-bsv-payment` header containing `{derivationPrefix, derivationSuffix, transaction}` where `transaction` is a base64 AtomicBEEF paying the server.',
|
|
50
|
+
headers: {
|
|
51
|
+
'x-bsv-payment-satoshis-required': {
|
|
52
|
+
schema: { type: 'string' },
|
|
53
|
+
description: 'Sats owed for this request.',
|
|
54
|
+
},
|
|
55
|
+
'x-bsv-payment-derivation-prefix': {
|
|
56
|
+
schema: { type: 'string' },
|
|
57
|
+
description: 'Server nonce to use as the BRC-29 derivation prefix.',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
content: { 'application/json': { schema: errorSchema } },
|
|
61
|
+
};
|
|
62
|
+
export function authPaths() {
|
|
63
|
+
return {
|
|
64
|
+
'/.well-known/auth': {
|
|
65
|
+
post: {
|
|
66
|
+
tags: ['auth'],
|
|
67
|
+
summary: 'BRC-104 mutual-auth handshake',
|
|
68
|
+
description: 'Establishes a mutually authenticated peer session (BRC-103/104). One handshake authenticates the client for every authed surface on this server.',
|
|
69
|
+
responses: {
|
|
70
|
+
'200': { description: 'Handshake message accepted.' },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function storagePaths() {
|
|
77
|
+
return {
|
|
78
|
+
'/': {
|
|
79
|
+
post: {
|
|
80
|
+
tags: ['storage'],
|
|
81
|
+
summary: 'Wallet storage JSON-RPC',
|
|
82
|
+
description: 'JSON-RPC 2.0 endpoint exposing wallet-toolbox storage methods (`createAction`, `listOutputs`, `findOrInsertUser`, …) to remote BRC-100 wallets. When account metering is enabled, requests from over-capacity accounts fail with JSON-RPC error `-32005` (insufficient capacity).',
|
|
83
|
+
security: brc104,
|
|
84
|
+
requestBody: {
|
|
85
|
+
required: true,
|
|
86
|
+
content: {
|
|
87
|
+
'application/json': {
|
|
88
|
+
schema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
required: ['jsonrpc', 'id', 'method'],
|
|
91
|
+
properties: {
|
|
92
|
+
jsonrpc: { type: 'string', example: '2.0' },
|
|
93
|
+
id: { type: 'integer' },
|
|
94
|
+
method: { type: 'string' },
|
|
95
|
+
params: { type: 'array', items: {} },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
responses: {
|
|
102
|
+
'200': {
|
|
103
|
+
description: 'JSON-RPC response (result or error object).',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function accountPaths() {
|
|
111
|
+
const status = {
|
|
112
|
+
type: 'object',
|
|
113
|
+
properties: {
|
|
114
|
+
identityKey: { type: 'string' },
|
|
115
|
+
serverIdentityKey: { type: 'string' },
|
|
116
|
+
accountsEnabled: { type: 'boolean' },
|
|
117
|
+
currentBlock: { type: 'integer' },
|
|
118
|
+
usedBytes: { type: 'integer' },
|
|
119
|
+
baselineBytes: { type: 'integer' },
|
|
120
|
+
paidBytes: { type: 'integer' },
|
|
121
|
+
capacityBytes: { type: 'integer' },
|
|
122
|
+
deficitBytes: { type: 'integer' },
|
|
123
|
+
paidThroughBlock: { type: 'integer', nullable: true },
|
|
124
|
+
pricing: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
purchaseUnitBytes: { type: 'integer' },
|
|
128
|
+
satsPerUnit: { type: 'integer' },
|
|
129
|
+
durationBlocks: { type: 'integer' },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
nextPayment: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: {
|
|
135
|
+
derivationPrefix: { type: 'string' },
|
|
136
|
+
derivationSuffix: { type: 'string' },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
'/account/status': {
|
|
143
|
+
get: {
|
|
144
|
+
tags: ['account'],
|
|
145
|
+
summary: 'Storage account status and pricing',
|
|
146
|
+
description: 'Capacity, usage, and pricing for the authenticated identity. Capacity/pricing fields are present only when `accountsEnabled` is true.',
|
|
147
|
+
security: brc104,
|
|
148
|
+
responses: {
|
|
149
|
+
'200': {
|
|
150
|
+
description: 'Account status.',
|
|
151
|
+
content: { 'application/json': { schema: status } },
|
|
152
|
+
},
|
|
153
|
+
'401': { description: 'Unauthenticated.' },
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
'/account/payment': {
|
|
158
|
+
post: {
|
|
159
|
+
tags: ['account'],
|
|
160
|
+
summary: 'Purchase storage capacity',
|
|
161
|
+
description: 'BRC-41 payment endpoint. Call without payment to receive a 402 quote for the sats owed (full price for needed capacity minus prorated credit for the active payment), then retry with the `x-bsv-payment` header.',
|
|
162
|
+
security: brc104,
|
|
163
|
+
responses: {
|
|
164
|
+
'200': {
|
|
165
|
+
description: 'Payment accepted; returns updated account status.',
|
|
166
|
+
content: { 'application/json': { schema: status } },
|
|
167
|
+
},
|
|
168
|
+
'402': paymentRequiredResponse,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
export function hostingPaths() {
|
|
175
|
+
const statusSchema = {
|
|
176
|
+
type: 'object',
|
|
177
|
+
properties: {
|
|
178
|
+
enabled: { type: 'boolean' },
|
|
179
|
+
identityKey: { type: 'string' },
|
|
180
|
+
active: { type: 'boolean' },
|
|
181
|
+
expiresAt: {
|
|
182
|
+
type: 'integer',
|
|
183
|
+
description: 'Unix seconds when the subscription expires.',
|
|
184
|
+
},
|
|
185
|
+
priceSats: { type: 'integer' },
|
|
186
|
+
priceUsd: { type: 'number' },
|
|
187
|
+
periodSeconds: { type: 'integer' },
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
'/hosting/price': {
|
|
192
|
+
get: {
|
|
193
|
+
tags: ['hosting'],
|
|
194
|
+
summary: 'Hosting subscription price',
|
|
195
|
+
description: 'Public. Current price of a paymail + messagebox hosting subscription. `priceUsd` is the configured USD target price and is present only when the operator sets one.',
|
|
196
|
+
responses: {
|
|
197
|
+
'200': {
|
|
198
|
+
description: 'Current price.',
|
|
199
|
+
content: {
|
|
200
|
+
'application/json': {
|
|
201
|
+
schema: {
|
|
202
|
+
type: 'object',
|
|
203
|
+
required: ['priceSats', 'periodSeconds'],
|
|
204
|
+
properties: {
|
|
205
|
+
priceSats: { type: 'integer' },
|
|
206
|
+
priceUsd: { type: 'number' },
|
|
207
|
+
periodSeconds: { type: 'integer' },
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
'404': { description: 'Hosting disabled on this server.' },
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
'/hosting/status': {
|
|
218
|
+
get: {
|
|
219
|
+
tags: ['hosting'],
|
|
220
|
+
summary: 'Hosting subscription status',
|
|
221
|
+
security: brc104,
|
|
222
|
+
responses: {
|
|
223
|
+
'200': {
|
|
224
|
+
description: 'Subscription status for the authenticated identity.',
|
|
225
|
+
content: { 'application/json': { schema: statusSchema } },
|
|
226
|
+
},
|
|
227
|
+
'401': { description: 'Unauthenticated.' },
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
'/hosting/subscribe': {
|
|
232
|
+
post: {
|
|
233
|
+
tags: ['hosting'],
|
|
234
|
+
summary: 'Buy or renew a hosting subscription',
|
|
235
|
+
description: 'BRC-41 payment endpoint (402 flow, price from `/hosting/price`). On success the server mints a receipt extending the subscription by one period from the later of now or the current expiry.',
|
|
236
|
+
security: brc104,
|
|
237
|
+
responses: {
|
|
238
|
+
'200': {
|
|
239
|
+
description: 'Subscription active.',
|
|
240
|
+
content: {
|
|
241
|
+
'application/json': {
|
|
242
|
+
schema: {
|
|
243
|
+
type: 'object',
|
|
244
|
+
properties: {
|
|
245
|
+
status: { type: 'string', example: 'ok' },
|
|
246
|
+
identityKey: { type: 'string' },
|
|
247
|
+
expiresAt: { type: 'integer' },
|
|
248
|
+
txid: { type: 'string' },
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
'402': paymentRequiredResponse,
|
|
255
|
+
'404': { description: 'Hosting disabled on this server.' },
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
export function messageboxPaths() {
|
|
262
|
+
return {
|
|
263
|
+
'/messagebox/sendMessage': {
|
|
264
|
+
post: {
|
|
265
|
+
tags: ['messagebox'],
|
|
266
|
+
summary: 'Send a message to a recipient inbox',
|
|
267
|
+
description: 'Stores a message for the recipient and delivers it live over WebSocket when connected. When hosting is enabled, every recipient must hold an active hosting subscription (403 `ERR_HOSTING_REQUIRED` otherwise).',
|
|
268
|
+
security: brc104,
|
|
269
|
+
requestBody: {
|
|
270
|
+
required: true,
|
|
271
|
+
content: {
|
|
272
|
+
'application/json': {
|
|
273
|
+
schema: {
|
|
274
|
+
type: 'object',
|
|
275
|
+
required: ['message'],
|
|
276
|
+
properties: {
|
|
277
|
+
message: {
|
|
278
|
+
type: 'object',
|
|
279
|
+
required: ['recipient', 'messageBox', 'messageId', 'body'],
|
|
280
|
+
properties: {
|
|
281
|
+
recipient: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
description: 'Recipient identity key (hex).',
|
|
284
|
+
},
|
|
285
|
+
messageBox: {
|
|
286
|
+
type: 'string',
|
|
287
|
+
description: 'Inbox name, e.g. `payment_inbox`.',
|
|
288
|
+
},
|
|
289
|
+
messageId: { type: 'string' },
|
|
290
|
+
body: {
|
|
291
|
+
description: 'Message payload (string or object).',
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
responses: {
|
|
301
|
+
'200': { description: 'Message stored.' },
|
|
302
|
+
'403': {
|
|
303
|
+
description: 'Recipient has no active hosting subscription (`ERR_HOSTING_REQUIRED`).',
|
|
304
|
+
content: { 'application/json': { schema: errorSchema } },
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
'/messagebox/listMessages': {
|
|
310
|
+
post: {
|
|
311
|
+
tags: ['messagebox'],
|
|
312
|
+
summary: 'List messages in one of your inboxes',
|
|
313
|
+
security: brc104,
|
|
314
|
+
requestBody: {
|
|
315
|
+
required: true,
|
|
316
|
+
content: {
|
|
317
|
+
'application/json': {
|
|
318
|
+
schema: {
|
|
319
|
+
type: 'object',
|
|
320
|
+
required: ['messageBox'],
|
|
321
|
+
properties: { messageBox: { type: 'string' } },
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
responses: { '200': { description: 'Messages in the box.' } },
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
'/messagebox/acknowledgeMessage': {
|
|
330
|
+
post: {
|
|
331
|
+
tags: ['messagebox'],
|
|
332
|
+
summary: 'Acknowledge (delete) received messages',
|
|
333
|
+
security: brc104,
|
|
334
|
+
requestBody: {
|
|
335
|
+
required: true,
|
|
336
|
+
content: {
|
|
337
|
+
'application/json': {
|
|
338
|
+
schema: {
|
|
339
|
+
type: 'object',
|
|
340
|
+
required: ['messageIds'],
|
|
341
|
+
properties: {
|
|
342
|
+
messageIds: { type: 'array', items: { type: 'string' } },
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
responses: { '200': { description: 'Messages acknowledged.' } },
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
'/messagebox/registerDevice': {
|
|
352
|
+
post: {
|
|
353
|
+
tags: ['messagebox'],
|
|
354
|
+
summary: 'Register a device for push notifications',
|
|
355
|
+
security: brc104,
|
|
356
|
+
requestBody: {
|
|
357
|
+
required: true,
|
|
358
|
+
content: {
|
|
359
|
+
'application/json': {
|
|
360
|
+
schema: {
|
|
361
|
+
type: 'object',
|
|
362
|
+
required: ['fcmToken'],
|
|
363
|
+
properties: {
|
|
364
|
+
fcmToken: { type: 'string' },
|
|
365
|
+
deviceId: { type: 'string' },
|
|
366
|
+
platform: { type: 'string' },
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
responses: { '200': { description: 'Device registered.' } },
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
'/messagebox/devices': {
|
|
376
|
+
get: {
|
|
377
|
+
tags: ['messagebox'],
|
|
378
|
+
summary: 'List your registered devices',
|
|
379
|
+
security: brc104,
|
|
380
|
+
responses: { '200': { description: 'Registered devices.' } },
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
export function paymailPaths() {
|
|
386
|
+
return {
|
|
387
|
+
'/.well-known/bsvalias': {
|
|
388
|
+
get: {
|
|
389
|
+
tags: ['paymail'],
|
|
390
|
+
summary: 'Paymail capability discovery',
|
|
391
|
+
description: 'Public bsvalias capability document. Paymail clients discover the PKI, public-profile, payment-destination, and receive-transaction endpoint templates from here rather than hardcoding paths.',
|
|
392
|
+
responses: {
|
|
393
|
+
'200': { description: 'Capability document.' },
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=fragments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fragments.js","sourceRoot":"","sources":["../../src/openapi/fragments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI assembly for the host server. The spec is built per request from
|
|
3
|
+
* the surfaces actually mounted, so a deployment's docs never advertise
|
|
4
|
+
* routes it doesn't serve. Canonical paths only — the legacy root-mounted
|
|
5
|
+
* messagebox aliases are undocumented by design.
|
|
6
|
+
*/
|
|
7
|
+
import type { Express } from 'express';
|
|
8
|
+
export interface OpenApiSurfaces {
|
|
9
|
+
storage?: boolean;
|
|
10
|
+
accounts?: boolean;
|
|
11
|
+
/** Getter so a live config toggle is reflected without restart. */
|
|
12
|
+
hosting?: () => boolean;
|
|
13
|
+
paymail?: boolean;
|
|
14
|
+
messagebox?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface OpenApiOptions {
|
|
17
|
+
serverIdentityKey: string;
|
|
18
|
+
surfaces: OpenApiSurfaces;
|
|
19
|
+
title?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
version?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function buildOpenApiSpec(options: OpenApiOptions): object;
|
|
24
|
+
export declare function mountOpenApiRoutes(app: Express, options: OpenApiOptions): void;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openapi/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAYtC,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC9B,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,eAAe,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAgDhE;AAuBD,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,cAAc,GACrB,IAAI,CAON"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI assembly for the host server. The spec is built per request from
|
|
3
|
+
* the surfaces actually mounted, so a deployment's docs never advertise
|
|
4
|
+
* routes it doesn't serve. Canonical paths only — the legacy root-mounted
|
|
5
|
+
* messagebox aliases are undocumented by design.
|
|
6
|
+
*/
|
|
7
|
+
import { TAG_DOCS, accountPaths, authPaths, hostingPaths, messageboxPaths, paymailPaths, storagePaths, } from './fragments';
|
|
8
|
+
export function buildOpenApiSpec(options) {
|
|
9
|
+
const paths = { ...authPaths() };
|
|
10
|
+
const tags = new Set(['auth']);
|
|
11
|
+
if (options.surfaces.storage) {
|
|
12
|
+
Object.assign(paths, storagePaths());
|
|
13
|
+
tags.add('storage');
|
|
14
|
+
}
|
|
15
|
+
if (options.surfaces.accounts) {
|
|
16
|
+
Object.assign(paths, accountPaths());
|
|
17
|
+
tags.add('account');
|
|
18
|
+
}
|
|
19
|
+
if (options.surfaces.hosting?.()) {
|
|
20
|
+
Object.assign(paths, hostingPaths());
|
|
21
|
+
tags.add('hosting');
|
|
22
|
+
}
|
|
23
|
+
if (options.surfaces.paymail) {
|
|
24
|
+
Object.assign(paths, paymailPaths());
|
|
25
|
+
tags.add('paymail');
|
|
26
|
+
}
|
|
27
|
+
if (options.surfaces.messagebox) {
|
|
28
|
+
Object.assign(paths, messageboxPaths());
|
|
29
|
+
tags.add('messagebox');
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
openapi: '3.0.3',
|
|
33
|
+
info: {
|
|
34
|
+
title: options.title ?? '1sat Wallet Host Server',
|
|
35
|
+
version: options.version ?? '1.0.0',
|
|
36
|
+
description: options.description ??
|
|
37
|
+
'BRC-100 wallet storage host. Authenticated surfaces use BRC-103/104 mutual auth (one handshake at POST /.well-known/auth covers all of them); paid surfaces use the BRC-41 402 payment flow.',
|
|
38
|
+
},
|
|
39
|
+
'x-server-identity-key': options.serverIdentityKey,
|
|
40
|
+
tags: TAG_DOCS.filter((t) => tags.has(t.name)),
|
|
41
|
+
components: {
|
|
42
|
+
securitySchemes: {
|
|
43
|
+
brc104: {
|
|
44
|
+
type: 'apiKey',
|
|
45
|
+
in: 'header',
|
|
46
|
+
name: 'x-bsv-auth-identity-key',
|
|
47
|
+
description: 'BRC-103/104 mutual authentication. Use an auth-capable client (e.g. AuthFetch from @bsv/sdk); requests are signed, not bearer-token authorized.',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
paths,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Scalar shell — renders /openapi.json client-side. Needs internet for the CDN script; the API itself does not. */
|
|
55
|
+
function docsShellHtml(title) {
|
|
56
|
+
const safeTitle = title
|
|
57
|
+
.replace(/&/g, '&')
|
|
58
|
+
.replace(/</g, '<')
|
|
59
|
+
.replace(/>/g, '>');
|
|
60
|
+
return `<!doctype html>
|
|
61
|
+
<html lang="en">
|
|
62
|
+
<head>
|
|
63
|
+
<meta charset="utf-8">
|
|
64
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
65
|
+
<title>${safeTitle}</title>
|
|
66
|
+
</head>
|
|
67
|
+
<body>
|
|
68
|
+
<div id="app"></div>
|
|
69
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
70
|
+
<script>Scalar.createApiReference('#app', { url: '/openapi.json' })</script>
|
|
71
|
+
</body>
|
|
72
|
+
</html>`;
|
|
73
|
+
}
|
|
74
|
+
export function mountOpenApiRoutes(app, options) {
|
|
75
|
+
app.get('/openapi.json', (_req, res) => {
|
|
76
|
+
res.json(buildOpenApiSpec(options));
|
|
77
|
+
});
|
|
78
|
+
app.get('/', (_req, res) => {
|
|
79
|
+
res.type('html').send(docsShellHtml(options.title ?? '1sat Wallet Host Server'));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/openapi/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BRC-29 payment destination for a bound identity (anyone-deriver path).
|
|
3
|
+
* Port of Go DerivePaymentDestination.
|
|
4
|
+
*/
|
|
5
|
+
import type { PendingPayment, PendingStore } from './types';
|
|
6
|
+
export declare function createPaymentDestination(store: PendingStore, opts: {
|
|
7
|
+
alias: string;
|
|
8
|
+
domain: string;
|
|
9
|
+
identityPubKey: string;
|
|
10
|
+
satoshis: number;
|
|
11
|
+
ttlMs?: number;
|
|
12
|
+
}): Promise<PendingPayment>;
|
|
13
|
+
export declare function verifyPaymentOutputs(outputScriptsHex: string[], satoshis: number[], pending: PendingPayment): number;
|
|
14
|
+
//# sourceMappingURL=destination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destination.d.ts","sourceRoot":"","sources":["../../src/paymail/destination.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAQ3D,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE;IACL,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd,GACC,OAAO,CAAC,cAAc,CAAC,CA+BzB;AAED,wBAAgB,oBAAoB,CACnC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,cAAc,GACrB,MAAM,CAQR"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BRC-29 payment destination for a bound identity (anyone-deriver path).
|
|
3
|
+
* Port of Go DerivePaymentDestination.
|
|
4
|
+
*/
|
|
5
|
+
import { BRC29_PROTOCOL_ID } from '@1sat/types';
|
|
6
|
+
import { KeyDeriver, P2PKH, PrivateKey, PublicKey, Utils } from '@bsv/sdk';
|
|
7
|
+
import { DEFAULT_TTL_MS, generateReference } from './pending';
|
|
8
|
+
function randomB64(n) {
|
|
9
|
+
const b = new Uint8Array(n);
|
|
10
|
+
crypto.getRandomValues(b);
|
|
11
|
+
return Utils.toBase64(Array.from(b));
|
|
12
|
+
}
|
|
13
|
+
export async function createPaymentDestination(store, opts) {
|
|
14
|
+
const derivationPrefix = randomB64(16);
|
|
15
|
+
const derivationSuffix = randomB64(16);
|
|
16
|
+
const keyID = `${derivationPrefix} ${derivationSuffix}`;
|
|
17
|
+
// Anyone-key derives the payment pub the recipient can spend (BRC-29).
|
|
18
|
+
const anyone = new KeyDeriver(new PrivateKey(1));
|
|
19
|
+
const paymentPub = anyone.derivePublicKey(BRC29_PROTOCOL_ID, keyID, PublicKey.fromString(opts.identityPubKey), false);
|
|
20
|
+
const outputScript = new P2PKH().lock(paymentPub.toAddress()).toHex();
|
|
21
|
+
const now = new Date();
|
|
22
|
+
const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
23
|
+
const pending = {
|
|
24
|
+
reference: generateReference(),
|
|
25
|
+
alias: opts.alias,
|
|
26
|
+
domain: opts.domain,
|
|
27
|
+
identityPubKey: opts.identityPubKey,
|
|
28
|
+
derivationPrefix,
|
|
29
|
+
derivationSuffix,
|
|
30
|
+
satoshis: opts.satoshis,
|
|
31
|
+
outputScript,
|
|
32
|
+
createdAt: now,
|
|
33
|
+
expiresAt: new Date(now.getTime() + ttl),
|
|
34
|
+
};
|
|
35
|
+
await store.create(pending);
|
|
36
|
+
return pending;
|
|
37
|
+
}
|
|
38
|
+
export function verifyPaymentOutputs(outputScriptsHex, satoshis, pending) {
|
|
39
|
+
for (let i = 0; i < outputScriptsHex.length; i++) {
|
|
40
|
+
if (outputScriptsHex[i] !== pending.outputScript)
|
|
41
|
+
continue;
|
|
42
|
+
if (pending.satoshis === 0 || satoshis[i] === pending.satoshis) {
|
|
43
|
+
return i;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
throw new Error('no output matches the expected payment destination');
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=destination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destination.js","sourceRoot":"","sources":["../../src/paymail/destination.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAG7D,SAAS,SAAS,CAAC,CAAS;IAC3B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAC3B,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IACzB,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC7C,KAAmB,EACnB,IAMC;IAED,MAAM,gBAAgB,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,gBAAgB,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,GAAG,gBAAgB,IAAI,gBAAgB,EAAE,CAAA;IAEvD,uEAAuE;IACvE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IAChD,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CACxC,iBAAiB,EACjB,KAAK,EACL,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,EACzC,KAAK,CACL,CAAA;IACD,MAAM,YAAY,GAAG,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAErE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,cAAc,CAAA;IACxC,MAAM,OAAO,GAAmB;QAC/B,SAAS,EAAE,iBAAiB,EAAE;QAC9B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,gBAAgB;QAChB,gBAAgB;QAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,YAAY;QACZ,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC;KACxC,CAAA;IACD,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,OAAO,CAAA;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,CACnC,gBAA0B,EAC1B,QAAkB,EAClB,OAAuB;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,IAAI,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY;YAAE,SAAQ;QAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;YAChE,OAAO,CAAC,CAAA;QACT,CAAC;IACF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;AACtE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host subscription check — wallet-local receipts in HOSTING_BASKET.
|
|
3
|
+
* Identity is only in tags (not on-chain script).
|
|
4
|
+
*/
|
|
5
|
+
import type { WalletInterface } from '@bsv/sdk';
|
|
6
|
+
export interface EntitlementStatus {
|
|
7
|
+
active: boolean;
|
|
8
|
+
expiresAt?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* True if host wallet has an unspent receipt for identity with exp > now.
|
|
12
|
+
* Uses max exp if multiple receipts exist.
|
|
13
|
+
*/
|
|
14
|
+
export declare function checkHostingEntitlement(wallet: WalletInterface, identityKeyHex: string, nowUnix?: number): Promise<EntitlementStatus>;
|
|
15
|
+
//# sourceMappingURL=entitlement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entitlement.d.ts","sourceRoot":"","sources":["../../src/paymail/entitlement.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,eAAe,EACvB,cAAc,EAAE,MAAM,EACtB,OAAO,SAAgC,GACrC,OAAO,CAAC,iBAAiB,CAAC,CAoB5B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host subscription check — wallet-local receipts in HOSTING_BASKET.
|
|
3
|
+
* Identity is only in tags (not on-chain script).
|
|
4
|
+
*/
|
|
5
|
+
import { HOSTING_BASKET, hostingPayerTag, readHostingExp, } from '@1sat/types';
|
|
6
|
+
/**
|
|
7
|
+
* True if host wallet has an unspent receipt for identity with exp > now.
|
|
8
|
+
* Uses max exp if multiple receipts exist.
|
|
9
|
+
*/
|
|
10
|
+
export async function checkHostingEntitlement(wallet, identityKeyHex, nowUnix = Math.floor(Date.now() / 1000)) {
|
|
11
|
+
const { outputs } = await wallet.listOutputs({
|
|
12
|
+
basket: HOSTING_BASKET,
|
|
13
|
+
tags: [hostingPayerTag(identityKeyHex)],
|
|
14
|
+
tagQueryMode: 'all',
|
|
15
|
+
includeTags: true,
|
|
16
|
+
limit: 100,
|
|
17
|
+
});
|
|
18
|
+
// Correct subscribe path leaves a single receipt; if more exist, use latest exp.
|
|
19
|
+
let maxExp = 0;
|
|
20
|
+
for (const o of outputs) {
|
|
21
|
+
const exp = readHostingExp(o.tags);
|
|
22
|
+
if (exp !== undefined && exp > maxExp)
|
|
23
|
+
maxExp = exp;
|
|
24
|
+
}
|
|
25
|
+
if (maxExp > nowUnix) {
|
|
26
|
+
return { active: true, expiresAt: maxExp };
|
|
27
|
+
}
|
|
28
|
+
return { active: false, expiresAt: maxExp > 0 ? maxExp : undefined };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=entitlement.js.map
|