@waiaas/daemon 2.9.0 → 2.10.0-rc

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 (172) hide show
  1. package/dist/api/middleware/master-auth.d.ts +3 -0
  2. package/dist/api/middleware/master-auth.d.ts.map +1 -1
  3. package/dist/api/middleware/master-auth.js +14 -0
  4. package/dist/api/middleware/master-auth.js.map +1 -1
  5. package/dist/api/routes/admin.d.ts +4 -0
  6. package/dist/api/routes/admin.d.ts.map +1 -1
  7. package/dist/api/routes/admin.js +186 -1
  8. package/dist/api/routes/admin.js.map +1 -1
  9. package/dist/api/routes/audit-logs.d.ts +15 -0
  10. package/dist/api/routes/audit-logs.d.ts.map +1 -0
  11. package/dist/api/routes/audit-logs.js +119 -0
  12. package/dist/api/routes/audit-logs.js.map +1 -0
  13. package/dist/api/routes/index.d.ts +2 -1
  14. package/dist/api/routes/index.d.ts.map +1 -1
  15. package/dist/api/routes/index.js +2 -1
  16. package/dist/api/routes/index.js.map +1 -1
  17. package/dist/api/routes/openapi-schemas.d.ts +324 -6
  18. package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
  19. package/dist/api/routes/openapi-schemas.js +76 -0
  20. package/dist/api/routes/openapi-schemas.js.map +1 -1
  21. package/dist/api/routes/sessions.d.ts +2 -0
  22. package/dist/api/routes/sessions.d.ts.map +1 -1
  23. package/dist/api/routes/sessions.js +21 -0
  24. package/dist/api/routes/sessions.js.map +1 -1
  25. package/dist/api/routes/transactions.d.ts +2 -1
  26. package/dist/api/routes/transactions.d.ts.map +1 -1
  27. package/dist/api/routes/transactions.js +72 -1
  28. package/dist/api/routes/transactions.js.map +1 -1
  29. package/dist/api/routes/wallets.d.ts.map +1 -1
  30. package/dist/api/routes/wallets.js +25 -0
  31. package/dist/api/routes/wallets.js.map +1 -1
  32. package/dist/api/routes/webhooks.d.ts +17 -0
  33. package/dist/api/routes/webhooks.d.ts.map +1 -0
  34. package/dist/api/routes/webhooks.js +218 -0
  35. package/dist/api/routes/webhooks.js.map +1 -0
  36. package/dist/api/server.d.ts +27 -0
  37. package/dist/api/server.d.ts.map +1 -1
  38. package/dist/api/server.js +31 -5
  39. package/dist/api/server.js.map +1 -1
  40. package/dist/index.d.ts +3 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +2 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/infrastructure/backup/backup-format.d.ts +107 -0
  45. package/dist/infrastructure/backup/backup-format.d.ts.map +1 -0
  46. package/dist/infrastructure/backup/backup-format.js +134 -0
  47. package/dist/infrastructure/backup/backup-format.js.map +1 -0
  48. package/dist/infrastructure/backup/encrypted-backup-service.d.ts +56 -0
  49. package/dist/infrastructure/backup/encrypted-backup-service.d.ts.map +1 -0
  50. package/dist/infrastructure/backup/encrypted-backup-service.js +269 -0
  51. package/dist/infrastructure/backup/encrypted-backup-service.js.map +1 -0
  52. package/dist/infrastructure/backup/index.d.ts +3 -0
  53. package/dist/infrastructure/backup/index.d.ts.map +1 -1
  54. package/dist/infrastructure/backup/index.js +2 -0
  55. package/dist/infrastructure/backup/index.js.map +1 -1
  56. package/dist/infrastructure/config/loader.d.ts +23 -0
  57. package/dist/infrastructure/config/loader.d.ts.map +1 -1
  58. package/dist/infrastructure/config/loader.js +8 -0
  59. package/dist/infrastructure/config/loader.js.map +1 -1
  60. package/dist/infrastructure/database/audit-helper.d.ts +29 -0
  61. package/dist/infrastructure/database/audit-helper.d.ts.map +1 -0
  62. package/dist/infrastructure/database/audit-helper.js +30 -0
  63. package/dist/infrastructure/database/audit-helper.js.map +1 -0
  64. package/dist/infrastructure/database/index.d.ts +2 -0
  65. package/dist/infrastructure/database/index.d.ts.map +1 -1
  66. package/dist/infrastructure/database/index.js +1 -0
  67. package/dist/infrastructure/database/index.js.map +1 -1
  68. package/dist/infrastructure/database/migrate.d.ts +1 -1
  69. package/dist/infrastructure/database/migrate.d.ts.map +1 -1
  70. package/dist/infrastructure/database/migrate.js +83 -2
  71. package/dist/infrastructure/database/migrate.js.map +1 -1
  72. package/dist/infrastructure/database/schema.d.ts +343 -1
  73. package/dist/infrastructure/database/schema.d.ts.map +1 -1
  74. package/dist/infrastructure/database/schema.js +41 -1
  75. package/dist/infrastructure/database/schema.js.map +1 -1
  76. package/dist/infrastructure/metrics/in-memory-counter.d.ts +34 -0
  77. package/dist/infrastructure/metrics/in-memory-counter.d.ts.map +1 -0
  78. package/dist/infrastructure/metrics/in-memory-counter.js +88 -0
  79. package/dist/infrastructure/metrics/in-memory-counter.js.map +1 -0
  80. package/dist/infrastructure/settings/hot-reload.d.ts +1 -0
  81. package/dist/infrastructure/settings/hot-reload.d.ts.map +1 -1
  82. package/dist/infrastructure/settings/hot-reload.js +23 -2
  83. package/dist/infrastructure/settings/hot-reload.js.map +1 -1
  84. package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
  85. package/dist/infrastructure/settings/setting-keys.js +4 -0
  86. package/dist/infrastructure/settings/setting-keys.js.map +1 -1
  87. package/dist/infrastructure/telegram/telegram-bot-service.d.ts +2 -0
  88. package/dist/infrastructure/telegram/telegram-bot-service.d.ts.map +1 -1
  89. package/dist/infrastructure/telegram/telegram-bot-service.js +36 -19
  90. package/dist/infrastructure/telegram/telegram-bot-service.js.map +1 -1
  91. package/dist/lifecycle/daemon.d.ts +21 -1
  92. package/dist/lifecycle/daemon.d.ts.map +1 -1
  93. package/dist/lifecycle/daemon.js +131 -2
  94. package/dist/lifecycle/daemon.js.map +1 -1
  95. package/dist/pipeline/dry-run.d.ts +68 -0
  96. package/dist/pipeline/dry-run.d.ts.map +1 -0
  97. package/dist/pipeline/dry-run.js +426 -0
  98. package/dist/pipeline/dry-run.js.map +1 -0
  99. package/dist/pipeline/index.d.ts +1 -0
  100. package/dist/pipeline/index.d.ts.map +1 -1
  101. package/dist/pipeline/index.js +2 -0
  102. package/dist/pipeline/index.js.map +1 -1
  103. package/dist/pipeline/pipeline.d.ts +18 -1
  104. package/dist/pipeline/pipeline.d.ts.map +1 -1
  105. package/dist/pipeline/pipeline.js +38 -0
  106. package/dist/pipeline/pipeline.js.map +1 -1
  107. package/dist/pipeline/stages.d.ts +31 -1
  108. package/dist/pipeline/stages.d.ts.map +1 -1
  109. package/dist/pipeline/stages.js +120 -22
  110. package/dist/pipeline/stages.js.map +1 -1
  111. package/dist/services/admin-stats-service.d.ts +48 -0
  112. package/dist/services/admin-stats-service.d.ts.map +1 -0
  113. package/dist/services/admin-stats-service.js +182 -0
  114. package/dist/services/admin-stats-service.js.map +1 -0
  115. package/dist/services/autostop/autostop-service.d.ts +83 -0
  116. package/dist/services/autostop/autostop-service.d.ts.map +1 -0
  117. package/dist/services/autostop/autostop-service.js +252 -0
  118. package/dist/services/autostop/autostop-service.js.map +1 -0
  119. package/dist/services/autostop/index.d.ts +15 -0
  120. package/dist/services/autostop/index.d.ts.map +1 -0
  121. package/dist/services/autostop/index.js +11 -0
  122. package/dist/services/autostop/index.js.map +1 -0
  123. package/dist/services/autostop/rule-registry.d.ts +42 -0
  124. package/dist/services/autostop/rule-registry.d.ts.map +1 -0
  125. package/dist/services/autostop/rule-registry.js +54 -0
  126. package/dist/services/autostop/rule-registry.js.map +1 -0
  127. package/dist/services/autostop/rules/consecutive-failures.rule.d.ts +38 -0
  128. package/dist/services/autostop/rules/consecutive-failures.rule.d.ts.map +1 -0
  129. package/dist/services/autostop/rules/consecutive-failures.rule.js +75 -0
  130. package/dist/services/autostop/rules/consecutive-failures.rule.js.map +1 -0
  131. package/dist/services/autostop/rules/idle-timeout.rule.d.ts +43 -0
  132. package/dist/services/autostop/rules/idle-timeout.rule.d.ts.map +1 -0
  133. package/dist/services/autostop/rules/idle-timeout.rule.js +128 -0
  134. package/dist/services/autostop/rules/idle-timeout.rule.js.map +1 -0
  135. package/dist/services/autostop/rules/unusual-activity.rule.d.ts +33 -0
  136. package/dist/services/autostop/rules/unusual-activity.rule.d.ts.map +1 -0
  137. package/dist/services/autostop/rules/unusual-activity.rule.js +73 -0
  138. package/dist/services/autostop/rules/unusual-activity.rule.js.map +1 -0
  139. package/dist/services/autostop/types.d.ts +49 -0
  140. package/dist/services/autostop/types.d.ts.map +1 -0
  141. package/dist/services/autostop/types.js +10 -0
  142. package/dist/services/autostop/types.js.map +1 -0
  143. package/dist/services/autostop-rules.d.ts +11 -74
  144. package/dist/services/autostop-rules.d.ts.map +1 -1
  145. package/dist/services/autostop-rules.js +9 -169
  146. package/dist/services/autostop-rules.js.map +1 -1
  147. package/dist/services/autostop-service.d.ts +6 -77
  148. package/dist/services/autostop-service.d.ts.map +1 -1
  149. package/dist/services/autostop-service.js +5 -212
  150. package/dist/services/autostop-service.js.map +1 -1
  151. package/dist/services/kill-switch-service.d.ts.map +1 -1
  152. package/dist/services/kill-switch-service.js +36 -21
  153. package/dist/services/kill-switch-service.js.map +1 -1
  154. package/dist/services/signing-sdk/sign-response-handler.d.ts +3 -0
  155. package/dist/services/signing-sdk/sign-response-handler.d.ts.map +1 -1
  156. package/dist/services/signing-sdk/sign-response-handler.js +5 -0
  157. package/dist/services/signing-sdk/sign-response-handler.js.map +1 -1
  158. package/dist/services/webhook-delivery-queue.d.ts +53 -0
  159. package/dist/services/webhook-delivery-queue.d.ts.map +1 -0
  160. package/dist/services/webhook-delivery-queue.js +118 -0
  161. package/dist/services/webhook-delivery-queue.js.map +1 -0
  162. package/dist/services/webhook-service.d.ts +46 -0
  163. package/dist/services/webhook-service.d.ts.map +1 -0
  164. package/dist/services/webhook-service.js +160 -0
  165. package/dist/services/webhook-service.js.map +1 -0
  166. package/dist/workflow/approval-workflow.d.ts +2 -0
  167. package/dist/workflow/approval-workflow.d.ts.map +1 -1
  168. package/dist/workflow/approval-workflow.js +6 -1
  169. package/dist/workflow/approval-workflow.js.map +1 -1
  170. package/package.json +5 -5
  171. package/public/admin/assets/{index-CBU6NfOH.js → index-RagPnRU1.js} +2 -2
  172. package/public/admin/index.html +1 -1
