@waiaas/daemon 2.4.0-rc.2 → 2.4.0-rc.3

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 (87) hide show
  1. package/README.md +1 -0
  2. package/dist/api/routes/admin.d.ts.map +1 -1
  3. package/dist/api/routes/admin.js +23 -32
  4. package/dist/api/routes/admin.js.map +1 -1
  5. package/dist/api/routes/openapi-schemas.d.ts +57 -0
  6. package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
  7. package/dist/api/routes/openapi-schemas.js +14 -1
  8. package/dist/api/routes/openapi-schemas.js.map +1 -1
  9. package/dist/api/routes/transactions.d.ts +2 -0
  10. package/dist/api/routes/transactions.d.ts.map +1 -1
  11. package/dist/api/routes/transactions.js +1 -0
  12. package/dist/api/routes/transactions.js.map +1 -1
  13. package/dist/api/routes/wallets.d.ts.map +1 -1
  14. package/dist/api/routes/wallets.js +9 -0
  15. package/dist/api/routes/wallets.js.map +1 -1
  16. package/dist/api/server.d.ts +2 -0
  17. package/dist/api/server.d.ts.map +1 -1
  18. package/dist/api/server.js +1 -0
  19. package/dist/api/server.js.map +1 -1
  20. package/dist/infrastructure/database/compatibility.js +2 -2
  21. package/dist/infrastructure/database/compatibility.js.map +1 -1
  22. package/dist/infrastructure/database/migrate.d.ts +1 -1
  23. package/dist/infrastructure/database/migrate.d.ts.map +1 -1
  24. package/dist/infrastructure/database/migrate.js +17 -3
  25. package/dist/infrastructure/database/migrate.js.map +1 -1
  26. package/dist/infrastructure/database/schema.d.ts +20 -0
  27. package/dist/infrastructure/database/schema.d.ts.map +1 -1
  28. package/dist/infrastructure/database/schema.js +2 -0
  29. package/dist/infrastructure/database/schema.js.map +1 -1
  30. package/dist/infrastructure/settings/setting-keys.d.ts +2 -2
  31. package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
  32. package/dist/infrastructure/settings/setting-keys.js +10 -1
  33. package/dist/infrastructure/settings/setting-keys.js.map +1 -1
  34. package/dist/infrastructure/telegram/telegram-auth.d.ts +1 -1
  35. package/dist/infrastructure/telegram/telegram-auth.d.ts.map +1 -1
  36. package/dist/infrastructure/telegram/telegram-auth.js +1 -1
  37. package/dist/infrastructure/telegram/telegram-auth.js.map +1 -1
  38. package/dist/infrastructure/telegram/telegram-bot-service.d.ts +9 -0
  39. package/dist/infrastructure/telegram/telegram-bot-service.d.ts.map +1 -1
  40. package/dist/infrastructure/telegram/telegram-bot-service.js +46 -1
  41. package/dist/infrastructure/telegram/telegram-bot-service.js.map +1 -1
  42. package/dist/infrastructure/telegram/telegram-types.d.ts +1 -0
  43. package/dist/infrastructure/telegram/telegram-types.d.ts.map +1 -1
  44. package/dist/lifecycle/daemon.d.ts +2 -0
  45. package/dist/lifecycle/daemon.d.ts.map +1 -1
  46. package/dist/lifecycle/daemon.js +63 -0
  47. package/dist/lifecycle/daemon.js.map +1 -1
  48. package/dist/pipeline/stages.d.ts +2 -0
  49. package/dist/pipeline/stages.d.ts.map +1 -1
  50. package/dist/pipeline/stages.js +14 -0
  51. package/dist/pipeline/stages.js.map +1 -1
  52. package/dist/services/signing-sdk/approval-channel-router.d.ts +65 -0
  53. package/dist/services/signing-sdk/approval-channel-router.d.ts.map +1 -0
  54. package/dist/services/signing-sdk/approval-channel-router.js +147 -0
  55. package/dist/services/signing-sdk/approval-channel-router.js.map +1 -0
  56. package/dist/services/signing-sdk/channels/index.d.ts +10 -0
  57. package/dist/services/signing-sdk/channels/index.d.ts.map +1 -0
  58. package/dist/services/signing-sdk/channels/index.js +8 -0
  59. package/dist/services/signing-sdk/channels/index.js.map +1 -0
  60. package/dist/services/signing-sdk/channels/ntfy-signing-channel.d.ts +66 -0
  61. package/dist/services/signing-sdk/channels/ntfy-signing-channel.d.ts.map +1 -0
  62. package/dist/services/signing-sdk/channels/ntfy-signing-channel.js +257 -0
  63. package/dist/services/signing-sdk/channels/ntfy-signing-channel.js.map +1 -0
  64. package/dist/services/signing-sdk/channels/telegram-signing-channel.d.ts +56 -0
  65. package/dist/services/signing-sdk/channels/telegram-signing-channel.d.ts.map +1 -0
  66. package/dist/services/signing-sdk/channels/telegram-signing-channel.js +87 -0
  67. package/dist/services/signing-sdk/channels/telegram-signing-channel.js.map +1 -0
  68. package/dist/services/signing-sdk/index.d.ts +34 -0
  69. package/dist/services/signing-sdk/index.d.ts.map +1 -0
  70. package/dist/services/signing-sdk/index.js +25 -0
  71. package/dist/services/signing-sdk/index.js.map +1 -0
  72. package/dist/services/signing-sdk/sign-request-builder.d.ts +61 -0
  73. package/dist/services/signing-sdk/sign-request-builder.d.ts.map +1 -0
  74. package/dist/services/signing-sdk/sign-request-builder.js +157 -0
  75. package/dist/services/signing-sdk/sign-request-builder.js.map +1 -0
  76. package/dist/services/signing-sdk/sign-response-handler.d.ts +92 -0
  77. package/dist/services/signing-sdk/sign-response-handler.d.ts.map +1 -0
  78. package/dist/services/signing-sdk/sign-response-handler.js +303 -0
  79. package/dist/services/signing-sdk/sign-response-handler.js.map +1 -0
  80. package/dist/services/signing-sdk/wallet-link-registry.d.ts +44 -0
  81. package/dist/services/signing-sdk/wallet-link-registry.d.ts.map +1 -0
  82. package/dist/services/signing-sdk/wallet-link-registry.js +116 -0
  83. package/dist/services/signing-sdk/wallet-link-registry.js.map +1 -0
  84. package/package.json +4 -4
  85. package/public/admin/assets/index-D7vqMezf.js +1 -0
  86. package/public/admin/index.html +1 -1
  87. package/public/admin/assets/index-BEqsuxTi.js +0 -1
