@toon-protocol/connector 3.8.1 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/btp/btp-claim-types.d.ts +3 -0
  2. package/dist/btp/btp-claim-types.d.ts.map +1 -1
  3. package/dist/btp/btp-claim-types.js +15 -0
  4. package/dist/btp/btp-claim-types.js.map +1 -1
  5. package/dist/btp/inbound-claim-validator.d.ts +4 -2
  6. package/dist/btp/inbound-claim-validator.d.ts.map +1 -1
  7. package/dist/btp/inbound-claim-validator.js +36 -9
  8. package/dist/btp/inbound-claim-validator.js.map +1 -1
  9. package/dist/config/types.d.ts +1 -0
  10. package/dist/config/types.d.ts.map +1 -1
  11. package/dist/config/types.js.map +1 -1
  12. package/dist/core/connector-node.d.ts +3 -0
  13. package/dist/core/connector-node.d.ts.map +1 -1
  14. package/dist/core/connector-node.js +213 -96
  15. package/dist/core/connector-node.js.map +1 -1
  16. package/dist/settlement/claim-receiver.d.ts +1 -0
  17. package/dist/settlement/claim-receiver.d.ts.map +1 -1
  18. package/dist/settlement/claim-receiver.js +22 -0
  19. package/dist/settlement/claim-receiver.js.map +1 -1
  20. package/dist/settlement/claim-sender.d.ts +5 -1
  21. package/dist/settlement/claim-sender.d.ts.map +1 -1
  22. package/dist/settlement/claim-sender.js +4 -1
  23. package/dist/settlement/claim-sender.js.map +1 -1
  24. package/dist/settlement/per-packet-claim-service.d.ts.map +1 -1
  25. package/dist/settlement/per-packet-claim-service.js +1 -0
  26. package/dist/settlement/per-packet-claim-service.js.map +1 -1
  27. package/dist/settlement/provider/signer-resolution.d.ts +3 -0
  28. package/dist/settlement/provider/signer-resolution.d.ts.map +1 -0
  29. package/dist/settlement/provider/signer-resolution.js +33 -0
  30. package/dist/settlement/provider/signer-resolution.js.map +1 -0
  31. package/dist/settlement/settlement-executor.d.ts +1 -0
  32. package/dist/settlement/settlement-executor.d.ts.map +1 -1
  33. package/dist/settlement/settlement-executor.js +95 -15
  34. package/dist/settlement/settlement-executor.js.map +1 -1
  35. package/package.json +1 -1