@@ -0,0 +1,426 @@
1
+ /**
2
+ * Dry-run simulation pipeline.
3
+ *
4
+ * Executes transaction stages in read-only mode with ZERO side effects:
5
+ * - No DB INSERT/UPDATE
6
+ * - No signing / key decryption
7
+ * - No on-chain submission
8
+ * - No notifications / events / audit logs
9
+ *
10
+ * Returns a DryRunSimulationResult with policy evaluation, fee estimate,
11
+ * balance changes, warnings, and simulation details.
12
+ *
13
+ * @see Phase 304 DESIGN-SPEC.md section 3 (SIM-02)
14
+ * @see Phase 309 Plan 01 Task 2
15
+ */
16
+ import { eq } from 'drizzle-orm';
17
+ import { TransactionRequestSchema, WAIaaSError, } from '@waiaas/core';
18
+ import { wallets } from '../infrastructure/database/schema.js';
19
+ import { buildByType, buildTransactionParam, getRequestAmount } from './stages.js';
20
+ import { resolveEffectiveAmountUsd } from './resolve-effective-amount-usd.js';
21
+ import { downgradeIfNoOwner } from '../workflow/owner-state.js';
22
+ // ---------------------------------------------------------------------------
23
+ // Constants
24
+ // ---------------------------------------------------------------------------
25
+ const NATIVE_DECIMALS = { solana: 9, ethereum: 18 };
26
+ const NATIVE_SYMBOLS = { solana: 'SOL', ethereum: 'ETH' };
27
+ // ---------------------------------------------------------------------------
28
+ // executeDryRun
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Execute a transaction dry-run simulation.
32
+ *
33
+ * Returns DryRunSimulationResult with zero side effects.
34
+ * Policy denials return success=false (not thrown errors).
35
+ * Build/simulation failures produce warnings (not exceptions).
36
+ *
37
+ * @param deps - Dry-run dependencies (no keyStore, no notifications)
38
+ * @param walletId - Wallet ID
39
+ * @param request - Transaction request (5-type discriminatedUnion)
40
+ * @param resolvedNetwork - Pre-resolved network
41
+ * @param walletInfo - Wallet public key, chain, environment
42
+ * @returns DryRunSimulationResult
43
+ * @throws WAIaaSError('ACTION_VALIDATION_FAILED') for invalid request format
44
+ */
45
+ export async function executeDryRun(deps, walletId, request, resolvedNetwork, walletInfo) {
46
+ const collector = {
47
+ validationPassed: false,
48
+ policyEvaluation: null,
49
+ downgraded: false,
50
+ unsignedTx: null,
51
+ simulationResult: null,
52
+ currentBalances: [],
53
+ warnings: [],
54
+ startTime: Date.now(),
55
+ amountUsd: null,
56
+ feeUsd: null,
57
+ };
58
+ const chain = walletInfo.chain;
59
+ const txType = request.type || 'TRANSFER';
60
+ const requestAmount = BigInt(getRequestAmount(request) || '0');
61
+ // -----------------------------------------------------------------------
62
+ // Stage 1': Validate only (no DB INSERT)
63
+ // -----------------------------------------------------------------------
64
+ const parseResult = TransactionRequestSchema.safeParse(request);
65
+ if (!parseResult.success) {
66
+ throw new WAIaaSError('ACTION_VALIDATION_FAILED', {
67
+ message: `Request validation failed: ${parseResult.error.message}`,
68
+ });
69
+ }
70
+ collector.validationPassed = true;
71
+ // -----------------------------------------------------------------------
72
+ // Stage 3': Policy evaluate only (no reserve, no DB update)
73
+ // -----------------------------------------------------------------------
74
+ const txParam = buildTransactionParam(request, txType, chain);
75
+ txParam.network = resolvedNetwork;
76
+ // Resolve USD amount from price oracle (read-only)
77
+ let priceResult;
78
+ if (deps.priceOracle) {
79
+ try {
80
+ priceResult = await resolveEffectiveAmountUsd(request, txType, chain, deps.priceOracle, resolvedNetwork);
81
+ if (priceResult.type === 'success') {
82
+ collector.amountUsd = priceResult.usdAmount;
83
+ }
84
+ else {
85
+ collector.warnings.push({
86
+ code: 'ORACLE_PRICE_UNAVAILABLE',
87
+ message: priceResult.type === 'notListed'
88
+ ? `Price unavailable for token ${priceResult.tokenAddress}`
89
+ : 'Price oracle unavailable',
90
+ severity: 'warning',
91
+ });
92
+ }
93
+ }
94
+ catch {
95
+ collector.warnings.push({
96
+ code: 'ORACLE_PRICE_UNAVAILABLE',
97
+ message: 'Price oracle unavailable',
98
+ severity: 'warning',
99
+ });
100
+ }
101
+ }
102
+ // Evaluate policy (read-only -- evaluate(), NOT evaluateAndReserve())
103
+ const evaluation = await deps.policyEngine.evaluate(walletId, { ...txParam, network: resolvedNetwork });
104
+ collector.policyEvaluation = evaluation;
105
+ // Check for owner downgrade (APPROVAL -> DELAY when no owner)
106
+ if (evaluation.tier === 'APPROVAL') {
107
+ const walletRow = deps.db
108
+ .select({ ownerAddress: wallets.ownerAddress, ownerVerified: wallets.ownerVerified })
109
+ .from(wallets)
110
+ .where(eq(wallets.id, walletId))
111
+ .get();
112
+ const downgradeResult = downgradeIfNoOwner({
113
+ ownerAddress: walletRow?.ownerAddress ?? null,
114
+ ownerVerified: !!walletRow?.ownerVerified,
115
+ }, evaluation.tier);
116
+ if (downgradeResult.downgraded) {
117
+ collector.downgraded = true;
118
+ evaluation.tier = downgradeResult.tier;
119
+ collector.warnings.push({
120
+ code: 'DOWNGRADED_NO_OWNER',
121
+ message: 'APPROVAL tier downgraded to DELAY because no owner is registered',
122
+ severity: 'info',
123
+ });
124
+ }
125
+ }
126
+ // Add tier-specific warnings
127
+ if (evaluation.tier === 'APPROVAL') {
128
+ collector.warnings.push({
129
+ code: 'APPROVAL_REQUIRED',
130
+ message: `Owner approval is required${evaluation.approvalReason ? ` (${evaluation.approvalReason})` : ''}`,
131
+ severity: 'warning',
132
+ });
133
+ }
134
+ if (evaluation.tier === 'DELAY') {
135
+ collector.warnings.push({
136
+ code: 'DELAY_REQUIRED',
137
+ message: `Time delay of ${evaluation.delaySeconds ?? 900} seconds will be applied`,
138
+ severity: 'info',
139
+ });
140
+ }
141
+ if (evaluation.cumulativeWarning && evaluation.cumulativeWarning.ratio >= 0.8) {
142
+ collector.warnings.push({
143
+ code: 'CUMULATIVE_LIMIT_WARNING',
144
+ message: `Cumulative ${evaluation.cumulativeWarning.type} spending at ${Math.round(evaluation.cumulativeWarning.ratio * 100)}% of limit`,
145
+ severity: 'warning',
146
+ });
147
+ }
148
+ // Add policy denial reason-based warnings
149
+ if (!evaluation.allowed && evaluation.reason) {
150
+ if (evaluation.reason.includes('not in allowed list') || evaluation.reason.includes('Token transfer not allowed')) {
151
+ collector.warnings.push({
152
+ code: 'TOKEN_NOT_IN_ALLOWED_LIST',
153
+ message: evaluation.reason,
154
+ severity: 'error',
155
+ });
156
+ }
157
+ else if (evaluation.reason.includes('not whitelisted') || evaluation.reason.includes('Contract calls disabled')) {
158
+ collector.warnings.push({
159
+ code: 'CONTRACT_NOT_WHITELISTED',
160
+ message: evaluation.reason,
161
+ severity: 'error',
162
+ });
163
+ }
164
+ else if (evaluation.reason.includes('not in allowed networks')) {
165
+ collector.warnings.push({
166
+ code: 'NETWORK_NOT_ALLOWED',
167
+ message: evaluation.reason,
168
+ severity: 'error',
169
+ });
170
+ }
171
+ }
172
+ // If policy denied, skip build/simulate/balance but still return result
173
+ if (!evaluation.allowed) {
174
+ return buildResult(collector, request, txType, chain, resolvedNetwork);
175
+ }
176
+ // -----------------------------------------------------------------------
177
+ // Balance query
178
+ // -----------------------------------------------------------------------
179
+ const nativeDecimals = NATIVE_DECIMALS[chain] ?? 18;
180
+ const nativeSymbol = NATIVE_SYMBOLS[chain] ?? chain.toUpperCase();
181
+ try {
182
+ const balanceInfo = await deps.adapter.getBalance(walletInfo.publicKey);
183
+ collector.currentBalances.push({
184
+ asset: 'native',
185
+ symbol: balanceInfo.symbol || nativeSymbol,
186
+ decimals: balanceInfo.decimals || nativeDecimals,
187
+ balance: balanceInfo.balance,
188
+ });
189
+ }
190
+ catch {
191
+ collector.currentBalances.push({
192
+ asset: 'native',
193
+ symbol: nativeSymbol,
194
+ decimals: nativeDecimals,
195
+ balance: 0n,
196
+ });
197
+ }
198
+ // For TOKEN_TRANSFER, fetch token balance via getAssets
199
+ if (txType === 'TOKEN_TRANSFER') {
200
+ const tokenReq = request;
201
+ try {
202
+ const assets = await deps.adapter.getAssets(walletInfo.publicKey);
203
+ const tokenAsset = assets.find((a) => a.mint.toLowerCase() === tokenReq.token.address.toLowerCase());
204
+ if (tokenAsset) {
205
+ collector.currentBalances.push({
206
+ asset: tokenReq.token.address,
207
+ symbol: tokenAsset.symbol || tokenReq.token.symbol,
208
+ decimals: tokenAsset.decimals ?? tokenReq.token.decimals,
209
+ balance: tokenAsset.balance ?? 0n,
210
+ });
211
+ }
212
+ else {
213
+ collector.currentBalances.push({
214
+ asset: tokenReq.token.address,
215
+ symbol: tokenReq.token.symbol,
216
+ decimals: tokenReq.token.decimals,
217
+ balance: 0n,
218
+ });
219
+ }
220
+ }
221
+ catch {
222
+ collector.currentBalances.push({
223
+ asset: tokenReq.token.address,
224
+ symbol: tokenReq.token.symbol,
225
+ decimals: tokenReq.token.decimals,
226
+ balance: 0n,
227
+ });
228
+ }
229
+ }
230
+ // -----------------------------------------------------------------------
231
+ // Stage 5a': Build (no signing)
232
+ // -----------------------------------------------------------------------
233
+ try {
234
+ collector.unsignedTx = await buildByType(deps.adapter, request, walletInfo.publicKey);
235
+ }
236
+ catch (err) {
237
+ const errMsg = err instanceof Error ? err.message : 'Build failed';
238
+ collector.warnings.push({
239
+ code: 'SIMULATION_FAILED',
240
+ message: `Transaction build failed: ${errMsg}`,
241
+ severity: 'warning',
242
+ });
243
+ collector.simulationResult = {
244
+ success: false,
245
+ logs: [],
246
+ error: errMsg,
247
+ };
248
+ return buildResult(collector, request, txType, chain, resolvedNetwork);
249
+ }
250
+ // -----------------------------------------------------------------------
251
+ // Stage 5b': Simulate (no signing, no submission)
252
+ // -----------------------------------------------------------------------
253
+ try {
254
+ collector.simulationResult = await deps.adapter.simulateTransaction(collector.unsignedTx);
255
+ if (!collector.simulationResult.success) {
256
+ collector.warnings.push({
257
+ code: 'SIMULATION_FAILED',
258
+ message: collector.simulationResult.error ?? 'Transaction simulation failed',
259
+ severity: 'warning',
260
+ });
261
+ }
262
+ }
263
+ catch (err) {
264
+ const errMsg = err instanceof Error ? err.message : 'Simulation failed';
265
+ collector.simulationResult = {
266
+ success: false,
267
+ logs: [],
268
+ error: errMsg,
269
+ };
270
+ collector.warnings.push({
271
+ code: 'SIMULATION_FAILED',
272
+ message: `Transaction simulation error: ${errMsg}`,
273
+ severity: 'warning',
274
+ });
275
+ }
276
+ // -----------------------------------------------------------------------
277
+ // Compute fee with gas safety margin and check balances
278
+ // -----------------------------------------------------------------------
279
+ const estimatedFee = collector.unsignedTx.estimatedFee;
280
+ const safetyFee = (estimatedFee * 120n) / 100n;
281
+ // Check balance sufficiency
282
+ const nativeBalance = collector.currentBalances.find((b) => b.asset === 'native');
283
+ if (nativeBalance) {
284
+ if (txType === 'TRANSFER' || txType === 'CONTRACT_CALL') {
285
+ const totalCost = requestAmount + safetyFee;
286
+ if (totalCost > nativeBalance.balance) {
287
+ collector.warnings.push({
288
+ code: 'INSUFFICIENT_BALANCE_WITH_FEE',
289
+ message: `Insufficient balance after fee: need ${totalCost.toString()}, have ${nativeBalance.balance.toString()}`,
290
+ severity: 'error',
291
+ });
292
+ }
293
+ }
294
+ else {
295
+ if (safetyFee > nativeBalance.balance) {
296
+ collector.warnings.push({
297
+ code: 'INSUFFICIENT_BALANCE_WITH_FEE',
298
+ message: `Insufficient native balance for fee: need ${safetyFee.toString()}, have ${nativeBalance.balance.toString()}`,
299
+ severity: 'error',
300
+ });
301
+ }
302
+ }
303
+ }
304
+ // For TOKEN_TRANSFER, check token balance
305
+ if (txType === 'TOKEN_TRANSFER') {
306
+ const tokenReq = request;
307
+ const tokenBalance = collector.currentBalances.find((b) => b.asset.toLowerCase() === tokenReq.token.address.toLowerCase());
308
+ if (tokenBalance && BigInt(tokenReq.amount) > tokenBalance.balance) {
309
+ collector.warnings.push({
310
+ code: 'INSUFFICIENT_BALANCE',
311
+ message: `Insufficient token balance: need ${tokenReq.amount}, have ${tokenBalance.balance.toString()}`,
312
+ severity: 'error',
313
+ });
314
+ }
315
+ }
316
+ // Check high fee ratio
317
+ if (requestAmount > 0n && safetyFee > 0n) {
318
+ const feeRatio = Number(safetyFee) / Number(requestAmount);
319
+ if (feeRatio > 0.1) {
320
+ collector.warnings.push({
321
+ code: 'HIGH_FEE_RATIO',
322
+ message: `Fee is ${Math.round(feeRatio * 100)}% of transaction amount`,
323
+ severity: 'info',
324
+ });
325
+ }
326
+ }
327
+ // Resolve fee USD if oracle available
328
+ if (deps.priceOracle) {
329
+ try {
330
+ const nativePrice = await deps.priceOracle.getNativePrice(chain);
331
+ const feeDecimals = NATIVE_DECIMALS[chain] ?? 18;
332
+ const feeHuman = Number(safetyFee) / Math.pow(10, feeDecimals);
333
+ collector.feeUsd = feeHuman * nativePrice.usdPrice;
334
+ }
335
+ catch {
336
+ // feeUsd stays null
337
+ }
338
+ }
339
+ return buildResult(collector, request, txType, chain, resolvedNetwork);
340
+ }
341
+ // ---------------------------------------------------------------------------
342
+ // Build the final result from collector
343
+ // ---------------------------------------------------------------------------
344
+ function buildResult(collector, request, txType, chain, resolvedNetwork) {
345
+ const evaluation = collector.policyEvaluation;
346
+ const unsignedTx = collector.unsignedTx;
347
+ const nativeDecimals = NATIVE_DECIMALS[chain] ?? 18;
348
+ const nativeSymbol = NATIVE_SYMBOLS[chain] ?? chain.toUpperCase();
349
+ // Determine success: policy allowed
350
+ const success = !!evaluation?.allowed;
351
+ // Build fee estimate
352
+ let fee = null;
353
+ if (unsignedTx) {
354
+ const safetyFee = (unsignedTx.estimatedFee * 120n) / 100n;
355
+ fee = {
356
+ estimatedFee: safetyFee.toString(),
357
+ feeSymbol: nativeSymbol,
358
+ feeDecimals: nativeDecimals,
359
+ feeUsd: collector.feeUsd,
360
+ };
361
+ }
362
+ // Build balance changes from collector
363
+ const requestAmount = BigInt(getRequestAmount(request) || '0');
364
+ const balanceChanges = [];
365
+ for (const bal of collector.currentBalances) {
366
+ let changeAmount;
367
+ if (bal.asset === 'native') {
368
+ const feeAmount = unsignedTx ? (unsignedTx.estimatedFee * 120n) / 100n : 0n;
369
+ if (txType === 'TRANSFER' || txType === 'CONTRACT_CALL') {
370
+ // Native transfer: deduct amount + fee
371
+ changeAmount = -(requestAmount + feeAmount);
372
+ }
373
+ else {
374
+ // Token transfer/Approve/Batch: only deduct fee from native
375
+ changeAmount = -feeAmount;
376
+ }
377
+ }
378
+ else {
379
+ // Token balance: deduct token amount
380
+ changeAmount = -requestAmount;
381
+ }
382
+ const afterBalance = bal.balance + changeAmount;
383
+ balanceChanges.push({
384
+ asset: bal.asset,
385
+ symbol: bal.symbol,
386
+ decimals: bal.decimals,
387
+ currentBalance: bal.balance.toString(),
388
+ changeAmount: changeAmount.toString(),
389
+ afterBalance: afterBalance.toString(),
390
+ });
391
+ }
392
+ // Build simulation detail
393
+ const simulation = {
394
+ success: collector.simulationResult?.success ?? false,
395
+ logs: collector.simulationResult?.logs ?? [],
396
+ unitsConsumed: collector.simulationResult?.unitsConsumed != null
397
+ ? collector.simulationResult.unitsConsumed.toString()
398
+ : null,
399
+ error: collector.simulationResult?.error ?? (evaluation?.allowed === false ? 'Skipped: policy denied' : null),
400
+ };
401
+ // Build meta
402
+ const meta = {
403
+ chain: chain,
404
+ network: resolvedNetwork,
405
+ transactionType: txType,
406
+ durationMs: Date.now() - collector.startTime,
407
+ };
408
+ return {
409
+ success,
410
+ policy: {
411
+ tier: evaluation?.tier ?? 'INSTANT',
412
+ allowed: evaluation?.allowed ?? false,
413
+ reason: evaluation?.reason,
414
+ delaySeconds: evaluation?.delaySeconds,
415
+ approvalReason: evaluation?.approvalReason,
416
+ downgraded: collector.downgraded || undefined,
417
+ cumulativeWarning: evaluation?.cumulativeWarning,
418
+ },
419
+ fee,
420
+ balanceChanges,
421
+ warnings: collector.warnings,
422
+ simulation,
423
+ meta,
424
+ };
425
+ }
426
+ //# sourceMappingURL=dry-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dry-run.js","sourceRoot":"","sources":["../../src/pipeline/dry-run.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,5 @@ export { DefaultPolicyEngine } from './default-policy-engine.js';
6
6
  export { DatabasePolicyEngine } from './database-policy-engine.js';
