@1sat/wallet-server 0.0.1

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.
Files changed (70) hide show
  1. package/README.md +50 -0
  2. package/dist/accounts/index.d.ts +8 -0
  3. package/dist/accounts/index.d.ts.map +1 -0
  4. package/dist/accounts/index.js +7 -0
  5. package/dist/accounts/index.js.map +1 -0
  6. package/dist/accounts/metering.d.ts +15 -0
  7. package/dist/accounts/metering.d.ts.map +1 -0
  8. package/dist/accounts/metering.js +32 -0
  9. package/dist/accounts/metering.js.map +1 -0
  10. package/dist/accounts/middleware.d.ts +41 -0
  11. package/dist/accounts/middleware.d.ts.map +1 -0
  12. package/dist/accounts/middleware.js +137 -0
  13. package/dist/accounts/middleware.js.map +1 -0
  14. package/dist/accounts/migrations.d.ts +18 -0
  15. package/dist/accounts/migrations.d.ts.map +1 -0
  16. package/dist/accounts/migrations.js +46 -0
  17. package/dist/accounts/migrations.js.map +1 -0
  18. package/dist/accounts/paymentValidation.d.ts +59 -0
  19. package/dist/accounts/paymentValidation.d.ts.map +1 -0
  20. package/dist/accounts/paymentValidation.js +112 -0
  21. package/dist/accounts/paymentValidation.js.map +1 -0
  22. package/dist/accounts/pricing.d.ts +30 -0
  23. package/dist/accounts/pricing.d.ts.map +1 -0
  24. package/dist/accounts/pricing.js +32 -0
  25. package/dist/accounts/pricing.js.map +1 -0
  26. package/dist/accounts/repo.d.ts +17 -0
  27. package/dist/accounts/repo.d.ts.map +1 -0
  28. package/dist/accounts/repo.js +94 -0
  29. package/dist/accounts/repo.js.map +1 -0
  30. package/dist/accounts/types.d.ts +45 -0
  31. package/dist/accounts/types.d.ts.map +1 -0
  32. package/dist/accounts/types.js +2 -0
  33. package/dist/accounts/types.js.map +1 -0
  34. package/dist/createBearerServer.d.ts +21 -0
  35. package/dist/createBearerServer.d.ts.map +1 -0
  36. package/dist/createBearerServer.js +30 -0
  37. package/dist/createBearerServer.js.map +1 -0
  38. package/dist/createWalletMonitor.d.ts +29 -0
  39. package/dist/createWalletMonitor.d.ts.map +1 -0
  40. package/dist/createWalletMonitor.js +90 -0
  41. package/dist/createWalletMonitor.js.map +1 -0
  42. package/dist/createWalletRpcHandler.d.ts +4 -0
  43. package/dist/createWalletRpcHandler.d.ts.map +1 -0
  44. package/dist/createWalletRpcHandler.js +92 -0
  45. package/dist/createWalletRpcHandler.js.map +1 -0
  46. package/dist/createWalletServer.d.ts +32 -0
  47. package/dist/createWalletServer.d.ts.map +1 -0
  48. package/dist/createWalletServer.js +183 -0
  49. package/dist/createWalletServer.js.map +1 -0
  50. package/dist/dispatch.d.ts +21 -0
  51. package/dist/dispatch.d.ts.map +1 -0
  52. package/dist/dispatch.js +183 -0
  53. package/dist/dispatch.js.map +1 -0
  54. package/dist/index.d.ts +15 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +8 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/resolvers/bearer.d.ts +12 -0
  59. package/dist/resolvers/bearer.d.ts.map +1 -0
  60. package/dist/resolvers/bearer.js +43 -0
  61. package/dist/resolvers/bearer.js.map +1 -0
  62. package/dist/resolvers/index.d.ts +3 -0
  63. package/dist/resolvers/index.d.ts.map +1 -0
  64. package/dist/resolvers/index.js +2 -0
  65. package/dist/resolvers/index.js.map +1 -0
  66. package/dist/types.d.ts +52 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +2 -0
  69. package/dist/types.js.map +1 -0
  70. package/package.json +48 -0