@@ -32,6 +32,9 @@ const in_memory_ledger_client_1 = require("../settlement/in-memory-ledger-client
32
32
  const per_packet_claim_service_1 = require("../settlement/per-packet-claim-service");
33
33
  const chain_provider_registry_1 = require("../settlement/provider/chain-provider-registry");
34
34
  const evm_payment_channel_provider_1 = require("../settlement/provider/evm-payment-channel-provider");
35
+ const mina_payment_channel_provider_1 = require("../settlement/provider/mina-payment-channel-provider");
36
+ const signer_resolution_1 = require("../settlement/provider/signer-resolution");
37
+ const solana_payment_channel_provider_1 = require("../settlement/provider/solana-payment-channel-provider");
35
38
  const claim_sender_db_schema_1 = require("../settlement/claim-sender-db-schema");
36
39
  const inbound_claim_validator_1 = require("../btp/inbound-claim-validator");
37
40
  const nip59_claim_wrapper_1 = require("../settlement/privacy/nip59-claim-wrapper");
@@ -54,6 +57,7 @@ class ConnectorNode {
54
57
  _claimReceiver = null;
55
58
  _settlementMonitor = null;
56
59
  _settlementExecutor = null;
60
+ _chainRegistry = null;
57
61
  _tigerBeetleClient = null;
58
62
  _inMemoryLedgerClient = null;
59
63
  _settlementPeers = new Map();
@@ -282,93 +286,133 @@ class ConnectorNode {
282
286
  const registryAddress = evmProviderConfig?.registryAddress;
283
287
  const m2mTokenAddress = evmProviderConfig?.tokenAddress;
284
288
  const treasuryPrivateKey = evmProviderConfig?.keyId;
285
- if (evmProviderConfig &&
289
+ const chainProviderConfigs = this._config.chainProviders ?? [];
290
+ const hasAnySettlementChain = chainProviderConfigs.some((p) => (p.chainType === 'evm' && p.rpcUrl && p.registryAddress && p.tokenAddress && p.keyId) ||
291
+ (p.chainType === 'solana' &&
292
+ p.rpcUrl &&
293
+ p.programId &&
294
+ (p.keyId || process.env.SOLANA_PRIVATE_KEY)) ||
295
+ (p.chainType === 'mina' &&
296
+ p.graphqlUrl &&
297
+ p.zkAppAddress &&
298
+ (p.keyId || process.env.MINA_PRIVATE_KEY)));
299
+ const hasEvm = !!(evmProviderConfig &&
286
300
  baseRpcUrl &&
287
301
  registryAddress &&
288
302
  m2mTokenAddress &&
289
- treasuryPrivateKey) {
303
+ treasuryPrivateKey);
304
+ if (hasAnySettlementChain) {
290
305
  try {
291
- const keyManager = new key_manager_1.KeyManager({
292
- backend: 'env',
293
- nodeId: this._config.nodeId,
294
- evmPrivateKey: treasuryPrivateKey,
295
- }, this._logger);
296
- const evmKeyId = 'evm';
297
- const { ethers } = await (0, optional_require_1.requireOptional)('ethers', 'EVM settlement');
298
- const provider = new ethers.JsonRpcProvider(baseRpcUrl);
299
- this._paymentChannelSDK = new payment_channel_sdk_1.PaymentChannelSDK(provider, keyManager, evmKeyId, registryAddress, this._logger);
300
- try {
301
- const resolvedSymbol = await this._paymentChannelSDK.getTokenSymbol(m2mTokenAddress);
302
- if (resolvedSymbol) {
303
- this._defaultSettlementTokenId = resolvedSymbol;
304
- this._logger.info({
305
- event: 'token_symbol_resolved',
306
- symbol: resolvedSymbol,
306
+ let primaryChainId;
307
+ if (hasEvm) {
308
+ const keyManager = new key_manager_1.KeyManager({
309
+ backend: 'env',
310
+ nodeId: this._config.nodeId,
311
+ evmPrivateKey: treasuryPrivateKey,
312
+ }, this._logger);
313
+ const evmKeyId = 'evm';
314
+ const { ethers } = await (0, optional_require_1.requireOptional)('ethers', 'EVM settlement');
315
+ const provider = new ethers.JsonRpcProvider(baseRpcUrl);
316
+ this._paymentChannelSDK = new payment_channel_sdk_1.PaymentChannelSDK(provider, keyManager, evmKeyId, registryAddress, this._logger);
317
+ try {
318
+ const resolvedSymbol = await this._paymentChannelSDK.getTokenSymbol(m2mTokenAddress);
319
+ if (resolvedSymbol) {
320
+ this._defaultSettlementTokenId = resolvedSymbol;
321
+ this._logger.info({
322
+ event: 'token_symbol_resolved',
323
+ symbol: resolvedSymbol,
324
+ tokenAddress: m2mTokenAddress,
325
+ }, `Resolved on-chain token symbol: ${resolvedSymbol}`);
326
+ }
327
+ else {
328
+ this._logger.warn({ event: 'token_symbol_empty', tokenAddress: m2mTokenAddress }, 'ERC-20 symbol() returned empty string, falling back to M2M');
329
+ }
330
+ }
331
+ catch (symbolError) {
332
+ this._logger.warn({
333
+ event: 'token_symbol_resolution_failed',
307
334
  tokenAddress: m2mTokenAddress,
308
- }, `Resolved on-chain token symbol: ${resolvedSymbol}`);
335
+ error: symbolError instanceof Error ? symbolError.message : String(symbolError),
336
+ }, 'Failed to resolve on-chain token symbol, falling back to M2M');
309
337
  }
310
- else {
311
- this._logger.warn({ event: 'token_symbol_empty', tokenAddress: m2mTokenAddress }, 'ERC-20 symbol() returned empty string, falling back to M2M');
338
+ primaryChainId =
339
+ this._config.blockchain?.base?.chainId ?? this._config.blockchain?.arbitrum?.chainId;
340
+ if (primaryChainId) {
341
+ this._chainSDKs.set(primaryChainId, this._paymentChannelSDK);
342
+ }
343
+ const enabledChains = [];
344
+ if (this._config.blockchain?.base?.enabled && this._config.blockchain.base) {
345
+ enabledChains.push({ name: 'Base', config: this._config.blockchain.base });
346
+ }
347
+ if (this._config.blockchain?.arbitrum?.enabled && this._config.blockchain.arbitrum) {
348
+ enabledChains.push({ name: 'Arbitrum', config: this._config.blockchain.arbitrum });
349
+ }
350
+ for (const chain of enabledChains) {
351
+ if (this._chainSDKs.has(chain.config.chainId)) {
352
+ continue;
353
+ }
354
+ const chainRpcUrl = chain.config.rpcUrl;
355
+ const chainRegistryAddress = chain.config.registryAddress ?? registryAddress;
356
+ const chainPrivateKey = chain.config.privateKey ?? treasuryPrivateKey;
357
+ const chainKeyManager = chainPrivateKey !== treasuryPrivateKey
358
+ ? new key_manager_1.KeyManager({
359
+ backend: 'env',
360
+ nodeId: this._config.nodeId,
361
+ evmPrivateKey: chainPrivateKey,
362
+ }, this._logger)
363
+ : keyManager;
364
+ const chainProvider = new ethers.JsonRpcProvider(chainRpcUrl);
365
+ const chainSDK = new payment_channel_sdk_1.PaymentChannelSDK(chainProvider, chainKeyManager, evmKeyId, chainRegistryAddress, this._logger);
366
+ this._chainSDKs.set(chain.config.chainId, chainSDK);
367
+ this._logger.info({
368
+ event: 'chain_sdk_initialized',
369
+ chain: chain.name,
370
+ chainId: chain.config.chainId,
371
+ rpcUrl: chainRpcUrl,
372
+ }, `PaymentChannelSDK initialized for ${chain.name} (chainId: ${chain.config.chainId})`);
312
373
  }
313
374
  }
314
- catch (symbolError) {
315
- this._logger.warn({
316
- event: 'token_symbol_resolution_failed',
317
- tokenAddress: m2mTokenAddress,
318
- error: symbolError instanceof Error ? symbolError.message : String(symbolError),
319
- }, 'Failed to resolve on-chain token symbol, falling back to M2M');
320
- }
321
- const primaryChainId = this._config.blockchain?.base?.chainId ?? this._config.blockchain?.arbitrum?.chainId;
322
- if (primaryChainId) {
323
- this._chainSDKs.set(primaryChainId, this._paymentChannelSDK);
324
- }
325
- const enabledChains = [];
326
- if (this._config.blockchain?.base?.enabled && this._config.blockchain.base) {
327
- enabledChains.push({ name: 'Base', config: this._config.blockchain.base });
328
- }
329
- if (this._config.blockchain?.arbitrum?.enabled && this._config.blockchain.arbitrum) {
330
- enabledChains.push({ name: 'Arbitrum', config: this._config.blockchain.arbitrum });
331
- }
332
- for (const chain of enabledChains) {
333
- if (this._chainSDKs.has(chain.config.chainId)) {
334
- continue;
375
+ const firstNonEvmConfig = chainProviderConfigs.find((p) => p.chainType === 'solana' || p.chainType === 'mina');
376
+ if (!hasEvm && firstNonEvmConfig) {
377
+ if (firstNonEvmConfig.chainType === 'solana') {
378
+ this._defaultSettlementTokenId = firstNonEvmConfig.tokenMint ?? 'SOL';
379
+ }
380
+ else if (firstNonEvmConfig.chainType === 'mina') {
381
+ this._defaultSettlementTokenId = firstNonEvmConfig.tokenId ?? 'MINA';
335
382
  }
336
- const chainRpcUrl = chain.config.rpcUrl;
337
- const chainRegistryAddress = chain.config.registryAddress ?? registryAddress;
338
- const chainPrivateKey = chain.config.privateKey ?? treasuryPrivateKey;
339
- const chainKeyManager = chainPrivateKey !== treasuryPrivateKey
340
- ? new key_manager_1.KeyManager({ backend: 'env', nodeId: this._config.nodeId, evmPrivateKey: chainPrivateKey }, this._logger)
341
- : keyManager;
342
- const chainProvider = new ethers.JsonRpcProvider(chainRpcUrl);
343
- const chainSDK = new payment_channel_sdk_1.PaymentChannelSDK(chainProvider, chainKeyManager, evmKeyId, chainRegistryAddress, this._logger);
344
- this._chainSDKs.set(chain.config.chainId, chainSDK);
345
- this._logger.info({
346
- event: 'chain_sdk_initialized',
347
- chain: chain.name,
348
- chainId: chain.config.chainId,
349
- rpcUrl: chainRpcUrl,
350
- }, `PaymentChannelSDK initialized for ${chain.name} (chainId: ${chain.config.chainId})`);
351
383
  }
352
384
  const peerIdToAddressMap = new Map();
353
385
  for (const peer of this._config.peers) {
354
- if (peer.evmAddress) {
355
- peerIdToAddressMap.set(peer.id, peer.evmAddress);
356
- this._logger.debug({ peerId: peer.id, address: peer.evmAddress }, 'Loaded peer EVM address from config');
386
+ const peerAddr = peer.evmAddress ?? peer.settlementAddress;
387
+ if (peerAddr) {
388
+ peerIdToAddressMap.set(peer.id, peerAddr);
389
+ this._logger.debug({ peerId: peer.id, address: peerAddr }, 'Loaded peer settlement address from config');
357
390
  }
358
391
  }
359
- for (let i = 1; i <= 10; i++) {
360
- const peerAddress = process.env[`PEER${i}_EVM_ADDRESS`];
361
- const peerId = `peer${i}`;
362
- if (peerAddress && !peerIdToAddressMap.has(peerId)) {
363
- peerIdToAddressMap.set(peerId, peerAddress);
364
- this._logger.debug({ peerId, address: peerAddress }, 'Loaded peer EVM address from env var (fallback)');
392
+ if (hasEvm) {
393
+ for (let i = 1; i <= 10; i++) {
394
+ const peerAddress = process.env[`PEER${i}_EVM_ADDRESS`];
395
+ const peerId = `peer${i}`;
396
+ if (peerAddress && !peerIdToAddressMap.has(peerId)) {
397
+ peerIdToAddressMap.set(peerId, peerAddress);
398
+ this._logger.debug({ peerId, address: peerAddress }, 'Loaded peer EVM address from env var (fallback)');
399
+ }
365
400
  }
366
401
  }
367
402
  const tokenAddressMap = new Map();
368
- tokenAddressMap.set(this._defaultSettlementTokenId, m2mTokenAddress);
369
- tokenAddressMap.set(m2mTokenAddress, m2mTokenAddress);
370
- const defaultSettlementTimeout = evmProviderConfig.settlementOptions?.settlementTimeoutSecs ?? 86400;
371
- const initialDepositMultiplier = evmProviderConfig.settlementOptions?.initialDepositMultiplier ?? 1;
403
+ if (hasEvm) {
404
+ tokenAddressMap.set(this._defaultSettlementTokenId, m2mTokenAddress);
405
+ tokenAddressMap.set(m2mTokenAddress, m2mTokenAddress);
406
+ }
407
+ else if (firstNonEvmConfig) {
408
+ const nonEvmTokenRef = firstNonEvmConfig.chainType === 'solana'
409
+ ? (firstNonEvmConfig.tokenMint ?? this._defaultSettlementTokenId)
410
+ : firstNonEvmConfig.zkAppAddress;
411
+ tokenAddressMap.set(this._defaultSettlementTokenId, nonEvmTokenRef);
412
+ }
413
+ const firstSettlementOptions = chainProviderConfigs.find((p) => p.chainType === 'evm' && !!p.settlementOptions)?.settlementOptions;
414
+ const defaultSettlementTimeout = firstSettlementOptions?.settlementTimeoutSecs ?? 86400;
415
+ const initialDepositMultiplier = firstSettlementOptions?.initialDepositMultiplier ?? 1;
372
416
  let accountManager;
373
417
  const tigerBeetleClusterId = process.env.TIGERBEETLE_CLUSTER_ID;
374
418
  const tigerBeetleReplicas = process.env.TIGERBEETLE_REPLICAS;
@@ -427,7 +471,7 @@ class ConnectorNode {
427
471
  this._accountManager = accountManager;
428
472
  }
429
473
  const peerIds = Array.from(peerIdToAddressMap.keys());
430
- const settlementThreshold = BigInt(evmProviderConfig.settlementOptions?.threshold ?? '1000000');
474
+ const settlementThreshold = BigInt(firstSettlementOptions?.threshold ?? '1000000');
431
475
  this._logger.info({
432
476
  event: 'settlement_monitor_config',
433
477
  peerIds,
@@ -441,25 +485,92 @@ class ConnectorNode {
441
485
  tokenIds: [this._defaultSettlementTokenId],
442
486
  }, this._logger);
443
487
  this._settlementMonitor = settlementMonitor;
488
+ const chainRegistry = new chain_provider_registry_1.ChainProviderRegistry();
489
+ this._chainRegistry = chainRegistry;
444
490
  const chainProviderChainId = this._config.chainProviders?.find((cp) => cp.chainType === 'evm')?.chainId;
445
- const primaryChainIdStr = primaryChainId
491
+ const evmChainIdStr = primaryChainId
446
492
  ? `evm:${primaryChainId}`
447
493
  : (chainProviderChainId ?? 'evm:unknown');
448
- const chainRegistry = new chain_provider_registry_1.ChainProviderRegistry();
449
- const evmProvider = new evm_payment_channel_provider_1.EVMPaymentChannelProvider(this._paymentChannelSDK, primaryChainIdStr, m2mTokenAddress, this._logger);
450
- chainRegistry.register(evmProvider);
494
+ if (hasEvm) {
495
+ const evmProvider = new evm_payment_channel_provider_1.EVMPaymentChannelProvider(this._paymentChannelSDK, evmChainIdStr, m2mTokenAddress, this._logger);
496
+ chainRegistry.register(evmProvider);
497
+ this._logger.info({ event: 'chain_provider_registered', chainType: 'evm', chainId: evmChainIdStr }, `EVM payment channel provider registered (${evmChainIdStr})`);
498
+ }
499
+ for (const cfg of chainProviderConfigs) {
500
+ if (cfg.chainType !== 'solana')
501
+ continue;
502
+ try {
503
+ const solanaCfg = cfg;
504
+ const signer = await (0, signer_resolution_1.resolveSolanaSigner)(solanaCfg.keyId, this._logger);
505
+ const tokenMint = solanaCfg.tokenMint ?? this._defaultSettlementTokenId;
506
+ const provider = (0, solana_payment_channel_provider_1.createSolanaProviderFactory)(this._logger, signer, tokenMint)(solanaCfg);
507
+ chainRegistry.register(provider);
508
+ this._logger.info({
509
+ event: 'chain_provider_registered',
510
+ chainType: 'solana',
511
+ chainId: provider.chainId,
512
+ }, `Solana payment channel provider registered (${provider.chainId})`);
513
+ }
514
+ catch (error) {
515
+ const errorMessage = error instanceof Error ? error.message : String(error);
516
+ this._logger.error({
517
+ event: 'chain_provider_registration_failed',
518
+ chainType: 'solana',
519
+ chainId: cfg.chainId,
520
+ error: errorMessage,
521
+ }, 'Failed to register Solana payment channel provider');
522
+ }
523
+ }
524
+ for (const cfg of chainProviderConfigs) {
525
+ if (cfg.chainType !== 'mina')
526
+ continue;
527
+ try {
528
+ const minaCfg = cfg;
529
+ const key = (0, signer_resolution_1.resolveMinaSignerKey)(minaCfg.keyId);
530
+ const provider = (0, mina_payment_channel_provider_1.createMinaProviderFactory)(this._logger, key)(minaCfg);
531
+ chainRegistry.register(provider);
532
+ this._logger.info({
533
+ event: 'chain_provider_registered',
534
+ chainType: 'mina',
535
+ chainId: provider.chainId,
536
+ }, `Mina payment channel provider registered (${provider.chainId})`);
537
+ }
538
+ catch (error) {
539
+ const errorMessage = error instanceof Error ? error.message : String(error);
540
+ this._logger.error({
541
+ event: 'chain_provider_registration_failed',
542
+ chainType: 'mina',
543
+ chainId: cfg.chainId,
544
+ error: errorMessage,
545
+ }, 'Failed to register Mina payment channel provider');
546
+ }
547
+ }
548
+ const registeredChainIds = chainRegistry.getAllProviders().map((p) => p.chainId);
549
+ const nonEvmChainIds = registeredChainIds.filter((id) => !id.startsWith('evm:'));
550
+ const primaryChainIdStr = hasEvm
551
+ ? evmChainIdStr
552
+ : nonEvmChainIds.length === 1
553
+ ? nonEvmChainIds[0]
554
+ : undefined;
451
555
  const peerIdToChainMap = new Map();
452
556
  for (const peer of this._config.peers) {
453
557
  if (peer.chain) {
454
558
  peerIdToChainMap.set(peer.id, peer.chain);
455
559
  }
456
560
  else if (peerIdToAddressMap.has(peer.id)) {
457
- peerIdToChainMap.set(peer.id, primaryChainIdStr);
561
+ if (primaryChainIdStr) {
562
+ peerIdToChainMap.set(peer.id, primaryChainIdStr);
563
+ }
564
+ else {
565
+ this._logger.warn({ event: 'peer_chain_ambiguous', peerId: peer.id, chains: nonEvmChainIds }, 'Peer has no explicit chain and multiple non-EVM chains are registered; skipping default chain mapping');
566
+ }
458
567
  }
459
568
  }
460
- for (const peerId of peerIdToAddressMap.keys()) {
461
- if (!peerIdToChainMap.has(peerId)) {
462
- peerIdToChainMap.set(peerId, primaryChainIdStr);
569
+ if (primaryChainIdStr) {
570
+ for (const peerId of peerIdToAddressMap.keys()) {
571
+ if (!peerIdToChainMap.has(peerId)) {
572
+ peerIdToChainMap.set(peerId, primaryChainIdStr);
573
+ }
463
574
  }
464
575
  }
465
576
  const nip59Enabled = this._config.nip59?.enabled ?? false;
@@ -467,7 +578,7 @@ class ConnectorNode {
467
578
  nip59Enabled,
468
579
  logger: this._logger,
469
580
  });
470
- const nodeSecp256k1PrivKey = treasuryPrivateKey
581
+ const nodeSecp256k1PrivKey = hasEvm && treasuryPrivateKey
471
582
  ? (0, utils_1.hexToBytes)(treasuryPrivateKey.replace(/^0x/, ''))
472
583
  : undefined;
473
584
  const peerIdToNip59PubKey = new Map();
@@ -498,20 +609,22 @@ class ConnectorNode {
498
609
  threshold: settlementThreshold.toString(),
499
610
  peerCount: peerIds.length,
500
611
  }, 'Event-driven settlement monitoring started');
501
- this._channelManager = new channel_manager_1.ChannelManager({
502
- nodeId: this._config.nodeId,
503
- defaultSettlementTimeout,
504
- initialDepositMultiplier,
505
- idleChannelThreshold: 86400,
506
- minDepositThreshold: 0.5,
507
- idleCheckInterval: 3600,
508
- tokenAddressMap,
509
- peerIdToAddressMap,
510
- registryAddress,
511
- rpcUrl: baseRpcUrl,
512
- privateKey: treasuryPrivateKey,
513
- }, this._paymentChannelSDK, this._settlementExecutor, this._logger);
514
- this._settlementExecutor.setChannelManager(this._channelManager);
612
+ if (hasEvm) {
613
+ this._channelManager = new channel_manager_1.ChannelManager({
614
+ nodeId: this._config.nodeId,
615
+ defaultSettlementTimeout,
616
+ initialDepositMultiplier,
617
+ idleChannelThreshold: 86400,
618
+ minDepositThreshold: 0.5,
619
+ idleCheckInterval: 3600,
620
+ tokenAddressMap,
621
+ peerIdToAddressMap,
622
+ registryAddress: registryAddress,
623
+ rpcUrl: baseRpcUrl,
624
+ privateKey: treasuryPrivateKey,
625
+ }, this._paymentChannelSDK, this._settlementExecutor, this._logger);
626
+ this._settlementExecutor.setChannelManager(this._channelManager);
627
+ }
515
628
  this._logger.info({
516
629
  event: 'payment_channel_sdk_initialized',
517
630
  registryAddress,
@@ -539,10 +652,10 @@ class ConnectorNode {
539
652
  throw error;
540
653
  }
541
654
  }
542
- const inboundClaimValidator = new inbound_claim_validator_1.InboundClaimValidator(this._paymentChannelSDK, this._config.nodeId, this._logger, this._channelManager ?? undefined, nip59Wrapper, nodeSecp256k1PrivKey, (peerId) => this._packetHandler.getPeerRelation(peerId));
655
+ const inboundClaimValidator = new inbound_claim_validator_1.InboundClaimValidator(this._paymentChannelSDK ?? undefined, this._config.nodeId, this._logger, this._channelManager ?? undefined, nip59Wrapper, nodeSecp256k1PrivKey, (peerId) => this._packetHandler.getPeerRelation(peerId), chainRegistry);
543
656
  this._btpServer.setInboundClaimValidator((protocolData, ilpPacket, peerId) => inboundClaimValidator.validate(protocolData, ilpPacket, peerId));
544
657
  this._logger.info({ event: 'inbound_claim_validator_enabled' }, 'Inbound claim validator wired to BTP server');
545
- if (this._paymentChannelSDK) {
658
+ if (chainRegistry.getAllProviders().length > 0) {
546
659
  try {
547
660
  const LibsqlModule = await (0, optional_require_1.requireOptional)('libsql', 'claim receiver persistence');
548
661
  const LibsqlDatabase = LibsqlModule.default;
@@ -767,6 +880,7 @@ class ConnectorNode {
767
880
  this._logger.info({ event: 'payment_channel_sdk_stopped' }, 'Payment channel SDK stopped');
768
881
  this._paymentChannelSDK = null;
769
882
  }
883
+ this._chainRegistry = null;
770
884
  if (this._tigerBeetleClient) {
771
885
  await this._tigerBeetleClient.close();
772
886
  this._logger.info({ event: 'tigerbeetle_client_closed' }, 'TigerBeetle client closed');
@@ -982,6 +1096,9 @@ class ConnectorNode {
982
1096
  get paymentChannelSDK() {
983
1097
  return this._paymentChannelSDK;
984
1098
  }
1099
+ get chainRegistry() {
1100
+ return this._chainRegistry;
1101
+ }
985
1102
  get channelManager() {
986
1103
  return this._channelManager;
987
1104
  }