7
7
  export { stage1Validate, stage2Auth, stage3Policy, stage4Wait, stage5Execute, stage6Confirm, type PipelineContext, } from './stages.js';
8
8
  export { resolveEffectiveAmountUsd, type PriceResult, type PriceResultSuccess, type PriceResultOracleDown, type PriceResultNotListed, } from './resolve-effective-amount-usd.js';
9
+ export { executeDryRun, type DryRunDeps, type DryRunCollector, } from './dry-run.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,aAAa,EACb,KAAK,UAAU,EACf,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC"}
@@ -6,4 +6,6 @@ export { DefaultPolicyEngine } from './default-policy-engine.js';
6
6
  export { DatabasePolicyEngine } from './database-policy-engine.js';
7
7
  export { stage1Validate, stage2Auth, stage3Policy, stage4Wait, stage5Execute, stage6Confirm, } from './stages.js';
8
8
  export { resolveEffectiveAmountUsd, } from './resolve-effective-amount-usd.js';
9
+ // v30.2 dry-run simulation
10
+ export { executeDryRun, } from './dry-run.js';
9
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAqB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,GAEd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,GAK1B,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAqB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,GAEd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,GAK1B,MAAM,mCAAmC,CAAC;AAC3C,2BAA2B;AAC3B,OAAO,EACL,aAAa,GAGd,MAAM,cAAc,CAAC"}
@@ -8,10 +8,11 @@
8
8
  */
