@waiaas/daemon 2.4.0-rc.2 → 2.4.0-rc.4
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/README.md +1 -0
- package/dist/api/routes/admin.d.ts.map +1 -1
- package/dist/api/routes/admin.js +23 -32
- package/dist/api/routes/admin.js.map +1 -1
- package/dist/api/routes/openapi-schemas.d.ts +57 -0
- package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
- package/dist/api/routes/openapi-schemas.js +14 -1
- package/dist/api/routes/openapi-schemas.js.map +1 -1
- package/dist/api/routes/transactions.d.ts +2 -0
- package/dist/api/routes/transactions.d.ts.map +1 -1
- package/dist/api/routes/transactions.js +1 -0
- package/dist/api/routes/transactions.js.map +1 -1
- package/dist/api/routes/wallets.d.ts.map +1 -1
- package/dist/api/routes/wallets.js +9 -0
- package/dist/api/routes/wallets.js.map +1 -1
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +1 -0
- package/dist/api/server.js.map +1 -1
- package/dist/infrastructure/database/compatibility.js +2 -2
- package/dist/infrastructure/database/compatibility.js.map +1 -1
- package/dist/infrastructure/database/migrate.d.ts +1 -1
- package/dist/infrastructure/database/migrate.d.ts.map +1 -1
- package/dist/infrastructure/database/migrate.js +17 -3
- package/dist/infrastructure/database/migrate.js.map +1 -1
- package/dist/infrastructure/database/schema.d.ts +20 -0
- package/dist/infrastructure/database/schema.d.ts.map +1 -1
- package/dist/infrastructure/database/schema.js +2 -0
- package/dist/infrastructure/database/schema.js.map +1 -1
- package/dist/infrastructure/settings/setting-keys.d.ts +2 -2
- package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
- package/dist/infrastructure/settings/setting-keys.js +10 -1
- package/dist/infrastructure/settings/setting-keys.js.map +1 -1
- package/dist/infrastructure/telegram/telegram-auth.d.ts +1 -1
- package/dist/infrastructure/telegram/telegram-auth.d.ts.map +1 -1
- package/dist/infrastructure/telegram/telegram-auth.js +1 -1
- package/dist/infrastructure/telegram/telegram-auth.js.map +1 -1
- package/dist/infrastructure/telegram/telegram-bot-service.d.ts +9 -0
- package/dist/infrastructure/telegram/telegram-bot-service.d.ts.map +1 -1
- package/dist/infrastructure/telegram/telegram-bot-service.js +46 -1
- package/dist/infrastructure/telegram/telegram-bot-service.js.map +1 -1
- package/dist/infrastructure/telegram/telegram-types.d.ts +1 -0
- package/dist/infrastructure/telegram/telegram-types.d.ts.map +1 -1
- package/dist/lifecycle/daemon.d.ts +2 -0
- package/dist/lifecycle/daemon.d.ts.map +1 -1
- package/dist/lifecycle/daemon.js +63 -0
- package/dist/lifecycle/daemon.js.map +1 -1
- package/dist/pipeline/stages.d.ts +2 -0
- package/dist/pipeline/stages.d.ts.map +1 -1
- package/dist/pipeline/stages.js +14 -0
- package/dist/pipeline/stages.js.map +1 -1
- package/dist/services/signing-sdk/approval-channel-router.d.ts +65 -0
- package/dist/services/signing-sdk/approval-channel-router.d.ts.map +1 -0
- package/dist/services/signing-sdk/approval-channel-router.js +147 -0
- package/dist/services/signing-sdk/approval-channel-router.js.map +1 -0
- package/dist/services/signing-sdk/channels/index.d.ts +10 -0
- package/dist/services/signing-sdk/channels/index.d.ts.map +1 -0
- package/dist/services/signing-sdk/channels/index.js +8 -0
- package/dist/services/signing-sdk/channels/index.js.map +1 -0
- package/dist/services/signing-sdk/channels/ntfy-signing-channel.d.ts +66 -0
- package/dist/services/signing-sdk/channels/ntfy-signing-channel.d.ts.map +1 -0
- package/dist/services/signing-sdk/channels/ntfy-signing-channel.js +257 -0
- package/dist/services/signing-sdk/channels/ntfy-signing-channel.js.map +1 -0
- package/dist/services/signing-sdk/channels/telegram-signing-channel.d.ts +56 -0
- package/dist/services/signing-sdk/channels/telegram-signing-channel.d.ts.map +1 -0
- package/dist/services/signing-sdk/channels/telegram-signing-channel.js +87 -0
- package/dist/services/signing-sdk/channels/telegram-signing-channel.js.map +1 -0
- package/dist/services/signing-sdk/index.d.ts +34 -0
- package/dist/services/signing-sdk/index.d.ts.map +1 -0
- package/dist/services/signing-sdk/index.js +25 -0
- package/dist/services/signing-sdk/index.js.map +1 -0
- package/dist/services/signing-sdk/sign-request-builder.d.ts +61 -0
- package/dist/services/signing-sdk/sign-request-builder.d.ts.map +1 -0
- package/dist/services/signing-sdk/sign-request-builder.js +157 -0
- package/dist/services/signing-sdk/sign-request-builder.js.map +1 -0
- package/dist/services/signing-sdk/sign-response-handler.d.ts +92 -0
- package/dist/services/signing-sdk/sign-response-handler.d.ts.map +1 -0
- package/dist/services/signing-sdk/sign-response-handler.js +303 -0
- package/dist/services/signing-sdk/sign-response-handler.js.map +1 -0
- package/dist/services/signing-sdk/wallet-link-registry.d.ts +44 -0
- package/dist/services/signing-sdk/wallet-link-registry.d.ts.map +1 -0
- package/dist/services/signing-sdk/wallet-link-registry.js +116 -0
- package/dist/services/signing-sdk/wallet-link-registry.js.map +1 -0
- package/package.json +4 -4
- package/public/admin/assets/index-D7vqMezf.js +1 -0
- package/public/admin/index.html +1 -1
- package/public/admin/assets/index-BEqsuxTi.js +0 -1
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SignResponseHandler -- processes SignResponse from wallet apps.
|
|
3
|
+
*
|
|
4
|
+
* Handles approve/reject responses for PENDING_APPROVAL transactions:
|
|
5
|
+
* - Validates SignResponse schema (Zod)
|
|
6
|
+
* - Matches requestId to registered pending requests
|
|
7
|
+
* - Checks request expiration
|
|
8
|
+
* - Verifies signer address matches wallet owner
|
|
9
|
+
* - Verifies cryptographic signature (EVM: EIP-191, Solana: Ed25519)
|
|
10
|
+
* - Updates pending_approvals and transactions tables directly
|
|
11
|
+
*
|
|
12
|
+
* **Design Decision: ApprovalWorkflow bypass (intentional)**
|
|
13
|
+
* SignResponseHandler directly updates pending_approvals/transactions tables,
|
|
14
|
+
* bypassing ApprovalWorkflow. This is the same pattern used by Telegram bot
|
|
15
|
+
* approval (/approve, /reject commands). Rationale: SignResponseHandler performs
|
|
16
|
+
* its own cryptographic signature verification (SIWE/SIWS), making
|
|
17
|
+
* ApprovalWorkflow's verification step redundant.
|
|
18
|
+
*
|
|
19
|
+
* @see internal/design/73-signing-protocol-v1.md (Section 4, 10, 11)
|
|
20
|
+
* @see internal/design/74-wallet-sdk-daemon-components.md
|
|
21
|
+
*/
|
|
22
|
+
import { SignResponseSchema, WAIaaSError, } from '@waiaas/core';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Default verification implementations
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Default EVM signature verification using viem.
|
|
28
|
+
* Uses lazy import to avoid loading viem at module level.
|
|
29
|
+
*/
|
|
30
|
+
const defaultEvmVerify = async ({ address, message, signature }) => {
|
|
31
|
+
const { verifyMessage } = await import('viem');
|
|
32
|
+
return verifyMessage({
|
|
33
|
+
address: address,
|
|
34
|
+
message,
|
|
35
|
+
signature: signature,
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Default Solana signature verification using @solana/kit.
|
|
40
|
+
* Decodes base64 signature, converts address to CryptoKey, verifies Ed25519.
|
|
41
|
+
*/
|
|
42
|
+
const defaultSolanaVerify = async ({ publicKeyAddress, message, signature }) => {
|
|
43
|
+
const { verifySignature, signatureBytes: toSignatureBytes, getPublicKeyFromAddress, address } = await import('@solana/kit');
|
|
44
|
+
// Convert address string to CryptoKey
|
|
45
|
+
const pubKey = await getPublicKeyFromAddress(address(publicKeyAddress));
|
|
46
|
+
// Decode base64 signature to bytes
|
|
47
|
+
const sigBytes = Buffer.from(signature, 'base64');
|
|
48
|
+
const sigTyped = toSignatureBytes(new Uint8Array(sigBytes));
|
|
49
|
+
// Encode message to bytes
|
|
50
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
51
|
+
return verifySignature(pubKey, sigTyped, messageBytes);
|
|
52
|
+
};
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// SignResponseHandler
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
export class SignResponseHandler {
|
|
57
|
+
sqlite;
|
|
58
|
+
/**
|
|
59
|
+
* In-memory store: requestId -> { request, createdAt }.
|
|
60
|
+
* Lost on daemon restart (acceptable -- 1-shot requests with expiry).
|
|
61
|
+
*/
|
|
62
|
+
pendingRequests = new Map();
|
|
63
|
+
/**
|
|
64
|
+
* Set of already-processed requestIds (for duplicate detection).
|
|
65
|
+
* Also lost on daemon restart.
|
|
66
|
+
*/
|
|
67
|
+
processedRequests = new Set();
|
|
68
|
+
/** Expiration timers by requestId */
|
|
69
|
+
expirationTimers = new Map();
|
|
70
|
+
/** Injectable verification functions (for testing) */
|
|
71
|
+
evmVerify;
|
|
72
|
+
solanaVerify;
|
|
73
|
+
constructor(deps, opts) {
|
|
74
|
+
this.sqlite = deps.sqlite;
|
|
75
|
+
this.evmVerify = opts?.evmVerify ?? defaultEvmVerify;
|
|
76
|
+
this.solanaVerify = opts?.solanaVerify ?? defaultSolanaVerify;
|
|
77
|
+
}
|
|
78
|
+
// -------------------------------------------------------------------------
|
|
79
|
+
// registerRequest -- store pending request for later matching
|
|
80
|
+
// -------------------------------------------------------------------------
|
|
81
|
+
/**
|
|
82
|
+
* Register a SignRequest for later response matching.
|
|
83
|
+
* Sets an expiration timer to auto-remove the request after expiresAt.
|
|
84
|
+
*/
|
|
85
|
+
registerRequest(request) {
|
|
86
|
+
this.pendingRequests.set(request.requestId, {
|
|
87
|
+
request,
|
|
88
|
+
createdAt: new Date(),
|
|
89
|
+
});
|
|
90
|
+
// Set expiration timer
|
|
91
|
+
const expiresAtMs = new Date(request.expiresAt).getTime();
|
|
92
|
+
const timeoutMs = Math.max(0, expiresAtMs - Date.now());
|
|
93
|
+
const timer = setTimeout(() => {
|
|
94
|
+
this.pendingRequests.delete(request.requestId);
|
|
95
|
+
this.expirationTimers.delete(request.requestId);
|
|
96
|
+
}, timeoutMs);
|
|
97
|
+
// Unref the timer so it doesn't prevent process exit
|
|
98
|
+
if (typeof timer === 'object' && 'unref' in timer) {
|
|
99
|
+
timer.unref();
|
|
100
|
+
}
|
|
101
|
+
this.expirationTimers.set(request.requestId, timer);
|
|
102
|
+
}
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
// handle -- process a SignResponse
|
|
105
|
+
// -------------------------------------------------------------------------
|
|
106
|
+
/**
|
|
107
|
+
* Process a SignResponse: validate, match, verify signature, update DB.
|
|
108
|
+
*
|
|
109
|
+
* @param signResponse - The response from the wallet app
|
|
110
|
+
* @returns { action: 'approved' | 'rejected', txId }
|
|
111
|
+
* @throws WAIaaSError with appropriate error code on validation failure
|
|
112
|
+
*/
|
|
113
|
+
async handle(signResponse) {
|
|
114
|
+
// 1. Zod validation
|
|
115
|
+
try {
|
|
116
|
+
SignResponseSchema.parse(signResponse);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
throw new WAIaaSError('INVALID_SIGN_RESPONSE', {
|
|
120
|
+
message: 'Sign response failed schema validation',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const { requestId, action, signerAddress } = signResponse;
|
|
124
|
+
// 2. Check if already processed (duplicate detection)
|
|
125
|
+
if (this.processedRequests.has(requestId)) {
|
|
126
|
+
throw new WAIaaSError('SIGN_REQUEST_ALREADY_PROCESSED', {
|
|
127
|
+
message: `Sign request ${requestId} has already been processed`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// 3. Find pending request
|
|
131
|
+
const pending = this.pendingRequests.get(requestId);
|
|
132
|
+
if (!pending) {
|
|
133
|
+
throw new WAIaaSError('SIGN_REQUEST_NOT_FOUND', {
|
|
134
|
+
message: `No pending sign request found for requestId: ${requestId}`,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const { request } = pending;
|
|
138
|
+
// 4. Check expiration
|
|
139
|
+
if (new Date() > new Date(request.expiresAt)) {
|
|
140
|
+
this.pendingRequests.delete(requestId);
|
|
141
|
+
this.clearTimer(requestId);
|
|
142
|
+
throw new WAIaaSError('SIGN_REQUEST_EXPIRED', {
|
|
143
|
+
message: `Sign request ${requestId} has expired`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// 5. Verify signer address matches wallet owner
|
|
147
|
+
const txId = request.metadata.txId;
|
|
148
|
+
const walletRow = this.sqlite
|
|
149
|
+
.prepare(`SELECT w.owner_address FROM wallets w
|
|
150
|
+
JOIN transactions t ON t.wallet_id = w.id
|
|
151
|
+
WHERE t.id = ?`)
|
|
152
|
+
.get(txId);
|
|
153
|
+
if (walletRow?.owner_address) {
|
|
154
|
+
// Case-insensitive comparison for EVM addresses (0x-prefixed hex)
|
|
155
|
+
const normalizedSigner = signerAddress.toLowerCase();
|
|
156
|
+
const normalizedOwner = walletRow.owner_address.toLowerCase();
|
|
157
|
+
if (normalizedSigner !== normalizedOwner) {
|
|
158
|
+
throw new WAIaaSError('SIGNER_ADDRESS_MISMATCH', {
|
|
159
|
+
message: `Signer address ${signerAddress} does not match wallet owner ${walletRow.owner_address}`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// 6. Handle action
|
|
164
|
+
if (action === 'approve') {
|
|
165
|
+
return this.handleApprove(request, signResponse);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return this.handleReject(request, signResponse);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// -------------------------------------------------------------------------
|
|
172
|
+
// Private: handleApprove
|
|
173
|
+
// -------------------------------------------------------------------------
|
|
174
|
+
async handleApprove(request, response) {
|
|
175
|
+
const { requestId, signature, signerAddress } = response;
|
|
176
|
+
const txId = request.metadata.txId;
|
|
177
|
+
// Signature is required for approve
|
|
178
|
+
if (!signature) {
|
|
179
|
+
throw new WAIaaSError('INVALID_SIGN_RESPONSE', {
|
|
180
|
+
message: 'Missing signature for approve action',
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// Verify cryptographic signature
|
|
184
|
+
let isValid = false;
|
|
185
|
+
try {
|
|
186
|
+
if (request.chain === 'evm') {
|
|
187
|
+
isValid = await this.evmVerify({
|
|
188
|
+
address: signerAddress,
|
|
189
|
+
message: request.message,
|
|
190
|
+
signature,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else if (request.chain === 'solana') {
|
|
194
|
+
isValid = await this.solanaVerify({
|
|
195
|
+
publicKeyAddress: signerAddress,
|
|
196
|
+
message: request.message,
|
|
197
|
+
signature,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
isValid = false;
|
|
203
|
+
}
|
|
204
|
+
if (!isValid) {
|
|
205
|
+
throw new WAIaaSError('INVALID_SIGNATURE', {
|
|
206
|
+
message: 'Cryptographic signature verification failed',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// Direct DB update (ApprovalWorkflow bypass -- same pattern as Telegram bot)
|
|
210
|
+
const now = Math.floor(Date.now() / 1000);
|
|
211
|
+
this.sqlite
|
|
212
|
+
.prepare(`UPDATE pending_approvals SET approved_at = ?, owner_signature = ?, approval_channel = 'signing_sdk'
|
|
213
|
+
WHERE tx_id = ? AND approved_at IS NULL AND rejected_at IS NULL`)
|
|
214
|
+
.run(now, signature, txId);
|
|
215
|
+
this.sqlite
|
|
216
|
+
.prepare(`UPDATE transactions SET status = 'EXECUTING', reserved_amount = NULL, reserved_amount_usd = NULL
|
|
217
|
+
WHERE id = ? AND status = 'QUEUED'`)
|
|
218
|
+
.run(txId);
|
|
219
|
+
// Cleanup
|
|
220
|
+
this.pendingRequests.delete(requestId);
|
|
221
|
+
this.processedRequests.add(requestId);
|
|
222
|
+
this.clearTimer(requestId);
|
|
223
|
+
return { action: 'approved', txId };
|
|
224
|
+
}
|
|
225
|
+
// -------------------------------------------------------------------------
|
|
226
|
+
// Private: handleReject
|
|
227
|
+
// -------------------------------------------------------------------------
|
|
228
|
+
async handleReject(request, response) {
|
|
229
|
+
const { requestId, signature, signerAddress } = response;
|
|
230
|
+
const txId = request.metadata.txId;
|
|
231
|
+
// Optional signature verification for reject
|
|
232
|
+
if (signature) {
|
|
233
|
+
try {
|
|
234
|
+
let isValid = false;
|
|
235
|
+
if (request.chain === 'evm') {
|
|
236
|
+
isValid = await this.evmVerify({
|
|
237
|
+
address: signerAddress,
|
|
238
|
+
message: request.message,
|
|
239
|
+
signature,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else if (request.chain === 'solana') {
|
|
243
|
+
isValid = await this.solanaVerify({
|
|
244
|
+
publicKeyAddress: signerAddress,
|
|
245
|
+
message: request.message,
|
|
246
|
+
signature,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
if (!isValid) {
|
|
250
|
+
throw new WAIaaSError('INVALID_SIGNATURE', {
|
|
251
|
+
message: 'Cryptographic signature verification failed for reject action',
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
if (err instanceof WAIaaSError && err.code === 'INVALID_SIGNATURE') {
|
|
257
|
+
throw err;
|
|
258
|
+
}
|
|
259
|
+
// Signature verification errors on reject are non-fatal if not INVALID_SIGNATURE
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Direct DB update (ApprovalWorkflow bypass -- same pattern as Telegram bot)
|
|
263
|
+
const now = Math.floor(Date.now() / 1000);
|
|
264
|
+
this.sqlite
|
|
265
|
+
.prepare(`UPDATE pending_approvals SET rejected_at = ?, approval_channel = 'signing_sdk'
|
|
266
|
+
WHERE tx_id = ? AND approved_at IS NULL AND rejected_at IS NULL`)
|
|
267
|
+
.run(now, txId);
|
|
268
|
+
this.sqlite
|
|
269
|
+
.prepare(`UPDATE transactions SET status = 'CANCELLED', error = 'Rejected via signing SDK', reserved_amount = NULL, reserved_amount_usd = NULL
|
|
270
|
+
WHERE id = ? AND status = 'QUEUED'`)
|
|
271
|
+
.run(txId);
|
|
272
|
+
// Cleanup
|
|
273
|
+
this.pendingRequests.delete(requestId);
|
|
274
|
+
this.processedRequests.add(requestId);
|
|
275
|
+
this.clearTimer(requestId);
|
|
276
|
+
return { action: 'rejected', txId };
|
|
277
|
+
}
|
|
278
|
+
// -------------------------------------------------------------------------
|
|
279
|
+
// Private: Timer cleanup
|
|
280
|
+
// -------------------------------------------------------------------------
|
|
281
|
+
clearTimer(requestId) {
|
|
282
|
+
const timer = this.expirationTimers.get(requestId);
|
|
283
|
+
if (timer) {
|
|
284
|
+
clearTimeout(timer);
|
|
285
|
+
this.expirationTimers.delete(requestId);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// -------------------------------------------------------------------------
|
|
289
|
+
// Cleanup: destroy (for graceful shutdown)
|
|
290
|
+
// -------------------------------------------------------------------------
|
|
291
|
+
/**
|
|
292
|
+
* Clear all pending timers. Call during daemon shutdown.
|
|
293
|
+
*/
|
|
294
|
+
destroy() {
|
|
295
|
+
for (const timer of this.expirationTimers.values()) {
|
|
296
|
+
clearTimeout(timer);
|
|
297
|
+
}
|
|
298
|
+
this.expirationTimers.clear();
|
|
299
|
+
this.pendingRequests.clear();
|
|
300
|
+
this.processedRequests.clear();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=sign-response-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-response-handler.js","sourceRoot":"","sources":["../../../src/services/signing-sdk/sign-response-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WalletLinkRegistry -- manages wallet registration for the Signing SDK.
|
|
3
|
+
*
|
|
4
|
+
* Stores wallet link configurations as a JSON array in SettingsService
|
|
5
|
+
* under the 'signing_sdk.wallets' key. Provides CRUD operations and
|
|
6
|
+
* universal link URL generation for registered wallets.
|
|
7
|
+
*
|
|
8
|
+
* @see internal/design/74-wallet-sdk-daemon-components.md
|
|
9
|
+
*/
|
|
10
|
+
import { type WalletLinkConfig, type SignRequest } from '@waiaas/core';
|
|
11
|
+
import type { SettingsService } from '../../infrastructure/settings/settings-service.js';
|
|
12
|
+
export declare class WalletLinkRegistry {
|
|
13
|
+
private readonly settings;
|
|
14
|
+
constructor(settings: SettingsService);
|
|
15
|
+
/**
|
|
16
|
+
* Get a wallet configuration by name.
|
|
17
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
18
|
+
*/
|
|
19
|
+
getWallet(name: string): WalletLinkConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Get all registered wallet configurations.
|
|
22
|
+
*/
|
|
23
|
+
getAllWallets(): WalletLinkConfig[];
|
|
24
|
+
/**
|
|
25
|
+
* Register a new wallet configuration.
|
|
26
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') is NOT thrown -- instead throws
|
|
27
|
+
* a generic error if the wallet name already exists (duplicate prevention).
|
|
28
|
+
*/
|
|
29
|
+
registerWallet(config: WalletLinkConfig): void;
|
|
30
|
+
/**
|
|
31
|
+
* Remove a wallet configuration by name.
|
|
32
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
33
|
+
*/
|
|
34
|
+
removeWallet(name: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Build a universal link URL for a wallet signing request.
|
|
37
|
+
* Combines getWallet() + buildUniversalLinkUrl().
|
|
38
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
39
|
+
*/
|
|
40
|
+
buildSignUrl(walletName: string, request: SignRequest): string;
|
|
41
|
+
private loadWallets;
|
|
42
|
+
private saveWallets;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=wallet-link-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-link-registry.d.ts","sourceRoot":"","sources":["../../../src/services/signing-sdk/wallet-link-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAGjB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAYzF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAE/B,QAAQ,EAAE,eAAe;IAQrC;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB;IAYzC;;OAEG;IACH,aAAa,IAAI,gBAAgB,EAAE;IAQnC;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAiB9C;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiBhC;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM;IAS9D,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WalletLinkRegistry -- manages wallet registration for the Signing SDK.
|
|
3
|
+
*
|
|
4
|
+
* Stores wallet link configurations as a JSON array in SettingsService
|
|
5
|
+
* under the 'signing_sdk.wallets' key. Provides CRUD operations and
|
|
6
|
+
* universal link URL generation for registered wallets.
|
|
7
|
+
*
|
|
8
|
+
* @see internal/design/74-wallet-sdk-daemon-components.md
|
|
9
|
+
*/
|
|
10
|
+
import { WalletLinkConfigSchema, buildUniversalLinkUrl, WAIaaSError, } from '@waiaas/core';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Internal: JSON array schema for wallet configs
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const WalletLinkConfigArraySchema = z.array(WalletLinkConfigSchema);
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// WalletLinkRegistry
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
export class WalletLinkRegistry {
|
|
20
|
+
settings;
|
|
21
|
+
constructor(settings) {
|
|
22
|
+
this.settings = settings;
|
|
23
|
+
}
|
|
24
|
+
// -------------------------------------------------------------------------
|
|
25
|
+
// Read: getWallet / getAllWallets
|
|
26
|
+
// -------------------------------------------------------------------------
|
|
27
|
+
/**
|
|
28
|
+
* Get a wallet configuration by name.
|
|
29
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
30
|
+
*/
|
|
31
|
+
getWallet(name) {
|
|
32
|
+
const wallets = this.loadWallets();
|
|
33
|
+
const wallet = wallets.find((w) => w.name === name);
|
|
34
|
+
if (!wallet) {
|
|
35
|
+
throw new WAIaaSError('WALLET_NOT_REGISTERED', {
|
|
36
|
+
message: `Wallet '${name}' not registered in signing SDK`,
|
|
37
|
+
details: { walletName: name },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return wallet;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get all registered wallet configurations.
|
|
44
|
+
*/
|
|
45
|
+
getAllWallets() {
|
|
46
|
+
return this.loadWallets();
|
|
47
|
+
}
|
|
48
|
+
// -------------------------------------------------------------------------
|
|
49
|
+
// Write: registerWallet / removeWallet
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
/**
|
|
52
|
+
* Register a new wallet configuration.
|
|
53
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') is NOT thrown -- instead throws
|
|
54
|
+
* a generic error if the wallet name already exists (duplicate prevention).
|
|
55
|
+
*/
|
|
56
|
+
registerWallet(config) {
|
|
57
|
+
// Validate input against schema
|
|
58
|
+
const validated = WalletLinkConfigSchema.parse(config);
|
|
59
|
+
const wallets = this.loadWallets();
|
|
60
|
+
const existing = wallets.find((w) => w.name === validated.name);
|
|
61
|
+
if (existing) {
|
|
62
|
+
throw new WAIaaSError('SIGN_REQUEST_ALREADY_PROCESSED', {
|
|
63
|
+
message: `Wallet '${validated.name}' is already registered`,
|
|
64
|
+
details: { walletName: validated.name },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
wallets.push(validated);
|
|
68
|
+
this.saveWallets(wallets);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Remove a wallet configuration by name.
|
|
72
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
73
|
+
*/
|
|
74
|
+
removeWallet(name) {
|
|
75
|
+
const wallets = this.loadWallets();
|
|
76
|
+
const index = wallets.findIndex((w) => w.name === name);
|
|
77
|
+
if (index === -1) {
|
|
78
|
+
throw new WAIaaSError('WALLET_NOT_REGISTERED', {
|
|
79
|
+
message: `Wallet '${name}' not registered in signing SDK`,
|
|
80
|
+
details: { walletName: name },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
wallets.splice(index, 1);
|
|
84
|
+
this.saveWallets(wallets);
|
|
85
|
+
}
|
|
86
|
+
// -------------------------------------------------------------------------
|
|
87
|
+
// URL generation: buildSignUrl
|
|
88
|
+
// -------------------------------------------------------------------------
|
|
89
|
+
/**
|
|
90
|
+
* Build a universal link URL for a wallet signing request.
|
|
91
|
+
* Combines getWallet() + buildUniversalLinkUrl().
|
|
92
|
+
* @throws WAIaaSError('WALLET_NOT_REGISTERED') if wallet is not found.
|
|
93
|
+
*/
|
|
94
|
+
buildSignUrl(walletName, request) {
|
|
95
|
+
const wallet = this.getWallet(walletName);
|
|
96
|
+
return buildUniversalLinkUrl(wallet, request);
|
|
97
|
+
}
|
|
98
|
+
// -------------------------------------------------------------------------
|
|
99
|
+
// Private: load/save from SettingsService
|
|
100
|
+
// -------------------------------------------------------------------------
|
|
101
|
+
loadWallets() {
|
|
102
|
+
const json = this.settings.get('signing_sdk.wallets');
|
|
103
|
+
try {
|
|
104
|
+
const parsed = JSON.parse(json);
|
|
105
|
+
return WalletLinkConfigArraySchema.parse(parsed);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// If the stored JSON is invalid, return empty array (graceful degradation)
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
saveWallets(wallets) {
|
|
113
|
+
this.settings.set('signing_sdk.wallets', JSON.stringify(wallets));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=wallet-link-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-link-registry.js","sourceRoot":"","sources":["../../../src/services/signing-sdk/wallet-link-registry.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waiaas/daemon",
|
|
3
|
-
"version": "2.4.0-rc.
|
|
3
|
+
"version": "2.4.0-rc.4",
|
|
4
4
|
"description": "WAIaaS daemon - self-hosted wallet service for AI agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"uuidv7": "^1.0.2",
|
|
48
48
|
"viem": "^2.21.0",
|
|
49
49
|
"zod": "^3.24.0",
|
|
50
|
-
"@waiaas/adapter-evm": "2.4.0-rc.
|
|
51
|
-
"@waiaas/core": "2.4.0-rc.
|
|
52
|
-
"@waiaas/adapter-solana": "2.4.0-rc.
|
|
50
|
+
"@waiaas/adapter-evm": "2.4.0-rc.4",
|
|
51
|
+
"@waiaas/core": "2.4.0-rc.4",
|
|
52
|
+
"@waiaas/adapter-solana": "2.4.0-rc.4"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/better-sqlite3": "^7.6.0",
|