@@ -0,0 +1,183 @@
1
+ import { createAuthMiddleware } from '@bsv/auth-express-middleware';
2
+ import { PrivateKey, ProtoWallet, PublicKey, } from '@bsv/sdk';
3
+ import express from 'express';
4
+ import { AccountsGate } from './accounts';
5
+ import { createWalletRpcHandler } from './createWalletRpcHandler';
6
+ import { dispatch } from './dispatch';
7
+ import { bearerResolver } from './resolvers/bearer';
8
+ export function createWalletServer(config) {
9
+ const publicPath = config.publicPath === undefined ? '/' : config.publicPath;
10
+ const internalPath = config.internalPath === undefined ? '/internal' : config.internalPath;
11
+ if (!publicPath && !internalPath) {
12
+ throw new Error('createWalletServer requires at least one of publicPath or internalPath');
13
+ }
14
+ if (internalPath && !config.internalAPIKey) {
15
+ throw new Error('internalAPIKey is required when internalPath is enabled');
16
+ }
17
+ const app = express();
18
+ app.use(express.json({ limit: config.bodyLimit ?? '30mb' }));
19
+ app.use(corsMiddleware);
20
+ const wallet = buildServerWallet(config.serverPrivateKey);
21
+ const serverIdentityKey = identityKeyFromPrivateKey(config.serverPrivateKey);
22
+ let gate;
23
+ if (config.accounts?.config.enabled) {
24
+ const deps = {
25
+ config: config.accounts.config,
26
+ walletStorage: config.storage,
27
+ knex: config.accounts.knex,
28
+ wallet,
29
+ serverIdentityKey,
30
+ currentBlock: config.accounts.currentBlock,
31
+ };
32
+ gate = new AccountsGate(deps);
33
+ }
34
+ if (publicPath) {
35
+ mountPublicRoute(app, publicPath, config, wallet, gate);
36
+ }
37
+ if (internalPath) {
38
+ mountInternalRoute(app, internalPath, config, gate);
39
+ }
40
+ let server;
41
+ return {
42
+ app,
43
+ start() {
44
+ return new Promise((resolve, reject) => {
45
+ server = app.listen(config.listen.port, config.listen.host ?? '0.0.0.0', () => {
46
+ const address = server?.address();
47
+ const port = typeof address === 'object' && address
48
+ ? address.port
49
+ : config.listen.port;
50
+ resolve(port);
51
+ });
52
+ server.on('error', reject);
53
+ });
54
+ },
55
+ stop() {
56
+ return new Promise((resolve, reject) => {
57
+ if (!server)
58
+ return resolve();
59
+ server.close((err) => (err ? reject(err) : resolve()));
60
+ });
61
+ },
62
+ };
63
+ }
64
+ function mountPublicRoute(app, path, config, wallet, gate) {
65
+ const authMiddleware = createAuthMiddleware({ wallet });
66
+ app.use(path, authMiddleware);
67
+ app.post(path, async (req, res) => {
68
+ const identityKey = req.auth?.identityKey;
69
+ if (!identityKey || identityKey === 'unknown') {
70
+ return res.status(401).json({
71
+ jsonrpc: '2.0',
72
+ error: { code: -32000, message: 'Unauthenticated' },
73
+ id: req.body?.id ?? null,
74
+ });
75
+ }
76
+ const body = req.body;
77
+ if (!isJsonRpcLike(body)) {
78
+ return res.status(400).json({
79
+ jsonrpc: '2.0',
80
+ error: { code: -32600, message: 'Invalid Request' },
81
+ id: body?.id ?? null,
82
+ });
83
+ }
84
+ const id = normalizeJsonRpcId(body.id);
85
+ if (gate) {
86
+ const decision = await gate.check({
87
+ method: body.method,
88
+ identity: { identityKey },
89
+ request: expressToFetchRequest(req),
90
+ id,
91
+ });
92
+ if (decision.type === 'blocked') {
93
+ return relayFetchResponse(res, decision.response);
94
+ }
95
+ }
96
+ const response = await dispatch({
97
+ storage: config.storage,
98
+ adminIdentityKeys: config.adminIdentityKeys,
99
+ makeLogger: config.makeLogger,
100
+ }, {
101
+ method: body.method,
102
+ params: Array.isArray(body.params) ? body.params : [],
103
+ id,
104
+ identity: { identityKey },
105
+ });
106
+ res.status(200).json(response);
107
+ });
108
+ }
109
+ async function relayFetchResponse(res, fetchRes) {
110
+ res.status(fetchRes.status);
111
+ fetchRes.headers.forEach((v, k) => res.set(k, v));
112
+ const buf = Buffer.from(await fetchRes.arrayBuffer());
113
+ res.send(buf);
114
+ }
115
+ function mountInternalRoute(app, path, config, gate) {
116
+ const preDispatch = gate
117
+ ? (ctx) => gate.check(ctx)
118
+ : undefined;
119
+ const handler = createWalletRpcHandler({
120
+ storage: config.storage,
121
+ resolveIdentity: bearerResolver({
122
+ token: config.internalAPIKey,
123
+ identityHeader: config.internalIdentityHeader,
124
+ }),
125
+ adminIdentityKeys: config.adminIdentityKeys,
126
+ makeLogger: config.makeLogger,
127
+ preDispatch,
128
+ });
129
+ app.post(path, async (req, res) => {
130
+ const fetchReq = expressToFetchRequest(req);
131
+ const fetchRes = await handler(fetchReq);
132
+ res.status(fetchRes.status);
133
+ fetchRes.headers.forEach((v, k) => res.set(k, v));
134
+ const buf = Buffer.from(await fetchRes.arrayBuffer());
135
+ res.send(buf);
136
+ });
137
+ }
138
+ function buildServerWallet(privateKeyHex) {
139
+ const key = PrivateKey.fromHex(privateKeyHex);
140
+ return new ProtoWallet(key);
141
+ }
142
+ function identityKeyFromPrivateKey(privateKeyHex) {
143
+ const key = PrivateKey.fromHex(privateKeyHex);
144
+ const pub = PublicKey.fromPrivateKey(key);
145
+ return pub.toString();
146
+ }
147
+ function corsMiddleware(_req, res, next) {
148
+ res.header('Access-Control-Allow-Origin', '*');
149
+ res.header('Access-Control-Allow-Headers', '*');
150
+ res.header('Access-Control-Allow-Methods', '*');
151
+ res.header('Access-Control-Expose-Headers', '*');
152
+ next();
153
+ }
154
+ function isJsonRpcLike(body) {
155
+ if (typeof body !== 'object' || body === null)
156
+ return false;
157
+ const b = body;
158
+ return b.jsonrpc === '2.0' && typeof b.method === 'string';
159
+ }
160
+ function normalizeJsonRpcId(id) {
161
+ if (typeof id === 'string' || typeof id === 'number')
162
+ return id;
163
+ return null;
164
+ }
165
+ function expressToFetchRequest(req) {
166
+ const protocol = req.headers['x-forwarded-proto'] ?? 'http';
167
+ const host = req.headers.host ?? 'localhost';
168
+ const url = new URL(req.originalUrl || req.url, `${protocol}://${host}`);
169
+ const headers = new Headers();
170
+ for (const [k, v] of Object.entries(req.headers)) {
171
+ if (typeof v === 'string')
172
+ headers.set(k, v);
173
+ else if (Array.isArray(v))
174
+ headers.set(k, v.join(', '));
175
+ }
176
+ const body = req.body !== undefined ? JSON.stringify(req.body) : undefined;
177
+ return new Request(url, {
178
+ method: req.method,
179
+ headers,
180
+ body,
181
+ });
182
+ }
183
+ //# sourceMappingURL=createWalletServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWalletServer.js","sourceRoot":"","sources":["../src/createWalletServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { JsonRpcResponse, MakeWalletLogger, ResolvedIdentity, WalletStorageProvider } from './types';
2
+ export interface DispatchContext {
3
+ storage: WalletStorageProvider;
4
+ adminIdentityKeys?: string[];
5
+ makeLogger?: MakeWalletLogger;
6
+ }
7
+ export interface DispatchInput {
8
+ method: string;
9
+ params: unknown[];
10
+ id: string | number | null;
11
+ identity: ResolvedIdentity;
12
+ }
13
+ /**
14
+ * Methods that grow persisted wallet state. The accounts middleware uses this
15
+ * to decide whether a request is subject to metering. All other methods
16
+ * (reads, sync, shrink) stay free.
17
+ */
18
+ export declare const BILLABLE_METHODS: ReadonlySet<string>;
19
+ export declare function isBillableMethod(method: string): boolean;
20
+ export declare function dispatch(ctx: DispatchContext, input: DispatchInput): Promise<JsonRpcResponse>;
21
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAEhB,qBAAqB,EACrB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,qBAAqB,CAAA;IAC9B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC7B;AAED,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,gBAAgB,CAAA;CAC1B;AAMD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAM/C,CAAA;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAsB,QAAQ,CAC7B,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,CAAC,CAoC1B"}
@@ -0,0 +1,183 @@
1
+ import { WERR_UNAUTHORIZED } from '@bsv/wallet-toolbox/out/src/sdk/WERR_errors.js';
2
+ import { WalletError } from '@bsv/wallet-toolbox/out/src/sdk/WalletError.js';
3
+ const METHODS_NO_AUTH = new Set(['getSettings']);
4
+ const METHODS_IGNORED = new Set(['destroy']);
5
+ const METHODS_ADMIN = new Set(['adminStats']);
6
+ /**
7
+ * Methods that grow persisted wallet state. The accounts middleware uses this
8
+ * to decide whether a request is subject to metering. All other methods
9
+ * (reads, sync, shrink) stay free.
10
+ */
11
+ export const BILLABLE_METHODS = new Set([
12
+ 'createAction',
13
+ 'processAction',
14
+ 'internalizeAction',
15
+ 'insertCertificateAuth',
16
+ 'processSyncChunk',
17
+ ]);
18
+ export function isBillableMethod(method) {
19
+ return BILLABLE_METHODS.has(method);
20
+ }
21
+ export async function dispatch(ctx, input) {
22
+ const { method, id } = input;
23
+ const storage = ctx.storage;
24
+ if (typeof storage[method] !== 'function') {
25
+ return methodNotFound(method, id);
26
+ }
27
+ if (METHODS_IGNORED.has(method)) {
28
+ return { jsonrpc: '2.0', result: undefined, id };
29
+ }
30
+ try {
31
+ const preparedParams = await prepareParams(ctx, input);
32
+ const logger = attachLoggerIfRequested(ctx, method, input.identity, preparedParams);
33
+ try {
34
+ const result = await storage[method](...preparedParams);
35
+ attachLoggerTail(logger, result);
36
+ return { jsonrpc: '2.0', result, id };
37
+ }
38
+ catch (err) {
39
+ logger?.flush?.();
40
+ throw err;
41
+ }
42
+ }
43
+ catch (err) {
44
+ return marshalError(err, id);
45
+ }
46
+ }
47
+ async function prepareParams(ctx, input) {
48
+ const { method, identity } = input;
49
+ const params = [...input.params];
50
+ if (METHODS_NO_AUTH.has(method)) {
51
+ return params;
52
+ }
53
+ if (method === 'findOrInsertUser') {
54
+ if (params[0] !== identity.identityKey) {
55
+ throw new WERR_UNAUTHORIZED('function may only access authenticated user.');
56
+ }
57
+ return params;
58
+ }
59
+ if (METHODS_ADMIN.has(method)) {
60
+ const arg0 = params[0];
61
+ if (!arg0 || arg0.identityKey !== identity.identityKey) {
62
+ throw new WERR_UNAUTHORIZED('function may only access authenticated admin user.');
63
+ }
64
+ if (!ctx.adminIdentityKeys?.includes(identity.identityKey)) {
65
+ throw new WERR_UNAUTHORIZED('function may only be accessed by admin user.');
66
+ }
67
+ return params;
68
+ }
69
+ await applyParam0Auth(ctx, identity, params);
70
+ if (method === 'processSyncChunk' && params[1]) {
71
+ normalizeSyncChunk(params[1]);
72
+ }
73
+ return params;
74
+ }
75
+ async function applyParam0Auth(ctx, identity, params) {
76
+ if (typeof params[0] !== 'object' || params[0] === null) {
77
+ params[0] = {};
78
+ }
79
+ const arg0 = params[0];
80
+ if (arg0.identityKey && arg0.identityKey !== identity.identityKey) {
81
+ throw new WERR_UNAUTHORIZED('identityKey does not match authentication');
82
+ }
83
+ const { user } = await ctx.storage.findOrInsertUser(identity.identityKey);
84
+ arg0.reqAuthUserId = user.userId;
85
+ if (arg0.identityKey) {
86
+ arg0.userId = user.userId;
87
+ }
88
+ }
89
+ function normalizeSyncChunk(chunk) {
90
+ const arrayFields = [
91
+ 'certificateFields',
92
+ 'certificates',
93
+ 'commissions',
94
+ 'outputBaskets',
95
+ 'outputTagMaps',
96
+ 'outputTags',
97
+ 'outputs',
98
+ 'provenTxReqs',
99
+ 'provenTxs',
100
+ 'transactions',
101
+ 'txLabelMaps',
102
+ 'txLabels',
103
+ ];
104
+ for (const field of arrayFields) {
105
+ const arr = chunk[field];
106
+ if (Array.isArray(arr)) {
107
+ for (let i = 0; i < arr.length; i++) {
108
+ arr[i] = validateEntity(arr[i]);
109
+ }
110
+ }
111
+ }
112
+ if (chunk.user && typeof chunk.user === 'object') {
113
+ chunk.user = validateEntity(chunk.user);
114
+ }
115
+ }
116
+ function validateEntity(entity) {
117
+ if ('created_at' in entity)
118
+ entity.created_at = validateDate(entity.created_at);
119
+ if ('updated_at' in entity)
120
+ entity.updated_at = validateDate(entity.updated_at);
121
+ for (const key of Object.keys(entity)) {
122
+ const val = entity[key];
123
+ if (val === null) {
124
+ entity[key] = undefined;
125
+ }
126
+ else if (isBuffer(val)) {
127
+ entity[key] = Array.from(val);
128
+ }
129
+ }
130
+ return entity;
131
+ }
132
+ function validateDate(date) {
133
+ return date instanceof Date ? date : new Date(date);
134
+ }
135
+ function isBuffer(val) {
136
+ if (val == null || typeof val !== 'object')
137
+ return false;
138
+ const buf = globalThis
139
+ .Buffer;
140
+ return typeof buf?.isBuffer === 'function' && buf.isBuffer(val);
141
+ }
142
+ function attachLoggerIfRequested(ctx, method, identity, params) {
143
+ if (!ctx.makeLogger)
144
+ return undefined;
145
+ const arg1 = params[1];
146
+ if (typeof arg1 !== 'object' || arg1 === null)
147
+ return undefined;
148
+ const logger = ctx.makeLogger(arg1.logger);
149
+ arg1.logger = logger;
150
+ logger.group?.(`wallet-server ${method}`);
151
+ if (identity.userId)
152
+ logger.log?.(`userId: ${identity.userId}`);
153
+ logger.log?.(`identityKey: ${identity.identityKey}`);
154
+ return logger;
155
+ }
156
+ function attachLoggerTail(logger, result) {
157
+ if (!logger)
158
+ return;
159
+ logger.groupEnd?.();
160
+ logger.flush?.();
161
+ if (logger.isOrigin)
162
+ return;
163
+ if (logger.logs && typeof result === 'object' && result !== null) {
164
+ ;
165
+ result.log = { logs: logger.logs };
166
+ }
167
+ }
168
+ function methodNotFound(method, id) {
169
+ return {
170
+ jsonrpc: '2.0',
171
+ error: { code: -32601, message: `Method not found: ${method}` },
172
+ id,
173
+ };
174
+ }
175
+ function marshalError(err, id) {
176
+ const json = WalletError.unknownToJson(err);
177
+ return {
178
+ jsonrpc: '2.0',
179
+ error: JSON.parse(json),
180
+ id,
181
+ };
182
+ }
183
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export { createWalletRpcHandler } from './createWalletRpcHandler';
2
+ export type { WalletRpcHandler } from './createWalletRpcHandler';
3
+ export { createBearerServer } from './createBearerServer';
4
+ export type { BearerServerConfig, BearerServerHandle, } from './createBearerServer';
5
+ export { createWalletServer } from './createWalletServer';
6
+ export type { WalletServerConfig, WalletServerHandle, } from './createWalletServer';
7
+ export { createWalletMonitor } from './createWalletMonitor';
8
+ export type { WalletMonitorConfig, WalletMonitorHandle, } from './createWalletMonitor';
9
+ export { BILLABLE_METHODS, dispatch, isBillableMethod } from './dispatch';
10
+ export type { DispatchContext, DispatchInput } from './dispatch';
11
+ export * from './resolvers';
12
+ export * from './accounts';
13
+ export type { IdentityResolver, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseErr, JsonRpcResponseOk, PreDispatchContext, PreDispatchHook, PreDispatchResult, ResolvedIdentity, WalletRpcHandlerConfig, WalletStorageProvider, } from './types';
14
+ export type { WalletServerAccounts } from './createWalletServer';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EACX,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EACX,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,YAAY,EACX,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACzE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAEhE,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAE1B,YAAY,EACX,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,GACrB,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { createWalletRpcHandler } from './createWalletRpcHandler';
2
+ export { createBearerServer } from './createBearerServer';
3
+ export { createWalletServer } from './createWalletServer';
4
+ export { createWalletMonitor } from './createWalletMonitor';
5
+ export { BILLABLE_METHODS, dispatch, isBillableMethod } from './dispatch';
6
+ export * from './resolvers';
7
+ export * from './accounts';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAMzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAMzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAM3D,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGzE,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { IdentityResolver } from '../types';
2
+ export interface BearerResolverConfig {
3
+ /** Shared secret the caller must present. */
4
+ token: string;
5
+ /** Header name carrying the authenticated identity pubkey. Defaults to `X-Identity-Key`. */
6
+ identityHeader?: string;
7
+ }
8
+ export declare function bearerResolver(config: BearerResolverConfig): IdentityResolver;
9
+ export declare class BearerAuthError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ //# sourceMappingURL=bearer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/resolvers/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACpC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,gBAAgB,CA4B7E;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI3B"}
@@ -0,0 +1,43 @@
1
+ export function bearerResolver(config) {
2
+ if (!config.token) {
3
+ throw new Error('bearerResolver requires a non-empty token');
4
+ }
5
+ const identityHeader = (config.identityHeader ?? 'X-Identity-Key').toLowerCase();
6
+ return async (req) => {
7
+ const auth = req.headers.get('authorization') ?? '';
8
+ const [scheme, value] = auth.split(/\s+/, 2);
9
+ if (scheme?.toLowerCase() !== 'bearer' || !value) {
10
+ throw new BearerAuthError('missing bearer token');
11
+ }
12
+ if (!timingSafeEqual(value, config.token)) {
13
+ throw new BearerAuthError('invalid bearer token');
14
+ }
15
+ const identityKey = req.headers.get(identityHeader);
16
+ if (!identityKey) {
17
+ throw new BearerAuthError(`missing ${identityHeader} header`);
18
+ }
19
+ if (!isHexPubKey(identityKey)) {
20
+ throw new BearerAuthError(`invalid ${identityHeader} header`);
21
+ }
22
+ return { identityKey };
23
+ };
24
+ }
25
+ export class BearerAuthError extends Error {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = 'BearerAuthError';
29
+ }
30
+ }
31
+ function isHexPubKey(value) {
32
+ return /^[0-9a-fA-F]{66}$/.test(value);
33
+ }
34
+ function timingSafeEqual(a, b) {
35
+ if (a.length !== b.length)
36
+ return false;
37
+ let diff = 0;
38
+ for (let i = 0; i < a.length; i++) {
39
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
40
+ }
41
+ return diff === 0;
42
+ }
43
+ //# sourceMappingURL=bearer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/resolvers/bearer.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,cAAc,CAAC,MAA4B;IAC1D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC7D,CAAC;IACD,MAAM,cAAc,GAAG,CACtB,MAAM,CAAC,cAAc,IAAI,gBAAgB,CACzC,CAAC,WAAW,EAAE,CAAA;IAEf,OAAO,KAAK,EAAE,GAAY,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAA;QACnD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QAC5C,IAAI,MAAM,EAAE,WAAW,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YAClD,MAAM,IAAI,eAAe,CAAC,sBAAsB,CAAC,CAAA;QAClD,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,eAAe,CAAC,sBAAsB,CAAC,CAAA;QAClD,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACnD,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,eAAe,CAAC,WAAW,cAAc,SAAS,CAAC,CAAA;QAC9D,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,eAAe,CAAC,WAAW,cAAc,SAAS,CAAC,CAAA;QAC9D,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,CAAA;IACvB,CAAC,CAAA;AACF,CAAC;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACzC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAC9B,CAAC;CACD;AAED,SAAS,WAAW,CAAC,KAAa;IACjC,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACvC,CAAC;AAED,SAAS,eAAe,CAAC,CAAS,EAAE,CAAS;IAC5C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACvC,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAA;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { bearerResolver, BearerAuthError } from './bearer';
2
+ export type { BearerResolverConfig } from './bearer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resolvers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { bearerResolver, BearerAuthError } from './bearer';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resolvers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type { MakeWalletLogger, WalletLoggerInterface } from '@bsv/sdk';
2
+ import type { sdk as walletSdk } from '@bsv/wallet-toolbox';
3
+ export type WalletStorageProvider = walletSdk.WalletStorageProvider;
4
+ export interface ResolvedIdentity {
5
+ identityKey: string;
6
+ userId?: number;
7
+ }
8
+ export type IdentityResolver = (req: Request) => Promise<ResolvedIdentity>;
9
+ export interface PreDispatchContext {
10
+ method: string;
11
+ identity: ResolvedIdentity;
12
+ request: Request;
13
+ id: string | number | null;
14
+ }
15
+ export type PreDispatchResult = {
16
+ type: 'allow';
17
+ } | {
18
+ type: 'blocked';
19
+ response: Response;
20
+ };
21
+ export type PreDispatchHook = (ctx: PreDispatchContext) => Promise<PreDispatchResult>;
22
+ export interface WalletRpcHandlerConfig {
23
+ storage: WalletStorageProvider;
24
+ resolveIdentity: IdentityResolver;
25
+ adminIdentityKeys?: string[];
26
+ makeLogger?: MakeWalletLogger;
27
+ /** Optional gate that runs after identity resolution and before dispatch. */
28
+ preDispatch?: PreDispatchHook;
29
+ }
30
+ export interface JsonRpcRequest {
31
+ jsonrpc: '2.0';
32
+ method: string;
33
+ params?: unknown[];
34
+ id?: string | number | null;
35
+ }
36
+ export interface JsonRpcResponseOk {
37
+ jsonrpc: '2.0';
38
+ result: unknown;
39
+ id: string | number | null;
40
+ }
41
+ export interface JsonRpcResponseErr {
42
+ jsonrpc: '2.0';
43
+ error: {
44
+ code: number;
45
+ message: string;
46
+ data?: unknown;
47
+ };
48
+ id: string | number | null;
49
+ }
50
+ export type JsonRpcResponse = JsonRpcResponseOk | JsonRpcResponseErr;
51
+ export type { MakeWalletLogger, WalletLoggerInterface };
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,GAAG,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE3D,MAAM,MAAM,qBAAqB,GAAG,SAAS,CAAC,qBAAqB,CAAA;AAEnE,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE1E,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAC1B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAA;AAE1C,MAAM,MAAM,eAAe,GAAG,CAC7B,GAAG,EAAE,kBAAkB,KACnB,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAE/B,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,qBAAqB,CAAA;IAC9B,eAAe,EAAE,gBAAgB,CAAA;IACjC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,eAAe,CAAA;CAC7B;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;IAClB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,KAAK,CAAA;IACd,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IACxD,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAEpE,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@1sat/wallet-server",
3
+ "version": "0.0.1",
4
+ "description": "BRC-100 wallet storage RPC server for 1Sat Ordinals SDK",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": ["dist"],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "clean": "rm -rf dist",
19
+ "test": "bun test"
20
+ },
21
+ "keywords": ["1sat", "bsv", "ordinals", "wallet", "server", "rpc", "brc-100"],
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@1sat/client": "0.0.21",
25
+ "@1sat/wallet": "0.0.47",
26
+ "express": "^4.21.2"
27
+ },
28
+ "peerDependencies": {
29
+ "@bsv/auth-express-middleware": "^2.0.4",
30
+ "@bsv/sdk": "^2.0.13",
31
+ "@bsv/wallet-toolbox": "^2.1.21",
32
+ "knex": "^3.1.0"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "pg": {
36
+ "optional": true
37
+ }
38
+ },
39
+ "devDependencies": {
40
+ "@bsv/auth-express-middleware": "^2.0.4",
41
+ "@bsv/sdk": "^2.0.13",
42
+ "@bsv/wallet-toolbox": "^2.1.21",
43
+ "@types/bun": "^1.3.10",
44
+ "@types/express": "^4.17.21",
45
+ "knex": "^3.1.0",
46
+ "typescript": "^5.9.3"
47
+ }
48
+ }