9
9
  import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
10
10
  import type { Database as SQLiteDatabase } from 'better-sqlite3';
11
- import type { IChainAdapter, IPolicyEngine, SendTransactionRequest, TransactionRequest } from '@waiaas/core';
11
+ import type { IChainAdapter, IPolicyEngine, SendTransactionRequest, TransactionRequest, DryRunSimulationResult, IPriceOracle, IMetricsCounter } from '@waiaas/core';
12
12
  import type { LocalKeyStore } from '../infrastructure/keystore/keystore.js';
13
13
  import type * as schema from '../infrastructure/database/schema.js';
14
14
  import type { NotificationService } from '../notifications/notification-service.js';
15
+ import type { SettingsService } from '../infrastructure/settings/settings-service.js';
15
16
  export interface PipelineDeps {
16
17
  db: BetterSQLite3Database<typeof schema>;
17
18
  adapter: IChainAdapter;
@@ -20,6 +21,9 @@ export interface PipelineDeps {
20
21
  masterPassword: string;
21
22
  sqlite?: SQLiteDatabase;
22
23
  notificationService?: NotificationService;
24
+ priceOracle?: IPriceOracle;
25
+ settingsService?: SettingsService;
26
+ metricsCounter?: IMetricsCounter;
23
27
  }
24
28
  export declare class TransactionPipeline {
25
29
  private readonly deps;
@@ -32,6 +36,19 @@ export declare class TransactionPipeline {
32
36
  * @returns The transaction ID (UUID v7)
33
37
  */
34
38
  executeSend(walletId: string, request: SendTransactionRequest | TransactionRequest): Promise<string>;
39
+ /**
40
+ * Execute a dry-run simulation of a transaction.
41
+ *
42
+ * Returns DryRunSimulationResult with zero side effects.
43
+ * No DB writes, no signing, no notifications, no events.
44
+ *
45
+ * @param walletId - Wallet initiating the simulation
46
+ * @param request - Transaction request (5-type discriminatedUnion)
47
+ * @returns DryRunSimulationResult
48
+ * @throws WAIaaSError('WALLET_NOT_FOUND') if wallet doesn't exist
49
+ * @throws WAIaaSError('WALLET_TERMINATED') if wallet is terminated
50
+ */
51
+ executeDryRun(walletId: string, request: TransactionRequest): Promise<DryRunSimulationResult>;
35
52
  /**
36
53
  * Get a transaction by ID.
37
54
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAA2C,aAAa,EAAE,aAAa,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGtJ,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAgBpF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC;IACzC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAMD,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAE/C;;;;;;OAMG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0C1G;;;;;;OAMG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkBnB,SAAS;CAGxB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAA2C,aAAa,EAAE,aAAa,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAI7M,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAgBtF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC;IACzC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,cAAc,CAAC,EAAE,eAAe,CAAC;CAClC;AAMD,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAE/C;;;;;;OAMG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0C1G;;;;;;;;;;;OAWG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAsCnG;;;;;;OAMG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkBnB,SAAS;CAGxB"}
@@ -9,6 +9,7 @@
9
9
  import { eq } from 'drizzle-orm';
10
10
  import { WAIaaSError } from '@waiaas/core';
11
11
  import { resolveNetwork } from './network-resolver.js';
12
+ import { executeDryRun as executeDryRunFn } from './dry-run.js';
12
13
  import { wallets, transactions } from '../infrastructure/database/schema.js';
13
14
  import { stage1Validate, stage2Auth, stage3Policy, stage3_5GasCondition, stage4Wait, stage5Execute, stage6Confirm, } from './stages.js';
14
15
  // ---------------------------------------------------------------------------
@@ -59,6 +60,43 @@ export class TransactionPipeline {
59
60
  await stage6Confirm(ctx);
60
61
  return ctx.txId;
61
62
  }
63
+ /**
64
+ * Execute a dry-run simulation of a transaction.
65
+ *
66
+ * Returns DryRunSimulationResult with zero side effects.
67
+ * No DB writes, no signing, no notifications, no events.
68
+ *
69
+ * @param walletId - Wallet initiating the simulation
70
+ * @param request - Transaction request (5-type discriminatedUnion)
71
+ * @returns DryRunSimulationResult
72
+ * @throws WAIaaSError('WALLET_NOT_FOUND') if wallet doesn't exist
73
+ * @throws WAIaaSError('WALLET_TERMINATED') if wallet is terminated
74
+ */
75
+ async executeDryRun(walletId, request) {
76
+ const wallet = await this.getWallet(walletId);
77
+ if (!wallet) {
78
+ throw new WAIaaSError('WALLET_NOT_FOUND', {
79
+ message: `Wallet '${walletId}' not found`,
80
+ });
81
+ }
82
+ if (wallet.status === 'TERMINATED') {
83
+ throw new WAIaaSError('WALLET_TERMINATED', {
84
+ message: `Wallet '${walletId}' is terminated`,
85
+ });
86
+ }
87
+ const resolvedNet = resolveNetwork(request.network, wallet.environment, wallet.chain);
88
+ return executeDryRunFn({
89
+ db: this.deps.db,
90
+ adapter: this.deps.adapter,
91
+ policyEngine: this.deps.policyEngine,
92
+ priceOracle: this.deps.priceOracle,
93
+ settingsService: this.deps.settingsService,
94
+ }, walletId, request, resolvedNet, {
95
+ publicKey: wallet.publicKey,
96
+ chain: wallet.chain,
97
+ environment: wallet.environment,
98
+ });
99
+ }
62
100
  /**
63
101
  * Get a transaction by ID.
64
102
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAK7E,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,aAAa,GACd,MAAM,aAAa,CAAC;AAgBrB,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,IAAkB;QAAlB,SAAI,GAAJ,IAAI,CAAc;IAAG,CAAC;IAEnD;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,OAAoD;QACtF,iBAAiB;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE;gBACxC,OAAO,EAAE,WAAW,QAAQ,aAAa;aAC1C,CAAC,CAAC;QACL,CAAC;QAED,4DAA4D;QAC5D,MAAM,eAAe,GAAG,cAAc,CACnC,OAAgC,CAAC,OAAkC,EACpE,MAAM,CAAC,WAA8B,EACrC,MAAM,CAAC,KAAkB,CAC1B,CAAC;QAEF,0BAA0B;QAC1B,MAAM,GAAG,GAAoB;YAC3B,GAAG,IAAI,CAAC,IAAI;YACZ,QAAQ;YACR,MAAM,EAAE;gBACN,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC;YACD,eAAe;YACf,OAAO;YACP,IAAI,EAAE,EAAE;SACT,CAAC;QAEF,6EAA6E;QAC7E,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE;aAC1B,MAAM,EAAE;aACR,IAAI,CAAC,YAAY,CAAC;aAClB,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;aAChC,GAAG,EAAE,CAAC;QAET,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,WAAW,CAAC,cAAc,EAAE;gBACpC,OAAO,EAAE,gBAAgB,IAAI,aAAa;aAC3C,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0BAA0B;IAElB,KAAK,CAAC,SAAS,CAAC,QAAgB;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACnF,CAAC;CACF"}
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ import type { DelayQueue } from '../workflow/delay-queue.js';
19
19
  import type { ApprovalWorkflow } from '../workflow/approval-workflow.js';
20
20
  import type { NotificationService } from '../notifications/notification-service.js';
21
21
  import type { SettingsService } from '../infrastructure/settings/settings-service.js';
22
- import type { IPriceOracle, IForexRateService } from '@waiaas/core';
22
+ import type { IPriceOracle, IForexRateService, IMetricsCounter } from '@waiaas/core';
23
23
  import { type EventBus } from '@waiaas/core';
24
24
  import type { WcSigningBridge } from '../services/wc-signing-bridge.js';
25
25
  import type { ApprovalChannelRouter } from '../services/signing-sdk/approval-channel-router.js';
@@ -62,7 +62,32 @@ export interface PipelineContext {
62
62
  eventBus?: EventBus;
63
63
  wcSigningBridge?: WcSigningBridge;
64
64
  approvalChannelRouter?: ApprovalChannelRouter;
65
+ metricsCounter?: IMetricsCounter;
65
66
  }
67
+ /** Safely extract `amount` from SendTransactionRequest | TransactionRequest. */
68
+ export declare function getRequestAmount(req: SendTransactionRequest | TransactionRequest): string;
69
+ /** Safely extract `to` from SendTransactionRequest | TransactionRequest. */
70
+ export declare function getRequestTo(req: SendTransactionRequest | TransactionRequest): string;
71
+ /** Safely extract `memo` from SendTransactionRequest | TransactionRequest. */
72
+ export declare function getRequestMemo(req: SendTransactionRequest | TransactionRequest): string | undefined;
73
+ export interface TransactionParam {
74
+ type: string;
75
+ amount: string;
76
+ toAddress: string;
77
+ chain: string;
78
+ network?: string;
79
+ tokenAddress?: string;
80
+ assetId?: string;
81
+ contractAddress?: string;
82
+ selector?: string;
83
+ spenderAddress?: string;
84
+ approveAmount?: string;
85
+ /** Token decimals for token_limits human-readable conversion (TOKEN_TRANSFER/APPROVE only). */
86
+ tokenDecimals?: number;
87
+ /** Action provider name for provider-trust policy bypass (set by ActionProviderRegistry). */
88
+ actionProvider?: string;
89
+ }
90
+ export declare function buildTransactionParam(req: SendTransactionRequest | TransactionRequest, txType: string, chain: string): TransactionParam;
66
91
  export declare function stage1Validate(ctx: PipelineContext): Promise<void>;
67
92
  export declare function stage2Auth(_ctx: PipelineContext): Promise<void>;
68
93
  export declare function stage3Policy(ctx: PipelineContext): Promise<void>;
@@ -82,6 +107,11 @@ export declare function stage3Policy(ctx: PipelineContext): Promise<void>;
82
107
  */
83
108
  export declare function stage3_5GasCondition(ctx: PipelineContext): Promise<void>;
84
109
  export declare function stage4Wait(ctx: PipelineContext): Promise<void>;
110
+ /**
111
+ * Build unsigned transaction by dispatching to the correct IChainAdapter method
112
+ * based on request.type (TRANSFER/TOKEN_TRANSFER/CONTRACT_CALL/APPROVE/BATCH).
113
+ */
114
+ export declare function buildByType(adapter: IChainAdapter, request: SendTransactionRequest | TransactionRequest, walletPublicKey: string): Promise<UnsignedTransaction>;
85
115
  /**
86
116
  * Stage 5: Build -> Simulate -> Sign -> Submit with CONC-01 retry logic.
87
117
  *