@toon-protocol/connector 1.7.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/LICENSE +21 -0
- package/README.md +421 -0
- package/dist/btp/btp-claim-types.d.ts +30 -0
- package/dist/btp/btp-claim-types.d.ts.map +1 -0
- package/dist/btp/btp-claim-types.js +103 -0
- package/dist/btp/btp-claim-types.js.map +1 -0
- package/dist/btp/btp-client-manager.d.ts +27 -0
- package/dist/btp/btp-client-manager.d.ts.map +1 -0
- package/dist/btp/btp-client-manager.js +138 -0
- package/dist/btp/btp-client-manager.js.map +1 -0
- package/dist/btp/btp-client.d.ts +55 -0
- package/dist/btp/btp-client.d.ts.map +1 -0
- package/dist/btp/btp-client.js +474 -0
- package/dist/btp/btp-client.js.map +1 -0
- package/dist/btp/btp-message-parser.d.ts +4 -0
- package/dist/btp/btp-message-parser.d.ts.map +1 -0
- package/dist/btp/btp-message-parser.js +211 -0
- package/dist/btp/btp-message-parser.js.map +1 -0
- package/dist/btp/btp-server.d.ts +30 -0
- package/dist/btp/btp-server.d.ts.map +1 -0
- package/dist/btp/btp-server.js +458 -0
- package/dist/btp/btp-server.js.map +1 -0
- package/dist/btp/btp-types.d.ts +43 -0
- package/dist/btp/btp-types.d.ts.map +1 -0
- package/dist/btp/btp-types.js +44 -0
- package/dist/btp/btp-types.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +175 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/onboarding-wizard.d.ts +7 -0
- package/dist/cli/onboarding-wizard.d.ts.map +1 -0
- package/dist/cli/onboarding-wizard.js +257 -0
- package/dist/cli/onboarding-wizard.js.map +1 -0
- package/dist/cli/types.d.ts +38 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +3 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/config/aptos-env-validator.d.ts +8 -0
- package/dist/config/aptos-env-validator.d.ts.map +1 -0
- package/dist/config/aptos-env-validator.js +25 -0
- package/dist/config/aptos-env-validator.js.map +1 -0
- package/dist/config/config-loader.d.ts +20 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +269 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/environment-validator.d.ts +4 -0
- package/dist/config/environment-validator.d.ts.map +1 -0
- package/dist/config/environment-validator.js +239 -0
- package/dist/config/environment-validator.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/key-manager-config.d.ts +7 -0
- package/dist/config/key-manager-config.d.ts.map +1 -0
- package/dist/config/key-manager-config.js +209 -0
- package/dist/config/key-manager-config.js.map +1 -0
- package/dist/config/topology-validator.d.ts +14 -0
- package/dist/config/topology-validator.d.ts.map +1 -0
- package/dist/config/topology-validator.js +142 -0
- package/dist/config/topology-validator.js.map +1 -0
- package/dist/config/types.d.ts +210 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +10 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/connector-node.d.ts +79 -0
- package/dist/core/connector-node.d.ts.map +1 -0
- package/dist/core/connector-node.js +1036 -0
- package/dist/core/connector-node.js.map +1 -0
- package/dist/core/local-delivery-client.d.ts +16 -0
- package/dist/core/local-delivery-client.d.ts.map +1 -0
- package/dist/core/local-delivery-client.js +176 -0
- package/dist/core/local-delivery-client.js.map +1 -0
- package/dist/core/packet-handler.d.ts +45 -0
- package/dist/core/packet-handler.d.ts.map +1 -0
- package/dist/core/packet-handler.js +606 -0
- package/dist/core/packet-handler.js.map +1 -0
- package/dist/core/payment-handler.d.ts +27 -0
- package/dist/core/payment-handler.d.ts.map +1 -0
- package/dist/core/payment-handler.js +115 -0
- package/dist/core/payment-handler.js.map +1 -0
- package/dist/discovery/index.d.ts +3 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +6 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/peer-discovery-service.d.ts +29 -0
- package/dist/discovery/peer-discovery-service.d.ts.map +1 -0
- package/dist/discovery/peer-discovery-service.js +230 -0
- package/dist/discovery/peer-discovery-service.js.map +1 -0
- package/dist/discovery/types.d.ts +38 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +3 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/encoding/oer-parser.d.ts +39 -0
- package/dist/encoding/oer-parser.d.ts.map +1 -0
- package/dist/encoding/oer-parser.js +154 -0
- package/dist/encoding/oer-parser.js.map +1 -0
- package/dist/explorer-ui/assets/EventDetailPanel-CnSaMk3V.js +6 -0
- package/dist/explorer-ui/assets/FilterBar-BEmAzBku.js +26 -0
- package/dist/explorer-ui/assets/chevron-right-BUT9VhYe.js +11 -0
- package/dist/explorer-ui/assets/index-BZ2INVgy.js +360 -0
- package/dist/explorer-ui/assets/index-Cemh6svI.css +1 -0
- package/dist/explorer-ui/index.html +14 -0
- package/dist/explorer-ui/vite.svg +1 -0
- package/dist/facilitator/index.d.ts +2 -0
- package/dist/facilitator/index.d.ts.map +1 -0
- package/dist/facilitator/index.js +7 -0
- package/dist/facilitator/index.js.map +1 -0
- package/dist/facilitator/spsp-client.d.ts +18 -0
- package/dist/facilitator/spsp-client.d.ts.map +1 -0
- package/dist/facilitator/spsp-client.js +95 -0
- package/dist/facilitator/spsp-client.js.map +1 -0
- package/dist/http/admin-api.d.ts +123 -0
- package/dist/http/admin-api.d.ts.map +1 -0
- package/dist/http/admin-api.js +1057 -0
- package/dist/http/admin-api.js.map +1 -0
- package/dist/http/admin-server.d.ts +41 -0
- package/dist/http/admin-server.d.ts.map +1 -0
- package/dist/http/admin-server.js +156 -0
- package/dist/http/admin-server.js.map +1 -0
- package/dist/http/health-server.d.ts +22 -0
- package/dist/http/health-server.d.ts.map +1 -0
- package/dist/http/health-server.js +192 -0
- package/dist/http/health-server.js.map +1 -0
- package/dist/http/ilp-send-handler.d.ts +19 -0
- package/dist/http/ilp-send-handler.d.ts.map +1 -0
- package/dist/http/ilp-send-handler.js +162 -0
- package/dist/http/ilp-send-handler.js.map +1 -0
- package/dist/http/types.d.ts +39 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/http/types.js +3 -0
- package/dist/http/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +22 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +41 -0
- package/dist/lib.js.map +1 -0
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +79 -0
- package/dist/main.js.map +1 -0
- package/dist/routing/packet-processor.d.ts +36 -0
- package/dist/routing/packet-processor.d.ts.map +1 -0
- package/dist/routing/packet-processor.js +112 -0
- package/dist/routing/packet-processor.js.map +1 -0
- package/dist/routing/packet-worker.d.ts +10 -0
- package/dist/routing/packet-worker.d.ts.map +1 -0
- package/dist/routing/packet-worker.js +34 -0
- package/dist/routing/packet-worker.js.map +1 -0
- package/dist/routing/routing-table.d.ts +15 -0
- package/dist/routing/routing-table.d.ts.map +1 -0
- package/dist/routing/routing-table.js +63 -0
- package/dist/routing/routing-table.js.map +1 -0
- package/dist/routing/worker-pool.d.ts +43 -0
- package/dist/routing/worker-pool.d.ts.map +1 -0
- package/dist/routing/worker-pool.js +228 -0
- package/dist/routing/worker-pool.js.map +1 -0
- package/dist/security/alert-notifier.d.ts +34 -0
- package/dist/security/alert-notifier.d.ts.map +1 -0
- package/dist/security/alert-notifier.js +136 -0
- package/dist/security/alert-notifier.js.map +1 -0
- package/dist/security/audit-logger.d.ts +34 -0
- package/dist/security/audit-logger.d.ts.map +1 -0
- package/dist/security/audit-logger.js +132 -0
- package/dist/security/audit-logger.js.map +1 -0
- package/dist/security/backends/aws-kms-backend.d.ts +18 -0
- package/dist/security/backends/aws-kms-backend.d.ts.map +1 -0
- package/dist/security/backends/aws-kms-backend.js +130 -0
- package/dist/security/backends/aws-kms-backend.js.map +1 -0
- package/dist/security/backends/azure-kv-backend.d.ts +17 -0
- package/dist/security/backends/azure-kv-backend.d.ts.map +1 -0
- package/dist/security/backends/azure-kv-backend.js +121 -0
- package/dist/security/backends/azure-kv-backend.js.map +1 -0
- package/dist/security/backends/environment-backend.d.ts +15 -0
- package/dist/security/backends/environment-backend.d.ts.map +1 -0
- package/dist/security/backends/environment-backend.js +56 -0
- package/dist/security/backends/environment-backend.js.map +1 -0
- package/dist/security/backends/gcp-kms-backend.d.ts +17 -0
- package/dist/security/backends/gcp-kms-backend.d.ts.map +1 -0
- package/dist/security/backends/gcp-kms-backend.js +110 -0
- package/dist/security/backends/gcp-kms-backend.js.map +1 -0
- package/dist/security/backends/hsm-backend.d.ts +18 -0
- package/dist/security/backends/hsm-backend.d.ts.map +1 -0
- package/dist/security/backends/hsm-backend.js +187 -0
- package/dist/security/backends/hsm-backend.js.map +1 -0
- package/dist/security/fraud-detector.d.ts +79 -0
- package/dist/security/fraud-detector.d.ts.map +1 -0
- package/dist/security/fraud-detector.js +147 -0
- package/dist/security/fraud-detector.js.map +1 -0
- package/dist/security/key-manager-signer.d.ts +15 -0
- package/dist/security/key-manager-signer.d.ts.map +1 -0
- package/dist/security/key-manager-signer.js +91 -0
- package/dist/security/key-manager-signer.js.map +1 -0
- package/dist/security/key-manager.d.ts +69 -0
- package/dist/security/key-manager.d.ts.map +1 -0
- package/dist/security/key-manager.js +79 -0
- package/dist/security/key-manager.js.map +1 -0
- package/dist/security/key-rotation-manager.d.ts +27 -0
- package/dist/security/key-rotation-manager.d.ts.map +1 -0
- package/dist/security/key-rotation-manager.js +142 -0
- package/dist/security/key-rotation-manager.js.map +1 -0
- package/dist/security/rate-limit-config.d.ts +7 -0
- package/dist/security/rate-limit-config.d.ts.map +1 -0
- package/dist/security/rate-limit-config.js +57 -0
- package/dist/security/rate-limit-config.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +46 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +170 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/security/reputation-tracker.d.ts +30 -0
- package/dist/security/reputation-tracker.d.ts.map +1 -0
- package/dist/security/reputation-tracker.js +111 -0
- package/dist/security/reputation-tracker.js.map +1 -0
- package/dist/security/rules/balance-manipulation-rule.d.ts +23 -0
- package/dist/security/rules/balance-manipulation-rule.d.ts.map +1 -0
- package/dist/security/rules/balance-manipulation-rule.js +70 -0
- package/dist/security/rules/balance-manipulation-rule.js.map +1 -0
- package/dist/security/rules/double-spend-detection-rule.d.ts +23 -0
- package/dist/security/rules/double-spend-detection-rule.d.ts.map +1 -0
- package/dist/security/rules/double-spend-detection-rule.js +61 -0
- package/dist/security/rules/double-spend-detection-rule.js.map +1 -0
- package/dist/security/rules/rapid-channel-closure-rule.d.ts +16 -0
- package/dist/security/rules/rapid-channel-closure-rule.d.ts.map +1 -0
- package/dist/security/rules/rapid-channel-closure-rule.js +57 -0
- package/dist/security/rules/rapid-channel-closure-rule.js.map +1 -0
- package/dist/security/rules/sudden-traffic-spike-rule.d.ts +18 -0
- package/dist/security/rules/sudden-traffic-spike-rule.d.ts.map +1 -0
- package/dist/security/rules/sudden-traffic-spike-rule.js +92 -0
- package/dist/security/rules/sudden-traffic-spike-rule.js.map +1 -0
- package/dist/security/rules/unusual-settlement-amount-rule.d.ts +12 -0
- package/dist/security/rules/unusual-settlement-amount-rule.d.ts.map +1 -0
- package/dist/security/rules/unusual-settlement-amount-rule.js +33 -0
- package/dist/security/rules/unusual-settlement-amount-rule.js.map +1 -0
- package/dist/security/token-bucket.d.ts +16 -0
- package/dist/security/token-bucket.d.ts.map +1 -0
- package/dist/security/token-bucket.js +49 -0
- package/dist/security/token-bucket.js.map +1 -0
- package/dist/security/violation-counter.d.ts +11 -0
- package/dist/security/violation-counter.d.ts.map +1 -0
- package/dist/security/violation-counter.js +61 -0
- package/dist/security/violation-counter.js.map +1 -0
- package/dist/settlement/account-id-generator.d.ts +4 -0
- package/dist/settlement/account-id-generator.d.ts.map +1 -0
- package/dist/settlement/account-id-generator.js +38 -0
- package/dist/settlement/account-id-generator.js.map +1 -0
- package/dist/settlement/account-manager.d.ts +47 -0
- package/dist/settlement/account-manager.d.ts.map +1 -0
- package/dist/settlement/account-manager.js +447 -0
- package/dist/settlement/account-manager.js.map +1 -0
- package/dist/settlement/account-metadata.d.ts +11 -0
- package/dist/settlement/account-metadata.d.ts.map +1 -0
- package/dist/settlement/account-metadata.js +40 -0
- package/dist/settlement/account-metadata.js.map +1 -0
- package/dist/settlement/aptos-channel-sdk.d.ts +66 -0
- package/dist/settlement/aptos-channel-sdk.d.ts.map +1 -0
- package/dist/settlement/aptos-channel-sdk.js +274 -0
- package/dist/settlement/aptos-channel-sdk.js.map +1 -0
- package/dist/settlement/aptos-claim-signer.d.ts +57 -0
- package/dist/settlement/aptos-claim-signer.d.ts.map +1 -0
- package/dist/settlement/aptos-claim-signer.js +200 -0
- package/dist/settlement/aptos-claim-signer.js.map +1 -0
- package/dist/settlement/aptos-client.d.ts +99 -0
- package/dist/settlement/aptos-client.d.ts.map +1 -0
- package/dist/settlement/aptos-client.js +474 -0
- package/dist/settlement/aptos-client.js.map +1 -0
- package/dist/settlement/channel-manager.d.ts +66 -0
- package/dist/settlement/channel-manager.d.ts.map +1 -0
- package/dist/settlement/channel-manager.js +214 -0
- package/dist/settlement/channel-manager.js.map +1 -0
- package/dist/settlement/claim-receiver-db-schema.d.ts +4 -0
- package/dist/settlement/claim-receiver-db-schema.d.ts.map +1 -0
- package/dist/settlement/claim-receiver-db-schema.js +25 -0
- package/dist/settlement/claim-receiver-db-schema.js.map +1 -0
- package/dist/settlement/claim-receiver.d.ts +31 -0
- package/dist/settlement/claim-receiver.d.ts.map +1 -0
- package/dist/settlement/claim-receiver.js +228 -0
- package/dist/settlement/claim-receiver.js.map +1 -0
- package/dist/settlement/claim-redemption-service.d.ts +39 -0
- package/dist/settlement/claim-redemption-service.d.ts.map +1 -0
- package/dist/settlement/claim-redemption-service.js +189 -0
- package/dist/settlement/claim-redemption-service.js.map +1 -0
- package/dist/settlement/claim-sender-db-schema.d.ts +3 -0
- package/dist/settlement/claim-sender-db-schema.d.ts.map +1 -0
- package/dist/settlement/claim-sender-db-schema.js +18 -0
- package/dist/settlement/claim-sender-db-schema.js.map +1 -0
- package/dist/settlement/claim-sender.d.ts +22 -0
- package/dist/settlement/claim-sender.d.ts.map +1 -0
- package/dist/settlement/claim-sender.js +108 -0
- package/dist/settlement/claim-sender.js.map +1 -0
- package/dist/settlement/eip712-helper.d.ts +13 -0
- package/dist/settlement/eip712-helper.d.ts.map +1 -0
- package/dist/settlement/eip712-helper.js +24 -0
- package/dist/settlement/eip712-helper.js.map +1 -0
- package/dist/settlement/in-memory-ledger-client.d.ts +40 -0
- package/dist/settlement/in-memory-ledger-client.d.ts.map +1 -0
- package/dist/settlement/in-memory-ledger-client.js +177 -0
- package/dist/settlement/in-memory-ledger-client.js.map +1 -0
- package/dist/settlement/ledger-client.d.ts +22 -0
- package/dist/settlement/ledger-client.d.ts.map +1 -0
- package/dist/settlement/ledger-client.js +3 -0
- package/dist/settlement/ledger-client.js.map +1 -0
- package/dist/settlement/metrics-collector.d.ts +29 -0
- package/dist/settlement/metrics-collector.d.ts.map +1 -0
- package/dist/settlement/metrics-collector.js +81 -0
- package/dist/settlement/metrics-collector.js.map +1 -0
- package/dist/settlement/payment-channel-sdk.d.ts +59 -0
- package/dist/settlement/payment-channel-sdk.d.ts.map +1 -0
- package/dist/settlement/payment-channel-sdk.js +677 -0
- package/dist/settlement/payment-channel-sdk.js.map +1 -0
- package/dist/settlement/per-packet-claim-service.d.ts +33 -0
- package/dist/settlement/per-packet-claim-service.d.ts.map +1 -0
- package/dist/settlement/per-packet-claim-service.js +177 -0
- package/dist/settlement/per-packet-claim-service.js.map +1 -0
- package/dist/settlement/settlement-api.d.ts +37 -0
- package/dist/settlement/settlement-api.d.ts.map +1 -0
- package/dist/settlement/settlement-api.js +172 -0
- package/dist/settlement/settlement-api.js.map +1 -0
- package/dist/settlement/settlement-coordinator.d.ts +47 -0
- package/dist/settlement/settlement-coordinator.d.ts.map +1 -0
- package/dist/settlement/settlement-coordinator.js +166 -0
- package/dist/settlement/settlement-coordinator.js.map +1 -0
- package/dist/settlement/settlement-executor.d.ts +44 -0
- package/dist/settlement/settlement-executor.d.ts.map +1 -0
- package/dist/settlement/settlement-executor.js +247 -0
- package/dist/settlement/settlement-executor.js.map +1 -0
- package/dist/settlement/settlement-monitor.d.ts +29 -0
- package/dist/settlement/settlement-monitor.d.ts.map +1 -0
- package/dist/settlement/settlement-monitor.js +172 -0
- package/dist/settlement/settlement-monitor.js.map +1 -0
- package/dist/settlement/tigerbeetle-batch-writer.d.ts +58 -0
- package/dist/settlement/tigerbeetle-batch-writer.d.ts.map +1 -0
- package/dist/settlement/tigerbeetle-batch-writer.js +162 -0
- package/dist/settlement/tigerbeetle-batch-writer.js.map +1 -0
- package/dist/settlement/tigerbeetle-client.d.ts +40 -0
- package/dist/settlement/tigerbeetle-client.d.ts.map +1 -0
- package/dist/settlement/tigerbeetle-client.js +279 -0
- package/dist/settlement/tigerbeetle-client.js.map +1 -0
- package/dist/settlement/tigerbeetle-errors.d.ts +23 -0
- package/dist/settlement/tigerbeetle-errors.d.ts.map +1 -0
- package/dist/settlement/tigerbeetle-errors.js +58 -0
- package/dist/settlement/tigerbeetle-errors.js.map +1 -0
- package/dist/settlement/types.d.ts +64 -0
- package/dist/settlement/types.d.ts.map +1 -0
- package/dist/settlement/types.js +42 -0
- package/dist/settlement/types.js.map +1 -0
- package/dist/settlement/unified-settlement-executor.d.ts +34 -0
- package/dist/settlement/unified-settlement-executor.d.ts.map +1 -0
- package/dist/settlement/unified-settlement-executor.js +145 -0
- package/dist/settlement/unified-settlement-executor.js.map +1 -0
- package/dist/settlement/xrp-channel-lifecycle.d.ts +41 -0
- package/dist/settlement/xrp-channel-lifecycle.d.ts.map +1 -0
- package/dist/settlement/xrp-channel-lifecycle.js +142 -0
- package/dist/settlement/xrp-channel-lifecycle.js.map +1 -0
- package/dist/settlement/xrp-channel-manager.d.ts +59 -0
- package/dist/settlement/xrp-channel-manager.d.ts.map +1 -0
- package/dist/settlement/xrp-channel-manager.js +160 -0
- package/dist/settlement/xrp-channel-manager.js.map +1 -0
- package/dist/settlement/xrp-channel-sdk.d.ts +30 -0
- package/dist/settlement/xrp-channel-sdk.d.ts.map +1 -0
- package/dist/settlement/xrp-channel-sdk.js +164 -0
- package/dist/settlement/xrp-channel-sdk.js.map +1 -0
- package/dist/settlement/xrp-claim-signer.d.ts +22 -0
- package/dist/settlement/xrp-claim-signer.d.ts.map +1 -0
- package/dist/settlement/xrp-claim-signer.js +122 -0
- package/dist/settlement/xrp-claim-signer.js.map +1 -0
- package/dist/settlement/xrpl-client.d.ts +104 -0
- package/dist/settlement/xrpl-client.d.ts.map +1 -0
- package/dist/settlement/xrpl-client.js +304 -0
- package/dist/settlement/xrpl-client.js.map +1 -0
- package/dist/test/testnet-config.d.ts +58 -0
- package/dist/test/testnet-config.d.ts.map +1 -0
- package/dist/test/testnet-config.js +89 -0
- package/dist/test/testnet-config.js.map +1 -0
- package/dist/test-utils/index.d.ts +3 -0
- package/dist/test-utils/index.d.ts.map +1 -0
- package/dist/test-utils/index.js +15 -0
- package/dist/test-utils/index.js.map +1 -0
- package/dist/test-utils/isolated-test-env.d.ts +31 -0
- package/dist/test-utils/isolated-test-env.d.ts.map +1 -0
- package/dist/test-utils/isolated-test-env.js +127 -0
- package/dist/test-utils/isolated-test-env.js.map +1 -0
- package/dist/test-utils/mock-factories-patch.d.ts +2 -0
- package/dist/test-utils/mock-factories-patch.d.ts.map +1 -0
- package/dist/test-utils/mock-factories-patch.js +3 -0
- package/dist/test-utils/mock-factories-patch.js.map +1 -0
- package/dist/test-utils/mock-factories.d.ts +22 -0
- package/dist/test-utils/mock-factories.d.ts.map +1 -0
- package/dist/test-utils/mock-factories.js +56 -0
- package/dist/test-utils/mock-factories.js.map +1 -0
- package/dist/utils/connection-pool.d.ts +42 -0
- package/dist/utils/connection-pool.d.ts.map +1 -0
- package/dist/utils/connection-pool.js +209 -0
- package/dist/utils/connection-pool.js.map +1 -0
- package/dist/utils/evm-rpc-connection-pool.d.ts +8 -0
- package/dist/utils/evm-rpc-connection-pool.d.ts.map +1 -0
- package/dist/utils/evm-rpc-connection-pool.js +40 -0
- package/dist/utils/evm-rpc-connection-pool.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +58 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/optional-require.d.ts +2 -0
- package/dist/utils/optional-require.d.ts.map +1 -0
- package/dist/utils/optional-require.js +54 -0
- package/dist/utils/optional-require.js.map +1 -0
- package/dist/utils/xrp-wss-connection-pool.d.ts +8 -0
- package/dist/utils/xrp-wss-connection-pool.d.ts.map +1 -0
- package/dist/utils/xrp-wss-connection-pool.js +42 -0
- package/dist/utils/xrp-wss-connection-pool.js.map +1 -0
- package/dist/wallet/audit-logger.d.ts +22 -0
- package/dist/wallet/audit-logger.d.ts.map +1 -0
- package/dist/wallet/audit-logger.js +120 -0
- package/dist/wallet/audit-logger.js.map +1 -0
- package/dist/wallet/fraud-detector-interface.d.ts +14 -0
- package/dist/wallet/fraud-detector-interface.d.ts.map +1 -0
- package/dist/wallet/fraud-detector-interface.js +3 -0
- package/dist/wallet/fraud-detector-interface.js.map +1 -0
- package/dist/wallet/key-manager.d.ts +6 -0
- package/dist/wallet/key-manager.d.ts.map +1 -0
- package/dist/wallet/key-manager.js +3 -0
- package/dist/wallet/key-manager.js.map +1 -0
- package/dist/wallet/placeholder-fraud-detector.d.ts +10 -0
- package/dist/wallet/placeholder-fraud-detector.d.ts.map +1 -0
- package/dist/wallet/placeholder-fraud-detector.js +10 -0
- package/dist/wallet/placeholder-fraud-detector.js.map +1 -0
- package/dist/wallet/rate-limiter.d.ts +26 -0
- package/dist/wallet/rate-limiter.d.ts.map +1 -0
- package/dist/wallet/rate-limiter.js +114 -0
- package/dist/wallet/rate-limiter.js.map +1 -0
- package/dist/wallet/suspicious-activity-detector.d.ts +25 -0
- package/dist/wallet/suspicious-activity-detector.d.ts.map +1 -0
- package/dist/wallet/suspicious-activity-detector.js +97 -0
- package/dist/wallet/suspicious-activity-detector.js.map +1 -0
- package/dist/wallet/treasury-wallet.d.ts +20 -0
- package/dist/wallet/treasury-wallet.d.ts.map +1 -0
- package/dist/wallet/treasury-wallet.js +151 -0
- package/dist/wallet/treasury-wallet.js.map +1 -0
- package/dist/wallet/wallet-authentication.d.ts +31 -0
- package/dist/wallet/wallet-authentication.d.ts.map +1 -0
- package/dist/wallet/wallet-authentication.js +102 -0
- package/dist/wallet/wallet-authentication.js.map +1 -0
- package/dist/wallet/wallet-db-schema.d.ts +11 -0
- package/dist/wallet/wallet-db-schema.d.ts.map +1 -0
- package/dist/wallet/wallet-db-schema.js +79 -0
- package/dist/wallet/wallet-db-schema.js.map +1 -0
- package/dist/wallet/wallet-security.d.ts +58 -0
- package/dist/wallet/wallet-security.d.ts.map +1 -0
- package/dist/wallet/wallet-security.js +148 -0
- package/dist/wallet/wallet-security.js.map +1 -0
- package/dist/wallet/wallet-seed-manager.d.ts +65 -0
- package/dist/wallet/wallet-seed-manager.d.ts.map +1 -0
- package/dist/wallet/wallet-seed-manager.js +418 -0
- package/dist/wallet/wallet-seed-manager.js.map +1 -0
- package/package.json +134 -0
|
@@ -0,0 +1,1036 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConnectorNode = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const routing_table_1 = require("../routing/routing-table");
|
|
6
|
+
const btp_client_manager_1 = require("../btp/btp-client-manager");
|
|
7
|
+
const btp_server_1 = require("../btp/btp-server");
|
|
8
|
+
const packet_handler_1 = require("./packet-handler");
|
|
9
|
+
const shared_1 = require("@toon-protocol/shared");
|
|
10
|
+
const payment_handler_1 = require("./payment-handler");
|
|
11
|
+
const types_1 = require("../settlement/types");
|
|
12
|
+
const admin_api_1 = require("../http/admin-api");
|
|
13
|
+
const config_loader_1 = require("../config/config-loader");
|
|
14
|
+
const health_server_1 = require("../http/health-server");
|
|
15
|
+
const admin_server_1 = require("../http/admin-server");
|
|
16
|
+
const payment_channel_sdk_1 = require("../settlement/payment-channel-sdk");
|
|
17
|
+
const channel_manager_1 = require("../settlement/channel-manager");
|
|
18
|
+
const settlement_executor_1 = require("../settlement/settlement-executor");
|
|
19
|
+
const account_manager_1 = require("../settlement/account-manager");
|
|
20
|
+
const settlement_monitor_1 = require("../settlement/settlement-monitor");
|
|
21
|
+
const key_manager_1 = require("../security/key-manager");
|
|
22
|
+
const optional_require_1 = require("../utils/optional-require");
|
|
23
|
+
const tigerbeetle_client_1 = require("../settlement/tigerbeetle-client");
|
|
24
|
+
const in_memory_ledger_client_1 = require("../settlement/in-memory-ledger-client");
|
|
25
|
+
const per_packet_claim_service_1 = require("../settlement/per-packet-claim-service");
|
|
26
|
+
const claim_sender_db_schema_1 = require("../settlement/claim-sender-db-schema");
|
|
27
|
+
const dns_1 = require("dns");
|
|
28
|
+
const package_json_1 = tslib_1.__importDefault(require("../../package.json"));
|
|
29
|
+
class ConnectorNode {
|
|
30
|
+
_config;
|
|
31
|
+
_logger;
|
|
32
|
+
_routingTable;
|
|
33
|
+
_btpClientManager;
|
|
34
|
+
_packetHandler;
|
|
35
|
+
_btpServer;
|
|
36
|
+
_healthServer;
|
|
37
|
+
_adminServer = null;
|
|
38
|
+
_paymentChannelSDK = null;
|
|
39
|
+
_chainSDKs = new Map();
|
|
40
|
+
_channelManager = null;
|
|
41
|
+
_accountManager = null;
|
|
42
|
+
_settlementMonitor = null;
|
|
43
|
+
_settlementExecutor = null;
|
|
44
|
+
_tigerBeetleClient = null;
|
|
45
|
+
_inMemoryLedgerClient = null;
|
|
46
|
+
_settlementPeers = new Map();
|
|
47
|
+
_healthStatus = 'starting';
|
|
48
|
+
_startTime = new Date();
|
|
49
|
+
_btpServerStarted = false;
|
|
50
|
+
_defaultSettlementTokenId = 'M2M';
|
|
51
|
+
get defaultSettlementTokenId() {
|
|
52
|
+
return this._defaultSettlementTokenId;
|
|
53
|
+
}
|
|
54
|
+
constructor(config, logger) {
|
|
55
|
+
let resolvedConfig;
|
|
56
|
+
try {
|
|
57
|
+
if (typeof config === 'string') {
|
|
58
|
+
resolvedConfig = config_loader_1.ConfigLoader.loadConfig(config);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
resolvedConfig = config_loader_1.ConfigLoader.validateConfig(config);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof config_loader_1.ConfigurationError) {
|
|
66
|
+
const logContext = typeof config === 'string'
|
|
67
|
+
? { event: 'config_load_failed', filePath: config, error: error.message }
|
|
68
|
+
: { event: 'config_load_failed', source: 'object', error: error.message };
|
|
69
|
+
logger.error(logContext, 'Failed to load configuration');
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
this._config = resolvedConfig;
|
|
75
|
+
this._logger = logger.child({ component: 'ConnectorNode', nodeId: resolvedConfig.nodeId });
|
|
76
|
+
const loadedLogContext = typeof config === 'string'
|
|
77
|
+
? { event: 'config_loaded', filePath: config, nodeId: resolvedConfig.nodeId }
|
|
78
|
+
: { event: 'config_loaded', source: 'object', nodeId: resolvedConfig.nodeId };
|
|
79
|
+
this._logger.info(loadedLogContext, 'Configuration loaded successfully');
|
|
80
|
+
const routingTableEntries = resolvedConfig.routes.map((route) => ({
|
|
81
|
+
prefix: route.prefix,
|
|
82
|
+
nextHop: route.nextHop,
|
|
83
|
+
priority: route.priority,
|
|
84
|
+
}));
|
|
85
|
+
this._routingTable = new routing_table_1.RoutingTable(routingTableEntries, logger.child({ component: 'RoutingTable' }));
|
|
86
|
+
this._btpClientManager = new btp_client_manager_1.BTPClientManager(resolvedConfig.nodeId, logger.child({ component: 'BTPClientManager' }));
|
|
87
|
+
this._packetHandler = new packet_handler_1.PacketHandler(this._routingTable, this._btpClientManager, resolvedConfig.nodeId, logger.child({ component: 'PacketHandler' }));
|
|
88
|
+
this._btpServer = new btp_server_1.BTPServer(logger.child({ component: 'BTPServer' }), this._packetHandler);
|
|
89
|
+
this._packetHandler.setBTPServer(this._btpServer);
|
|
90
|
+
const localDeliveryEnabled = resolvedConfig.localDelivery?.enabled || process.env.LOCAL_DELIVERY_ENABLED === 'true';
|
|
91
|
+
if (localDeliveryEnabled) {
|
|
92
|
+
const localDeliveryConfig = {
|
|
93
|
+
enabled: true,
|
|
94
|
+
handlerUrl: resolvedConfig.localDelivery?.handlerUrl || process.env.LOCAL_DELIVERY_URL || '',
|
|
95
|
+
timeout: resolvedConfig.localDelivery?.timeout ||
|
|
96
|
+
parseInt(process.env.LOCAL_DELIVERY_TIMEOUT || '30000', 10),
|
|
97
|
+
authToken: resolvedConfig.localDelivery?.authToken || process.env.LOCAL_DELIVERY_AUTH_TOKEN,
|
|
98
|
+
perHopNotification: resolvedConfig.localDelivery?.perHopNotification ??
|
|
99
|
+
process.env.LOCAL_DELIVERY_PER_HOP_NOTIFICATION === 'true',
|
|
100
|
+
};
|
|
101
|
+
this._packetHandler.setLocalDelivery(localDeliveryConfig);
|
|
102
|
+
}
|
|
103
|
+
this._btpClientManager.setPacketHandler(this._packetHandler);
|
|
104
|
+
this._healthServer = new health_server_1.HealthServer(logger.child({ component: 'HealthServer' }), this);
|
|
105
|
+
this._logger.info({
|
|
106
|
+
event: 'connector_initialized',
|
|
107
|
+
nodeId: resolvedConfig.nodeId,
|
|
108
|
+
peersCount: resolvedConfig.peers.length,
|
|
109
|
+
routesCount: resolvedConfig.routes.length,
|
|
110
|
+
}, 'Connector node initialized');
|
|
111
|
+
}
|
|
112
|
+
setLocalDeliveryHandler(handler) {
|
|
113
|
+
this._logger.info({ event: 'local_delivery_handler_set', hasHandler: handler !== null }, handler
|
|
114
|
+
? 'Local delivery function handler registered'
|
|
115
|
+
: 'Local delivery function handler cleared');
|
|
116
|
+
this._packetHandler.setLocalDeliveryHandler(handler);
|
|
117
|
+
}
|
|
118
|
+
setPacketHandler(handler) {
|
|
119
|
+
this._logger.info({ event: 'packet_handler_set', hasHandler: handler !== null }, handler ? 'Packet handler registered' : 'Packet handler cleared');
|
|
120
|
+
if (handler) {
|
|
121
|
+
const adapter = (0, payment_handler_1.createPaymentHandlerAdapter)(handler, this._logger);
|
|
122
|
+
this._packetHandler.setLocalDeliveryHandler(adapter);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this._packetHandler.setLocalDeliveryHandler(null);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
getDeploymentMode() {
|
|
129
|
+
if (this._config.deploymentMode) {
|
|
130
|
+
return this._config.deploymentMode;
|
|
131
|
+
}
|
|
132
|
+
const hasLocalDelivery = this._config.localDelivery?.enabled === true;
|
|
133
|
+
const hasAdminApi = this._config.adminApi?.enabled === true;
|
|
134
|
+
if (hasLocalDelivery && hasAdminApi) {
|
|
135
|
+
return 'standalone';
|
|
136
|
+
}
|
|
137
|
+
if (!hasLocalDelivery && !hasAdminApi) {
|
|
138
|
+
return 'embedded';
|
|
139
|
+
}
|
|
140
|
+
return 'embedded';
|
|
141
|
+
}
|
|
142
|
+
isEmbedded() {
|
|
143
|
+
return this.getDeploymentMode() === 'embedded';
|
|
144
|
+
}
|
|
145
|
+
isStandalone() {
|
|
146
|
+
return this.getDeploymentMode() === 'standalone';
|
|
147
|
+
}
|
|
148
|
+
async sendPacket(params) {
|
|
149
|
+
if (!this._btpServerStarted) {
|
|
150
|
+
throw new config_loader_1.ConnectorNotStartedError();
|
|
151
|
+
}
|
|
152
|
+
const packet = {
|
|
153
|
+
type: shared_1.PacketType.PREPARE,
|
|
154
|
+
destination: params.destination,
|
|
155
|
+
amount: params.amount,
|
|
156
|
+
executionCondition: params.executionCondition,
|
|
157
|
+
expiresAt: params.expiresAt,
|
|
158
|
+
data: params.data ?? Buffer.alloc(0),
|
|
159
|
+
};
|
|
160
|
+
this._logger.info({
|
|
161
|
+
event: 'send_packet',
|
|
162
|
+
destination: params.destination,
|
|
163
|
+
amount: params.amount.toString(),
|
|
164
|
+
expiresAt: params.expiresAt.toISOString(),
|
|
165
|
+
}, 'Sending packet via public API');
|
|
166
|
+
try {
|
|
167
|
+
return await this._packetHandler.handlePreparePacket(packet, this._config.nodeId);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
this._logger.error({
|
|
171
|
+
event: 'send_packet_error',
|
|
172
|
+
destination: params.destination,
|
|
173
|
+
error: error instanceof Error ? error.message : String(error),
|
|
174
|
+
}, 'Unexpected error sending packet');
|
|
175
|
+
return {
|
|
176
|
+
type: shared_1.PacketType.REJECT,
|
|
177
|
+
code: shared_1.ILPErrorCode.T00_INTERNAL_ERROR,
|
|
178
|
+
triggeredBy: this._config.nodeId,
|
|
179
|
+
message: 'Internal connector error',
|
|
180
|
+
data: Buffer.alloc(0),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async start() {
|
|
185
|
+
this._logger.info({
|
|
186
|
+
event: 'connector_starting',
|
|
187
|
+
nodeId: this._config.nodeId,
|
|
188
|
+
peersCount: this._config.peers.length,
|
|
189
|
+
routesCount: this._config.routes.length,
|
|
190
|
+
}, 'Starting connector node');
|
|
191
|
+
try {
|
|
192
|
+
const settlementEnabled = this._config.settlementInfra?.enabled ?? process.env.SETTLEMENT_ENABLED === 'true';
|
|
193
|
+
const baseRpcUrl = this._config.settlementInfra?.rpcUrl ?? process.env.BASE_L2_RPC_URL;
|
|
194
|
+
const registryAddress = this._config.settlementInfra?.registryAddress ?? process.env.TOKEN_NETWORK_REGISTRY;
|
|
195
|
+
const m2mTokenAddress = this._config.settlementInfra?.tokenAddress ?? process.env.M2M_TOKEN_ADDRESS;
|
|
196
|
+
const treasuryPrivateKey = this._config.settlementInfra?.privateKey ?? process.env.TREASURY_EVM_PRIVATE_KEY;
|
|
197
|
+
if (settlementEnabled &&
|
|
198
|
+
baseRpcUrl &&
|
|
199
|
+
registryAddress &&
|
|
200
|
+
m2mTokenAddress &&
|
|
201
|
+
treasuryPrivateKey) {
|
|
202
|
+
try {
|
|
203
|
+
const keyManager = new key_manager_1.KeyManager({
|
|
204
|
+
backend: 'env',
|
|
205
|
+
nodeId: this._config.nodeId,
|
|
206
|
+
evmPrivateKey: treasuryPrivateKey,
|
|
207
|
+
}, this._logger);
|
|
208
|
+
const evmKeyId = 'evm';
|
|
209
|
+
const { ethers } = await (0, optional_require_1.requireOptional)('ethers', 'EVM settlement');
|
|
210
|
+
const provider = new ethers.JsonRpcProvider(baseRpcUrl);
|
|
211
|
+
this._paymentChannelSDK = new payment_channel_sdk_1.PaymentChannelSDK(provider, keyManager, evmKeyId, registryAddress, this._logger);
|
|
212
|
+
try {
|
|
213
|
+
const resolvedSymbol = await this._paymentChannelSDK.getTokenSymbol(m2mTokenAddress);
|
|
214
|
+
if (resolvedSymbol) {
|
|
215
|
+
this._defaultSettlementTokenId = resolvedSymbol;
|
|
216
|
+
this._logger.info({
|
|
217
|
+
event: 'token_symbol_resolved',
|
|
218
|
+
symbol: resolvedSymbol,
|
|
219
|
+
tokenAddress: m2mTokenAddress,
|
|
220
|
+
}, `Resolved on-chain token symbol: ${resolvedSymbol}`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
this._logger.warn({ event: 'token_symbol_empty', tokenAddress: m2mTokenAddress }, 'ERC-20 symbol() returned empty string, falling back to M2M');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (symbolError) {
|
|
227
|
+
this._logger.warn({
|
|
228
|
+
event: 'token_symbol_resolution_failed',
|
|
229
|
+
tokenAddress: m2mTokenAddress,
|
|
230
|
+
error: symbolError instanceof Error ? symbolError.message : String(symbolError),
|
|
231
|
+
}, 'Failed to resolve on-chain token symbol, falling back to M2M');
|
|
232
|
+
}
|
|
233
|
+
const primaryChainId = this._config.blockchain?.base?.chainId ?? this._config.blockchain?.arbitrum?.chainId;
|
|
234
|
+
if (primaryChainId) {
|
|
235
|
+
this._chainSDKs.set(primaryChainId, this._paymentChannelSDK);
|
|
236
|
+
}
|
|
237
|
+
const enabledChains = [];
|
|
238
|
+
if (this._config.blockchain?.base?.enabled && this._config.blockchain.base) {
|
|
239
|
+
enabledChains.push({ name: 'Base', config: this._config.blockchain.base });
|
|
240
|
+
}
|
|
241
|
+
if (this._config.blockchain?.arbitrum?.enabled && this._config.blockchain.arbitrum) {
|
|
242
|
+
enabledChains.push({ name: 'Arbitrum', config: this._config.blockchain.arbitrum });
|
|
243
|
+
}
|
|
244
|
+
for (const chain of enabledChains) {
|
|
245
|
+
if (this._chainSDKs.has(chain.config.chainId)) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const chainRpcUrl = chain.config.rpcUrl;
|
|
249
|
+
const chainRegistryAddress = chain.config.registryAddress ?? registryAddress;
|
|
250
|
+
const chainPrivateKey = chain.config.privateKey ?? treasuryPrivateKey;
|
|
251
|
+
const chainKeyManager = chainPrivateKey !== treasuryPrivateKey
|
|
252
|
+
? new key_manager_1.KeyManager({ backend: 'env', nodeId: this._config.nodeId, evmPrivateKey: chainPrivateKey }, this._logger)
|
|
253
|
+
: keyManager;
|
|
254
|
+
const chainProvider = new ethers.JsonRpcProvider(chainRpcUrl);
|
|
255
|
+
const chainSDK = new payment_channel_sdk_1.PaymentChannelSDK(chainProvider, chainKeyManager, evmKeyId, chainRegistryAddress, this._logger);
|
|
256
|
+
this._chainSDKs.set(chain.config.chainId, chainSDK);
|
|
257
|
+
this._logger.info({
|
|
258
|
+
event: 'chain_sdk_initialized',
|
|
259
|
+
chain: chain.name,
|
|
260
|
+
chainId: chain.config.chainId,
|
|
261
|
+
rpcUrl: chainRpcUrl,
|
|
262
|
+
}, `PaymentChannelSDK initialized for ${chain.name} (chainId: ${chain.config.chainId})`);
|
|
263
|
+
}
|
|
264
|
+
const peerIdToAddressMap = new Map();
|
|
265
|
+
for (const peer of this._config.peers) {
|
|
266
|
+
if (peer.evmAddress) {
|
|
267
|
+
peerIdToAddressMap.set(peer.id, peer.evmAddress);
|
|
268
|
+
this._logger.debug({ peerId: peer.id, address: peer.evmAddress }, 'Loaded peer EVM address from config');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
for (let i = 1; i <= 10; i++) {
|
|
272
|
+
const peerAddress = process.env[`PEER${i}_EVM_ADDRESS`];
|
|
273
|
+
const peerId = `peer${i}`;
|
|
274
|
+
if (peerAddress && !peerIdToAddressMap.has(peerId)) {
|
|
275
|
+
peerIdToAddressMap.set(peerId, peerAddress);
|
|
276
|
+
this._logger.debug({ peerId, address: peerAddress }, 'Loaded peer EVM address from env var (fallback)');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const tokenAddressMap = new Map();
|
|
280
|
+
tokenAddressMap.set(this._defaultSettlementTokenId, m2mTokenAddress);
|
|
281
|
+
tokenAddressMap.set(m2mTokenAddress, m2mTokenAddress);
|
|
282
|
+
const defaultSettlementTimeout = this._config.settlementInfra?.settlementTimeoutSecs ?? 86400;
|
|
283
|
+
const initialDepositMultiplier = this._config.settlementInfra?.initialDepositMultiplier ??
|
|
284
|
+
parseInt(process.env.INITIAL_DEPOSIT_MULTIPLIER ?? '1', 10);
|
|
285
|
+
let accountManager;
|
|
286
|
+
const tigerBeetleClusterId = process.env.TIGERBEETLE_CLUSTER_ID;
|
|
287
|
+
const tigerBeetleReplicas = process.env.TIGERBEETLE_REPLICAS;
|
|
288
|
+
if (tigerBeetleClusterId && tigerBeetleReplicas) {
|
|
289
|
+
try {
|
|
290
|
+
const rawAddresses = tigerBeetleReplicas.split(',').map((s) => s.trim());
|
|
291
|
+
const resolvedAddresses = await Promise.all(rawAddresses.map(async (addr) => {
|
|
292
|
+
const parts = addr.split(':');
|
|
293
|
+
const hostOrIp = parts[0] || addr;
|
|
294
|
+
const port = parts[1] || '3000';
|
|
295
|
+
if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostOrIp)) {
|
|
296
|
+
return addr;
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
const result = await dns_1.promises.lookup(hostOrIp);
|
|
300
|
+
this._logger.debug({ hostname: hostOrIp, ip: result.address }, 'Resolved TigerBeetle hostname to IP');
|
|
301
|
+
return `${result.address}:${port}`;
|
|
302
|
+
}
|
|
303
|
+
catch (dnsError) {
|
|
304
|
+
this._logger.warn({ hostname: hostOrIp, error: dnsError }, 'Failed to resolve TigerBeetle hostname, using as-is');
|
|
305
|
+
return addr;
|
|
306
|
+
}
|
|
307
|
+
}));
|
|
308
|
+
const tbOperationTimeout = parseInt(process.env.TIGERBEETLE_OPERATION_TIMEOUT ?? '15000', 10);
|
|
309
|
+
const tigerBeetleClient = new tigerbeetle_client_1.TigerBeetleClient({
|
|
310
|
+
clusterId: parseInt(tigerBeetleClusterId, 10),
|
|
311
|
+
replicaAddresses: resolvedAddresses,
|
|
312
|
+
connectionTimeout: 5000,
|
|
313
|
+
operationTimeout: tbOperationTimeout,
|
|
314
|
+
}, this._logger);
|
|
315
|
+
await tigerBeetleClient.initialize();
|
|
316
|
+
this._tigerBeetleClient = tigerBeetleClient;
|
|
317
|
+
accountManager = new account_manager_1.AccountManager({ nodeId: this._config.nodeId }, tigerBeetleClient, this._logger);
|
|
318
|
+
this._accountManager = accountManager;
|
|
319
|
+
this._logger.info({
|
|
320
|
+
event: 'tigerbeetle_account_manager_initialized',
|
|
321
|
+
clusterId: tigerBeetleClusterId,
|
|
322
|
+
replicas: tigerBeetleReplicas,
|
|
323
|
+
}, `Accounting backend: TigerBeetle (cluster: ${tigerBeetleClusterId}, replicas: ${tigerBeetleReplicas})`);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
327
|
+
this._logger.warn({
|
|
328
|
+
event: 'tigerbeetle_init_failed',
|
|
329
|
+
error: errorMessage,
|
|
330
|
+
clusterId: tigerBeetleClusterId,
|
|
331
|
+
replicas: tigerBeetleReplicas,
|
|
332
|
+
}, 'TigerBeetle initialization failed, using in-memory ledger');
|
|
333
|
+
accountManager = await this._createInMemoryAccountManager();
|
|
334
|
+
this._accountManager = accountManager;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
this._logger.info({ event: 'tigerbeetle_not_configured' }, 'TigerBeetle not configured (TIGERBEETLE_CLUSTER_ID or TIGERBEETLE_REPLICAS not set), using in-memory ledger');
|
|
339
|
+
accountManager = await this._createInMemoryAccountManager();
|
|
340
|
+
this._accountManager = accountManager;
|
|
341
|
+
}
|
|
342
|
+
const peerIds = Array.from(peerIdToAddressMap.keys());
|
|
343
|
+
const settlementThreshold = BigInt(this._config.settlementInfra?.threshold ?? process.env.SETTLEMENT_THRESHOLD ?? '1000000');
|
|
344
|
+
const settlementPollingInterval = this._config.settlementInfra?.pollingIntervalMs ??
|
|
345
|
+
parseInt(process.env.SETTLEMENT_POLLING_INTERVAL ?? '30000', 10);
|
|
346
|
+
this._logger.info({
|
|
347
|
+
event: 'settlement_monitor_config',
|
|
348
|
+
peerIds,
|
|
349
|
+
threshold: settlementThreshold.toString(),
|
|
350
|
+
pollingInterval: settlementPollingInterval,
|
|
351
|
+
}, 'Initializing settlement monitor with peer list');
|
|
352
|
+
const settlementMonitor = new settlement_monitor_1.SettlementMonitor({
|
|
353
|
+
thresholds: {
|
|
354
|
+
defaultThreshold: settlementThreshold,
|
|
355
|
+
pollingInterval: settlementPollingInterval,
|
|
356
|
+
},
|
|
357
|
+
peers: peerIds,
|
|
358
|
+
tokenIds: [this._defaultSettlementTokenId],
|
|
359
|
+
}, accountManager, this._logger);
|
|
360
|
+
this._settlementMonitor = settlementMonitor;
|
|
361
|
+
this._settlementExecutor = new settlement_executor_1.SettlementExecutor({
|
|
362
|
+
nodeId: this._config.nodeId,
|
|
363
|
+
defaultSettlementTimeout,
|
|
364
|
+
initialDepositMultiplier,
|
|
365
|
+
minDepositThreshold: 0.5,
|
|
366
|
+
maxRetries: 3,
|
|
367
|
+
retryDelayMs: 5000,
|
|
368
|
+
tokenAddressMap,
|
|
369
|
+
peerIdToAddressMap,
|
|
370
|
+
registryAddress,
|
|
371
|
+
rpcUrl: baseRpcUrl,
|
|
372
|
+
privateKey: treasuryPrivateKey,
|
|
373
|
+
}, accountManager, this._paymentChannelSDK, settlementMonitor, this._logger);
|
|
374
|
+
this._settlementExecutor.start();
|
|
375
|
+
this._logger.info({ event: 'settlement_executor_started' }, 'Automatic settlement execution enabled');
|
|
376
|
+
setTimeout(async () => {
|
|
377
|
+
try {
|
|
378
|
+
await settlementMonitor.start();
|
|
379
|
+
this._logger.info({
|
|
380
|
+
event: 'settlement_monitor_started',
|
|
381
|
+
threshold: settlementThreshold.toString(),
|
|
382
|
+
peerCount: peerIds.length,
|
|
383
|
+
pollingInterval: settlementPollingInterval,
|
|
384
|
+
}, 'Settlement threshold monitoring started');
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
388
|
+
this._logger.error({ event: 'settlement_monitor_start_failed', error: errorMessage }, 'Failed to start settlement monitor');
|
|
389
|
+
}
|
|
390
|
+
}, 5000);
|
|
391
|
+
this._channelManager = new channel_manager_1.ChannelManager({
|
|
392
|
+
nodeId: this._config.nodeId,
|
|
393
|
+
defaultSettlementTimeout,
|
|
394
|
+
initialDepositMultiplier,
|
|
395
|
+
idleChannelThreshold: 86400,
|
|
396
|
+
minDepositThreshold: 0.5,
|
|
397
|
+
idleCheckInterval: 3600,
|
|
398
|
+
tokenAddressMap,
|
|
399
|
+
peerIdToAddressMap,
|
|
400
|
+
registryAddress,
|
|
401
|
+
rpcUrl: baseRpcUrl,
|
|
402
|
+
privateKey: treasuryPrivateKey,
|
|
403
|
+
}, this._paymentChannelSDK, this._settlementExecutor, this._logger);
|
|
404
|
+
this._logger.info({
|
|
405
|
+
event: 'payment_channel_sdk_initialized',
|
|
406
|
+
registryAddress,
|
|
407
|
+
tokenAddress: m2mTokenAddress,
|
|
408
|
+
peerCount: peerIdToAddressMap.size,
|
|
409
|
+
}, 'Payment channel infrastructure initialized');
|
|
410
|
+
if (this._channelManager && this._paymentChannelSDK) {
|
|
411
|
+
try {
|
|
412
|
+
const BetterSqlite3Module = await (0, optional_require_1.requireOptional)('better-sqlite3', 'per-packet claims persistence');
|
|
413
|
+
const BetterSqlite3 = BetterSqlite3Module.default;
|
|
414
|
+
const claimDbPath = `./data/claims-${this._config.nodeId}.db`;
|
|
415
|
+
const claimDb = new BetterSqlite3(claimDbPath);
|
|
416
|
+
claimDb.exec(claim_sender_db_schema_1.SENT_CLAIMS_TABLE_SCHEMA);
|
|
417
|
+
for (const indexSql of claim_sender_db_schema_1.SENT_CLAIMS_INDEXES) {
|
|
418
|
+
claimDb.exec(indexSql);
|
|
419
|
+
}
|
|
420
|
+
const perPacketClaimService = new per_packet_claim_service_1.PerPacketClaimService(this._paymentChannelSDK, this._channelManager, claimDb, this._logger, this._config.nodeId);
|
|
421
|
+
this._packetHandler.setPerPacketClaimService(perPacketClaimService);
|
|
422
|
+
this._settlementExecutor?.setPerPacketClaimService(perPacketClaimService);
|
|
423
|
+
this._logger.info({ event: 'per_packet_claims_enabled' }, 'Per-packet claim service wired to PacketHandler and SettlementExecutor');
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
427
|
+
this._logger.error({ event: 'per_packet_claims_init_failed', error: errorMessage }, 'Failed to initialize per-packet claim service');
|
|
428
|
+
throw error;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (accountManager) {
|
|
432
|
+
const settlementConfig = {
|
|
433
|
+
connectorFeePercentage: this._config.settlement?.connectorFeePercentage ?? 0.1,
|
|
434
|
+
enableSettlement: settlementEnabled,
|
|
435
|
+
tigerBeetleClusterId: tigerBeetleClusterId ? parseInt(tigerBeetleClusterId, 10) : 0,
|
|
436
|
+
tigerBeetleReplicas: tigerBeetleReplicas
|
|
437
|
+
? tigerBeetleReplicas.split(',').map((s) => s.trim())
|
|
438
|
+
: [],
|
|
439
|
+
};
|
|
440
|
+
this._packetHandler.setSettlement(accountManager, settlementConfig, this._defaultSettlementTokenId);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch (error) {
|
|
444
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
445
|
+
this._logger.error({ event: 'payment_channel_init_failed', error: errorMessage }, 'Failed to initialize payment channel infrastructure (connector continues without channels)');
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this._logger.info({ event: 'payment_channels_disabled' }, 'Payment channel infrastructure disabled (missing configuration)');
|
|
450
|
+
}
|
|
451
|
+
await this._btpServer.start(this._config.btpServerPort);
|
|
452
|
+
this._btpServerStarted = true;
|
|
453
|
+
this._logger.info({
|
|
454
|
+
event: 'btp_server_started',
|
|
455
|
+
port: this._config.btpServerPort,
|
|
456
|
+
}, 'BTP server started');
|
|
457
|
+
const healthCheckPort = this._config.healthCheckPort || 8080;
|
|
458
|
+
await this._healthServer.start(healthCheckPort);
|
|
459
|
+
this._logger.info({
|
|
460
|
+
event: 'health_server_started',
|
|
461
|
+
port: healthCheckPort,
|
|
462
|
+
}, 'Health server started');
|
|
463
|
+
const adminApiEnabled = this._config.adminApi?.enabled || process.env.ADMIN_API_ENABLED === 'true';
|
|
464
|
+
if (adminApiEnabled) {
|
|
465
|
+
const adminConfig = {
|
|
466
|
+
enabled: true,
|
|
467
|
+
port: this._config.adminApi?.port ?? parseInt(process.env.ADMIN_API_PORT || '8081', 10),
|
|
468
|
+
host: this._config.adminApi?.host ?? process.env.ADMIN_API_HOST ?? '0.0.0.0',
|
|
469
|
+
apiKey: this._config.adminApi?.apiKey ?? process.env.ADMIN_API_KEY,
|
|
470
|
+
};
|
|
471
|
+
this._adminServer = new admin_server_1.AdminServer({
|
|
472
|
+
routingTable: this._routingTable,
|
|
473
|
+
btpClientManager: this._btpClientManager,
|
|
474
|
+
nodeId: this._config.nodeId,
|
|
475
|
+
config: adminConfig,
|
|
476
|
+
logger: this._logger,
|
|
477
|
+
settlementPeers: this._settlementPeers,
|
|
478
|
+
channelManager: this._channelManager ?? undefined,
|
|
479
|
+
paymentChannelSDK: this._paymentChannelSDK ?? undefined,
|
|
480
|
+
accountManager: this._accountManager ?? undefined,
|
|
481
|
+
settlementMonitor: this._settlementMonitor ?? undefined,
|
|
482
|
+
defaultSettlementTokenId: this._defaultSettlementTokenId,
|
|
483
|
+
packetSender: (params) => this.sendPacket(params),
|
|
484
|
+
isReady: () => this._btpServerStarted,
|
|
485
|
+
});
|
|
486
|
+
await this._adminServer.start();
|
|
487
|
+
this._logger.info({
|
|
488
|
+
event: 'admin_server_started',
|
|
489
|
+
port: adminConfig.port,
|
|
490
|
+
host: adminConfig.host,
|
|
491
|
+
apiKeyConfigured: !!adminConfig.apiKey,
|
|
492
|
+
}, 'Admin API server started');
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
this._logger.debug({ event: 'admin_api_disabled' }, 'Admin API disabled (set ADMIN_API_ENABLED=true or adminApi.enabled=true to enable)');
|
|
496
|
+
}
|
|
497
|
+
const peerConnections = [];
|
|
498
|
+
for (const peerConfig of this._config.peers) {
|
|
499
|
+
const peer = {
|
|
500
|
+
id: peerConfig.id,
|
|
501
|
+
url: peerConfig.url,
|
|
502
|
+
authToken: peerConfig.authToken,
|
|
503
|
+
connected: false,
|
|
504
|
+
lastSeen: new Date(),
|
|
505
|
+
};
|
|
506
|
+
peerConnections.push(this._btpClientManager.addPeer(peer));
|
|
507
|
+
}
|
|
508
|
+
const peerResults = await Promise.allSettled(peerConnections);
|
|
509
|
+
const failedPeers = peerResults.filter((r) => r.status === 'rejected');
|
|
510
|
+
if (failedPeers.length > 0) {
|
|
511
|
+
this._logger.warn({
|
|
512
|
+
event: 'peer_connection_failures',
|
|
513
|
+
failedCount: failedPeers.length,
|
|
514
|
+
totalPeers: this._config.peers.length,
|
|
515
|
+
}, 'Some peer connections failed during startup (will retry in background)');
|
|
516
|
+
}
|
|
517
|
+
const connectedPeers = this._btpClientManager.getPeerStatus();
|
|
518
|
+
const connectedCount = Array.from(connectedPeers.values()).filter(Boolean).length;
|
|
519
|
+
if (this._channelManager && this._paymentChannelSDK) {
|
|
520
|
+
this._logger.info({ event: 'creating_payment_channels', connectedCount }, 'Creating payment channels for connected peers');
|
|
521
|
+
const channelCreationPromises = [];
|
|
522
|
+
for (const [peerId, connected] of connectedPeers.entries()) {
|
|
523
|
+
if (!connected) {
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
const channelPromise = (async () => {
|
|
527
|
+
try {
|
|
528
|
+
const tokenId = this._defaultSettlementTokenId;
|
|
529
|
+
const channelId = await this._channelManager.ensureChannelExists(peerId, tokenId);
|
|
530
|
+
this._logger.info({ event: 'payment_channel_ready', peerId, channelId }, 'Payment channel ready for peer');
|
|
531
|
+
}
|
|
532
|
+
catch (error) {
|
|
533
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
534
|
+
this._logger.warn({ event: 'payment_channel_creation_failed', peerId, error: errorMessage }, 'Failed to create payment channel for peer (will retry on-demand)');
|
|
535
|
+
}
|
|
536
|
+
})();
|
|
537
|
+
channelCreationPromises.push(channelPromise);
|
|
538
|
+
}
|
|
539
|
+
await Promise.allSettled(channelCreationPromises);
|
|
540
|
+
this._logger.info({ event: 'payment_channels_initialized' }, 'Payment channel creation completed');
|
|
541
|
+
}
|
|
542
|
+
this._updateHealthStatus();
|
|
543
|
+
this._logger.info({
|
|
544
|
+
event: 'connector_ready',
|
|
545
|
+
nodeId: this._config.nodeId,
|
|
546
|
+
connectedPeers: connectedCount,
|
|
547
|
+
totalPeers: this._config.peers.length,
|
|
548
|
+
healthStatus: this._healthStatus,
|
|
549
|
+
}, 'Connector node ready');
|
|
550
|
+
}
|
|
551
|
+
catch (error) {
|
|
552
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
553
|
+
this._logger.error({
|
|
554
|
+
event: 'connector_start_failed',
|
|
555
|
+
nodeId: this._config.nodeId,
|
|
556
|
+
error: errorMessage,
|
|
557
|
+
}, 'Failed to start connector node');
|
|
558
|
+
this._healthStatus = 'unhealthy';
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async stop() {
|
|
563
|
+
if (!this._btpServerStarted && !this._adminServer) {
|
|
564
|
+
this._logger.debug({ event: 'connector_already_stopped' }, 'Connector already stopped, ignoring');
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
this._logger.info({
|
|
568
|
+
event: 'connector_stopping',
|
|
569
|
+
nodeId: this._config.nodeId,
|
|
570
|
+
}, 'Stopping connector node');
|
|
571
|
+
try {
|
|
572
|
+
if (this._settlementMonitor) {
|
|
573
|
+
await this._settlementMonitor.stop();
|
|
574
|
+
this._logger.info({ event: 'settlement_monitor_stopped' }, 'Settlement monitor stopped');
|
|
575
|
+
this._settlementMonitor = null;
|
|
576
|
+
}
|
|
577
|
+
if (this._settlementExecutor) {
|
|
578
|
+
await this._settlementExecutor.stop();
|
|
579
|
+
this._logger.info({ event: 'settlement_executor_stopped' }, 'Settlement executor stopped');
|
|
580
|
+
this._settlementExecutor = null;
|
|
581
|
+
}
|
|
582
|
+
if (this._channelManager) {
|
|
583
|
+
this._channelManager.stop();
|
|
584
|
+
this._logger.info({ event: 'channel_manager_stopped' }, 'Channel manager stopped');
|
|
585
|
+
this._channelManager = null;
|
|
586
|
+
}
|
|
587
|
+
for (const [chainId, sdk] of this._chainSDKs.entries()) {
|
|
588
|
+
sdk.removeAllListeners();
|
|
589
|
+
this._logger.debug({ event: 'chain_sdk_stopped', chainId }, `Chain SDK stopped (chainId: ${chainId})`);
|
|
590
|
+
}
|
|
591
|
+
this._chainSDKs.clear();
|
|
592
|
+
if (this._paymentChannelSDK) {
|
|
593
|
+
this._logger.info({ event: 'payment_channel_sdk_stopped' }, 'Payment channel SDK stopped');
|
|
594
|
+
this._paymentChannelSDK = null;
|
|
595
|
+
}
|
|
596
|
+
if (this._tigerBeetleClient) {
|
|
597
|
+
await this._tigerBeetleClient.close();
|
|
598
|
+
this._logger.info({ event: 'tigerbeetle_client_closed' }, 'TigerBeetle client closed');
|
|
599
|
+
this._tigerBeetleClient = null;
|
|
600
|
+
}
|
|
601
|
+
if (this._inMemoryLedgerClient) {
|
|
602
|
+
await this._inMemoryLedgerClient.close();
|
|
603
|
+
this._logger.info({ event: 'in_memory_ledger_closed' }, 'In-memory ledger client closed');
|
|
604
|
+
this._inMemoryLedgerClient = null;
|
|
605
|
+
}
|
|
606
|
+
this._accountManager = null;
|
|
607
|
+
const peerIds = this._btpClientManager.getPeerIds();
|
|
608
|
+
for (const peerId of peerIds) {
|
|
609
|
+
await this._btpClientManager.removePeer(peerId);
|
|
610
|
+
}
|
|
611
|
+
if (this._adminServer) {
|
|
612
|
+
await this._adminServer.stop();
|
|
613
|
+
this._logger.info({ event: 'admin_server_stopped' }, 'Admin API server stopped');
|
|
614
|
+
this._adminServer = null;
|
|
615
|
+
}
|
|
616
|
+
await this._healthServer.stop();
|
|
617
|
+
await this._btpServer.stop();
|
|
618
|
+
this._logger.info({
|
|
619
|
+
event: 'connector_stopped',
|
|
620
|
+
nodeId: this._config.nodeId,
|
|
621
|
+
}, 'Connector node stopped');
|
|
622
|
+
this._healthStatus = 'starting';
|
|
623
|
+
this._btpServerStarted = false;
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
627
|
+
this._logger.error({
|
|
628
|
+
event: 'connector_stop_failed',
|
|
629
|
+
nodeId: this._config.nodeId,
|
|
630
|
+
error: errorMessage,
|
|
631
|
+
}, 'Failed to stop connector node gracefully');
|
|
632
|
+
throw error;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
getHealthStatus() {
|
|
636
|
+
const peerStatus = this._btpClientManager.getPeerStatus();
|
|
637
|
+
const peersConnected = Array.from(peerStatus.values()).filter(Boolean).length;
|
|
638
|
+
const totalPeers = this._config.peers.length;
|
|
639
|
+
const uptime = Math.floor((Date.now() - this._startTime.getTime()) / 1000);
|
|
640
|
+
const healthStatus = {
|
|
641
|
+
status: this._healthStatus,
|
|
642
|
+
uptime,
|
|
643
|
+
peersConnected,
|
|
644
|
+
totalPeers,
|
|
645
|
+
timestamp: new Date().toISOString(),
|
|
646
|
+
nodeId: this._config.nodeId,
|
|
647
|
+
version: package_json_1.default.version,
|
|
648
|
+
};
|
|
649
|
+
return healthStatus;
|
|
650
|
+
}
|
|
651
|
+
get routingTable() {
|
|
652
|
+
return this._routingTable;
|
|
653
|
+
}
|
|
654
|
+
get btpClientManager() {
|
|
655
|
+
return this._btpClientManager;
|
|
656
|
+
}
|
|
657
|
+
get paymentChannelSDK() {
|
|
658
|
+
return this._paymentChannelSDK;
|
|
659
|
+
}
|
|
660
|
+
get channelManager() {
|
|
661
|
+
return this._channelManager;
|
|
662
|
+
}
|
|
663
|
+
get accountManager() {
|
|
664
|
+
return this._accountManager;
|
|
665
|
+
}
|
|
666
|
+
getPaymentChannelSDKForChain(chainId) {
|
|
667
|
+
return this._chainSDKs.get(chainId) ?? null;
|
|
668
|
+
}
|
|
669
|
+
async _createInMemoryAccountManager() {
|
|
670
|
+
const snapshotPath = this._config.settlementInfra?.ledgerSnapshotPath ??
|
|
671
|
+
process.env.LEDGER_SNAPSHOT_PATH ??
|
|
672
|
+
'./data/ledger-snapshot.json';
|
|
673
|
+
const persistIntervalMs = this._config.settlementInfra?.ledgerPersistIntervalMs ??
|
|
674
|
+
parseInt(process.env.LEDGER_PERSIST_INTERVAL_MS || '30000', 10);
|
|
675
|
+
let inMemoryClient;
|
|
676
|
+
try {
|
|
677
|
+
inMemoryClient = new in_memory_ledger_client_1.InMemoryLedgerClient({
|
|
678
|
+
snapshotPath,
|
|
679
|
+
persistIntervalMs,
|
|
680
|
+
}, this._logger);
|
|
681
|
+
await inMemoryClient.initialize();
|
|
682
|
+
this._logger.info({
|
|
683
|
+
event: 'in_memory_ledger_initialized',
|
|
684
|
+
snapshotPath,
|
|
685
|
+
persistIntervalMs,
|
|
686
|
+
}, `Accounting backend: in-memory ledger (snapshot: ${snapshotPath})`);
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
690
|
+
this._logger.warn({
|
|
691
|
+
event: 'in_memory_ledger_snapshot_restore_failed',
|
|
692
|
+
error: errorMessage,
|
|
693
|
+
snapshotPath,
|
|
694
|
+
}, 'Failed to restore from snapshot, starting with fresh in-memory ledger');
|
|
695
|
+
try {
|
|
696
|
+
inMemoryClient = new in_memory_ledger_client_1.InMemoryLedgerClient({
|
|
697
|
+
snapshotPath: `${snapshotPath}.fresh-${Date.now()}`,
|
|
698
|
+
persistIntervalMs,
|
|
699
|
+
}, this._logger);
|
|
700
|
+
await inMemoryClient.initialize();
|
|
701
|
+
this._logger.info({
|
|
702
|
+
event: 'in_memory_ledger_fresh_start',
|
|
703
|
+
snapshotPath,
|
|
704
|
+
}, 'In-memory ledger started with empty state');
|
|
705
|
+
}
|
|
706
|
+
catch (freshInitError) {
|
|
707
|
+
const freshErrorMessage = freshInitError instanceof Error ? freshInitError.message : String(freshInitError);
|
|
708
|
+
this._logger.error({
|
|
709
|
+
event: 'in_memory_ledger_fresh_init_failed',
|
|
710
|
+
error: freshErrorMessage,
|
|
711
|
+
}, 'Critical: Fresh in-memory ledger initialization failed');
|
|
712
|
+
throw freshInitError;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
this._inMemoryLedgerClient = inMemoryClient;
|
|
716
|
+
const accountManager = new account_manager_1.AccountManager({ nodeId: this._config.nodeId }, inMemoryClient, this._logger);
|
|
717
|
+
return accountManager;
|
|
718
|
+
}
|
|
719
|
+
_updateHealthStatus() {
|
|
720
|
+
if (!this._btpServerStarted) {
|
|
721
|
+
if (this._healthStatus !== 'starting') {
|
|
722
|
+
this._logger.info({
|
|
723
|
+
event: 'health_status_changed',
|
|
724
|
+
oldStatus: this._healthStatus,
|
|
725
|
+
newStatus: 'starting',
|
|
726
|
+
reason: 'BTP server not started',
|
|
727
|
+
}, 'Health status changed');
|
|
728
|
+
this._healthStatus = 'starting';
|
|
729
|
+
}
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const totalPeers = this._config.peers.length;
|
|
733
|
+
if (totalPeers === 0) {
|
|
734
|
+
if (this._healthStatus !== 'healthy') {
|
|
735
|
+
this._logger.info({
|
|
736
|
+
event: 'health_status_changed',
|
|
737
|
+
oldStatus: this._healthStatus,
|
|
738
|
+
newStatus: 'healthy',
|
|
739
|
+
reason: 'No peers configured (standalone mode)',
|
|
740
|
+
}, 'Health status changed');
|
|
741
|
+
this._healthStatus = 'healthy';
|
|
742
|
+
}
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
const peerStatus = this._btpClientManager.getPeerStatus();
|
|
746
|
+
const connectedCount = Array.from(peerStatus.values()).filter(Boolean).length;
|
|
747
|
+
const connectionPercentage = (connectedCount / totalPeers) * 100;
|
|
748
|
+
let newStatus;
|
|
749
|
+
let reason;
|
|
750
|
+
if (connectionPercentage < 50) {
|
|
751
|
+
newStatus = 'unhealthy';
|
|
752
|
+
reason = `Only ${connectedCount}/${totalPeers} peers connected (<50%)`;
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
newStatus = 'healthy';
|
|
756
|
+
reason = `${connectedCount}/${totalPeers} peers connected (≥50%)`;
|
|
757
|
+
}
|
|
758
|
+
if (this._healthStatus !== newStatus) {
|
|
759
|
+
this._logger.info({ event: 'health_status_changed', oldStatus: this._healthStatus, newStatus, reason }, 'Health status changed');
|
|
760
|
+
this._healthStatus = newStatus;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
async registerPeer(config) {
|
|
764
|
+
if (!this._btpServerStarted) {
|
|
765
|
+
throw new config_loader_1.ConnectorNotStartedError('Connector is not started. Call start() before registerPeer().');
|
|
766
|
+
}
|
|
767
|
+
if (!config.id || typeof config.id !== 'string') {
|
|
768
|
+
throw new Error('Missing or invalid peer id');
|
|
769
|
+
}
|
|
770
|
+
if (!config.url || typeof config.url !== 'string') {
|
|
771
|
+
throw new Error('Missing or invalid peer url');
|
|
772
|
+
}
|
|
773
|
+
if (config.authToken === undefined ||
|
|
774
|
+
config.authToken === null ||
|
|
775
|
+
typeof config.authToken !== 'string') {
|
|
776
|
+
throw new Error('authToken must be a string (can be empty for no auth)');
|
|
777
|
+
}
|
|
778
|
+
if (!config.url.startsWith('ws://') && !config.url.startsWith('wss://')) {
|
|
779
|
+
throw new Error('URL must start with ws:// or wss://');
|
|
780
|
+
}
|
|
781
|
+
if (config.routes) {
|
|
782
|
+
for (const route of config.routes) {
|
|
783
|
+
if (!route.prefix || typeof route.prefix !== 'string') {
|
|
784
|
+
throw new Error('Invalid route: missing prefix');
|
|
785
|
+
}
|
|
786
|
+
if (!(0, shared_1.isValidILPAddress)(route.prefix)) {
|
|
787
|
+
throw new Error(`Invalid ILP address prefix: ${route.prefix}`);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
if (config.settlement) {
|
|
792
|
+
const settlementError = (0, admin_api_1.validateSettlementConfig)(config.settlement);
|
|
793
|
+
if (settlementError) {
|
|
794
|
+
throw new Error(settlementError);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
const existingPeers = this._btpClientManager.getPeerIds();
|
|
798
|
+
const isUpdate = existingPeers.includes(config.id);
|
|
799
|
+
if (!isUpdate) {
|
|
800
|
+
const peer = {
|
|
801
|
+
id: config.id,
|
|
802
|
+
url: config.url,
|
|
803
|
+
authToken: config.authToken,
|
|
804
|
+
connected: false,
|
|
805
|
+
lastSeen: new Date(),
|
|
806
|
+
};
|
|
807
|
+
await this._btpClientManager.addPeer(peer);
|
|
808
|
+
this._logger.info({ event: 'peer_registered', peerId: config.id, url: config.url }, `Registered peer: ${config.id}`);
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
this._logger.info({ event: 'peer_reregistered', peerId: config.id }, `Re-registering peer: ${config.id}`);
|
|
812
|
+
}
|
|
813
|
+
if (config.routes) {
|
|
814
|
+
for (const route of config.routes) {
|
|
815
|
+
this._routingTable.addRoute(route.prefix, config.id, route.priority ?? 0);
|
|
816
|
+
this._logger.info({ event: 'route_added', prefix: route.prefix, nextHop: config.id }, `Added route: ${route.prefix} -> ${config.id}`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (config.settlement) {
|
|
820
|
+
this._applySettlementConfig(config.id, config.settlement, config.routes, isUpdate);
|
|
821
|
+
}
|
|
822
|
+
const routes = this._routingTable.getAllRoutes();
|
|
823
|
+
const peerRoutes = routes.filter((r) => r.nextHop === config.id);
|
|
824
|
+
const connected = this._btpClientManager.isConnected(config.id);
|
|
825
|
+
const peerInfo = {
|
|
826
|
+
id: config.id,
|
|
827
|
+
connected,
|
|
828
|
+
ilpAddresses: peerRoutes.map((r) => r.prefix),
|
|
829
|
+
routeCount: peerRoutes.length,
|
|
830
|
+
};
|
|
831
|
+
const peerConfig = this._settlementPeers.get(config.id);
|
|
832
|
+
if (peerConfig) {
|
|
833
|
+
peerInfo.settlement = {
|
|
834
|
+
preference: peerConfig.settlementPreference,
|
|
835
|
+
evmAddress: peerConfig.evmAddress,
|
|
836
|
+
tokenAddress: peerConfig.tokenAddress,
|
|
837
|
+
chainId: peerConfig.chainId,
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
return peerInfo;
|
|
841
|
+
}
|
|
842
|
+
async removePeer(peerId, removeRoutes = true) {
|
|
843
|
+
if (!this._btpServerStarted) {
|
|
844
|
+
throw new config_loader_1.ConnectorNotStartedError('Connector is not started. Call start() before removePeer().');
|
|
845
|
+
}
|
|
846
|
+
const existingPeers = this._btpClientManager.getPeerIds();
|
|
847
|
+
if (!existingPeers.includes(peerId)) {
|
|
848
|
+
throw new Error(`Peer not found: ${peerId}`);
|
|
849
|
+
}
|
|
850
|
+
await this._btpClientManager.removePeer(peerId);
|
|
851
|
+
this._logger.info({ event: 'peer_removed', peerId }, `Removed peer: ${peerId}`);
|
|
852
|
+
if (this._settlementPeers.delete(peerId)) {
|
|
853
|
+
this._logger.info({ event: 'settlement_config_removed', peerId }, `Removed settlement config for peer: ${peerId}`);
|
|
854
|
+
}
|
|
855
|
+
const removedRoutes = [];
|
|
856
|
+
if (removeRoutes) {
|
|
857
|
+
const routes = this._routingTable.getAllRoutes();
|
|
858
|
+
for (const route of routes) {
|
|
859
|
+
if (route.nextHop === peerId) {
|
|
860
|
+
this._routingTable.removeRoute(route.prefix);
|
|
861
|
+
removedRoutes.push(route.prefix);
|
|
862
|
+
this._logger.info({ event: 'route_removed', prefix: route.prefix }, `Removed route: ${route.prefix}`);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return { peerId, removedRoutes };
|
|
867
|
+
}
|
|
868
|
+
listPeers() {
|
|
869
|
+
const peerIds = this._btpClientManager.getPeerIds();
|
|
870
|
+
const peerStatus = this._btpClientManager.getPeerStatus();
|
|
871
|
+
const routes = this._routingTable.getAllRoutes();
|
|
872
|
+
return peerIds.map((peerId) => {
|
|
873
|
+
const peerRoutes = routes.filter((r) => r.nextHop === peerId);
|
|
874
|
+
const peerInfo = {
|
|
875
|
+
id: peerId,
|
|
876
|
+
connected: peerStatus.get(peerId) ?? false,
|
|
877
|
+
ilpAddresses: peerRoutes.map((r) => r.prefix),
|
|
878
|
+
routeCount: peerRoutes.length,
|
|
879
|
+
};
|
|
880
|
+
const peerConfig = this._settlementPeers.get(peerId);
|
|
881
|
+
if (peerConfig) {
|
|
882
|
+
peerInfo.settlement = {
|
|
883
|
+
preference: peerConfig.settlementPreference,
|
|
884
|
+
evmAddress: peerConfig.evmAddress,
|
|
885
|
+
tokenAddress: peerConfig.tokenAddress,
|
|
886
|
+
chainId: peerConfig.chainId,
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
return peerInfo;
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
async getBalance(peerId, tokenId = this._defaultSettlementTokenId) {
|
|
893
|
+
if (!this._accountManager) {
|
|
894
|
+
throw new Error('Account management not enabled');
|
|
895
|
+
}
|
|
896
|
+
const balance = await this._accountManager.getAccountBalance(peerId, tokenId);
|
|
897
|
+
return {
|
|
898
|
+
peerId,
|
|
899
|
+
balances: [
|
|
900
|
+
{
|
|
901
|
+
tokenId,
|
|
902
|
+
debitBalance: balance.debitBalance.toString(),
|
|
903
|
+
creditBalance: balance.creditBalance.toString(),
|
|
904
|
+
netBalance: balance.netBalance.toString(),
|
|
905
|
+
},
|
|
906
|
+
],
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
listRoutes() {
|
|
910
|
+
const routes = this._routingTable.getAllRoutes();
|
|
911
|
+
return routes.map((r) => ({
|
|
912
|
+
prefix: r.prefix,
|
|
913
|
+
nextHop: r.nextHop,
|
|
914
|
+
priority: r.priority ?? 0,
|
|
915
|
+
}));
|
|
916
|
+
}
|
|
917
|
+
addRoute(route) {
|
|
918
|
+
if (!(0, shared_1.isValidILPAddress)(route.prefix)) {
|
|
919
|
+
throw new Error(`Invalid ILP address prefix: ${route.prefix}`);
|
|
920
|
+
}
|
|
921
|
+
if (!route.nextHop || typeof route.nextHop !== 'string') {
|
|
922
|
+
throw new Error('Missing or invalid nextHop');
|
|
923
|
+
}
|
|
924
|
+
const existingPeers = this._btpClientManager.getPeerIds();
|
|
925
|
+
if (!existingPeers.includes(route.nextHop)) {
|
|
926
|
+
this._logger.warn({ event: 'route_nextHop_unknown', prefix: route.prefix, nextHop: route.nextHop }, `Adding route with unknown nextHop peer: ${route.nextHop}`);
|
|
927
|
+
}
|
|
928
|
+
this._routingTable.addRoute(route.prefix, route.nextHop, route.priority ?? 0);
|
|
929
|
+
this._logger.info({ event: 'route_added', prefix: route.prefix, nextHop: route.nextHop }, `Added route: ${route.prefix} -> ${route.nextHop}`);
|
|
930
|
+
}
|
|
931
|
+
removeRoute(prefix) {
|
|
932
|
+
const routes = this._routingTable.getAllRoutes();
|
|
933
|
+
const exists = routes.some((r) => r.prefix === prefix);
|
|
934
|
+
if (!exists) {
|
|
935
|
+
throw new Error(`Route not found: ${prefix}`);
|
|
936
|
+
}
|
|
937
|
+
this._routingTable.removeRoute(prefix);
|
|
938
|
+
this._logger.info({ event: 'route_removed', prefix }, `Removed route: ${prefix}`);
|
|
939
|
+
}
|
|
940
|
+
async openChannel(params) {
|
|
941
|
+
if (!this._btpServerStarted) {
|
|
942
|
+
throw new config_loader_1.ConnectorNotStartedError('Connector is not started. Call start() before openChannel().');
|
|
943
|
+
}
|
|
944
|
+
if (!this._channelManager) {
|
|
945
|
+
throw new Error('Settlement infrastructure not enabled');
|
|
946
|
+
}
|
|
947
|
+
const existingPeers = this._btpClientManager.getPeerIds();
|
|
948
|
+
if (!existingPeers.includes(params.peerId)) {
|
|
949
|
+
throw new Error(`Peer '${params.peerId}' must be registered before opening channels`);
|
|
950
|
+
}
|
|
951
|
+
const tokenId = params.token ?? 'AGENT';
|
|
952
|
+
const peerAddress = params.peerAddress || this._settlementPeers.get(params.peerId)?.evmAddress;
|
|
953
|
+
if (!peerAddress) {
|
|
954
|
+
throw new Error('Peer EVM address must be provided in params or peer registration');
|
|
955
|
+
}
|
|
956
|
+
const existing = this._channelManager.getChannelForPeer(params.peerId, tokenId);
|
|
957
|
+
if (existing && existing.status !== 'closed') {
|
|
958
|
+
throw new Error(`Channel already exists for peer ${params.peerId} with token ${tokenId} on chain ${params.chain}`);
|
|
959
|
+
}
|
|
960
|
+
const channelId = await this._channelManager.ensureChannelExists(params.peerId, tokenId, {
|
|
961
|
+
initialDeposit: BigInt(params.initialDeposit ?? '0'),
|
|
962
|
+
settlementTimeout: params.settlementTimeout,
|
|
963
|
+
chain: params.chain,
|
|
964
|
+
peerAddress,
|
|
965
|
+
});
|
|
966
|
+
const metadata = this._channelManager.getChannelById(channelId);
|
|
967
|
+
const status = metadata ? (0, types_1.normalizeChannelStatus)(metadata.status, this._logger) : 'opening';
|
|
968
|
+
this._logger.info({ event: 'channel_opened', peerId: params.peerId, chain: params.chain, channelId }, 'Channel opened via direct API');
|
|
969
|
+
return { channelId, status };
|
|
970
|
+
}
|
|
971
|
+
async getChannelState(channelId) {
|
|
972
|
+
if (!this._btpServerStarted) {
|
|
973
|
+
throw new config_loader_1.ConnectorNotStartedError('Connector is not started. Call start() before getChannelState().');
|
|
974
|
+
}
|
|
975
|
+
if (!this._channelManager) {
|
|
976
|
+
throw new Error('Settlement infrastructure not enabled');
|
|
977
|
+
}
|
|
978
|
+
const metadata = this._channelManager.getChannelById(channelId);
|
|
979
|
+
if (!metadata) {
|
|
980
|
+
throw new Error(`Channel not found: ${channelId}`);
|
|
981
|
+
}
|
|
982
|
+
return {
|
|
983
|
+
channelId: metadata.channelId,
|
|
984
|
+
status: (0, types_1.normalizeChannelStatus)(metadata.status, this._logger),
|
|
985
|
+
chain: metadata.chain,
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
_applySettlementConfig(peerId, s, routes, isUpdate) {
|
|
989
|
+
const ilpAddress = routes && routes.length > 0 ? routes[0].prefix : '';
|
|
990
|
+
const settlementTokens = [];
|
|
991
|
+
if (s.tokenAddress) {
|
|
992
|
+
settlementTokens.push(s.tokenAddress);
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
if (s.evmAddress)
|
|
996
|
+
settlementTokens.push('EVM');
|
|
997
|
+
}
|
|
998
|
+
const newConfig = {
|
|
999
|
+
peerId,
|
|
1000
|
+
address: ilpAddress,
|
|
1001
|
+
settlementPreference: s.preference,
|
|
1002
|
+
settlementTokens,
|
|
1003
|
+
evmAddress: s.evmAddress,
|
|
1004
|
+
tokenAddress: s.tokenAddress,
|
|
1005
|
+
tokenNetworkAddress: s.tokenNetworkAddress,
|
|
1006
|
+
chainId: s.chainId,
|
|
1007
|
+
channelId: s.channelId,
|
|
1008
|
+
initialDeposit: s.initialDeposit,
|
|
1009
|
+
};
|
|
1010
|
+
if (isUpdate) {
|
|
1011
|
+
const existingConfig = this._settlementPeers.get(peerId);
|
|
1012
|
+
if (existingConfig) {
|
|
1013
|
+
const mergedConfig = { ...existingConfig };
|
|
1014
|
+
for (const [key, value] of Object.entries(newConfig)) {
|
|
1015
|
+
if (value !== undefined) {
|
|
1016
|
+
mergedConfig[key] = value;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
this._settlementPeers.set(peerId, mergedConfig);
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
this._settlementPeers.set(peerId, newConfig);
|
|
1023
|
+
}
|
|
1024
|
+
this._logger.info({ event: 'settlement_config_merged', peerId, preference: s.preference }, `Merged settlement config for peer: ${peerId}`);
|
|
1025
|
+
}
|
|
1026
|
+
else {
|
|
1027
|
+
this._settlementPeers.set(peerId, newConfig);
|
|
1028
|
+
this._logger.info({ event: 'settlement_config_added', peerId, preference: s.preference }, `Added settlement config for peer: ${peerId}`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
getRoutingTable() {
|
|
1032
|
+
return this._routingTable.getAllRoutes();
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
exports.ConnectorNode = ConnectorNode;
|
|
1036
|
+
//# sourceMappingURL=connector-node.js.map
|