@@ -0,0 +1,87 @@
1
+ /**
2
+ * TelegramSigningChannel -- sends SignRequests via Telegram inline button message.
3
+ *
4
+ * When a PENDING_APPROVAL transaction triggers a SignRequest:
5
+ * 1. Builds the SignRequest via SignRequestBuilder
6
+ * 2. Registers the request with SignResponseHandler for later matching
7
+ * 3. Sends a Telegram message to the admin chat with an inline "Open in Wallet"
8
+ * button containing the universal link URL
9
+ *
10
+ * Unlike NtfySigningChannel, TelegramSigningChannel does NOT subscribe to a response
11
+ * topic. The response arrives via the /sign_response Telegram bot command, which
12
+ * delegates to SignResponseHandler. This is a one-way push channel.
13
+ *
14
+ * Implements ISigningChannel interface for consistent channel abstraction.
15
+ *
16
+ * @see internal/design/73-signing-protocol-v1.md (Section 7.2, 7.3)
17
+ * @see internal/design/74-wallet-sdk-daemon-components.md
18
+ */
19
+ import { escapeMarkdownV2 } from '../../../infrastructure/telegram/telegram-bot-service.js';
20
+ // ---------------------------------------------------------------------------
21
+ // TelegramSigningChannel
22
+ // ---------------------------------------------------------------------------
23
+ export class TelegramSigningChannel {
24
+ signRequestBuilder;
25
+ signResponseHandler;
26
+ settings;
27
+ telegramApi;
28
+ constructor(opts) {
29
+ this.signRequestBuilder = opts.signRequestBuilder;
30
+ this.signResponseHandler = opts.signResponseHandler;
31
+ this.settings = opts.settingsService;
32
+ this.telegramApi = opts.telegramApi;
33
+ }
34
+ // -------------------------------------------------------------------------
35
+ // sendRequest -- send Telegram message with universal link inline button
36
+ // -------------------------------------------------------------------------
37
+ /**
38
+ * Send a SignRequest via Telegram message with an inline "Open in Wallet" button.
39
+ *
40
+ * @param params - Transaction metadata + walletId
41
+ * @returns requestId, requestTopic (empty for Telegram), responseTopic (empty)
42
+ * @throws Error if telegram chat_id is not configured
43
+ */
44
+ async sendRequest(params) {
45
+ // 1. Build SignRequest via SignRequestBuilder
46
+ const { request, universalLinkUrl, requestTopic } = this.signRequestBuilder.buildRequest(params);
47
+ // 2. Register request with SignResponseHandler for later matching
48
+ this.signResponseHandler.registerRequest(request);
49
+ // 3. Get admin chat_id from settings
50
+ const chatIdStr = this.settings.get('notifications.telegram_chat_id');
51
+ if (!chatIdStr) {
52
+ throw new Error('Telegram chat_id is not configured in notifications.telegram_chat_id');
53
+ }
54
+ const chatId = parseInt(chatIdStr, 10);
55
+ if (isNaN(chatId)) {
56
+ throw new Error('Invalid telegram_chat_id: must be a numeric value');
57
+ }
58
+ // 4. Format display message with MarkdownV2 escaping
59
+ const header = '*WAIaaS Sign Request*';
60
+ const body = escapeMarkdownV2(request.displayMessage);
61
+ const txInfo = `TX: \`${escapeMarkdownV2(request.metadata.txId.slice(0, 8))}\\.\\.\\.\``;
62
+ const chain = `Chain: ${escapeMarkdownV2(request.chain)}/${escapeMarkdownV2(request.network)}`;
63
+ const text = `${header}\n\n${body}\n${txInfo}\n${chain}`;
64
+ // 5. Send Telegram message with inline keyboard (universal link button)
65
+ await this.telegramApi.sendMessage(chatId, text, {
66
+ inline_keyboard: [
67
+ [{ text: 'Open in Wallet', url: universalLinkUrl }],
68
+ ],
69
+ });
70
+ // 6. Return result (no ntfy topics for Telegram channel)
71
+ return {
72
+ requestId: request.requestId,
73
+ requestTopic,
74
+ responseTopic: '',
75
+ };
76
+ }
77
+ // -------------------------------------------------------------------------
78
+ // shutdown -- no-op (no active subscriptions)
79
+ // -------------------------------------------------------------------------
80
+ /**
81
+ * Shutdown the channel. No-op for Telegram (no SSE subscriptions to clean up).
82
+ */
83
+ shutdown() {
84
+ // No active subscriptions to clean up
85
+ }
86
+ }
87
+ //# sourceMappingURL=telegram-signing-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-signing-channel.js","sourceRoot":"","sources":["../../../../src/services/signing-sdk/channels/telegram-signing-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0DAA0D,CAAC;AAuB5F,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,MAAM,OAAO,sBAAsB;IAChB,kBAAkB,CAAqB;IACvC,mBAAmB,CAAsB;IACzC,QAAQ,CAAkB;IAC1B,WAAW,CAAc;IAE1C,YAAY,IAAgC;QAC1C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAClD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACtC,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,4EAA4E;IAE5E;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,MAAyB;QACzC,8CAA8C;QAC9C,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAC/C,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE/C,kEAAkE;QAClE,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAElD,qCAAqC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QACtE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QAED,qDAAqD;QACrD,MAAM,MAAM,GAAG,uBAAuB,CAAC;QACvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,SAAS,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACzF,MAAM,KAAK,GAAG,UAAU,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,GAAG,GAAG,MAAM,OAAO,IAAI,KAAK,MAAM,KAAK,KAAK,EAAE,CAAC;QAEzD,wEAAwE;QACxE,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE;YAC/C,eAAe,EAAE;gBACf,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;aACpD;SACF,CAAC,CAAC;QAEH,yDAAyD;QACzD,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,YAAY;YACZ,aAAa,EAAE,EAAE;SAClB,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,8CAA8C;IAC9C,4EAA4E;IAE5E;;OAEG;IACH,QAAQ;QACN,sCAAsC;IACxC,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * signing-sdk module -- unified exports for the daemon signing SDK.
3
+ *
4
+ * Provides:
5
+ * - SignRequestBuilder: builds SignRequest from PENDING_APPROVAL transactions
6
+ * - SignResponseHandler: processes wallet app SignResponse (approve/reject)
7
+ * - WalletLinkRegistry: manages registered wallet configurations
8
+ * - NtfySigningChannel: ntfy-based publish/subscribe signing channel
9
+ * - TelegramSigningChannel: Telegram-based one-way push signing channel
10
+ * - ApprovalChannelRouter: routes to correct channel based on wallet's owner_approval_method
11
+ * - ISigningChannel: channel interface for future channel implementations
12
+ *
13
+ * @see internal/design/73-signing-protocol-v1.md
14
+ * @see internal/design/74-wallet-sdk-daemon-components.md
15
+ */
16
+ export { SignRequestBuilder } from './sign-request-builder.js';
17
+ export type { BuildRequestParams, BuildRequestResult } from './sign-request-builder.js';
18
+ export { SignResponseHandler } from './sign-response-handler.js';
19
+ export type { SignResponseHandlerDeps, HandleResult } from './sign-response-handler.js';
20
+ export { WalletLinkRegistry } from './wallet-link-registry.js';
21
+ export { NtfySigningChannel } from './channels/index.js';
22
+ export type { NtfySigningChannelOpts, SendRequestParams, SendRequestResult } from './channels/index.js';
23
+ export { TelegramSigningChannel } from './channels/index.js';
24
+ export type { TelegramSigningChannelOpts } from './channels/index.js';
25
+ export { ApprovalChannelRouter } from './approval-channel-router.js';
26
+ export type { ApprovalChannelRouterDeps, RouteResult } from './approval-channel-router.js';
27
+ import type { SendRequestParams as _SendRequestParams } from './channels/index.js';
28
+ export interface ISigningChannel {
29
+ sendRequest(params: _SendRequestParams): Promise<{
30
+ requestId: string;
31
+ }>;
32
+ shutdown(): void;
33
+ }
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/signing-sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExG,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,YAAY,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAGtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,YAAY,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAM3F,OAAO,KAAK,EAAE,iBAAiB,IAAI,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,QAAQ,IAAI,IAAI,CAAC;CAClB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * signing-sdk module -- unified exports for the daemon signing SDK.
3
+ *
4
+ * Provides:
5
+ * - SignRequestBuilder: builds SignRequest from PENDING_APPROVAL transactions
6
+ * - SignResponseHandler: processes wallet app SignResponse (approve/reject)
7
+ * - WalletLinkRegistry: manages registered wallet configurations
8
+ * - NtfySigningChannel: ntfy-based publish/subscribe signing channel
9
+ * - TelegramSigningChannel: Telegram-based one-way push signing channel
10
+ * - ApprovalChannelRouter: routes to correct channel based on wallet's owner_approval_method
11
+ * - ISigningChannel: channel interface for future channel implementations
12
+ *
13
+ * @see internal/design/73-signing-protocol-v1.md
14
+ * @see internal/design/74-wallet-sdk-daemon-components.md
15
+ */
16
+ // Core services
17
+ export { SignRequestBuilder } from './sign-request-builder.js';
18
+ export { SignResponseHandler } from './sign-response-handler.js';
19
+ export { WalletLinkRegistry } from './wallet-link-registry.js';
20
+ // Channels
21
+ export { NtfySigningChannel } from './channels/index.js';
22
+ export { TelegramSigningChannel } from './channels/index.js';
23
+ // Routing
24
+ export { ApprovalChannelRouter } from './approval-channel-router.js';
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/signing-sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,gBAAgB;AAChB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,WAAW;AACX,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,UAAU;AACV,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * SignRequestBuilder -- builds SignRequest objects for PENDING_APPROVAL transactions.
3
+ *
4
+ * Transforms transaction metadata into a SignRequest with a signing message
5
+ * (doc 73 Section 5 template), response channel config, and a universal link URL
6
+ * for the target wallet app.
7
+ *
8
+ * Intentionally does NOT go through ApprovalWorkflow -- SignRequestBuilder is
9
+ * invoked *after* the pipeline has already set the transaction to PENDING_APPROVAL
10
+ * state. It produces the data needed to notify the owner via ntfy/Telegram channels.
11
+ *
12
+ * @see internal/design/73-signing-protocol-v1.md (Section 3, 5)
13
+ * @see internal/design/74-wallet-sdk-daemon-components.md
14
+ */
15
+ import { type SignRequest } from '@waiaas/core';
16
+ import type { SettingsService } from '../../infrastructure/settings/settings-service.js';
17
+ import type { WalletLinkRegistry } from './wallet-link-registry.js';
18
+ export interface BuildRequestParams {
19
+ txId: string;
20
+ chain: 'solana' | 'evm';
21
+ network: string;
22
+ type: string;
23
+ from: string;
24
+ to: string;
25
+ amount?: string;
26
+ symbol?: string;
27
+ policyTier: 'APPROVAL' | 'DELAY';
28
+ walletName?: string;
29
+ }
30
+ export interface BuildRequestResult {
31
+ request: SignRequest;
32
+ universalLinkUrl: string;
33
+ requestTopic: string;
34
+ }
35
+ export declare class SignRequestBuilder {
36
+ private readonly settings;
37
+ private readonly walletLinkRegistry;
38
+ constructor(opts: {
39
+ settingsService: SettingsService;
40
+ walletLinkRegistry: WalletLinkRegistry;
41
+ });
42
+ /**
43
+ * Build a SignRequest from a PENDING_APPROVAL transaction.
44
+ *
45
+ * @param params - Transaction metadata
46
+ * @returns The SignRequest, universal link URL, and ntfy request topic
47
+ * @throws WAIaaSError('SIGNING_SDK_DISABLED') if signing SDK is disabled
48
+ * @throws WAIaaSError('WALLET_NOT_REGISTERED') if no wallet is configured
49
+ */
50
+ buildRequest(params: BuildRequestParams): BuildRequestResult;
51
+ /**
52
+ * Build signing message text per doc 73 Section 5 template.
53
+ * Amount/symbol line is omitted when both are absent.
54
+ */
55
+ private buildSigningMessage;
56
+ /**
57
+ * Build a concise display message for wallet app UI.
58
+ */
59
+ private buildDisplayMessage;
60
+ }
61
+ //# sourceMappingURL=sign-request-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-request-builder.d.ts","sourceRoot":"","sources":["../../../src/services/signing-sdk/sign-request-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAOpE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,GAAG,KAAK,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,WAAW,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;gBAE5C,IAAI,EAAE;QAChB,eAAe,EAAE,eAAe,CAAC;QACjC,kBAAkB,EAAE,kBAAkB,CAAC;KACxC;IASD;;;;;;;OAOG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB;IAmG5D;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuC3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAM5B"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * SignRequestBuilder -- builds SignRequest objects for PENDING_APPROVAL transactions.
3
+ *
4
+ * Transforms transaction metadata into a SignRequest with a signing message
5
+ * (doc 73 Section 5 template), response channel config, and a universal link URL
6
+ * for the target wallet app.
7
+ *
8
+ * Intentionally does NOT go through ApprovalWorkflow -- SignRequestBuilder is
9
+ * invoked *after* the pipeline has already set the transaction to PENDING_APPROVAL
10
+ * state. It produces the data needed to notify the owner via ntfy/Telegram channels.
11
+ *
12
+ * @see internal/design/73-signing-protocol-v1.md (Section 3, 5)
13
+ * @see internal/design/74-wallet-sdk-daemon-components.md
14
+ */
15
+ import { SignRequestSchema, WAIaaSError, } from '@waiaas/core';
16
+ import { generateId } from '../../infrastructure/database/id.js';
17
+ // ---------------------------------------------------------------------------
18
+ // SignRequestBuilder
19
+ // ---------------------------------------------------------------------------
20
+ export class SignRequestBuilder {
21
+ settings;
22
+ walletLinkRegistry;
23
+ constructor(opts) {
24
+ this.settings = opts.settingsService;
25
+ this.walletLinkRegistry = opts.walletLinkRegistry;
26
+ }
27
+ // -------------------------------------------------------------------------
28
+ // buildRequest
29
+ // -------------------------------------------------------------------------
30
+ /**
31
+ * Build a SignRequest from a PENDING_APPROVAL transaction.
32
+ *
33
+ * @param params - Transaction metadata
34
+ * @returns The SignRequest, universal link URL, and ntfy request topic
35
+ * @throws WAIaaSError('SIGNING_SDK_DISABLED') if signing SDK is disabled
36
+ * @throws WAIaaSError('WALLET_NOT_REGISTERED') if no wallet is configured
37
+ */
38
+ buildRequest(params) {
39
+ // 1. Check signing SDK enabled
40
+ const enabled = this.settings.get('signing_sdk.enabled');
41
+ if (enabled !== 'true') {
42
+ throw new WAIaaSError('SIGNING_SDK_DISABLED');
43
+ }
44
+ // 2. Determine wallet name
45
+ const walletName = params.walletName ||
46
+ this.settings.get('signing_sdk.preferred_wallet') ||
47
+ undefined;
48
+ if (!walletName) {
49
+ throw new WAIaaSError('WALLET_NOT_REGISTERED', {
50
+ message: 'No wallet name specified and no preferred_wallet configured',
51
+ });
52
+ }
53
+ // 3. Verify wallet exists (throws WALLET_NOT_REGISTERED if not found)
54
+ const walletConfig = this.walletLinkRegistry.getWallet(walletName);
55
+ // 4. Generate requestId (UUID v7)
56
+ const requestId = generateId();
57
+ // 5. Build signing message (doc 73 Section 5 template)
58
+ const now = new Date();
59
+ const message = this.buildSigningMessage(params, params.network, requestId, now);
60
+ // 6. Build display message (concise human-readable version)
61
+ const displayMessage = this.buildDisplayMessage(params);
62
+ // 7. Calculate expiresAt from settings
63
+ const expiryMinStr = this.settings.get('signing_sdk.request_expiry_min');
64
+ const expiryMin = parseInt(expiryMinStr, 10) || 30;
65
+ const expiresAt = new Date(now.getTime() + expiryMin * 60 * 1000);
66
+ // 8. Determine response channel
67
+ const preferredChannel = this.settings.get('signing_sdk.preferred_channel');
68
+ const responseTopicPrefix = this.settings.get('signing_sdk.ntfy_response_topic_prefix');
69
+ let responseChannel;
70
+ if (preferredChannel === 'telegram') {
71
+ // Telegram channel -- bot username from telegram settings
72
+ const botToken = this.settings.get('telegram.bot_token');
73
+ responseChannel = {
74
+ type: 'telegram',
75
+ botUsername: botToken ? 'waiaas_bot' : 'waiaas_bot',
76
+ };
77
+ }
78
+ else {
79
+ // Default: ntfy channel
80
+ const ntfyServer = this.settings.get('notifications.ntfy_server');
81
+ responseChannel = {
82
+ type: 'ntfy',
83
+ responseTopic: `${responseTopicPrefix}-${requestId}`,
84
+ ...(ntfyServer !== 'https://ntfy.sh' ? { serverUrl: ntfyServer } : {}),
85
+ };
86
+ }
87
+ // 9. Assemble SignRequest + validate with Zod
88
+ const request = SignRequestSchema.parse({
89
+ version: '1',
90
+ requestId,
91
+ chain: params.chain,
92
+ network: params.network,
93
+ message,
94
+ displayMessage,
95
+ metadata: {
96
+ txId: params.txId,
97
+ type: params.type,
98
+ from: params.from,
99
+ to: params.to,
100
+ ...(params.amount !== undefined ? { amount: params.amount } : {}),
101
+ ...(params.symbol !== undefined ? { symbol: params.symbol } : {}),
102
+ policyTier: params.policyTier,
103
+ },
104
+ responseChannel,
105
+ expiresAt: expiresAt.toISOString(),
106
+ });
107
+ // 10. Build universal link URL
108
+ const universalLinkUrl = this.walletLinkRegistry.buildSignUrl(walletName, request);
109
+ // 11. Build request topic for ntfy publish
110
+ const requestTopicPrefix = this.settings.get('signing_sdk.ntfy_request_topic_prefix');
111
+ const ntfyTopic = walletConfig.ntfy?.requestTopic ?? `${requestTopicPrefix}-${walletName}`;
112
+ return {
113
+ request,
114
+ universalLinkUrl,
115
+ requestTopic: ntfyTopic,
116
+ };
117
+ }
118
+ // -------------------------------------------------------------------------
119
+ // Private: buildSigningMessage (doc 73 Section 5 template)
120
+ // -------------------------------------------------------------------------
121
+ /**
122
+ * Build signing message text per doc 73 Section 5 template.
123
+ * Amount/symbol line is omitted when both are absent.
124
+ */
125
+ buildSigningMessage(params, network, requestId, now) {
126
+ const lines = [
127
+ 'WAIaaS Transaction Approval',
128
+ '',
129
+ `Transaction: ${params.txId}`,
130
+ `Type: ${params.type}`,
131
+ `From: ${params.from}`,
132
+ `To: ${params.to}`,
133
+ ];
134
+ // Amount line: only include if amount is present
135
+ if (params.amount !== undefined) {
136
+ const amountLine = params.symbol
137
+ ? `Amount: ${params.amount} ${params.symbol}`
138
+ : `Amount: ${params.amount}`;
139
+ lines.push(amountLine);
140
+ }
141
+ lines.push(`Network: ${network}`, `Policy Tier: ${params.policyTier}`, '', 'Approve this transaction by signing this message.', `Timestamp: ${now.toISOString()}`, `Nonce: ${requestId}`);
142
+ return lines.join('\n');
143
+ }
144
+ // -------------------------------------------------------------------------
145
+ // Private: buildDisplayMessage (human-readable summary)
146
+ // -------------------------------------------------------------------------
147
+ /**
148
+ * Build a concise display message for wallet app UI.
149
+ */
150
+ buildDisplayMessage(params) {
151
+ const amountPart = params.amount
152
+ ? ` ${params.amount}${params.symbol ? ' ' + params.symbol : ''}`
153
+ : '';
154
+ return `${params.type}${amountPart} from ${params.from.slice(0, 8)}... to ${params.to.slice(0, 8)}...`;
155
+ }
156
+ }
157
+ //# sourceMappingURL=sign-request-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-request-builder.js","sourceRoot":"","sources":["../../../src/services/signing-sdk/sign-request-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
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 type { Database as SQLiteDatabase } from 'better-sqlite3';
23
+ import { type SignRequest, type SignResponse } from '@waiaas/core';
24
+ export interface SignResponseHandlerDeps {
25
+ /** Raw better-sqlite3 database handle for direct SQL (same pattern as Telegram bot) */
26
+ sqlite: SQLiteDatabase;
27
+ }
28
+ export interface HandleResult {
29
+ action: 'approved' | 'rejected';
30
+ txId: string;
31
+ }
32
+ /**
33
+ * Verifies an EVM EIP-191 personal_sign signature.
34
+ * Default implementation uses viem's verifyMessage.
35
+ */
36
+ export type EvmVerifyFn = (params: {
37
+ address: string;
38
+ message: string;
39
+ signature: string;
40
+ }) => Promise<boolean>;
41
+ /**
42
+ * Verifies a Solana Ed25519 signature.
43
+ * Default implementation uses @solana/kit's verifySignature.
44
+ */
45
+ export type SolanaVerifyFn = (params: {
46
+ publicKeyAddress: string;
47
+ message: string;
48
+ signature: string;
49
+ }) => Promise<boolean>;
50
+ export declare class SignResponseHandler {
51
+ private readonly sqlite;
52
+ /**
53
+ * In-memory store: requestId -> { request, createdAt }.
54
+ * Lost on daemon restart (acceptable -- 1-shot requests with expiry).
55
+ */
56
+ private readonly pendingRequests;
57
+ /**
58
+ * Set of already-processed requestIds (for duplicate detection).
59
+ * Also lost on daemon restart.
60
+ */
61
+ private readonly processedRequests;
62
+ /** Expiration timers by requestId */
63
+ private readonly expirationTimers;
64
+ /** Injectable verification functions (for testing) */
65
+ private readonly evmVerify;
66
+ private readonly solanaVerify;
67
+ constructor(deps: SignResponseHandlerDeps, opts?: {
68
+ evmVerify?: EvmVerifyFn;
69
+ solanaVerify?: SolanaVerifyFn;
70
+ });
71
+ /**
72
+ * Register a SignRequest for later response matching.
73
+ * Sets an expiration timer to auto-remove the request after expiresAt.
74
+ */
75
+ registerRequest(request: SignRequest): void;
76
+ /**
77
+ * Process a SignResponse: validate, match, verify signature, update DB.
78
+ *
79
+ * @param signResponse - The response from the wallet app
80
+ * @returns { action: 'approved' | 'rejected', txId }
81
+ * @throws WAIaaSError with appropriate error code on validation failure
82
+ */
83
+ handle(signResponse: SignResponse): Promise<HandleResult>;
84
+ private handleApprove;
85
+ private handleReject;
86
+ private clearTimer;
87
+ /**
88
+ * Clear all pending timers. Call during daemon shutdown.
89
+ */
90
+ destroy(): void;
91
+ }
92
+ //# sourceMappingURL=sign-response-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-response-handler.d.ts","sourceRoot":"","sources":["../../../src/services/signing-sdk/sign-response-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EAGlB,MAAM,cAAc,CAAC;AAMtB,MAAM,WAAW,uBAAuB;IACtC,uFAAuF;IACvF,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAUD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AA4CvB,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG5B;IAEJ;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAEvD,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoD;IAErF,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;gBAG5C,IAAI,EAAE,uBAAuB,EAC7B,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,WAAW,CAAC;QACxB,YAAY,CAAC,EAAE,cAAc,CAAC;KAC/B;IAWH;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IA0B3C;;;;;;OAMG;IACG,MAAM,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;YAuEjD,aAAa;YAoEb,YAAY;IAiE1B,OAAO,CAAC,UAAU;IAYlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAQhB"}