@seams/wallet-server 0.10.2 → 0.12.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.
Files changed (106) hide show
  1. package/THIRD_PARTY_NOTICES.md +33 -1812
  2. package/artifact-manifest.json +28 -28
  3. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/deriver-a/index.js +2 -2
  5. package/cloudflare-router-ab/build/deriver-a/index_bg.wasm +0 -0
  6. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  7. package/cloudflare-router-ab/build/deriver-b/index.js +2 -2
  8. package/cloudflare-router-ab/build/deriver-b/index_bg.wasm +0 -0
  9. package/cloudflare-router-ab/build/local-tools/darwin-arm64/router_ab_local_init +0 -0
  10. package/cloudflare-router-ab/build/local-tools/darwin-x64/router_ab_local_init +0 -0
  11. package/cloudflare-router-ab/build/local-tools/linux-x64/router_ab_local_init +0 -0
  12. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  13. package/cloudflare-router-ab/build/router/index.js +2 -2
  14. package/cloudflare-router-ab/build/router/index_bg.wasm +0 -0
  15. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  16. package/cloudflare-router-ab/build/signing-worker/index.js +2 -2
  17. package/cloudflare-router-ab/build/signing-worker/index_bg.wasm +0 -0
  18. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  19. package/cloudflare-router-ab/build/tenant-root-control-plane/index.js +2 -2
  20. package/cloudflare-router-ab/build/tenant-root-control-plane/index_bg.wasm +0 -0
  21. package/cloudflare-router-ab/scripts/start-local-role-workers.mjs +3 -0
  22. package/cloudflare-router-ab/scripts/start-local-wallet-system.mjs +3 -0
  23. package/dist/esm/cloud-host.js +7 -7
  24. package/dist/esm/core/ThresholdService/kv.js +1 -218
  25. package/dist/esm/hosted-wallet-gateway.js +1 -1
  26. package/dist/esm/index.js +3 -4
  27. package/dist/esm/localHostedWalletGatewayHandler.js +17 -11
  28. package/dist/esm/localIntendedYaoFault.js +34 -3
  29. package/dist/esm/localIntendedYaoRecoveryFault.js +19 -16
  30. package/dist/esm/localIntendedYaoSigningFault.js +31 -16
  31. package/dist/esm/router/auth/routerApiKeyAuth.js +1 -13
  32. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +3 -3
  33. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +1 -1
  34. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +1 -1
  35. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +1 -1
  36. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +1 -1
  37. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.js +19 -0
  38. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +5 -5
  39. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.js +5 -2
  40. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationSetupSupport.js +7 -1
  41. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +29 -4
  42. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationRead.js +6 -3
  43. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +51 -29
  44. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +23 -7
  45. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerFinalizeRecord.js +1 -1
  46. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerService.js +2 -2
  47. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +3 -3
  48. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +1 -1
  49. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +1 -1
  50. package/dist/esm/router/cloudflare-adaptor.js +2 -3
  51. package/dist/esm/router/cloudflare.js +2470 -2515
  52. package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.js +1 -1
  53. package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +39 -32
  54. package/dist/esm/router/framework/registrationSetupDispatch.js +11 -3
  55. package/dist/esm/router/framework/routeResponses.js +1 -5
  56. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
  57. package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +2 -2
  58. package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +51 -24
  59. package/dist/esm/shared-ts/src/utils/validation.js +5 -1
  60. package/dist/esm/threshold/session/signingSessionSeal/guards/backends.js +2 -98
  61. package/dist/esm/threshold/session/signingSessionSeal/idempotencyBackends.js +2 -69
  62. package/dist/esm/threshold/session/signingSessionSeal/index.js +3 -4
  63. package/dist/esm/wasm/evm_crypto/pkg/evm_crypto_bg.wasm +0 -0
  64. package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
  65. package/dist/esm/wasm/shamir3pass_runtime/pkg/shamir3pass_runtime_bg.wasm +0 -0
  66. package/dist/types/wallet-server/src/cloud-host.d.ts +1 -0
  67. package/dist/types/wallet-server/src/core/ThresholdService/kv.d.ts +0 -29
  68. package/dist/types/wallet-server/src/localHostedWalletGatewayHandler.d.ts +1 -1
  69. package/dist/types/wallet-server/src/localIntendedYaoFault.d.ts +13 -3
  70. package/dist/types/wallet-server/src/localIntendedYaoRecoveryFault.d.ts +4 -2
  71. package/dist/types/wallet-server/src/localIntendedYaoSigningFault.d.ts +4 -2
  72. package/dist/types/wallet-server/src/router/auth/routerApiKeyAuth.d.ts +0 -8
  73. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.d.ts +2 -0
  74. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.d.ts +1 -0
  75. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationSetupSupport.d.ts +2 -0
  76. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.d.ts +25 -5
  77. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationRead.d.ts +15 -0
  78. package/dist/types/wallet-server/src/router/cloudflare-adaptor.d.ts +1 -3
  79. package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +2 -0
  80. package/dist/types/wallet-server/src/router/framework/routeResponses.d.ts +0 -2
  81. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/guards/backends.d.ts +1 -16
  82. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/idempotencyBackends.d.ts +1 -16
  83. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/index.d.ts +5 -6
  84. package/package.json +2 -9
  85. package/src/README.md +5 -3
  86. package/dist/esm/router/cloudflare/runtime/createSelfHostedCloudflareSigningWorker.js +0 -93
  87. package/dist/esm/router/express-adaptor.js +0 -84
  88. package/dist/esm/router/express.js +0 -26400
  89. package/dist/esm/router/node/nodeHostedWalletGateway.js +0 -64
  90. package/dist/esm/router/node/nodeHostedWalletGatewayCheck.js +0 -163
  91. package/dist/esm/router/node/nodeHostedWalletGatewayMain.js +0 -120
  92. package/dist/esm/router/node/nodeHttp.js +0 -79
  93. package/dist/esm/router/node/nodeSqlite.js +0 -43
  94. package/dist/esm/router/node/signerSqlMigrations.js +0 -48
  95. package/dist/esm/storage/syncSqlite.js +0 -79
  96. package/dist/esm/threshold/session/signingSessionSeal/transport/express.js +0 -75
  97. package/dist/types/wallet-server/src/router/cloudflare/runtime/createSelfHostedCloudflareSigningWorker.d.ts +0 -23
  98. package/dist/types/wallet-server/src/router/express-adaptor.d.ts +0 -22
  99. package/dist/types/wallet-server/src/router/node/nodeHostedWalletGateway.d.ts +0 -34
  100. package/dist/types/wallet-server/src/router/node/nodeHostedWalletGatewayCheck.d.ts +0 -21
  101. package/dist/types/wallet-server/src/router/node/nodeHostedWalletGatewayMain.d.ts +0 -2
  102. package/dist/types/wallet-server/src/router/node/nodeHttp.d.ts +0 -13
  103. package/dist/types/wallet-server/src/router/node/nodeSqlite.d.ts +0 -22
  104. package/dist/types/wallet-server/src/router/node/signerSqlMigrations.d.ts +0 -20
  105. package/dist/types/wallet-server/src/storage/syncSqlite.d.ts +0 -28
  106. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/transport/express.d.ts +0 -12
