@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.
- package/README.md +15 -2
- package/dist/aid-settlement/application/reconciler.d.ts +13 -0
- package/dist/aid-settlement/application/reconciler.d.ts.map +1 -0
- package/dist/aid-settlement/application/reconciler.js +77 -0
- package/dist/aid-settlement/domain/entities.d.ts +24 -0
- package/dist/aid-settlement/domain/entities.d.ts.map +1 -0
- package/dist/aid-settlement/domain/entities.js +1 -0
- package/dist/aid-settlement/domain/ports.d.ts +10 -0
- package/dist/aid-settlement/domain/ports.d.ts.map +1 -0
- package/dist/aid-settlement/domain/ports.js +1 -0
- package/dist/aid-settlement/index.d.ts +19 -0
- package/dist/aid-settlement/index.d.ts.map +1 -0
- package/dist/aid-settlement/index.js +23 -0
- package/dist/aid-settlement/infrastructure/in-memory-store.d.ts +12 -0
- package/dist/aid-settlement/infrastructure/in-memory-store.d.ts.map +1 -0
- package/dist/aid-settlement/infrastructure/in-memory-store.js +17 -0
- package/dist/credentialing/application/clearance-evaluator.d.ts +10 -0
- package/dist/credentialing/application/clearance-evaluator.d.ts.map +1 -0
- package/dist/credentialing/application/clearance-evaluator.js +63 -0
- package/dist/credentialing/domain/entities.d.ts +28 -0
- package/dist/credentialing/domain/entities.d.ts.map +1 -0
- package/dist/credentialing/domain/entities.js +1 -0
- package/dist/credentialing/domain/ports.d.ts +9 -0
- package/dist/credentialing/domain/ports.d.ts.map +1 -0
- package/dist/credentialing/domain/ports.js +1 -0
- package/dist/credentialing/index.d.ts +19 -0
- package/dist/credentialing/index.d.ts.map +1 -0
- package/dist/credentialing/index.js +23 -0
- package/dist/credentialing/infrastructure/in-memory-store.d.ts +11 -0
- package/dist/credentialing/infrastructure/in-memory-store.d.ts.map +1 -0
- package/dist/credentialing/infrastructure/in-memory-store.js +14 -0
- package/dist/hsm/application/asymmetric-key-service.d.ts +23 -0
- package/dist/hsm/application/asymmetric-key-service.d.ts.map +1 -0
- package/dist/hsm/application/asymmetric-key-service.js +109 -0
- package/dist/hsm/application/envelope-encryption-service.d.ts +18 -0
- package/dist/hsm/application/envelope-encryption-service.d.ts.map +1 -0
- package/dist/hsm/application/envelope-encryption-service.js +59 -0
- package/dist/hsm/application/symmetric-key-service.d.ts +34 -0
- package/dist/hsm/application/symmetric-key-service.d.ts.map +1 -0
- package/dist/hsm/application/symmetric-key-service.js +107 -0
- package/dist/hsm/domain/entities.d.ts +104 -0
- package/dist/hsm/domain/entities.d.ts.map +1 -0
- package/dist/hsm/domain/entities.js +10 -0
- package/dist/hsm/domain/ports.d.ts +20 -0
- package/dist/hsm/domain/ports.d.ts.map +1 -0
- package/dist/hsm/domain/ports.js +1 -0
- package/dist/hsm/index.d.ts +48 -0
- package/dist/hsm/index.d.ts.map +1 -0
- package/dist/hsm/index.js +97 -0
- package/dist/hsm/infrastructure/audit-log-factory.d.ts +59 -0
- package/dist/hsm/infrastructure/audit-log-factory.d.ts.map +1 -0
- package/dist/hsm/infrastructure/audit-log-factory.js +95 -0
- package/dist/hsm/infrastructure/audit-log.d.ts +8 -0
- package/dist/hsm/infrastructure/audit-log.d.ts.map +1 -0
- package/dist/hsm/infrastructure/audit-log.js +18 -0
- package/dist/hsm/infrastructure/file-audit-log.d.ts +55 -0
- package/dist/hsm/infrastructure/file-audit-log.d.ts.map +1 -0
- package/dist/hsm/infrastructure/file-audit-log.js +128 -0
- package/dist/hsm/infrastructure/key-store.d.ts +9 -0
- package/dist/hsm/infrastructure/key-store.d.ts.map +1 -0
- package/dist/hsm/infrastructure/key-store.js +12 -0
- package/dist/hsm/infrastructure/syslog-audit-log.d.ts +64 -0
- package/dist/hsm/infrastructure/syslog-audit-log.d.ts.map +1 -0
- package/dist/hsm/infrastructure/syslog-audit-log.js +167 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/integrations/besu-client/error-mapper.d.ts +9 -0
- package/dist/integrations/besu-client/error-mapper.d.ts.map +1 -0
- package/dist/integrations/besu-client/error-mapper.js +22 -0
- package/dist/integrations/besu-client/index.d.ts +65 -0
- package/dist/integrations/besu-client/index.d.ts.map +1 -0
- package/dist/integrations/besu-client/index.js +276 -0
- package/dist/integrations/besu-client/ports.d.ts +44 -0
- package/dist/integrations/besu-client/ports.d.ts.map +1 -0
- package/dist/integrations/besu-client/ports.js +1 -0
- package/dist/integrations/corda-gateway/index.d.ts +37 -0
- package/dist/integrations/corda-gateway/index.d.ts.map +1 -0
- package/dist/integrations/corda-gateway/index.js +234 -0
- package/dist/integrations/corda-gateway/ports.d.ts +33 -0
- package/dist/integrations/corda-gateway/ports.d.ts.map +1 -0
- package/dist/integrations/corda-gateway/ports.js +1 -0
- package/dist/integrations/fabric-gateway/index.d.ts +78 -0
- package/dist/integrations/fabric-gateway/index.d.ts.map +1 -0
- package/dist/integrations/fabric-gateway/index.js +214 -0
- package/dist/integrations/fabric-gateway/ports.d.ts +50 -0
- package/dist/integrations/fabric-gateway/ports.d.ts.map +1 -0
- package/dist/integrations/fabric-gateway/ports.js +1 -0
- package/dist/integrations/index.d.ts +19 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +19 -0
- package/dist/integrations/shared/env.d.ts +4 -0
- package/dist/integrations/shared/env.d.ts.map +1 -0
- package/dist/integrations/shared/env.js +24 -0
- package/dist/integrations/shared/retry.d.ts +79 -0
- package/dist/integrations/shared/retry.d.ts.map +1 -0
- package/dist/integrations/shared/retry.js +315 -0
- package/dist/mpc/adapters.d.ts +36 -0
- package/dist/mpc/adapters.d.ts.map +1 -0
- package/dist/mpc/adapters.js +46 -0
- package/dist/mpc/crypto.d.ts +2 -0
- package/dist/mpc/crypto.d.ts.map +1 -0
- package/dist/mpc/crypto.js +2 -0
- package/dist/mpc/dsa.d.ts +134 -0
- package/dist/mpc/dsa.d.ts.map +1 -0
- package/dist/mpc/dsa.js +127 -0
- package/dist/mpc/field.d.ts +127 -0
- package/dist/mpc/field.d.ts.map +1 -0
- package/dist/mpc/field.js +209 -0
- package/dist/mpc/hybrid-kem.d.ts +96 -0
- package/dist/mpc/hybrid-kem.d.ts.map +1 -0
- package/dist/mpc/hybrid-kem.js +136 -0
- package/dist/mpc/index.d.ts +135 -0
- package/dist/mpc/index.d.ts.map +1 -0
- package/dist/mpc/index.js +348 -0
- package/dist/mpc/kyber.d.ts +134 -0
- package/dist/mpc/kyber.d.ts.map +1 -0
- package/dist/mpc/kyber.js +143 -0
- package/dist/mpc/ports.d.ts +67 -0
- package/dist/mpc/ports.d.ts.map +1 -0
- package/dist/mpc/ports.js +9 -0
- package/dist/mpc/quantum.d.ts +80 -0
- package/dist/mpc/quantum.d.ts.map +1 -0
- package/dist/mpc/quantum.js +180 -0
- package/dist/p2mr/adapters.d.ts +31 -0
- package/dist/p2mr/adapters.d.ts.map +1 -0
- package/dist/p2mr/adapters.js +35 -0
- package/dist/p2mr/index.d.ts +63 -0
- package/dist/p2mr/index.d.ts.map +1 -0
- package/dist/p2mr/index.js +59 -0
- package/dist/p2mr/merkle-tree.d.ts +109 -0
- package/dist/p2mr/merkle-tree.d.ts.map +1 -0
- package/dist/p2mr/merkle-tree.js +239 -0
- package/dist/p2mr/p2mr-output.d.ts +142 -0
- package/dist/p2mr/p2mr-output.d.ts.map +1 -0
- package/dist/p2mr/p2mr-output.js +150 -0
- package/dist/p2mr/ports.d.ts +52 -0
- package/dist/p2mr/ports.d.ts.map +1 -0
- package/dist/p2mr/ports.js +9 -0
- package/dist/p2mr/script-interpreter.d.ts +92 -0
- package/dist/p2mr/script-interpreter.d.ts.map +1 -0
- package/dist/p2mr/script-interpreter.js +535 -0
- package/dist/p2mr/script-leaf.d.ts +70 -0
- package/dist/p2mr/script-leaf.d.ts.map +1 -0
- package/dist/p2mr/script-leaf.js +203 -0
- package/dist/p2mr/spend-proof.d.ts +95 -0
- package/dist/p2mr/spend-proof.d.ts.map +1 -0
- package/dist/p2mr/spend-proof.js +358 -0
- package/dist/p2mr/types.d.ts +209 -0
- package/dist/p2mr/types.d.ts.map +1 -0
- package/dist/p2mr/types.js +9 -0
- package/dist/privacy/application/view-projector.d.ts +13 -0
- package/dist/privacy/application/view-projector.d.ts.map +1 -0
- package/dist/privacy/application/view-projector.js +85 -0
- package/dist/privacy/domain/entities.d.ts +26 -0
- package/dist/privacy/domain/entities.d.ts.map +1 -0
- package/dist/privacy/domain/entities.js +1 -0
- package/dist/privacy/domain/ports.d.ts +7 -0
- package/dist/privacy/domain/ports.d.ts.map +1 -0
- package/dist/privacy/domain/ports.js +1 -0
- package/dist/privacy/index.d.ts +21 -0
- package/dist/privacy/index.d.ts.map +1 -0
- package/dist/privacy/index.js +25 -0
- package/dist/privacy/infrastructure/in-memory-store.d.ts +8 -0
- package/dist/privacy/infrastructure/in-memory-store.d.ts.map +1 -0
- package/dist/privacy/infrastructure/in-memory-store.js +7 -0
- package/dist/protocols/besu-port.d.ts +80 -0
- package/dist/protocols/besu-port.d.ts.map +1 -0
- package/dist/protocols/besu-port.js +1 -0
- package/dist/protocols/corda-port.d.ts +103 -0
- package/dist/protocols/corda-port.d.ts.map +1 -0
- package/dist/protocols/corda-port.js +9 -0
- package/dist/protocols/credentialing-port.d.ts +11 -0
- package/dist/protocols/credentialing-port.d.ts.map +1 -0
- package/dist/protocols/credentialing-port.js +1 -0
- package/dist/protocols/fabric-port.d.ts +89 -0
- package/dist/protocols/fabric-port.d.ts.map +1 -0
- package/dist/protocols/fabric-port.js +9 -0
- package/dist/protocols/index.d.ts +14 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/index.js +7 -0
- package/dist/protocols/p2mr-port.d.ts +159 -0
- package/dist/protocols/p2mr-port.d.ts.map +1 -0
- package/dist/protocols/p2mr-port.js +12 -0
- package/dist/protocols/privacy-port.d.ts +9 -0
- package/dist/protocols/privacy-port.d.ts.map +1 -0
- package/dist/protocols/privacy-port.js +1 -0
- package/dist/protocols/traceability-port.d.ts +12 -0
- package/dist/protocols/traceability-port.d.ts.map +1 -0
- package/dist/protocols/traceability-port.js +1 -0
- package/dist/shared/collection-store.d.ts +12 -0
- package/dist/shared/collection-store.d.ts.map +1 -0
- package/dist/shared/collection-store.js +26 -0
- package/dist/shared/commit.d.ts +24 -0
- package/dist/shared/commit.d.ts.map +1 -0
- package/dist/shared/commit.js +50 -0
- package/dist/shared/crypto.d.ts +2 -0
- package/dist/shared/crypto.d.ts.map +1 -0
- package/dist/shared/crypto.js +4 -0
- package/dist/shared/date.d.ts +2 -0
- package/dist/shared/date.d.ts.map +1 -0
- package/dist/shared/date.js +3 -0
- package/dist/shared/index.d.ts +9 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +11 -0
- package/dist/shared/logger.d.ts +37 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +45 -0
- package/dist/shared/store.d.ts +25 -0
- package/dist/shared/store.d.ts.map +1 -0
- package/dist/shared/store.js +18 -0
- package/dist/shared/telemetry-sdk.d.ts +26 -0
- package/dist/shared/telemetry-sdk.d.ts.map +1 -0
- package/dist/shared/telemetry-sdk.js +97 -0
- package/dist/shared/telemetry.d.ts +86 -0
- package/dist/shared/telemetry.d.ts.map +1 -0
- package/dist/shared/telemetry.js +137 -0
- package/dist/stark-settlement/application/aggregator-service.d.ts +112 -0
- package/dist/stark-settlement/application/aggregator-service.d.ts.map +1 -0
- package/dist/stark-settlement/application/aggregator-service.js +256 -0
- package/dist/stark-settlement/application/ledger-service.d.ts +114 -0
- package/dist/stark-settlement/application/ledger-service.d.ts.map +1 -0
- package/dist/stark-settlement/application/ledger-service.js +318 -0
- package/dist/stark-settlement/application/settlement-service.d.ts +104 -0
- package/dist/stark-settlement/application/settlement-service.d.ts.map +1 -0
- package/dist/stark-settlement/application/settlement-service.js +251 -0
- package/dist/stark-settlement/domain/entities.d.ts +365 -0
- package/dist/stark-settlement/domain/entities.d.ts.map +1 -0
- package/dist/stark-settlement/domain/entities.js +29 -0
- package/dist/stark-settlement/domain/ports.d.ts +485 -0
- package/dist/stark-settlement/domain/ports.d.ts.map +1 -0
- package/dist/stark-settlement/domain/ports.js +14 -0
- package/dist/stark-settlement/domain/value-objects.d.ts +268 -0
- package/dist/stark-settlement/domain/value-objects.d.ts.map +1 -0
- package/dist/stark-settlement/domain/value-objects.js +500 -0
- package/dist/stark-settlement/index.d.ts +172 -0
- package/dist/stark-settlement/index.d.ts.map +1 -0
- package/dist/stark-settlement/index.js +193 -0
- package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts +52 -0
- package/dist/stark-settlement/infrastructure/adapters/audit-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/audit-adapter.js +154 -0
- package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts +88 -0
- package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/bitcoin-adapter.js +187 -0
- package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts +59 -0
- package/dist/stark-settlement/infrastructure/adapters/clock-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/clock-adapter.js +85 -0
- package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts +60 -0
- package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/dilithium-adapter.js +104 -0
- package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts +115 -0
- package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/event-emitter-adapter.js +191 -0
- package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts +65 -0
- package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/fiat-adapter.js +207 -0
- package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts +73 -0
- package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/mock-stark-adapter.js +287 -0
- package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts +78 -0
- package/dist/stark-settlement/infrastructure/adapters/solana-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/solana-adapter.js +172 -0
- package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts +56 -0
- package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/starknet-proof-adapter.js +261 -0
- package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts +125 -0
- package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/adapters/stone-proof-adapter.js +416 -0
- package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts +68 -0
- package/dist/stark-settlement/infrastructure/persistence/ledger-store.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/persistence/ledger-store.js +238 -0
- package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts +30 -0
- package/dist/stark-settlement/infrastructure/persistence/offset-store.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/persistence/offset-store.js +57 -0
- package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts +45 -0
- package/dist/stark-settlement/infrastructure/persistence/outbox-store.d.ts.map +1 -0
- package/dist/stark-settlement/infrastructure/persistence/outbox-store.js +171 -0
- package/dist/traceability/application/recall-assessor.d.ts +13 -0
- package/dist/traceability/application/recall-assessor.d.ts.map +1 -0
- package/dist/traceability/application/recall-assessor.js +74 -0
- package/dist/traceability/domain/entities.d.ts +23 -0
- package/dist/traceability/domain/entities.d.ts.map +1 -0
- package/dist/traceability/domain/entities.js +1 -0
- package/dist/traceability/domain/ports.d.ts +23 -0
- package/dist/traceability/domain/ports.d.ts.map +1 -0
- package/dist/traceability/domain/ports.js +1 -0
- package/dist/traceability/domain/recall.d.ts +12 -0
- package/dist/traceability/domain/recall.d.ts.map +1 -0
- package/dist/traceability/domain/recall.js +1 -0
- package/dist/traceability/index.d.ts +22 -0
- package/dist/traceability/index.d.ts.map +1 -0
- package/dist/traceability/index.js +26 -0
- package/dist/traceability/infrastructure/in-memory-store.d.ts +13 -0
- package/dist/traceability/infrastructure/in-memory-store.d.ts.map +1 -0
- package/dist/traceability/infrastructure/in-memory-store.js +24 -0
- package/package.json +12 -9
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @enterprise-blockchain/stark-settlement
|
|
3
|
+
*
|
|
4
|
+
* Aggregated STARK Settlement Layer with Recursive Proof Composition
|
|
5
|
+
*
|
|
6
|
+
* A production-grade, quantum-resistant settlement system that:
|
|
7
|
+
* - Uses zk-STARK proofs for verifiable state transitions
|
|
8
|
+
* - Aggregates thousands of transactions into single block proofs
|
|
9
|
+
* - Settles to multiple external chains (Solana, Bitcoin, Fiat)
|
|
10
|
+
* - Provides post-quantum security via ML-DSA-65 signatures
|
|
11
|
+
*
|
|
12
|
+
* Architecture:
|
|
13
|
+
* - Hexagonal (ports & adapters) with no SDK imports in domain layer
|
|
14
|
+
* - 3-tier recursive proof aggregation (Base → Tier-1 → Tier-2)
|
|
15
|
+
* - Exactly-once settlement semantics via idempotency keys
|
|
16
|
+
* - Full observability with OpenTelemetry
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import {
|
|
21
|
+
* LedgerService,
|
|
22
|
+
* AggregatorService,
|
|
23
|
+
* SettlementService,
|
|
24
|
+
* createDefaultContext,
|
|
25
|
+
* } from "@enterprise-blockchain/stark-settlement";
|
|
26
|
+
*
|
|
27
|
+
* // Create services with default adapters
|
|
28
|
+
* const ctx = createDefaultContext();
|
|
29
|
+
* const ledger = new LedgerService(ctx);
|
|
30
|
+
* const aggregator = new AggregatorService(ctx);
|
|
31
|
+
* const settler = new SettlementService(ctx);
|
|
32
|
+
*
|
|
33
|
+
* // Submit a transaction
|
|
34
|
+
* const tx = await ledger.submitTransaction({
|
|
35
|
+
* type: "transfer",
|
|
36
|
+
* fromAccountId: "alice",
|
|
37
|
+
* toAccountId: "bob",
|
|
38
|
+
* assetType: "SOL",
|
|
39
|
+
* amount: 1000000000n, // 1 SOL in lamports
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Generate proofs and settle
|
|
43
|
+
* const blockProof = await aggregator.processToBlockProof();
|
|
44
|
+
* const result = await settler.settleAllRails(blockProof);
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @packageDocumentation
|
|
48
|
+
*/
|
|
49
|
+
export { ASSET_CONFIGS } from "./domain/entities.js";
|
|
50
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
51
|
+
// Value Objects
|
|
52
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
+
export { STARK_PRIME, STARK_GENERATOR, FieldElement, IdempotencyKey, ProofCommitment, StateRoot, Amount, sha256, sha256Bytes, pedersenHash, } from "./domain/value-objects.js";
|
|
54
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
+
// Infrastructure Adapters
|
|
56
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
57
|
+
// Persistence
|
|
58
|
+
export { InMemoryLedgerStore } from "./infrastructure/persistence/ledger-store.js";
|
|
59
|
+
export { InMemoryOutboxStore } from "./infrastructure/persistence/outbox-store.js";
|
|
60
|
+
export { InMemoryOffsetStore } from "./infrastructure/persistence/offset-store.js";
|
|
61
|
+
// STARK Proofs
|
|
62
|
+
export { MockStarkAdapter, FlexibleMockStarkAdapter, } from "./infrastructure/adapters/mock-stark-adapter.js";
|
|
63
|
+
// Clock
|
|
64
|
+
export { SystemClock, FixedClock, defaultClock, } from "./infrastructure/adapters/clock-adapter.js";
|
|
65
|
+
// Events
|
|
66
|
+
export { InMemoryEventEmitter, AsyncEventEmitter, defaultEventEmitter, } from "./infrastructure/adapters/event-emitter-adapter.js";
|
|
67
|
+
// Signing
|
|
68
|
+
export { DilithiumSigningAdapter, TransactionSigningAdapter, MockDilithiumAdapter, defaultDilithiumAdapter, createTransactionSigningAdapter, } from "./infrastructure/adapters/dilithium-adapter.js";
|
|
69
|
+
// Audit
|
|
70
|
+
export { InMemoryAuditLog, defaultAuditLog, } from "./infrastructure/adapters/audit-adapter.js";
|
|
71
|
+
// StarkNet
|
|
72
|
+
export { StarknetProofAdapter, createStarknetProofAdapter, } from "./infrastructure/adapters/starknet-proof-adapter.js";
|
|
73
|
+
// Stone Prover (Production)
|
|
74
|
+
export { StoneProofAdapter, createStoneProofAdapter, } from "./infrastructure/adapters/stone-proof-adapter.js";
|
|
75
|
+
// External Chains
|
|
76
|
+
export { SolanaDevnetAdapter, MockSolanaAdapter, } from "./infrastructure/adapters/solana-adapter.js";
|
|
77
|
+
export { BitcoinTestnetAdapter, MockBitcoinAdapter, } from "./infrastructure/adapters/bitcoin-adapter.js";
|
|
78
|
+
export { FiatMockAdapter, MockFiatAdapter, } from "./infrastructure/adapters/fiat-adapter.js";
|
|
79
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
// Application Services
|
|
81
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
export { LedgerService } from "./application/ledger-service.js";
|
|
83
|
+
export { AggregatorService } from "./application/aggregator-service.js";
|
|
84
|
+
export { SettlementService } from "./application/settlement-service.js";
|
|
85
|
+
import { InMemoryLedgerStore } from "./infrastructure/persistence/ledger-store.js";
|
|
86
|
+
import { InMemoryOutboxStore } from "./infrastructure/persistence/outbox-store.js";
|
|
87
|
+
import { InMemoryOffsetStore } from "./infrastructure/persistence/offset-store.js";
|
|
88
|
+
import { FlexibleMockStarkAdapter } from "./infrastructure/adapters/mock-stark-adapter.js";
|
|
89
|
+
import { StoneProofAdapter } from "./infrastructure/adapters/stone-proof-adapter.js";
|
|
90
|
+
import { SystemClock } from "./infrastructure/adapters/clock-adapter.js";
|
|
91
|
+
import { InMemoryEventEmitter } from "./infrastructure/adapters/event-emitter-adapter.js";
|
|
92
|
+
import { DilithiumSigningAdapter, TransactionSigningAdapter, } from "./infrastructure/adapters/dilithium-adapter.js";
|
|
93
|
+
import { InMemoryAuditLog } from "./infrastructure/adapters/audit-adapter.js";
|
|
94
|
+
/**
|
|
95
|
+
* Create a settlement context with default or custom adapters.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* // Default context (all in-memory, mock STARK)
|
|
100
|
+
* const ctx = createDefaultContext();
|
|
101
|
+
*
|
|
102
|
+
* // Custom batch sizes for demos
|
|
103
|
+
* const demoCtx = createDefaultContext({
|
|
104
|
+
* tier1BatchSize: 4,
|
|
105
|
+
* tier2BatchSize: 2,
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* // Custom adapters (clock must be passed to StarknetProofAdapter)
|
|
109
|
+
* const clock = new SystemClock();
|
|
110
|
+
* const prodCtx = createDefaultContext({
|
|
111
|
+
* clock,
|
|
112
|
+
* starkProver: new StarknetProofAdapter(clock),
|
|
113
|
+
* ledgerStore: new PostgresLedgerStore(connectionString),
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export function createDefaultContext(options = {}) {
|
|
118
|
+
const clock = options.clock ?? new SystemClock();
|
|
119
|
+
const ledgerStore = options.ledgerStore ?? new InMemoryLedgerStore();
|
|
120
|
+
const outboxStore = options.outboxStore ?? new InMemoryOutboxStore();
|
|
121
|
+
const offsetStore = options.offsetStore ?? new InMemoryOffsetStore();
|
|
122
|
+
const dilithium = options.dilithium ?? new DilithiumSigningAdapter();
|
|
123
|
+
const transactionSigning = options.transactionSigning ?? new TransactionSigningAdapter(dilithium);
|
|
124
|
+
const auditLog = options.auditLog ?? new InMemoryAuditLog();
|
|
125
|
+
const events = options.events ?? new InMemoryEventEmitter();
|
|
126
|
+
// Default to small batch sizes for demos (full: 128/64)
|
|
127
|
+
const tier1BatchSize = options.tier1BatchSize ?? 8;
|
|
128
|
+
const tier2BatchSize = options.tier2BatchSize ?? 4;
|
|
129
|
+
const starkProver = options.starkProver ??
|
|
130
|
+
new FlexibleMockStarkAdapter(clock, {
|
|
131
|
+
tier1BatchSize,
|
|
132
|
+
tier2BatchSize,
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
clock,
|
|
136
|
+
ledgerStore,
|
|
137
|
+
outboxStore,
|
|
138
|
+
offsetStore,
|
|
139
|
+
starkProver,
|
|
140
|
+
dilithium,
|
|
141
|
+
transactionSigning,
|
|
142
|
+
auditLog,
|
|
143
|
+
events,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create a context for production with full batch sizes.
|
|
148
|
+
*
|
|
149
|
+
* By default, uses the StoneProofAdapter for real STARK proof generation.
|
|
150
|
+
* Set useMockProver: true to use the mock adapter for testing without Docker.
|
|
151
|
+
*
|
|
152
|
+
* Requires 128 * 64 = 8,192 transactions per block proof.
|
|
153
|
+
*/
|
|
154
|
+
export function createProductionContext(options = {}) {
|
|
155
|
+
const clock = options.clock ?? new SystemClock();
|
|
156
|
+
// Use Stone prover by default, mock if explicitly requested
|
|
157
|
+
let starkProver = options.starkProver;
|
|
158
|
+
if (!starkProver) {
|
|
159
|
+
if (options.useMockProver) {
|
|
160
|
+
starkProver = new FlexibleMockStarkAdapter(clock, {
|
|
161
|
+
tier1BatchSize: 128,
|
|
162
|
+
tier2BatchSize: 64,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
starkProver = new StoneProofAdapter(clock, {
|
|
167
|
+
proverEndpoint: options.proverEndpoint ?? "localhost:10000",
|
|
168
|
+
cairoArtifactsPath: options.cairoArtifactsPath ?? "./cairo/artifacts",
|
|
169
|
+
tier1BatchSize: 128,
|
|
170
|
+
tier2BatchSize: 64,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return createDefaultContext({
|
|
175
|
+
...options,
|
|
176
|
+
clock,
|
|
177
|
+
starkProver,
|
|
178
|
+
tier1BatchSize: 128,
|
|
179
|
+
tier2BatchSize: 64,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Create a context for testing with minimal batch sizes.
|
|
184
|
+
*
|
|
185
|
+
* Requires only 2 * 2 = 4 transactions per block proof.
|
|
186
|
+
*/
|
|
187
|
+
export function createTestContext(options = {}) {
|
|
188
|
+
return createDefaultContext({
|
|
189
|
+
...options,
|
|
190
|
+
tier1BatchSize: 2,
|
|
191
|
+
tier2BatchSize: 2,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements AuditPort for compliance logging.
|
|
5
|
+
* Maintains a cryptographically chained audit log.
|
|
6
|
+
*
|
|
7
|
+
* @see domain/ports.ts for AuditPort interface
|
|
8
|
+
*/
|
|
9
|
+
import type { AuditRecord } from "../../domain/entities.js";
|
|
10
|
+
import type { AuditPort } from "../../domain/ports.js";
|
|
11
|
+
/**
|
|
12
|
+
* In-memory audit log with chain integrity verification.
|
|
13
|
+
*/
|
|
14
|
+
export declare class InMemoryAuditLog implements AuditPort {
|
|
15
|
+
private readonly records;
|
|
16
|
+
private readonly recordsById;
|
|
17
|
+
private readonly recordsByEntity;
|
|
18
|
+
private lastHash;
|
|
19
|
+
append(record: Omit<AuditRecord, "recordId" | "previousHash" | "recordHash">): Promise<AuditRecord>;
|
|
20
|
+
getRecordsForEntity(entityId: string): Promise<readonly AuditRecord[]>;
|
|
21
|
+
verifyChainIntegrity(): Promise<{
|
|
22
|
+
valid: boolean;
|
|
23
|
+
lastValidRecord: string | null;
|
|
24
|
+
errorMessage: string | null;
|
|
25
|
+
}>;
|
|
26
|
+
getLatestRecord(): Promise<AuditRecord | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Get all records (for debugging/export).
|
|
29
|
+
*/
|
|
30
|
+
getAllRecords(): readonly AuditRecord[];
|
|
31
|
+
/**
|
|
32
|
+
* Get the total number of records.
|
|
33
|
+
*/
|
|
34
|
+
getRecordCount(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get records by event type.
|
|
37
|
+
*/
|
|
38
|
+
getRecordsByEventType(eventType: AuditRecord["eventType"]): readonly AuditRecord[];
|
|
39
|
+
/**
|
|
40
|
+
* Export audit log as JSON (for compliance reporting).
|
|
41
|
+
*/
|
|
42
|
+
exportAsJson(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Clear all records (for testing).
|
|
45
|
+
*/
|
|
46
|
+
clear(): void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Default audit log instance.
|
|
50
|
+
*/
|
|
51
|
+
export declare const defaultAuditLog: InMemoryAuditLog;
|
|
52
|
+
//# sourceMappingURL=audit-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-adapter.d.ts","sourceRoot":"","sources":["../../../../src/stark-settlement/infrastructure/adapters/audit-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;GAEG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+B;IAC/D,OAAO,CAAC,QAAQ,CAAkB;IAE5B,MAAM,CACV,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC,GACpE,OAAO,CAAC,WAAW,CAAC;IAoCjB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC;IAetE,oBAAoB,IAAI,OAAO,CAAC;QACpC,KAAK,EAAE,OAAO,CAAC;QACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,CAAC;IAoDI,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IASpD;;OAEG;IACH,aAAa,IAAI,SAAS,WAAW,EAAE;IAIvC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,qBAAqB,CACnB,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,GAClC,SAAS,WAAW,EAAE;IAIzB;;OAEG;IACH,YAAY,IAAI,MAAM;IAatB;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements AuditPort for compliance logging.
|
|
5
|
+
* Maintains a cryptographically chained audit log.
|
|
6
|
+
*
|
|
7
|
+
* @see domain/ports.ts for AuditPort interface
|
|
8
|
+
*/
|
|
9
|
+
/* eslint-disable @typescript-eslint/require-await */
|
|
10
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
11
|
+
/**
|
|
12
|
+
* In-memory audit log with chain integrity verification.
|
|
13
|
+
*/
|
|
14
|
+
export class InMemoryAuditLog {
|
|
15
|
+
records = [];
|
|
16
|
+
recordsById = new Map(); // recordId -> AuditRecord (O(1) lookup)
|
|
17
|
+
recordsByEntity = new Map(); // entityId -> recordIds
|
|
18
|
+
lastHash = "0".repeat(64); // Genesis hash
|
|
19
|
+
async append(record) {
|
|
20
|
+
const recordId = randomUUID();
|
|
21
|
+
const previousHash = this.lastHash;
|
|
22
|
+
// Compute record hash (includes previous hash for chain integrity)
|
|
23
|
+
// IMPORTANT: Use explicit property order for deterministic hashing
|
|
24
|
+
const hashInput = JSON.stringify({
|
|
25
|
+
recordId,
|
|
26
|
+
eventType: record.eventType,
|
|
27
|
+
entityId: record.entityId,
|
|
28
|
+
entityType: record.entityType,
|
|
29
|
+
actor: record.actor,
|
|
30
|
+
timestamp: record.timestamp,
|
|
31
|
+
data: record.data,
|
|
32
|
+
previousHash,
|
|
33
|
+
});
|
|
34
|
+
const recordHash = createHash("sha256").update(hashInput).digest("hex");
|
|
35
|
+
const fullRecord = {
|
|
36
|
+
recordId,
|
|
37
|
+
...record,
|
|
38
|
+
previousHash,
|
|
39
|
+
recordHash,
|
|
40
|
+
};
|
|
41
|
+
this.records.push(fullRecord);
|
|
42
|
+
this.recordsById.set(recordId, fullRecord); // O(1) lookup index
|
|
43
|
+
this.lastHash = recordHash;
|
|
44
|
+
// Index by entity
|
|
45
|
+
const existingRecordIds = this.recordsByEntity.get(record.entityId) ?? [];
|
|
46
|
+
this.recordsByEntity.set(record.entityId, [...existingRecordIds, recordId]);
|
|
47
|
+
return fullRecord;
|
|
48
|
+
}
|
|
49
|
+
async getRecordsForEntity(entityId) {
|
|
50
|
+
const recordIds = this.recordsByEntity.get(entityId) ?? [];
|
|
51
|
+
const records = [];
|
|
52
|
+
// Use recordsById Map for O(1) lookup instead of O(n) find()
|
|
53
|
+
for (const recordId of recordIds) {
|
|
54
|
+
const record = this.recordsById.get(recordId);
|
|
55
|
+
if (record) {
|
|
56
|
+
records.push(record);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return records.sort((a, b) => a.timestamp - b.timestamp);
|
|
60
|
+
}
|
|
61
|
+
async verifyChainIntegrity() {
|
|
62
|
+
if (this.records.length === 0) {
|
|
63
|
+
return { valid: true, lastValidRecord: null, errorMessage: null };
|
|
64
|
+
}
|
|
65
|
+
let expectedPreviousHash = "0".repeat(64); // Genesis hash
|
|
66
|
+
let lastValidRecordId = null;
|
|
67
|
+
for (let i = 0; i < this.records.length; i++) {
|
|
68
|
+
const record = this.records[i];
|
|
69
|
+
// Check previous hash
|
|
70
|
+
if (record.previousHash !== expectedPreviousHash) {
|
|
71
|
+
return {
|
|
72
|
+
valid: false,
|
|
73
|
+
lastValidRecord: lastValidRecordId,
|
|
74
|
+
errorMessage: `Chain broken at record ${record.recordId}: expected previousHash ${expectedPreviousHash}, got ${record.previousHash}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Verify record hash
|
|
78
|
+
const hashInput = JSON.stringify({
|
|
79
|
+
recordId: record.recordId,
|
|
80
|
+
eventType: record.eventType,
|
|
81
|
+
entityId: record.entityId,
|
|
82
|
+
entityType: record.entityType,
|
|
83
|
+
actor: record.actor,
|
|
84
|
+
timestamp: record.timestamp,
|
|
85
|
+
data: record.data,
|
|
86
|
+
previousHash: record.previousHash,
|
|
87
|
+
});
|
|
88
|
+
const computedHash = createHash("sha256").update(hashInput).digest("hex");
|
|
89
|
+
if (record.recordHash !== computedHash) {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
lastValidRecord: lastValidRecordId,
|
|
93
|
+
errorMessage: `Hash mismatch at record ${record.recordId}: expected ${computedHash}, got ${record.recordHash}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
lastValidRecordId = record.recordId;
|
|
97
|
+
expectedPreviousHash = record.recordHash;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
valid: true,
|
|
101
|
+
lastValidRecord: lastValidRecordId,
|
|
102
|
+
errorMessage: null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async getLatestRecord() {
|
|
106
|
+
if (this.records.length === 0) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return this.records[this.records.length - 1] ?? null;
|
|
110
|
+
}
|
|
111
|
+
// ─── Utilities ──────────────────────────────────────────────────────────
|
|
112
|
+
/**
|
|
113
|
+
* Get all records (for debugging/export).
|
|
114
|
+
*/
|
|
115
|
+
getAllRecords() {
|
|
116
|
+
return [...this.records];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the total number of records.
|
|
120
|
+
*/
|
|
121
|
+
getRecordCount() {
|
|
122
|
+
return this.records.length;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get records by event type.
|
|
126
|
+
*/
|
|
127
|
+
getRecordsByEventType(eventType) {
|
|
128
|
+
return this.records.filter((r) => r.eventType === eventType);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Export audit log as JSON (for compliance reporting).
|
|
132
|
+
*/
|
|
133
|
+
exportAsJson() {
|
|
134
|
+
return JSON.stringify({
|
|
135
|
+
exportedAt: new Date().toISOString(),
|
|
136
|
+
recordCount: this.records.length,
|
|
137
|
+
chainIntegrity: "pending-verification",
|
|
138
|
+
records: this.records,
|
|
139
|
+
}, null, 2);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Clear all records (for testing).
|
|
143
|
+
*/
|
|
144
|
+
clear() {
|
|
145
|
+
this.records.length = 0;
|
|
146
|
+
this.recordsById.clear();
|
|
147
|
+
this.recordsByEntity.clear();
|
|
148
|
+
this.lastHash = "0".repeat(64);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Default audit log instance.
|
|
153
|
+
*/
|
|
154
|
+
export const defaultAuditLog = new InMemoryAuditLog();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bitcoin Settlement Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements BitcoinSettlementPort for Bitcoin testnet settlement.
|
|
5
|
+
* Uses PSBT (Partially Signed Bitcoin Transactions) for batched UTXO spends.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Batched outputs in single transaction
|
|
9
|
+
* - PSBT format for multi-party signing
|
|
10
|
+
* - OP_RETURN for proof commitment
|
|
11
|
+
* - Address watching for deposit detection
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki for PSBT
|
|
14
|
+
* @see domain/ports.ts for BitcoinSettlementPort interface
|
|
15
|
+
*/
|
|
16
|
+
import type { NetTransfer, Tier2BlockProof, BitcoinSettlementResult, DepositEvent } from "../../domain/entities.js";
|
|
17
|
+
import type { BitcoinSettlementPort, ClockPort } from "../../domain/ports.js";
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for Bitcoin adapter.
|
|
20
|
+
*/
|
|
21
|
+
export interface BitcoinAdapterConfig {
|
|
22
|
+
/** API endpoint (default: Blockstream testnet) */
|
|
23
|
+
apiUrl?: string;
|
|
24
|
+
/** Network (testnet or mainnet) */
|
|
25
|
+
network?: "testnet" | "mainnet";
|
|
26
|
+
/** Fee rate in sat/vB (default: 10) */
|
|
27
|
+
feeRate?: number;
|
|
28
|
+
/** Confirmation threshold for deposits (default: 1) */
|
|
29
|
+
confirmationThreshold?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Bitcoin testnet adapter for settlement operations.
|
|
33
|
+
*/
|
|
34
|
+
export declare class BitcoinTestnetAdapter implements BitcoinSettlementPort {
|
|
35
|
+
private readonly clock;
|
|
36
|
+
private readonly config;
|
|
37
|
+
private readonly watchedAddresses;
|
|
38
|
+
private watchCounter;
|
|
39
|
+
constructor(clock: ClockPort, config?: BitcoinAdapterConfig);
|
|
40
|
+
executeBatchedSpend(transfers: readonly NetTransfer[], blockProof: Tier2BlockProof): Promise<BitcoinSettlementResult>;
|
|
41
|
+
watchAddresses(addresses: readonly string[], callback: (deposit: DepositEvent) => void): Promise<{
|
|
42
|
+
unwatch: () => void;
|
|
43
|
+
}>;
|
|
44
|
+
getHealth(): Promise<{
|
|
45
|
+
healthy: boolean;
|
|
46
|
+
blockHeight: number;
|
|
47
|
+
}>;
|
|
48
|
+
getUtxos(address: string): Promise<readonly {
|
|
49
|
+
txid: string;
|
|
50
|
+
vout: number;
|
|
51
|
+
value: bigint;
|
|
52
|
+
confirmed: boolean;
|
|
53
|
+
}[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Simulate a deposit event (for testing).
|
|
56
|
+
*/
|
|
57
|
+
simulateDeposit(address: string, amount: bigint, txid: string, confirmations: number): void;
|
|
58
|
+
private generateMockTxid;
|
|
59
|
+
private generateMockPsbt;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Mock Bitcoin adapter for testing without network.
|
|
63
|
+
*/
|
|
64
|
+
export declare class MockBitcoinAdapter implements BitcoinSettlementPort {
|
|
65
|
+
private readonly clock;
|
|
66
|
+
private blockHeight;
|
|
67
|
+
readonly settlements: Array<{
|
|
68
|
+
transfers: readonly NetTransfer[];
|
|
69
|
+
blockProofId: string;
|
|
70
|
+
result: BitcoinSettlementResult;
|
|
71
|
+
}>;
|
|
72
|
+
constructor(clock: ClockPort);
|
|
73
|
+
executeBatchedSpend(transfers: readonly NetTransfer[], blockProof: Tier2BlockProof): Promise<BitcoinSettlementResult>;
|
|
74
|
+
watchAddresses(_addresses: readonly string[], _callback: (deposit: DepositEvent) => void): Promise<{
|
|
75
|
+
unwatch: () => void;
|
|
76
|
+
}>;
|
|
77
|
+
getHealth(): Promise<{
|
|
78
|
+
healthy: boolean;
|
|
79
|
+
blockHeight: number;
|
|
80
|
+
}>;
|
|
81
|
+
getUtxos(_address: string): Promise<readonly {
|
|
82
|
+
txid: string;
|
|
83
|
+
vout: number;
|
|
84
|
+
value: bigint;
|
|
85
|
+
confirmed: boolean;
|
|
86
|
+
}[]>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=bitcoin-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitcoin-adapter.d.ts","sourceRoot":"","sources":["../../../../src/stark-settlement/infrastructure/adapters/bitcoin-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bitcoin Settlement Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements BitcoinSettlementPort for Bitcoin testnet settlement.
|
|
5
|
+
* Uses PSBT (Partially Signed Bitcoin Transactions) for batched UTXO spends.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Batched outputs in single transaction
|
|
9
|
+
* - PSBT format for multi-party signing
|
|
10
|
+
* - OP_RETURN for proof commitment
|
|
11
|
+
* - Address watching for deposit detection
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki for PSBT
|
|
14
|
+
* @see domain/ports.ts for BitcoinSettlementPort interface
|
|
15
|
+
*/
|
|
16
|
+
/* eslint-disable @typescript-eslint/require-await, @typescript-eslint/no-unused-vars */
|
|
17
|
+
import { createHash } from "node:crypto";
|
|
18
|
+
import { ProofCommitment } from "../../domain/value-objects.js";
|
|
19
|
+
/**
|
|
20
|
+
* Bitcoin testnet adapter for settlement operations.
|
|
21
|
+
*/
|
|
22
|
+
export class BitcoinTestnetAdapter {
|
|
23
|
+
clock;
|
|
24
|
+
config;
|
|
25
|
+
watchedAddresses = new Map();
|
|
26
|
+
watchCounter = 0;
|
|
27
|
+
constructor(clock, config) {
|
|
28
|
+
this.clock = clock;
|
|
29
|
+
this.config = {
|
|
30
|
+
apiUrl: config?.apiUrl ?? "https://blockstream.info/testnet/api",
|
|
31
|
+
network: config?.network ?? "testnet",
|
|
32
|
+
feeRate: config?.feeRate ?? 10,
|
|
33
|
+
confirmationThreshold: config?.confirmationThreshold ?? 1,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async executeBatchedSpend(transfers, blockProof) {
|
|
37
|
+
// Compute proof commitment for OP_RETURN
|
|
38
|
+
const proofCommitment = ProofCommitment.create(blockProof.blockProofId, blockProof.finalProof, blockProof.publicInputs);
|
|
39
|
+
// In production, this would:
|
|
40
|
+
// 1. Gather UTXOs from all source addresses
|
|
41
|
+
// 2. Build PSBT with outputs for each transfer
|
|
42
|
+
// 3. Add OP_RETURN output with proof commitment
|
|
43
|
+
// 4. Sign all inputs
|
|
44
|
+
// 5. Broadcast via API
|
|
45
|
+
// Simulate transaction
|
|
46
|
+
const txid = this.generateMockTxid(proofCommitment.toString());
|
|
47
|
+
const psbtBase64 = this.generateMockPsbt(transfers, proofCommitment.toString());
|
|
48
|
+
// Estimate fee (simplified)
|
|
49
|
+
const inputSize = 148n; // P2PKH input
|
|
50
|
+
const outputSize = 34n; // P2PKH output
|
|
51
|
+
const opReturnSize = 43n; // OP_RETURN with 32 bytes
|
|
52
|
+
const txOverhead = 10n;
|
|
53
|
+
const estimatedSize = txOverhead +
|
|
54
|
+
inputSize * BigInt(transfers.length) +
|
|
55
|
+
outputSize * BigInt(transfers.length) +
|
|
56
|
+
opReturnSize;
|
|
57
|
+
const fee = estimatedSize * BigInt(this.config.feeRate);
|
|
58
|
+
// Mock UTXOs spent
|
|
59
|
+
const utxosSpent = transfers.map((t, i) => `${this.generateMockTxid(t.externalAddress)}:${i}`);
|
|
60
|
+
console.log(`[Bitcoin] Settled ${transfers.length} transfers`);
|
|
61
|
+
console.log(`[Bitcoin] Txid: ${txid}`);
|
|
62
|
+
console.log(`[Bitcoin] OP_RETURN: ${proofCommitment.toString().slice(0, 40)}...`);
|
|
63
|
+
return {
|
|
64
|
+
txid,
|
|
65
|
+
psbtBase64,
|
|
66
|
+
utxosSpent,
|
|
67
|
+
fee,
|
|
68
|
+
opReturnData: proofCommitment.toString(),
|
|
69
|
+
confirmations: 0, // Just broadcast
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async watchAddresses(addresses, callback) {
|
|
73
|
+
const watchId = `watch-${this.watchCounter++}`;
|
|
74
|
+
for (const address of addresses) {
|
|
75
|
+
this.watchedAddresses.set(`${watchId}:${address}`, { callback });
|
|
76
|
+
}
|
|
77
|
+
console.log(`[Bitcoin] Watching ${addresses.length} addresses for deposits`);
|
|
78
|
+
return {
|
|
79
|
+
unwatch: () => {
|
|
80
|
+
for (const address of addresses) {
|
|
81
|
+
this.watchedAddresses.delete(`${watchId}:${address}`);
|
|
82
|
+
}
|
|
83
|
+
console.log(`[Bitcoin] Stopped watching addresses (${watchId})`);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async getHealth() {
|
|
88
|
+
// In production, this would call /blocks/tip/height
|
|
89
|
+
const blockHeight = Math.floor(Date.now() / 600000) + 2500000; // ~10 min blocks
|
|
90
|
+
return { healthy: true, blockHeight };
|
|
91
|
+
}
|
|
92
|
+
async getUtxos(address) {
|
|
93
|
+
// In production, this would call /address/{address}/utxo
|
|
94
|
+
// Return mock UTXOs for testing
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
txid: this.generateMockTxid(address),
|
|
98
|
+
vout: 0,
|
|
99
|
+
value: 100000n, // 0.001 BTC
|
|
100
|
+
confirmed: true,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
105
|
+
// Test Helpers
|
|
106
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* Simulate a deposit event (for testing).
|
|
109
|
+
*/
|
|
110
|
+
simulateDeposit(address, amount, txid, confirmations) {
|
|
111
|
+
const event = {
|
|
112
|
+
eventId: this.clock.uuid(),
|
|
113
|
+
assetType: "BTC",
|
|
114
|
+
externalAddress: address,
|
|
115
|
+
amount,
|
|
116
|
+
externalTxId: txid,
|
|
117
|
+
confirmations,
|
|
118
|
+
detectedAt: this.clock.now(),
|
|
119
|
+
mirrored: false,
|
|
120
|
+
};
|
|
121
|
+
for (const [key, { callback }] of this.watchedAddresses) {
|
|
122
|
+
if (key.endsWith(`:${address}`)) {
|
|
123
|
+
callback(event);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
128
|
+
// Private Helpers
|
|
129
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
130
|
+
generateMockTxid(seed) {
|
|
131
|
+
return createHash("sha256").update(seed).digest("hex");
|
|
132
|
+
}
|
|
133
|
+
generateMockPsbt(transfers, proofCommitment) {
|
|
134
|
+
// Generate a mock PSBT structure (simplified)
|
|
135
|
+
const psbtData = {
|
|
136
|
+
inputs: transfers.map((t) => ({
|
|
137
|
+
txid: this.generateMockTxid(t.externalAddress),
|
|
138
|
+
vout: 0,
|
|
139
|
+
})),
|
|
140
|
+
outputs: [
|
|
141
|
+
...transfers.map((t) => ({
|
|
142
|
+
address: t.externalAddress,
|
|
143
|
+
value: t.netAmount,
|
|
144
|
+
})),
|
|
145
|
+
{ opReturn: proofCommitment },
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
return Buffer.from(JSON.stringify(psbtData)).toString("base64");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Mock Bitcoin adapter for testing without network.
|
|
153
|
+
*/
|
|
154
|
+
export class MockBitcoinAdapter {
|
|
155
|
+
clock;
|
|
156
|
+
blockHeight = 2500000;
|
|
157
|
+
settlements = [];
|
|
158
|
+
constructor(clock) {
|
|
159
|
+
this.clock = clock;
|
|
160
|
+
}
|
|
161
|
+
async executeBatchedSpend(transfers, blockProof) {
|
|
162
|
+
this.blockHeight++;
|
|
163
|
+
const result = {
|
|
164
|
+
txid: `mock-txid-${this.blockHeight}`,
|
|
165
|
+
psbtBase64: "mock-psbt-base64",
|
|
166
|
+
utxosSpent: transfers.map((_, i) => `mock-utxo:${i}`),
|
|
167
|
+
fee: 1000n + BigInt(transfers.length) * 148n * 10n,
|
|
168
|
+
opReturnData: blockProof.stateRoot,
|
|
169
|
+
confirmations: 0,
|
|
170
|
+
};
|
|
171
|
+
this.settlements.push({
|
|
172
|
+
transfers,
|
|
173
|
+
blockProofId: blockProof.blockProofId,
|
|
174
|
+
result,
|
|
175
|
+
});
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
async watchAddresses(_addresses, _callback) {
|
|
179
|
+
return { unwatch: () => { } };
|
|
180
|
+
}
|
|
181
|
+
async getHealth() {
|
|
182
|
+
return { healthy: true, blockHeight: this.blockHeight };
|
|
183
|
+
}
|
|
184
|
+
async getUtxos(_address) {
|
|
185
|
+
return [{ txid: "mock-utxo", vout: 0, value: 100000n, confirmed: true }];
|
|
186
|
+
}
|
|
187
|
+
}
|