@psavelis/enterprise-blockchain 0.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/README.md +15 -2
  2. package/dist/aid-settlement/application/reconciler.d.ts +13 -0
  3. package/dist/aid-settlement/application/reconciler.d.ts.map +1 -0
  4. package/dist/aid-settlement/application/reconciler.js +77 -0
  5. package/dist/aid-settlement/domain/entities.d.ts +24 -0
  6. package/dist/aid-settlement/domain/entities.d.ts.map +1 -0
  7. package/dist/aid-settlement/domain/entities.js +1 -0
  8. package/dist/aid-settlement/domain/ports.d.ts +10 -0
  9. package/dist/aid-settlement/domain/ports.d.ts.map +1 -0
  10. package/dist/aid-settlement/domain/ports.js +1 -0
  11. package/dist/aid-settlement/index.d.ts +19 -0
  12. package/dist/aid-settlement/index.d.ts.map +1 -0
  13. package/dist/aid-settlement/index.js +23 -0
  14. package/dist/aid-settlement/infrastructure/in-memory-store.d.ts +12 -0
  15. package/dist/aid-settlement/infrastructure/in-memory-store.d.ts.map +1 -0
  16. package/dist/aid-settlement/infrastructure/in-memory-store.js +17 -0
  17. package/dist/credentialing/application/clearance-evaluator.d.ts +10 -0
  18. package/dist/credentialing/application/clearance-evaluator.d.ts.map +1 -0
  19. package/dist/credentialing/application/clearance-evaluator.js +63 -0
  20. package/dist/credentialing/domain/entities.d.ts +28 -0
  21. package/dist/credentialing/domain/entities.d.ts.map +1 -0
  22. package/dist/credentialing/domain/entities.js +1 -0
  23. package/dist/credentialing/domain/ports.d.ts +9 -0
  24. package/dist/credentialing/domain/ports.d.ts.map +1 -0
  25. package/dist/credentialing/domain/ports.js +1 -0
  26. package/dist/credentialing/index.d.ts +19 -0
  27. package/dist/credentialing/index.d.ts.map +1 -0
  28. package/dist/credentialing/index.js +23 -0
  29. package/dist/credentialing/infrastructure/in-memory-store.d.ts +11 -0
  30. package/dist/credentialing/infrastructure/in-memory-store.d.ts.map +1 -0
  31. package/dist/credentialing/infrastructure/in-memory-store.js +14 -0
  32. package/dist/hsm/application/asymmetric-key-service.d.ts +23 -0
  33. package/dist/hsm/application/asymmetric-key-service.d.ts.map +1 -0
  34. package/dist/hsm/application/asymmetric-key-service.js +109 -0
  35. package/dist/hsm/application/envelope-encryption-service.d.ts +18 -0
  36. package/dist/hsm/application/envelope-encryption-service.d.ts.map +1 -0
  37. package/dist/hsm/application/envelope-encryption-service.js +59 -0
  38. package/dist/hsm/application/symmetric-key-service.d.ts +34 -0
  39. package/dist/hsm/application/symmetric-key-service.d.ts.map +1 -0
  40. package/dist/hsm/application/symmetric-key-service.js +107 -0
  41. package/dist/hsm/domain/entities.d.ts +104 -0
  42. package/dist/hsm/domain/entities.d.ts.map +1 -0
  43. package/dist/hsm/domain/entities.js +10 -0
  44. package/dist/hsm/domain/ports.d.ts +20 -0
  45. package/dist/hsm/domain/ports.d.ts.map +1 -0
  46. package/dist/hsm/domain/ports.js +1 -0
  47. package/dist/hsm/index.d.ts +48 -0
  48. package/dist/hsm/index.d.ts.map +1 -0
  49. package/dist/hsm/index.js +97 -0
  50. package/dist/hsm/infrastructure/audit-log-factory.d.ts +59 -0
  51. package/dist/hsm/infrastructure/audit-log-factory.d.ts.map +1 -0
  52. package/dist/hsm/infrastructure/audit-log-factory.js +95 -0
  53. package/dist/hsm/infrastructure/audit-log.d.ts +8 -0
  54. package/dist/hsm/infrastructure/audit-log.d.ts.map +1 -0
  55. package/dist/hsm/infrastructure/audit-log.js +18 -0
  56. package/dist/hsm/infrastructure/file-audit-log.d.ts +55 -0
  57. package/dist/hsm/infrastructure/file-audit-log.d.ts.map +1 -0
  58. package/dist/hsm/infrastructure/file-audit-log.js +128 -0
  59. package/dist/hsm/infrastructure/key-store.d.ts +9 -0
  60. package/dist/hsm/infrastructure/key-store.d.ts.map +1 -0
  61. package/dist/hsm/infrastructure/key-store.js +12 -0
  62. package/dist/hsm/infrastructure/syslog-audit-log.d.ts +64 -0
  63. package/dist/hsm/infrastructure/syslog-audit-log.d.ts.map +1 -0
  64. package/dist/hsm/infrastructure/syslog-audit-log.js +167 -0
  65. package/dist/index.d.ts +22 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +37 -0
  68. package/dist/integrations/besu-client/error-mapper.d.ts +9 -0
  69. package/dist/integrations/besu-client/error-mapper.d.ts.map +1 -0
  70. package/dist/integrations/besu-client/error-mapper.js +22 -0
  71. package/dist/integrations/besu-client/index.d.ts +65 -0
  72. package/dist/integrations/besu-client/index.d.ts.map +1 -0
  73. package/dist/integrations/besu-client/index.js +276 -0
  74. package/dist/integrations/besu-client/ports.d.ts +44 -0
  75. package/dist/integrations/besu-client/ports.d.ts.map +1 -0
  76. package/dist/integrations/besu-client/ports.js +1 -0
  77. package/dist/integrations/corda-gateway/index.d.ts +37 -0
  78. package/dist/integrations/corda-gateway/index.d.ts.map +1 -0
  79. package/dist/integrations/corda-gateway/index.js +234 -0
  80. package/dist/integrations/corda-gateway/ports.d.ts +33 -0
  81. package/dist/integrations/corda-gateway/ports.d.ts.map +1 -0
  82. package/dist/integrations/corda-gateway/ports.js +1 -0
  83. package/dist/integrations/fabric-gateway/index.d.ts +78 -0
  84. package/dist/integrations/fabric-gateway/index.d.ts.map +1 -0
  85. package/dist/integrations/fabric-gateway/index.js +214 -0
  86. package/dist/integrations/fabric-gateway/ports.d.ts +50 -0
  87. package/dist/integrations/fabric-gateway/ports.d.ts.map +1 -0
  88. package/dist/integrations/fabric-gateway/ports.js +1 -0
  89. package/dist/integrations/index.d.ts +19 -0
  90. package/dist/integrations/index.d.ts.map +1 -0
  91. package/dist/integrations/index.js +19 -0
  92. package/dist/integrations/shared/env.d.ts +4 -0
  93. package/dist/integrations/shared/env.d.ts.map +1 -0
  94. package/dist/integrations/shared/env.js +24 -0
  95. package/dist/integrations/shared/retry.d.ts +79 -0
  96. package/dist/integrations/shared/retry.d.ts.map +1 -0
  97. package/dist/integrations/shared/retry.js +315 -0
  98. package/dist/mpc/adapters.d.ts +36 -0
  99. package/dist/mpc/adapters.d.ts.map +1 -0
  100. package/dist/mpc/adapters.js +46 -0
  101. package/dist/mpc/crypto.d.ts +2 -0
  102. package/dist/mpc/crypto.d.ts.map +1 -0
  103. package/dist/mpc/crypto.js +2 -0
  104. package/dist/mpc/dsa.d.ts +134 -0
  105. package/dist/mpc/dsa.d.ts.map +1 -0
  106. package/dist/mpc/dsa.js +127 -0
  107. package/dist/mpc/field.d.ts +127 -0
  108. package/dist/mpc/field.d.ts.map +1 -0
  109. package/dist/mpc/field.js +209 -0
  110. package/dist/mpc/hybrid-kem.d.ts +96 -0
  111. package/dist/mpc/hybrid-kem.d.ts.map +1 -0
  112. package/dist/mpc/hybrid-kem.js +136 -0
  113. package/dist/mpc/index.d.ts +135 -0
  114. package/dist/mpc/index.d.ts.map +1 -0
  115. package/dist/mpc/index.js +348 -0
  116. package/dist/mpc/kyber.d.ts +134 -0
  117. package/dist/mpc/kyber.d.ts.map +1 -0
  118. package/dist/mpc/kyber.js +143 -0
  119. package/dist/mpc/ports.d.ts +67 -0
  120. package/dist/mpc/ports.d.ts.map +1 -0
  121. package/dist/mpc/ports.js +9 -0
  122. package/dist/mpc/quantum.d.ts +80 -0
  123. package/dist/mpc/quantum.d.ts.map +1 -0
  124. package/dist/mpc/quantum.js +180 -0
  125. package/dist/p2mr/adapters.d.ts +31 -0
  126. package/dist/p2mr/adapters.d.ts.map +1 -0
  127. package/dist/p2mr/adapters.js +35 -0
  128. package/dist/p2mr/index.d.ts +63 -0
  129. package/dist/p2mr/index.d.ts.map +1 -0
  130. package/dist/p2mr/index.js +59 -0
  131. package/dist/p2mr/merkle-tree.d.ts +109 -0
  132. package/dist/p2mr/merkle-tree.d.ts.map +1 -0
  133. package/dist/p2mr/merkle-tree.js +239 -0
  134. package/dist/p2mr/p2mr-output.d.ts +142 -0
  135. package/dist/p2mr/p2mr-output.d.ts.map +1 -0
  136. package/dist/p2mr/p2mr-output.js +150 -0
  137. package/dist/p2mr/ports.d.ts +52 -0
  138. package/dist/p2mr/ports.d.ts.map +1 -0
  139. package/dist/p2mr/ports.js +9 -0
  140. package/dist/p2mr/script-interpreter.d.ts +92 -0
  141. package/dist/p2mr/script-interpreter.d.ts.map +1 -0
  142. package/dist/p2mr/script-interpreter.js +535 -0
  143. package/dist/p2mr/script-leaf.d.ts +70 -0
  144. package/dist/p2mr/script-leaf.d.ts.map +1 -0
  145. package/dist/p2mr/script-leaf.js +203 -0
  146. package/dist/p2mr/spend-proof.d.ts +95 -0
  147. package/dist/p2mr/spend-proof.d.ts.map +1 -0
  148. package/dist/p2mr/spend-proof.js +358 -0
  149. package/dist/p2mr/types.d.ts +209 -0
  150. package/dist/p2mr/types.d.ts.map +1 -0
  151. package/dist/p2mr/types.js +9 -0
  152. package/dist/privacy/application/view-projector.d.ts +13 -0
  153. package/dist/privacy/application/view-projector.d.ts.map +1 -0
  154. package/dist/privacy/application/view-projector.js +85 -0
  155. package/dist/privacy/domain/entities.d.ts +26 -0
  156. package/dist/privacy/domain/entities.d.ts.map +1 -0
  157. package/dist/privacy/domain/entities.js +1 -0
  158. package/dist/privacy/domain/ports.d.ts +7 -0
  159. package/dist/privacy/domain/ports.d.ts.map +1 -0
  160. package/dist/privacy/domain/ports.js +1 -0
  161. package/dist/privacy/index.d.ts +21 -0
  162. package/dist/privacy/index.d.ts.map +1 -0
  163. package/dist/privacy/index.js +25 -0
  164. package/dist/privacy/infrastructure/in-memory-store.d.ts +8 -0
  165. package/dist/privacy/infrastructure/in-memory-store.d.ts.map +1 -0
  166. package/dist/privacy/infrastructure/in-memory-store.js +7 -0
  167. package/dist/protocols/besu-port.d.ts +80 -0
  168. package/dist/protocols/besu-port.d.ts.map +1 -0
  169. package/dist/protocols/besu-port.js +1 -0
  170. package/dist/protocols/corda-port.d.ts +103 -0
  171. package/dist/protocols/corda-port.d.ts.map +1 -0
  172. package/dist/protocols/corda-port.js +9 -0
  173. package/dist/protocols/credentialing-port.d.ts +11 -0
  174. package/dist/protocols/credentialing-port.d.ts.map +1 -0
  175. package/dist/protocols/credentialing-port.js +1 -0
  176. package/dist/protocols/fabric-port.d.ts +89 -0
  177. package/dist/protocols/fabric-port.d.ts.map +1 -0
  178. package/dist/protocols/fabric-port.js +9 -0
  179. package/dist/protocols/index.d.ts +14 -0
  180. package/dist/protocols/index.d.ts.map +1 -0
  181. package/dist/protocols/index.js +7 -0
  182. package/dist/protocols/p2mr-port.d.ts +159 -0
  183. package/dist/protocols/p2mr-port.d.ts.map +1 -0
  184. package/dist/protocols/p2mr-port.js +12 -0
  185. package/dist/protocols/privacy-port.d.ts +9 -0
  186. package/dist/protocols/privacy-port.d.ts.map +1 -0
  187. package/dist/protocols/privacy-port.js +1 -0
  188. package/dist/protocols/traceability-port.d.ts +12 -0
  189. package/dist/protocols/traceability-port.d.ts.map +1 -0
  190. package/dist/protocols/traceability-port.js +1 -0
  191. package/dist/shared/collection-store.d.ts +12 -0
  192. package/dist/shared/collection-store.d.ts.map +1 -0
  193. package/dist/shared/collection-store.js +26 -0
  194. package/dist/shared/commit.d.ts +24 -0
  195. package/dist/shared/commit.d.ts.map +1 -0
  196. package/dist/shared/commit.js +50 -0
  197. package/dist/shared/crypto.d.ts +2 -0
  198. package/dist/shared/crypto.d.ts.map +1 -0
  199. package/dist/shared/crypto.js +4 -0
  200. package/dist/shared/date.d.ts +2 -0
  201. package/dist/shared/date.d.ts.map +1 -0
  202. package/dist/shared/date.js +3 -0
  203. package/dist/shared/index.d.ts +9 -0
  204. package/dist/shared/index.d.ts.map +1 -0
  205. package/dist/shared/index.js +11 -0
  206. package/dist/shared/logger.d.ts +37 -0
  207. package/dist/shared/logger.d.ts.map +1 -0
  208. package/dist/shared/logger.js +45 -0
  209. package/dist/shared/store.d.ts +25 -0
  210. package/dist/shared/store.d.ts.map +1 -0
  211. package/dist/shared/store.js +18 -0
  212. package/dist/shared/telemetry-sdk.d.ts +26 -0
  213. package/dist/shared/telemetry-sdk.d.ts.map +1 -0
  214. package/dist/shared/telemetry-sdk.js +97 -0
  215. package/dist/shared/telemetry.d.ts +86 -0
  216. package/dist/shared/telemetry.d.ts.map +1 -0
  217. package/dist/shared/telemetry.js +137 -0
  218. package/dist/stark-settlement/application/aggregator-service.d.ts +112 -0
  219. package/dist/stark-settlement/application/aggregator-service.d.ts.map +1 -0
  220. package/dist/stark-settlement/application/aggregator-service.js +256 -0
  221. package/dist/stark-settlement/application/ledger-service.d.ts +114 -0
  222. package/dist/stark-settlement/application/ledger-service.d.ts.map +1 -0
  223. package/dist/stark-settlement/application/ledger-service.js +318 -0
  224. package/dist/stark-settlement/application/settlement-service.d.ts +104 -0
  225. package/dist/stark-settlement/application/settlement-service.d.ts.map +1 -0
  226. package/dist/stark-settlement/application/settlement-service.js +251 -0
  227. package/dist/stark-settlement/domain/entities.d.ts +365 -0
  228. package/dist/stark-settlement/domain/entities.d.ts.map +1 -0
  229. package/dist/stark-settlement/domain/entities.js +29 -0
  230. package/dist/stark-settlement/domain/ports.d.ts +485 -0
  231. package/dist/stark-settlement/domain/ports.d.ts.map +1 -0
  232. package/dist/stark-settlement/domain/ports.js +14 -0
  233. package/dist/stark-settlement/domain/value-objects.d.ts +268 -0
  234. package/dist/stark-settlement/domain/value-objects.d.ts.map +1 -0
  235. package/dist/stark-settlement/domain/value-objects.js +500 -0
  236. package/dist/stark-settlement/index.d.ts +172 -0
  237. package/dist/stark-settlement/index.d.ts.map +1 -0
  238. package/dist/stark-settlement/index.js +193 -0
  239. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts +52 -0
  240. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts.map +1 -0
  241. package/dist/stark-settlement/infrastructure/adapters/audit-adapter.js +154 -0
  242. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts +88 -0
  243. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts.map +1 -0
  244. package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.js +187 -0
  245. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts +59 -0
  246. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts.map +1 -0
  247. package/dist/stark-settlement/infrastructure/adapters/clock-adapter.js +85 -0
  248. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts +60 -0
  249. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts.map +1 -0
  250. package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.js +104 -0
  251. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts +115 -0
  252. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts.map +1 -0
  253. package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.js +191 -0
  254. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts +65 -0
  255. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts.map +1 -0
  256. package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.js +207 -0
  257. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts +73 -0
  258. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts.map +1 -0
  259. package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.js +287 -0
  260. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts +78 -0
  261. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts.map +1 -0
  262. package/dist/stark-settlement/infrastructure/adapters/solana-adapter.js +172 -0
  263. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts +56 -0
  264. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts.map +1 -0
  265. package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.js +261 -0
  266. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts +125 -0
  267. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts.map +1 -0
  268. package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.js +416 -0
  269. package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts +68 -0
  270. package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts.map +1 -0
  271. package/dist/stark-settlement/infrastructure/persistence/ledger-store.js +238 -0
  272. package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts +30 -0
  273. package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts.map +1 -0
  274. package/dist/stark-settlement/infrastructure/persistence/offset-store.js +57 -0
  275. package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts +45 -0
  276. package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts.map +1 -0
  277. package/dist/stark-settlement/infrastructure/persistence/outbox-store.js +171 -0
  278. package/dist/traceability/application/recall-assessor.d.ts +13 -0
  279. package/dist/traceability/application/recall-assessor.d.ts.map +1 -0
  280. package/dist/traceability/application/recall-assessor.js +74 -0
  281. package/dist/traceability/domain/entities.d.ts +23 -0
  282. package/dist/traceability/domain/entities.d.ts.map +1 -0
  283. package/dist/traceability/domain/entities.js +1 -0
  284. package/dist/traceability/domain/ports.d.ts +23 -0
  285. package/dist/traceability/domain/ports.d.ts.map +1 -0
  286. package/dist/traceability/domain/ports.js +1 -0
  287. package/dist/traceability/domain/recall.d.ts +12 -0
  288. package/dist/traceability/domain/recall.d.ts.map +1 -0
  289. package/dist/traceability/domain/recall.js +1 -0
  290. package/dist/traceability/index.d.ts +22 -0
  291. package/dist/traceability/index.d.ts.map +1 -0
  292. package/dist/traceability/index.js +26 -0
  293. package/dist/traceability/infrastructure/in-memory-store.d.ts +13 -0
  294. package/dist/traceability/infrastructure/in-memory-store.d.ts.map +1 -0
  295. package/dist/traceability/infrastructure/in-memory-store.js +24 -0
  296. package/package.json +12 -9
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Ledger Service
3
+ *
4
+ * Orchestrates the ZKP ledger operations:
5
+ * - Account management (create, query, update)
6
+ * - Transaction submission with ML-DSA-65 signing
7
+ * - State transition proof generation
8
+ * - Audit logging
9
+ *
10
+ * All transactions are signed with post-quantum ML-DSA-65 signatures.
11
+ *
12
+ * @see domain/ports.ts for port interfaces
13
+ */
14
+ import { createHash } from "node:crypto";
15
+ import { StateRoot } from "../domain/value-objects.js";
16
+ /**
17
+ * Ledger service for managing accounts and transactions.
18
+ */
19
+ export class LedgerService {
20
+ ctx;
21
+ currentStateRoot;
22
+ constructor(ctx) {
23
+ this.ctx = ctx;
24
+ this.currentStateRoot = StateRoot.genesis();
25
+ }
26
+ // ─────────────────────────────────────────────────────────────────────────
27
+ // Account Management
28
+ // ─────────────────────────────────────────────────────────────────────────
29
+ /**
30
+ * Create a new mirror account.
31
+ */
32
+ async createAccount(options) {
33
+ const now = this.ctx.clock.now();
34
+ const id = this.ctx.clock.uuid();
35
+ const account = {
36
+ id,
37
+ externalAddress: options.externalAddress,
38
+ assetType: options.assetType,
39
+ balance: options.initialBalance ?? 0n,
40
+ lastProofRoot: this.currentStateRoot.toString().replace("0x", ""),
41
+ createdAt: now,
42
+ updatedAt: now,
43
+ isActive: true,
44
+ metadata: options.metadata ?? {},
45
+ };
46
+ await this.ctx.ledgerStore.createAccount(account);
47
+ // Update state root to reflect new account
48
+ this.currentStateRoot = this.currentStateRoot.hash(new TextEncoder().encode(serializeWithBigInt(account)));
49
+ // Emit event
50
+ this.ctx.events.emit({
51
+ type: "transaction:submitted",
52
+ tx: {
53
+ txId: `account-creation-${id}`,
54
+ type: "deposit",
55
+ fromAccountId: null,
56
+ toAccountId: id,
57
+ assetType: options.assetType,
58
+ amount: options.initialBalance ?? 0n,
59
+ idempotencyKey: `account-creation-${id}`,
60
+ mlDsaSignature: new Uint8Array(0),
61
+ mlDsaPublicKeyHash: "",
62
+ status: "finalized",
63
+ metadata: { accountCreation: "true" },
64
+ createdAt: now,
65
+ updatedAt: now,
66
+ },
67
+ });
68
+ return account;
69
+ }
70
+ /**
71
+ * Get an account by ID.
72
+ */
73
+ async getAccount(accountId) {
74
+ return this.ctx.ledgerStore.getAccount(accountId);
75
+ }
76
+ /**
77
+ * Get an account by external address and asset type.
78
+ */
79
+ async getAccountByAddress(externalAddress, assetType) {
80
+ return this.ctx.ledgerStore.getAccountByAddress(externalAddress, assetType);
81
+ }
82
+ /**
83
+ * Get all accounts for an asset type.
84
+ */
85
+ async getAccountsByAssetType(assetType) {
86
+ return this.ctx.ledgerStore.getAccountsByAssetType(assetType);
87
+ }
88
+ // ─────────────────────────────────────────────────────────────────────────
89
+ // Transaction Submission
90
+ // ─────────────────────────────────────────────────────────────────────────
91
+ /**
92
+ * Submit a transaction to the ledger.
93
+ *
94
+ * The transaction is:
95
+ * 1. Validated (balances, account existence)
96
+ * 2. Signed with ML-DSA-65
97
+ * 3. Recorded in the ledger
98
+ * 4. A base STARK proof is generated
99
+ * 5. Account balances are updated
100
+ *
101
+ * @returns The transaction and its base proof
102
+ * @throws If validation fails
103
+ */
104
+ async submitTransaction(options) {
105
+ const now = this.ctx.clock.now();
106
+ const txId = this.ctx.clock.uuid();
107
+ // Generate idempotency key if not provided
108
+ const idempotencyKey = options.idempotencyKey ??
109
+ createHash("sha256").update(`${txId}:${now}`).digest("hex");
110
+ // Check for duplicate (idempotent replay)
111
+ const existingTxs = await this.ctx.ledgerStore.getTransactionsByIdempotencyKey(idempotencyKey);
112
+ if (existingTxs.length > 0) {
113
+ const existingTx = existingTxs[0];
114
+ // Look up proof using the proofId stored on the transaction (if present)
115
+ // or fall back to the deterministic proof ID pattern for backward compatibility
116
+ const txWithProofId = existingTx;
117
+ const proofId = txWithProofId.proofId ?? `proof-${existingTx.txId}`;
118
+ const existingProof = await this.ctx.ledgerStore.getBaseProof(proofId);
119
+ if (existingProof) {
120
+ return {
121
+ transaction: existingTx,
122
+ baseProof: existingProof,
123
+ isDuplicate: true,
124
+ };
125
+ }
126
+ // Transaction exists but proof not found - refuse to create duplicate
127
+ throw new Error(`Idempotency violation: transaction with key "${idempotencyKey}" already exists (txId: ${existingTx.txId}), but proof could not be found. Refusing to create duplicate.`);
128
+ }
129
+ // Validate transaction
130
+ await this.validateTransaction(options);
131
+ // Create transaction payload for signing
132
+ const payload = {
133
+ txId,
134
+ type: options.type,
135
+ fromAccountId: options.fromAccountId ?? null,
136
+ toAccountId: options.toAccountId ?? null,
137
+ assetType: options.assetType,
138
+ amount: options.amount.toString(),
139
+ idempotencyKey,
140
+ createdAt: now,
141
+ };
142
+ // Sign with ML-DSA-65
143
+ const signature = this.ctx.transactionSigning.signPayload(payload, options.signerSecretKey);
144
+ const publicKeyHash = this.ctx.dilithium.hashPublicKey(options.signerPublicKey);
145
+ // Create transaction record
146
+ const transaction = {
147
+ txId,
148
+ type: options.type,
149
+ fromAccountId: options.fromAccountId ?? null,
150
+ toAccountId: options.toAccountId ?? null,
151
+ assetType: options.assetType,
152
+ amount: options.amount,
153
+ idempotencyKey,
154
+ mlDsaSignature: signature,
155
+ mlDsaPublicKeyHash: publicKeyHash,
156
+ status: "pending",
157
+ metadata: options.metadata ?? {},
158
+ createdAt: now,
159
+ updatedAt: now,
160
+ };
161
+ // Save transaction
162
+ await this.ctx.ledgerStore.appendTransaction(transaction);
163
+ // Compute state transition
164
+ const preStateRoot = this.currentStateRoot.toString().replace("0x", "");
165
+ await this.applyTransaction(transaction);
166
+ const postStateRoot = this.currentStateRoot.toString().replace("0x", "");
167
+ // Generate base STARK proof
168
+ const baseProof = await this.ctx.starkProver.generateBaseProof(transaction, preStateRoot, postStateRoot);
169
+ // Save base proof
170
+ await this.ctx.ledgerStore.saveBaseProof(baseProof);
171
+ // Update transaction status
172
+ await this.ctx.ledgerStore.updateTransactionStatus(txId, "proved");
173
+ // Create updated transaction with correct status for return/events
174
+ const provedTransaction = {
175
+ ...transaction,
176
+ status: "proved",
177
+ updatedAt: this.ctx.clock.now(),
178
+ };
179
+ // Log audit record
180
+ await this.ctx.auditLog.append({
181
+ eventType: "transaction_submitted",
182
+ entityId: txId,
183
+ entityType: "transaction",
184
+ actor: publicKeyHash,
185
+ timestamp: now,
186
+ data: {
187
+ type: options.type,
188
+ assetType: options.assetType,
189
+ amount: options.amount.toString(),
190
+ preStateRoot,
191
+ postStateRoot,
192
+ },
193
+ });
194
+ // Emit event with updated transaction
195
+ this.ctx.events.emit({
196
+ type: "transaction:submitted",
197
+ tx: provedTransaction,
198
+ });
199
+ this.ctx.events.emit({ type: "proof:base:generated", proof: baseProof });
200
+ return {
201
+ transaction: provedTransaction,
202
+ baseProof,
203
+ isDuplicate: false,
204
+ };
205
+ }
206
+ /**
207
+ * Get pending transactions that need proof generation.
208
+ */
209
+ async getPendingTransactions(limit = 1000) {
210
+ return this.ctx.ledgerStore.getPendingTransactions(limit);
211
+ }
212
+ /**
213
+ * Get the current state root.
214
+ */
215
+ getCurrentStateRoot() {
216
+ return this.currentStateRoot;
217
+ }
218
+ // ─────────────────────────────────────────────────────────────────────────
219
+ // Private Helpers
220
+ // ─────────────────────────────────────────────────────────────────────────
221
+ async validateTransaction(options) {
222
+ // Validate based on transaction type
223
+ switch (options.type) {
224
+ case "deposit":
225
+ if (!options.toAccountId) {
226
+ throw new Error("Deposit requires toAccountId");
227
+ }
228
+ await this.validateAccountExists(options.toAccountId, options.assetType);
229
+ break;
230
+ case "withdrawal":
231
+ if (!options.fromAccountId) {
232
+ throw new Error("Withdrawal requires fromAccountId");
233
+ }
234
+ await this.validateAccountExists(options.fromAccountId, options.assetType);
235
+ await this.validateSufficientBalance(options.fromAccountId, options.amount);
236
+ break;
237
+ case "transfer":
238
+ if (!options.fromAccountId || !options.toAccountId) {
239
+ throw new Error("Transfer requires both fromAccountId and toAccountId");
240
+ }
241
+ await this.validateAccountExists(options.fromAccountId, options.assetType);
242
+ await this.validateAccountExists(options.toAccountId, options.assetType);
243
+ await this.validateSufficientBalance(options.fromAccountId, options.amount);
244
+ break;
245
+ }
246
+ // Validate amount is positive
247
+ if (options.amount <= 0n) {
248
+ throw new Error("Amount must be positive");
249
+ }
250
+ // Verify signature is valid
251
+ const payload = {
252
+ txId: "validation-check",
253
+ type: options.type,
254
+ fromAccountId: options.fromAccountId ?? null,
255
+ toAccountId: options.toAccountId ?? null,
256
+ assetType: options.assetType,
257
+ amount: options.amount.toString(),
258
+ idempotencyKey: "validation-check",
259
+ createdAt: this.ctx.clock.now(),
260
+ };
261
+ const testSignature = this.ctx.transactionSigning.signPayload(payload, options.signerSecretKey);
262
+ const isValid = this.ctx.transactionSigning.verifyPayload(payload, testSignature, options.signerPublicKey);
263
+ if (!isValid) {
264
+ throw new Error("Invalid signature");
265
+ }
266
+ }
267
+ async validateAccountExists(accountId, expectedAssetType) {
268
+ const account = await this.ctx.ledgerStore.getAccount(accountId);
269
+ if (!account) {
270
+ throw new Error(`Account ${accountId} not found`);
271
+ }
272
+ if (account.assetType !== expectedAssetType) {
273
+ throw new Error(`Account ${accountId} has asset type ${account.assetType}, expected ${expectedAssetType}`);
274
+ }
275
+ if (!account.isActive) {
276
+ throw new Error(`Account ${accountId} is not active`);
277
+ }
278
+ }
279
+ async validateSufficientBalance(accountId, amount) {
280
+ const account = await this.ctx.ledgerStore.getAccount(accountId);
281
+ if (!account) {
282
+ throw new Error(`Account ${accountId} not found`);
283
+ }
284
+ if (account.balance < amount) {
285
+ throw new Error(`Insufficient balance: ${account.balance} < ${amount}`);
286
+ }
287
+ }
288
+ async applyTransaction(tx) {
289
+ // First, advance the state root to reflect the new transaction
290
+ this.currentStateRoot = this.currentStateRoot.hash(new TextEncoder().encode(serializeWithBigInt(tx)));
291
+ // Use the post-transaction state root for account updates
292
+ const postTxStateRoot = this.currentStateRoot.toString().replace("0x", "");
293
+ switch (tx.type) {
294
+ case "deposit":
295
+ if (tx.toAccountId) {
296
+ await this.ctx.ledgerStore.updateAccountBalance(tx.toAccountId, tx.amount, postTxStateRoot);
297
+ }
298
+ break;
299
+ case "withdrawal":
300
+ if (tx.fromAccountId) {
301
+ await this.ctx.ledgerStore.updateAccountBalance(tx.fromAccountId, -tx.amount, postTxStateRoot);
302
+ }
303
+ break;
304
+ case "transfer":
305
+ if (tx.fromAccountId && tx.toAccountId) {
306
+ await this.ctx.ledgerStore.updateAccountBalance(tx.fromAccountId, -tx.amount, postTxStateRoot);
307
+ await this.ctx.ledgerStore.updateAccountBalance(tx.toAccountId, tx.amount, postTxStateRoot);
308
+ }
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ /**
314
+ * Serialize an object to JSON, converting BigInt values to strings.
315
+ */
316
+ function serializeWithBigInt(obj) {
317
+ return JSON.stringify(obj, (_key, value) => typeof value === "bigint" ? value.toString() : value);
318
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Settlement Service
3
+ *
4
+ * Orchestrates outbound settlement to external chains:
5
+ * - Solana (devnet): VersionedTransaction with lookup tables
6
+ * - Bitcoin (testnet): PSBT batched UTXO spends
7
+ * - Fiat (mock): ISO 20022 pain.001 credit transfers
8
+ *
9
+ * Uses idempotency keys and outbox entry state transitions to coordinate
10
+ * settlement attempts and reduce duplicate processing.
11
+ *
12
+ * @see domain/ports.ts for settlement port interfaces
13
+ */
14
+ import type { AssetType, Tier2BlockProof, OutboxEntry, SolanaSettlementResult, BitcoinSettlementResult, FiatSettlementResult } from "../domain/entities.js";
15
+ import type { SolanaSettlementPort, BitcoinSettlementPort, FiatSettlementPort } from "../domain/ports.js";
16
+ import type { SettlementContext } from "../index.js";
17
+ /**
18
+ * Result of settling a single rail.
19
+ */
20
+ export type SettlementRailResult = {
21
+ success: true;
22
+ assetType: AssetType;
23
+ result: SolanaSettlementResult | BitcoinSettlementResult | FiatSettlementResult;
24
+ } | {
25
+ success: false;
26
+ assetType: AssetType;
27
+ error: string;
28
+ };
29
+ /**
30
+ * Result of settling all rails.
31
+ */
32
+ export interface SettleAllRailsResult {
33
+ blockProofId: string;
34
+ results: SettlementRailResult[];
35
+ allSucceeded: boolean;
36
+ }
37
+ /**
38
+ * Settlement service configuration.
39
+ */
40
+ export interface SettlementServiceConfig {
41
+ /** Delay between retries in ms (default: 1000) */
42
+ retryDelayMs?: number;
43
+ }
44
+ /**
45
+ * Settlement service for external chain settlement.
46
+ */
47
+ export declare class SettlementService {
48
+ private readonly ctx;
49
+ private readonly config;
50
+ private solanaAdapter;
51
+ private bitcoinAdapter;
52
+ private fiatAdapter;
53
+ constructor(ctx: SettlementContext, config?: SettlementServiceConfig);
54
+ /**
55
+ * Set the Solana settlement adapter.
56
+ */
57
+ setSolanaAdapter(adapter: SolanaSettlementPort): void;
58
+ /**
59
+ * Set the Bitcoin settlement adapter.
60
+ */
61
+ setBitcoinAdapter(adapter: BitcoinSettlementPort): void;
62
+ /**
63
+ * Set the Fiat settlement adapter.
64
+ */
65
+ setFiatAdapter(adapter: FiatSettlementPort): void;
66
+ /**
67
+ * Settle all pending outbox entries for a block proof.
68
+ */
69
+ settleAllRails(blockProof: Tier2BlockProof): Promise<SettleAllRailsResult>;
70
+ /**
71
+ * Settle a single outbox entry.
72
+ */
73
+ settleEntry(entry: OutboxEntry, blockProof: Tier2BlockProof): Promise<SettlementRailResult>;
74
+ /**
75
+ * Process all retryable entries.
76
+ */
77
+ processRetries(): Promise<SettlementRailResult[]>;
78
+ /**
79
+ * Get health status of all settlement rails.
80
+ */
81
+ getHealth(): Promise<{
82
+ solana: {
83
+ available: boolean;
84
+ healthy: boolean;
85
+ details?: unknown;
86
+ };
87
+ bitcoin: {
88
+ available: boolean;
89
+ healthy: boolean;
90
+ details?: unknown;
91
+ };
92
+ fiat: {
93
+ available: boolean;
94
+ healthy: boolean;
95
+ details?: unknown;
96
+ };
97
+ }>;
98
+ private executeSettlement;
99
+ private settleSolana;
100
+ private settleBitcoin;
101
+ private settleFiat;
102
+ private getSettlementTxId;
103
+ }
104
+ //# sourceMappingURL=settlement-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settlement-service.d.ts","sourceRoot":"","sources":["../../../src/stark-settlement/application/settlement-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,WAAW,EAEX,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EACF,sBAAsB,GACtB,uBAAuB,GACvB,oBAAoB,CAAC;CAC1B,GACD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAO1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,WAAW,CAAmC;gBAGnC,GAAG,EAAE,iBAAiB,EACvC,MAAM,CAAC,EAAE,uBAAuB;IAOlC;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAIrD;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAIvD;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAQjD;;OAEG;IACG,cAAc,CAClB,UAAU,EAAE,eAAe,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IA0BhC;;OAEG;IACG,WAAW,CACf,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,eAAe,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IAoFhC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAkCvD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC;QACzB,MAAM,EAAE;YAAE,SAAS,EAAE,OAAO,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;QACpE,OAAO,EAAE;YAAE,SAAS,EAAE,OAAO,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;QACrE,IAAI,EAAE;YAAE,SAAS,EAAE,OAAO,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACnE,CAAC;YA0DY,iBAAiB;YAgBjB,YAAY;YAUZ,aAAa;YAUb,UAAU;IAUxB,OAAO,CAAC,iBAAiB;CAc1B"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Settlement Service
3
+ *
4
+ * Orchestrates outbound settlement to external chains:
5
+ * - Solana (devnet): VersionedTransaction with lookup tables
6
+ * - Bitcoin (testnet): PSBT batched UTXO spends
7
+ * - Fiat (mock): ISO 20022 pain.001 credit transfers
8
+ *
9
+ * Uses idempotency keys and outbox entry state transitions to coordinate
10
+ * settlement attempts and reduce duplicate processing.
11
+ *
12
+ * @see domain/ports.ts for settlement port interfaces
13
+ */
14
+ /**
15
+ * Settlement service for external chain settlement.
16
+ */
17
+ export class SettlementService {
18
+ ctx;
19
+ config;
20
+ solanaAdapter = null;
21
+ bitcoinAdapter = null;
22
+ fiatAdapter = null;
23
+ constructor(ctx, config) {
24
+ this.ctx = ctx;
25
+ this.config = {
26
+ retryDelayMs: config?.retryDelayMs ?? 1000,
27
+ };
28
+ }
29
+ /**
30
+ * Set the Solana settlement adapter.
31
+ */
32
+ setSolanaAdapter(adapter) {
33
+ this.solanaAdapter = adapter;
34
+ }
35
+ /**
36
+ * Set the Bitcoin settlement adapter.
37
+ */
38
+ setBitcoinAdapter(adapter) {
39
+ this.bitcoinAdapter = adapter;
40
+ }
41
+ /**
42
+ * Set the Fiat settlement adapter.
43
+ */
44
+ setFiatAdapter(adapter) {
45
+ this.fiatAdapter = adapter;
46
+ }
47
+ // ─────────────────────────────────────────────────────────────────────────
48
+ // Settlement Operations
49
+ // ─────────────────────────────────────────────────────────────────────────
50
+ /**
51
+ * Settle all pending outbox entries for a block proof.
52
+ */
53
+ async settleAllRails(blockProof) {
54
+ const results = [];
55
+ // Get all pending entries for this block
56
+ for (const assetType of ["SOL", "BTC", "USD"]) {
57
+ const entries = await this.ctx.outboxStore.getPendingEntries(assetType, 100);
58
+ const blockEntries = entries.filter((e) => e.blockProofId === blockProof.blockProofId);
59
+ for (const entry of blockEntries) {
60
+ const result = await this.settleEntry(entry, blockProof);
61
+ results.push(result);
62
+ }
63
+ }
64
+ return {
65
+ blockProofId: blockProof.blockProofId,
66
+ results,
67
+ allSucceeded: results.every((r) => r.success),
68
+ };
69
+ }
70
+ /**
71
+ * Settle a single outbox entry.
72
+ */
73
+ async settleEntry(entry, blockProof) {
74
+ // Mark as processing
75
+ await this.ctx.outboxStore.markProcessing(entry.entryId);
76
+ try {
77
+ const result = await this.executeSettlement(entry, blockProof);
78
+ // Mark as settled
79
+ await this.ctx.outboxStore.markSettled(entry.entryId, this.getSettlementTxId(result));
80
+ // Log audit record
81
+ await this.ctx.auditLog.append({
82
+ eventType: "settlement_confirmed",
83
+ entityId: entry.entryId,
84
+ entityType: "outbox_entry",
85
+ actor: "settlement-service",
86
+ timestamp: this.ctx.clock.now(),
87
+ data: {
88
+ assetType: entry.assetType,
89
+ blockProofId: blockProof.blockProofId,
90
+ settlementTxId: this.getSettlementTxId(result),
91
+ },
92
+ });
93
+ // Emit event with updated entry status
94
+ const settledEntry = {
95
+ ...entry,
96
+ status: "settled",
97
+ settledAt: this.ctx.clock.now(),
98
+ settlementTxId: this.getSettlementTxId(result),
99
+ };
100
+ this.ctx.events.emit({
101
+ type: "settlement:completed",
102
+ entry: settledEntry,
103
+ result,
104
+ });
105
+ return { success: true, assetType: entry.assetType, result };
106
+ }
107
+ catch (error) {
108
+ const errorMessage = error instanceof Error ? error.message : String(error);
109
+ // Mark as failed
110
+ await this.ctx.outboxStore.markFailed(entry.entryId, errorMessage);
111
+ // Log audit record
112
+ await this.ctx.auditLog.append({
113
+ eventType: "settlement_failed",
114
+ entityId: entry.entryId,
115
+ entityType: "outbox_entry",
116
+ actor: "settlement-service",
117
+ timestamp: this.ctx.clock.now(),
118
+ data: {
119
+ assetType: entry.assetType,
120
+ blockProofId: blockProof.blockProofId,
121
+ error: errorMessage,
122
+ retryCount: entry.retryCount + 1,
123
+ },
124
+ });
125
+ // Emit event with updated entry status
126
+ const failedEntry = {
127
+ ...entry,
128
+ status: "failed",
129
+ retryCount: entry.retryCount + 1,
130
+ errorMessage,
131
+ };
132
+ this.ctx.events.emit({
133
+ type: "settlement:failed",
134
+ entry: failedEntry,
135
+ error: errorMessage,
136
+ });
137
+ return {
138
+ success: false,
139
+ assetType: entry.assetType,
140
+ error: errorMessage,
141
+ };
142
+ }
143
+ }
144
+ /**
145
+ * Process all retryable entries.
146
+ */
147
+ async processRetries() {
148
+ const results = [];
149
+ for (const assetType of ["SOL", "BTC", "USD"]) {
150
+ const entries = await this.ctx.outboxStore.getRetryableEntries(assetType, 10);
151
+ for (const entry of entries) {
152
+ // Get the block proof for this entry
153
+ const blockProof = await this.ctx.ledgerStore.getTier2Proof(entry.blockProofId);
154
+ if (!blockProof) {
155
+ console.warn(`Block proof ${entry.blockProofId} not found for retry`);
156
+ continue;
157
+ }
158
+ const result = await this.settleEntry(entry, blockProof);
159
+ results.push(result);
160
+ // Delay between retries
161
+ if (this.config.retryDelayMs > 0) {
162
+ await new Promise((resolve) => setTimeout(resolve, this.config.retryDelayMs));
163
+ }
164
+ }
165
+ }
166
+ return results;
167
+ }
168
+ /**
169
+ * Get health status of all settlement rails.
170
+ */
171
+ async getHealth() {
172
+ const result = {
173
+ solana: { available: false, healthy: false },
174
+ bitcoin: { available: false, healthy: false },
175
+ fiat: { available: false, healthy: false },
176
+ };
177
+ if (this.solanaAdapter) {
178
+ result.solana.available = true;
179
+ try {
180
+ const health = await this.solanaAdapter.getHealth();
181
+ result.solana.healthy = health.healthy;
182
+ result.solana.details = health;
183
+ }
184
+ catch {
185
+ result.solana.healthy = false;
186
+ }
187
+ }
188
+ if (this.bitcoinAdapter) {
189
+ result.bitcoin.available = true;
190
+ try {
191
+ const health = await this.bitcoinAdapter.getHealth();
192
+ result.bitcoin.healthy = health.healthy;
193
+ result.bitcoin.details = health;
194
+ }
195
+ catch {
196
+ result.bitcoin.healthy = false;
197
+ }
198
+ }
199
+ if (this.fiatAdapter) {
200
+ result.fiat.available = true;
201
+ try {
202
+ const health = await this.fiatAdapter.getHealth();
203
+ result.fiat.healthy = health.healthy;
204
+ }
205
+ catch {
206
+ result.fiat.healthy = false;
207
+ }
208
+ }
209
+ return result;
210
+ }
211
+ // ─────────────────────────────────────────────────────────────────────────
212
+ // Private Helpers
213
+ // ─────────────────────────────────────────────────────────────────────────
214
+ async executeSettlement(entry, blockProof) {
215
+ switch (entry.assetType) {
216
+ case "SOL":
217
+ return this.settleSolana(entry.netTransfers, blockProof);
218
+ case "BTC":
219
+ return this.settleBitcoin(entry.netTransfers, blockProof);
220
+ case "USD":
221
+ return this.settleFiat(entry.netTransfers, blockProof);
222
+ }
223
+ }
224
+ async settleSolana(transfers, blockProof) {
225
+ if (!this.solanaAdapter) {
226
+ throw new Error("Solana adapter not configured");
227
+ }
228
+ return this.solanaAdapter.executeBatchedTransfer(transfers, blockProof);
229
+ }
230
+ async settleBitcoin(transfers, blockProof) {
231
+ if (!this.bitcoinAdapter) {
232
+ throw new Error("Bitcoin adapter not configured");
233
+ }
234
+ return this.bitcoinAdapter.executeBatchedSpend(transfers, blockProof);
235
+ }
236
+ async settleFiat(transfers, blockProof) {
237
+ if (!this.fiatAdapter) {
238
+ throw new Error("Fiat adapter not configured");
239
+ }
240
+ return this.fiatAdapter.executeTransfer(transfers, blockProof);
241
+ }
242
+ getSettlementTxId(result) {
243
+ if ("signature" in result) {
244
+ return result.signature; // Solana
245
+ }
246
+ if ("txid" in result) {
247
+ return result.txid; // Bitcoin
248
+ }
249
+ return result.iso20022MessageId; // Fiat
250
+ }
251
+ }