@@ -1,64 +0,0 @@
1
- import { createStaticWalletConsoleBindingV1, parseStaticWalletConsoleBindingConfigV1 } from "../cloudflare/runtime/staticWalletConsoleBinding.js";
2
- import { handleSplitGatewayRequest } from "../../hosted-wallet-gateway.js";
3
- import { createSyncSqliteDatabase } from "../../storage/syncSqlite.js";
4
- import { NODE_HOP_BY_HOP_HEADERS_V1 } from "./nodeHttp.js";
5
- import { readFileSync } from "node:fs";
6
- //#region src/router/node/nodeHostedWalletGateway.ts
7
- function createNodeHostedWalletGatewayV1(options) {
8
- const deploymentJson = options.vars.WALLET_LOCAL_DEPLOYMENT_JSON;
9
- if (!deploymentJson) throw new Error("WALLET_LOCAL_DEPLOYMENT_JSON is required");
10
- const env = {
11
- ...options.vars,
12
- WALLET_LOCAL_DEPLOYMENT_JSON: deploymentJson,
13
- ROUTER_AB_PREWARM_ENABLED: options.vars.ROUTER_AB_PREWARM_ENABLED ?? "false",
14
- SIGNER_DB: createSyncSqliteDatabase(options.connection),
15
- MPC_ROUTER: httpServiceBinding(options.routerUrl),
16
- SIGNING_WORKER: httpServiceBinding(options.signingWorkerUrl),
17
- WALLET_CONSOLE: createStaticWalletConsoleBindingV1(parseStaticWalletConsoleBindingConfigV1(JSON.parse(deploymentJson)))
18
- };
19
- const signerWasmBytes = readFileSync(options.signerWasmPath);
20
- const dependencies = { signerWasm: async () => await WebAssembly.compile(signerWasmBytes) };
21
- const handler = options.handler ?? handleSplitGatewayRequest;
22
- const pending = /* @__PURE__ */ new Set();
23
- const ctx = {
24
- waitUntil(promise) {
25
- const tracked = promise.catch((error) => options.onBackgroundError?.(error));
26
- pending.add(tracked);
27
- tracked.finally(() => pending.delete(tracked));
28
- },
29
- passThroughOnException() {}
30
- };
31
- return {
32
- handle: async (request) => await handler(request, env, ctx, dependencies),
33
- drain: async () => {
34
- await Promise.all([...pending]);
35
- }
36
- };
37
- }
38
- /**
39
- * A Cloudflare service binding delivers to one Worker whatever URL the
40
- * caller used; the Gateway sends both its fixed internal origins and
41
- * forwarded public requests through them. On a VM each binding forwards the
42
- * path and query to its one configured base URL, and nowhere else.
43
- */
44
- function httpServiceBinding(baseUrl) {
45
- const base = new URL(baseUrl);
46
- return { async fetch(input, init) {
47
- const request = new Request(input, init);
48
- const url = new URL(request.url);
49
- const target = new URL(`${url.pathname}${url.search}`, base);
50
- const body = request.method === "GET" || request.method === "HEAD" ? void 0 : await request.arrayBuffer();
51
- const headers = new Headers(request.headers);
52
- for (const name of NODE_HOP_BY_HOP_HEADERS_V1) headers.delete(name);
53
- return await fetch(target, {
54
- method: request.method,
55
- headers,
56
- body,
57
- redirect: "manual"
58
- });
59
- } };
60
- }
61
- //#endregion
62
- export { createNodeHostedWalletGatewayV1 };
63
-
64
- //# sourceMappingURL=nodeHostedWalletGateway.js.map
@@ -1,163 +0,0 @@
1
- import { parseStaticWalletConsoleBindingConfigV1 } from "../cloudflare/runtime/staticWalletConsoleBinding.js";
2
- import { nodeSqliteConnection } from "./nodeSqlite.js";
3
- import { inspectSignerSqlMigrationsV1 } from "./signerSqlMigrations.js";
4
- import { existsSync } from "node:fs";
5
- //#region src/router/node/nodeHostedWalletGatewayCheck.ts
6
- async function checkNodeHostedWalletGatewayV1(input) {
7
- return [
8
- configurationCheck(input),
9
- signerWasmCheck(input.signerWasmPath),
10
- storageCheck(input),
11
- await peerCheck("router", input.routerUrl),
12
- await peerCheck("signing_worker", input.signingWorkerUrl),
13
- {
14
- check: "peer_authentication",
15
- status: "unverified",
16
- detail: { reason: "the check sends no credential; a peer that refuses the Gateway's service credentials is found only by an authenticated call, such as the explicit smoke test" }
17
- }
18
- ];
19
- }
20
- function configurationCheck(input) {
21
- const missing = [
22
- ["WALLET_GATEWAY_VARS_FILE", input.varsPath],
23
- ["WALLET_GATEWAY_ROUTER_URL", input.routerUrl],
24
- ["WALLET_GATEWAY_SIGNING_WORKER_URL", input.signingWorkerUrl],
25
- ["WALLET_GATEWAY_SIGNER_WASM_PATH", input.signerWasmPath]
26
- ].filter(([, value]) => !value).map(([name]) => name);
27
- if (missing.length > 0 || !input.varsPath) return {
28
- check: "configuration",
29
- status: "failed",
30
- detail: { missing }
31
- };
32
- let vars;
33
- try {
34
- vars = input.readVars(input.varsPath);
35
- } catch (error) {
36
- return {
37
- check: "configuration",
38
- status: "failed",
39
- detail: { error: error instanceof Error ? error.message : "the vars file cannot be read" }
40
- };
41
- }
42
- const deploymentJson = vars.WALLET_LOCAL_DEPLOYMENT_JSON;
43
- if (!deploymentJson) return {
44
- check: "configuration",
45
- status: "failed",
46
- detail: { missing: ["WALLET_LOCAL_DEPLOYMENT_JSON"] }
47
- };
48
- try {
49
- parseStaticWalletConsoleBindingConfigV1(JSON.parse(deploymentJson));
50
- } catch {
51
- return {
52
- check: "configuration",
53
- status: "failed",
54
- detail: { error: "WALLET_LOCAL_DEPLOYMENT_JSON is not a valid deployment" }
55
- };
56
- }
57
- return {
58
- check: "configuration",
59
- status: "passed",
60
- detail: { keys: Object.keys(vars).length }
61
- };
62
- }
63
- function signerWasmCheck(path) {
64
- if (!path) return {
65
- check: "artifact:signer_wasm",
66
- status: "failed",
67
- detail: { missing: true }
68
- };
69
- return existsSync(path) ? {
70
- check: "artifact:signer_wasm",
71
- status: "passed",
72
- detail: { path }
73
- } : {
74
- check: "artifact:signer_wasm",
75
- status: "failed",
76
- detail: {
77
- path,
78
- state: "missing"
79
- }
80
- };
81
- }
82
- function storageCheck(input) {
83
- const path = input.databasePath;
84
- if (!existsSync(path)) return {
85
- check: "storage:gateway_store",
86
- status: "failed",
87
- detail: {
88
- path,
89
- state: "missing",
90
- action: "apply the schema with `migrate`"
91
- }
92
- };
93
- const database = new input.DatabaseSync(path, { readOnly: true });
94
- try {
95
- const status = inspectSignerSqlMigrationsV1(nodeSqliteConnection(database), input.migrationsDir);
96
- const current = status.pending.length === 0 && status.unknown.length === 0;
97
- return {
98
- check: "storage:gateway_store",
99
- status: current ? "passed" : "failed",
100
- detail: current ? {
101
- path,
102
- applied: status.applied.length
103
- } : {
104
- path,
105
- applied: status.applied.length,
106
- pending: status.pending,
107
- unknown: status.unknown
108
- }
109
- };
110
- } finally {
111
- database.close();
112
- }
113
- }
114
- /** The role a peer's health endpoint answers as. Sends no credential. */
115
- async function peerCheck(role, url) {
116
- const check = `peer:${role}`;
117
- if (!url) return {
118
- check,
119
- status: "failed",
120
- detail: { missing: true }
121
- };
122
- let answered;
123
- try {
124
- const response = await fetch(new URL("/healthz", url), { signal: AbortSignal.timeout(5e3) });
125
- if (response.status !== 200) return {
126
- check,
127
- status: "failed",
128
- detail: {
129
- url,
130
- error: `answered HTTP ${response.status}`
131
- }
132
- };
133
- const body = await response.json();
134
- answered = body.role_label ?? body.role;
135
- } catch (error) {
136
- return {
137
- check,
138
- status: "failed",
139
- detail: {
140
- url,
141
- state: "unreachable",
142
- error: error instanceof Error ? error.message : "failed"
143
- }
144
- };
145
- }
146
- return answered === role ? {
147
- check,
148
- status: "passed",
149
- detail: { url }
150
- } : {
151
- check,
152
- status: "failed",
153
- detail: {
154
- url,
155
- answered_as: answered ?? null,
156
- action: "point this URL at the role it names"
157
- }
158
- };
159
- }
160
- //#endregion
161
- export { checkNodeHostedWalletGatewayV1 };
162
-
163
- //# sourceMappingURL=nodeHostedWalletGatewayCheck.js.map
@@ -1,120 +0,0 @@
1
- import { handleLocalHostedWalletGatewayRequestV1 } from "../../localHostedWalletGatewayHandler.js";
2
- import { listenNodeFetchHandler } from "./nodeHttp.js";
3
- import { createNodeHostedWalletGatewayV1 } from "./nodeHostedWalletGateway.js";
4
- import { loadNodeDatabaseSync, nodeSqliteConnection, openNodeSqliteFile } from "./nodeSqlite.js";
5
- import { applySignerSqlMigrationsV1, inspectSignerSqlMigrationsV1 } from "./signerSqlMigrations.js";
6
- import { checkNodeHostedWalletGatewayV1 } from "./nodeHostedWalletGatewayCheck.js";
7
- import { readFileSync } from "node:fs";
8
- //#region src/router/node/nodeHostedWalletGatewayMain.ts
9
- async function main(argv) {
10
- const command = argv[0];
11
- const databasePath = requireEnv("WALLET_GATEWAY_DATABASE_PATH");
12
- const migrationsDir = requireEnv("WALLET_GATEWAY_MIGRATIONS_DIR");
13
- const DatabaseSync = await loadNodeDatabaseSync();
14
- if (command === "check") {
15
- const checks = await checkNodeHostedWalletGatewayV1({
16
- DatabaseSync,
17
- databasePath,
18
- migrationsDir,
19
- varsPath: optionalEnv("WALLET_GATEWAY_VARS_FILE"),
20
- readVars: readVarsFile,
21
- routerUrl: optionalEnv("WALLET_GATEWAY_ROUTER_URL"),
22
- signingWorkerUrl: optionalEnv("WALLET_GATEWAY_SIGNING_WORKER_URL"),
23
- signerWasmPath: optionalEnv("WALLET_GATEWAY_SIGNER_WASM_PATH")
24
- });
25
- const ok = checks.every((check) => check.status !== "failed");
26
- report({
27
- kind: "wallet_gateway_check_v1",
28
- ok,
29
- checks
30
- });
31
- return ok ? 0 : 1;
32
- }
33
- const database = openNodeSqliteFile(DatabaseSync, databasePath);
34
- const connection = nodeSqliteConnection(database);
35
- if (command === "migrate") {
36
- report({
37
- kind: "wallet_gateway_migrate_v1",
38
- ...applySignerSqlMigrationsV1(connection, migrationsDir, Date.now())
39
- });
40
- database.close();
41
- return 0;
42
- }
43
- if (command === "serve" || command === "serve-local") {
44
- const status = inspectSignerSqlMigrationsV1(connection, migrationsDir);
45
- if (status.pending.length > 0 || status.unknown.length > 0) throw new Error("shared store schema is not current; run `migrate` first");
46
- const [host, port] = splitListen(requireEnv("WALLET_GATEWAY_LISTEN"));
47
- const gateway = createNodeHostedWalletGatewayV1({
48
- vars: readVarsFile(requireEnv("WALLET_GATEWAY_VARS_FILE")),
49
- connection,
50
- routerUrl: requireEnv("WALLET_GATEWAY_ROUTER_URL"),
51
- signingWorkerUrl: requireEnv("WALLET_GATEWAY_SIGNING_WORKER_URL"),
52
- signerWasmPath: requireEnv("WALLET_GATEWAY_SIGNER_WASM_PATH"),
53
- ...command === "serve-local" ? { handler: handleLocalHostedWalletGatewayRequestV1 } : {},
54
- onBackgroundError: (error) => process.stderr.write(`gateway background task failed: ${describe(error)}\n`)
55
- });
56
- const server = await listenNodeFetchHandler({
57
- host,
58
- port,
59
- handle: gateway.handle
60
- });
61
- report({
62
- kind: "wallet_gateway_listening_v1",
63
- address: server.address()
64
- });
65
- const stop = () => server.close(() => {
66
- gateway.drain().finally(() => {
67
- database.close();
68
- process.exit(0);
69
- });
70
- });
71
- process.once("SIGTERM", stop);
72
- process.once("SIGINT", stop);
73
- return await new Promise(() => void 0);
74
- }
75
- process.stderr.write("usage: wallet-gateway <migrate|check|serve|serve-local>\n");
76
- return 2;
77
- }
78
- /** Reads `KEY='value'` / `KEY=value` lines; values are never logged. */
79
- function readVarsFile(path) {
80
- const vars = {};
81
- for (const rawLine of readFileSync(path, "utf8").split(/\r?\n/)) {
82
- const line = rawLine.trim();
83
- if (!line || line.startsWith("#")) continue;
84
- const separator = line.indexOf("=");
85
- if (separator <= 0) throw new Error(`invalid entry in ${path}`);
86
- const key = line.slice(0, separator);
87
- let value = line.slice(separator + 1);
88
- if (value.length >= 2 && value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
89
- if (key in vars) throw new Error(`duplicate ${key} in ${path}`);
90
- vars[key] = value;
91
- }
92
- return vars;
93
- }
94
- function requireEnv(name) {
95
- const value = process.env[name]?.trim();
96
- if (!value) throw new Error(`${name} is required`);
97
- return value;
98
- }
99
- function optionalEnv(name) {
100
- return process.env[name]?.trim() || void 0;
101
- }
102
- function splitListen(value) {
103
- const index = value.lastIndexOf(":");
104
- const port = Number(value.slice(index + 1));
105
- if (index <= 0 || !Number.isInteger(port)) throw new Error("WALLET_GATEWAY_LISTEN must be host:port");
106
- return [value.slice(0, index), port];
107
- }
108
- function report(value) {
109
- process.stdout.write(`${JSON.stringify(value)}\n`);
110
- }
111
- function describe(error) {
112
- return error instanceof Error ? error.message : String(error);
113
- }
114
- main(process.argv.slice(2)).then((code) => process.exit(code), (error) => {
115
- process.stderr.write(`${describe(error)}\n`);
116
- process.exit(1);
117
- });
118
- //#endregion
119
-
120
- //# sourceMappingURL=nodeHostedWalletGatewayMain.js.map
@@ -1,79 +0,0 @@
1
- import { createServer } from "node:http";
2
- //#region src/router/node/nodeHttp.ts
3
- const MAX_REQUEST_BODY_BYTES = 1024 * 1024;
4
- /**
5
- * Headers that describe one connection or one message's framing. A Worker's
6
- * runtime sets them for the bytes it actually sends; on Node they are never
7
- * copied from a Request or Response that another hop produced.
8
- */
9
- const NODE_HOP_BY_HOP_HEADERS_V1 = [
10
- "connection",
11
- "content-length",
12
- "expect",
13
- "host",
14
- "keep-alive",
15
- "proxy-connection",
16
- "te",
17
- "trailer",
18
- "transfer-encoding",
19
- "upgrade"
20
- ];
21
- function listenNodeFetchHandler(input) {
22
- const server = createServer((incoming, outgoing) => {
23
- forward(incoming, outgoing, input.handle);
24
- });
25
- return new Promise((resolve, reject) => {
26
- server.once("error", reject);
27
- server.listen(input.port, input.host, () => resolve(server));
28
- });
29
- }
30
- async function forward(incoming, outgoing, handle) {
31
- try {
32
- if (Number(incoming.headers["content-length"]) > MAX_REQUEST_BODY_BYTES) {
33
- rejectOversizedBody(incoming, outgoing);
34
- return;
35
- }
36
- const chunks = [];
37
- let bodyBytes = 0;
38
- for await (const chunk of incoming.iterator({ destroyOnReturn: false })) {
39
- bodyBytes += chunk.length;
40
- if (bodyBytes > MAX_REQUEST_BODY_BYTES) {
41
- rejectOversizedBody(incoming, outgoing);
42
- return;
43
- }
44
- chunks.push(chunk);
45
- }
46
- const headers = new Headers();
47
- for (const [name, value] of Object.entries(incoming.headers)) if (typeof value === "string") headers.set(name, value);
48
- else if (Array.isArray(value)) for (const item of value) headers.append(name, item);
49
- const method = incoming.method ?? "GET";
50
- const response = await handle(new Request(`http://${incoming.headers.host ?? "localhost"}${incoming.url ?? "/"}`, {
51
- method,
52
- headers,
53
- body: method === "GET" || method === "HEAD" ? void 0 : Buffer.concat(chunks)
54
- }));
55
- outgoing.statusCode = response.status;
56
- response.headers.forEach((value, name) => {
57
- if (name === "set-cookie" || NODE_HOP_BY_HOP_HEADERS_V1.includes(name)) return;
58
- outgoing.setHeader(name, value);
59
- });
60
- const cookies = response.headers.getSetCookie();
61
- if (cookies.length > 0) outgoing.setHeader("set-cookie", cookies);
62
- outgoing.end(Buffer.from(await response.arrayBuffer()));
63
- } catch {
64
- outgoing.statusCode = 500;
65
- outgoing.end("internal error");
66
- }
67
- }
68
- function rejectOversizedBody(incoming, outgoing) {
69
- incoming.pause();
70
- outgoing.writeHead(413, {
71
- connection: "close",
72
- "content-type": "text/plain; charset=utf-8"
73
- });
74
- outgoing.end("request body too large");
75
- }
76
- //#endregion
77
- export { NODE_HOP_BY_HOP_HEADERS_V1, listenNodeFetchHandler };
78
-
79
- //# sourceMappingURL=nodeHttp.js.map
@@ -1,43 +0,0 @@
1
- //#region src/router/node/nodeSqlite.ts
2
- const BUSY_TIMEOUT_MS = 5e3;
3
- /** Loads `node:sqlite` at runtime so the package builds without its typings. */
4
- async function loadNodeDatabaseSync() {
5
- const module = await import("node:sqlite");
6
- if (typeof module.DatabaseSync !== "function") throw new Error("node:sqlite DatabaseSync is unavailable; use Node.js 22.13 or newer");
7
- return module.DatabaseSync;
8
- }
9
- /**
10
- * Opens a SQLite file for one role-private store. Writers from separate
11
- * processes serialize on `BEGIN IMMEDIATE`; WAL lets readers proceed.
12
- */
13
- function openNodeSqliteFile(DatabaseSync, path) {
14
- const database = new DatabaseSync(path);
15
- database.exec(`PRAGMA busy_timeout = ${BUSY_TIMEOUT_MS}; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;`);
16
- return database;
17
- }
18
- function nodeSqliteConnection(database) {
19
- let inTransaction = false;
20
- return {
21
- execute: (sql, params) => database.prepare(sql).all(...params),
22
- executeScript: (sql) => database.exec(sql),
23
- transaction: (body) => {
24
- if (inTransaction) throw new Error("nested SQLite transactions are not supported");
25
- database.exec("BEGIN IMMEDIATE");
26
- inTransaction = true;
27
- try {
28
- const result = body();
29
- database.exec("COMMIT");
30
- return result;
31
- } catch (error) {
32
- database.exec("ROLLBACK");
33
- throw error;
34
- } finally {
35
- inTransaction = false;
36
- }
37
- }
38
- };
39
- }
40
- //#endregion
41
- export { loadNodeDatabaseSync, nodeSqliteConnection, openNodeSqliteFile };
42
-
43
- //# sourceMappingURL=nodeSqlite.js.map
@@ -1,48 +0,0 @@
1
- import { readFileSync, readdirSync } from "node:fs";
2
- import { join } from "node:path";
3
- //#region src/router/node/signerSqlMigrations.ts
4
- const LEDGER_TABLE = "seams_signer_sql_migrations";
5
- function migrationNames(directory) {
6
- return readdirSync(directory).filter((name) => name.endsWith(".sql")).sort();
7
- }
8
- function appliedNames(connection) {
9
- if (connection.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?1", [LEDGER_TABLE]).length === 0) return [];
10
- return connection.execute(`SELECT name FROM ${LEDGER_TABLE} ORDER BY name`, []).map((row) => String(row.name));
11
- }
12
- /** Read-only: compares the database ledger with the shipped migration chain. */
13
- function inspectSignerSqlMigrationsV1(connection, directory) {
14
- const shipped = migrationNames(directory);
15
- const applied = appliedNames(connection);
16
- return {
17
- applied,
18
- pending: shipped.filter((name) => !applied.includes(name)),
19
- unknown: applied.filter((name) => !shipped.includes(name))
20
- };
21
- }
22
- /**
23
- * Applies pending migrations in order, each in one transaction together
24
- * with its ledger row, so an interrupted run resumes at the first missing
25
- * migration. Refuses a database that already carries migrations this
26
- * package does not know, or whose applied set is not a prefix of the chain.
27
- */
28
- function applySignerSqlMigrationsV1(connection, directory, nowMs) {
29
- const status = inspectSignerSqlMigrationsV1(connection, directory);
30
- if (status.unknown.length > 0) throw new Error(`database has migrations this package does not ship: ${status.unknown.join(", ")}`);
31
- const shipped = migrationNames(directory);
32
- if (status.applied.some((name, index) => shipped[index] !== name)) throw new Error("applied migrations are not a prefix of the shipped migration chain");
33
- connection.executeScript(`CREATE TABLE IF NOT EXISTS ${LEDGER_TABLE} (name TEXT PRIMARY KEY, applied_at_ms INTEGER NOT NULL)`);
34
- const applied = [];
35
- for (const name of status.pending) {
36
- const sql = readFileSync(join(directory, name), "utf8");
37
- connection.transaction(() => {
38
- connection.executeScript(sql);
39
- connection.execute(`INSERT INTO ${LEDGER_TABLE} (name, applied_at_ms) VALUES (?1, ?2)`, [name, nowMs]);
40
- });
41
- applied.push(name);
42
- }
43
- return { applied };
44
- }
45
- //#endregion
46
- export { applySignerSqlMigrationsV1, inspectSignerSqlMigrationsV1 };
47
-
48
- //# sourceMappingURL=signerSqlMigrations.js.map
@@ -1,79 +0,0 @@
1
- //#region src/storage/syncSqlite.ts
2
- /**
3
- * Presents a synchronous SQLite connection through the async SQL shape used
4
- * by the shared stores. `batch` is one SQLite transaction: a failing statement
5
- * rolls back every earlier statement, so guarded compare-and-set batches keep
6
- * the all-or-nothing semantics they have on D1.
7
- */
8
- function createSyncSqliteDatabase(connection) {
9
- return new SyncSqliteDatabase(connection);
10
- }
11
- var SyncSqliteDatabase = class {
12
- constructor(connection) {
13
- this.connection = connection;
14
- }
15
- prepare(query) {
16
- return new SyncSqliteStatement(this.connection, query, []);
17
- }
18
- async batch(statements) {
19
- const owned = statements.map((statement) => {
20
- if (!(statement instanceof SyncSqliteStatement) || statement.connection !== this.connection) throw new Error("SQLite batch statements must be prepared by the same database");
21
- return statement;
22
- });
23
- return this.connection.transaction(() => owned.map((statement) => statement.executeNow()));
24
- }
25
- async exec(query) {
26
- this.connection.executeScript(query);
27
- return { success: true };
28
- }
29
- };
30
- var SyncSqliteStatement = class SyncSqliteStatement {
31
- constructor(connection, query, values) {
32
- this.connection = connection;
33
- this.query = query;
34
- this.values = values;
35
- }
36
- bind(...values) {
37
- return new SyncSqliteStatement(this.connection, this.query, values.map(toSqliteValue));
38
- }
39
- async first(columnName) {
40
- const row = this.connection.execute(this.query, this.values)[0];
41
- if (!row) return null;
42
- if (columnName === void 0) return row;
43
- return row[columnName] ?? null;
44
- }
45
- async all() {
46
- return this.executeNow();
47
- }
48
- async run() {
49
- return this.executeNow();
50
- }
51
- /** Executes synchronously so a batch can run inside one host transaction. */
52
- executeNow() {
53
- const results = this.connection.execute(this.query, this.values);
54
- const [counters] = this.connection.execute("SELECT changes() AS changes, last_insert_rowid() AS last_row_id", []);
55
- return {
56
- results,
57
- success: true,
58
- meta: {
59
- changes: Number(counters?.changes ?? 0),
60
- last_row_id: Number(counters?.last_row_id ?? 0)
61
- }
62
- };
63
- }
64
- };
65
- function toSqliteValue(value) {
66
- if (value === null || typeof value === "string") return value;
67
- if (typeof value === "number") {
68
- if (!Number.isFinite(value)) throw new Error("SQLite binding must be a finite number");
69
- return value;
70
- }
71
- if (typeof value === "boolean") return value ? 1 : 0;
72
- if (value instanceof Uint8Array) return value;
73
- if (value instanceof ArrayBuffer) return new Uint8Array(value);
74
- throw new Error(`unsupported SQLite binding type ${typeof value}`);
75
- }
76
- //#endregion
77
- export { createSyncSqliteDatabase };
78
-
79
- //# sourceMappingURL=syncSqlite.js.map
@@ -1,75 +0,0 @@
1
- import { failure } from "../../../../shared-ts/src/utils/failure.js";
2
- import { authorizeSigningSessionSealRequest, buildSigningSessionSealApplyPath, buildSigningSessionSealRemovePath, parseSigningSessionSealApplyBody, parseSigningSessionSealRemoveBody, resolveSigningSessionSealBasePath, signingSessionSealAuthorizeStatusCode, signingSessionSealStatusCode } from "./shared.js";
3
- //#region src/threshold/session/signingSessionSeal/transport/express.ts
4
- function errMessage(error) {
5
- return error instanceof Error ? error.message : String(error || "Internal error");
6
- }
7
- function registerSigningSessionSealRoutes(router, ctx) {
8
- const options = ctx.options;
9
- ctx.logger.info("[threshold-signing-session-seal] routes", { enabled: Boolean(options) });
10
- if (!options) return;
11
- const basePath = resolveSigningSessionSealBasePath(options.basePath);
12
- const applyPath = buildSigningSessionSealApplyPath(basePath);
13
- const removePath = buildSigningSessionSealRemovePath(basePath);
14
- const handleSealRoute = (route, operation) => async (req, res) => {
15
- const startedAtMs = Date.now();
16
- try {
17
- ctx.logger.info("[threshold-signing-session-seal] request", {
18
- route,
19
- operation
20
- });
21
- const parsed = operation === "apply-server-seal" ? parseSigningSessionSealApplyBody(req.body || {}) : parseSigningSessionSealRemoveBody(req.body || {});
22
- if (!parsed.ok) {
23
- ctx.logger.warn("[threshold-signing-session-seal] invalid_body", {
24
- route,
25
- operation,
26
- code: parsed.code,
27
- message: parsed.message,
28
- durationMs: Math.max(0, Date.now() - startedAtMs)
29
- });
30
- res.status(400).json(failure(parsed.code, parsed.message));
31
- return;
32
- }
33
- const authorized = await authorizeSigningSessionSealRequest({
34
- options,
35
- headers: req.headers || {},
36
- thresholdSessionId: parsed.value.thresholdSessionId
37
- });
38
- if (!authorized.ok) {
39
- ctx.logger.warn("[threshold-signing-session-seal] unauthorized", {
40
- route,
41
- operation,
42
- code: authorized.code || "unauthorized",
43
- message: authorized.message || "Unauthorized",
44
- durationMs: Math.max(0, Date.now() - startedAtMs)
45
- });
46
- res.status(signingSessionSealAuthorizeStatusCode(authorized)).json(failure(authorized.code || "unauthorized", authorized.message || "Unauthorized"));
47
- return;
48
- }
49
- const result = operation === "apply-server-seal" ? await options.service.applyServerSeal(parsed.value, authorized.auth) : await options.service.removeServerSeal(parsed.value, authorized.auth);
50
- const status = signingSessionSealStatusCode(result);
51
- res.status(status).json(result);
52
- ctx.logger.info("[threshold-signing-session-seal] response", {
53
- route,
54
- status,
55
- ok: result.ok,
56
- durationMs: Math.max(0, Date.now() - startedAtMs),
57
- userId: authorized.auth.userId
58
- });
59
- } catch (error) {
60
- const message = errMessage(error);
61
- ctx.logger.error("[threshold-signing-session-seal] error", {
62
- route,
63
- message,
64
- durationMs: Math.max(0, Date.now() - startedAtMs)
65
- });
66
- res.status(500).json(failure("internal", message));
67
- }
68
- };
69
- router.post(applyPath, handleSealRoute(applyPath, "apply-server-seal"));
70
- router.post(removePath, handleSealRoute(removePath, "remove-server-seal"));
71
- }
72
- //#endregion
73
- export { registerSigningSessionSealRoutes };
74
-
75
- //# sourceMappingURL=express.js.map