@terkoizmy/intent-sdk 1.0.0
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 +258 -0
- package/dist/config/chains.d.ts +25 -0
- package/dist/config/chains.d.ts.map +1 -0
- package/dist/config/chains.js +85 -0
- package/dist/config/chains.js.map +1 -0
- package/dist/config/default.d.ts +39 -0
- package/dist/config/default.d.ts.map +1 -0
- package/dist/config/default.js +46 -0
- package/dist/config/default.js.map +1 -0
- package/dist/config/testnets.d.ts +31 -0
- package/dist/config/testnets.d.ts.map +1 -0
- package/dist/config/testnets.js +99 -0
- package/dist/config/testnets.js.map +1 -0
- package/dist/errors/inventory-errors.d.ts +31 -0
- package/dist/errors/inventory-errors.d.ts.map +1 -0
- package/dist/errors/inventory-errors.js +45 -0
- package/dist/errors/inventory-errors.js.map +1 -0
- package/dist/errors/settlement-errors.d.ts +27 -0
- package/dist/errors/settlement-errors.d.ts.map +1 -0
- package/dist/errors/settlement-errors.js +39 -0
- package/dist/errors/settlement-errors.js.map +1 -0
- package/dist/errors/solver-errors.d.ts +45 -0
- package/dist/errors/solver-errors.d.ts.map +1 -0
- package/dist/errors/solver-errors.js +66 -0
- package/dist/errors/solver-errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/classifiers/intent-classifier.d.ts +40 -0
- package/dist/parser/classifiers/intent-classifier.d.ts.map +1 -0
- package/dist/parser/classifiers/intent-classifier.js +72 -0
- package/dist/parser/classifiers/intent-classifier.js.map +1 -0
- package/dist/parser/extractors/action.d.ts +32 -0
- package/dist/parser/extractors/action.d.ts.map +1 -0
- package/dist/parser/extractors/action.js +72 -0
- package/dist/parser/extractors/action.js.map +1 -0
- package/dist/parser/extractors/amount.d.ts +39 -0
- package/dist/parser/extractors/amount.d.ts.map +1 -0
- package/dist/parser/extractors/amount.js +113 -0
- package/dist/parser/extractors/amount.js.map +1 -0
- package/dist/parser/extractors/constraints.d.ts +37 -0
- package/dist/parser/extractors/constraints.d.ts.map +1 -0
- package/dist/parser/extractors/constraints.js +119 -0
- package/dist/parser/extractors/constraints.js.map +1 -0
- package/dist/parser/extractors/index.d.ts +5 -0
- package/dist/parser/extractors/index.d.ts.map +1 -0
- package/dist/parser/extractors/index.js +5 -0
- package/dist/parser/extractors/index.js.map +1 -0
- package/dist/parser/extractors/token.d.ts +24 -0
- package/dist/parser/extractors/token.d.ts.map +1 -0
- package/dist/parser/extractors/token.js +124 -0
- package/dist/parser/extractors/token.js.map +1 -0
- package/dist/parser/index.d.ts +125 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +293 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/template/bridge.d.ts +37 -0
- package/dist/parser/template/bridge.d.ts.map +1 -0
- package/dist/parser/template/bridge.js +80 -0
- package/dist/parser/template/bridge.js.map +1 -0
- package/dist/parser/template/claim.d.ts +15 -0
- package/dist/parser/template/claim.d.ts.map +1 -0
- package/dist/parser/template/claim.js +36 -0
- package/dist/parser/template/claim.js.map +1 -0
- package/dist/parser/template/index.d.ts +28 -0
- package/dist/parser/template/index.d.ts.map +1 -0
- package/dist/parser/template/index.js +50 -0
- package/dist/parser/template/index.js.map +1 -0
- package/dist/parser/template/nft.d.ts +3 -0
- package/dist/parser/template/nft.d.ts.map +1 -0
- package/dist/parser/template/nft.js +19 -0
- package/dist/parser/template/nft.js.map +1 -0
- package/dist/parser/template/send.d.ts +24 -0
- package/dist/parser/template/send.d.ts.map +1 -0
- package/dist/parser/template/send.js +61 -0
- package/dist/parser/template/send.js.map +1 -0
- package/dist/parser/template/swap.d.ts +3 -0
- package/dist/parser/template/swap.d.ts.map +1 -0
- package/dist/parser/template/swap.js +21 -0
- package/dist/parser/template/swap.js.map +1 -0
- package/dist/parser/template/unknown.d.ts +3 -0
- package/dist/parser/template/unknown.d.ts.map +1 -0
- package/dist/parser/template/unknown.js +11 -0
- package/dist/parser/template/unknown.js.map +1 -0
- package/dist/parser/template/yield.d.ts +3 -0
- package/dist/parser/template/yield.d.ts.map +1 -0
- package/dist/parser/template/yield.js +25 -0
- package/dist/parser/template/yield.js.map +1 -0
- package/dist/parser/utils/normalize.d.ts +41 -0
- package/dist/parser/utils/normalize.d.ts.map +1 -0
- package/dist/parser/utils/normalize.js +71 -0
- package/dist/parser/utils/normalize.js.map +1 -0
- package/dist/parser/utils/parser-helpers.d.ts +20 -0
- package/dist/parser/utils/parser-helpers.d.ts.map +1 -0
- package/dist/parser/utils/parser-helpers.js +282 -0
- package/dist/parser/utils/parser-helpers.js.map +1 -0
- package/dist/parser/validators/schema.d.ts +14 -0
- package/dist/parser/validators/schema.d.ts.map +1 -0
- package/dist/parser/validators/schema.js +81 -0
- package/dist/parser/validators/schema.js.map +1 -0
- package/dist/sdk-factory.d.ts +55 -0
- package/dist/sdk-factory.d.ts.map +1 -0
- package/dist/sdk-factory.js +49 -0
- package/dist/sdk-factory.js.map +1 -0
- package/dist/services/token-resolver.d.ts +142 -0
- package/dist/services/token-resolver.d.ts.map +1 -0
- package/dist/services/token-resolver.js +254 -0
- package/dist/services/token-resolver.js.map +1 -0
- package/dist/shared/chain-registry/chain-names.d.ts +22 -0
- package/dist/shared/chain-registry/chain-names.d.ts.map +1 -0
- package/dist/shared/chain-registry/chain-names.js +49 -0
- package/dist/shared/chain-registry/chain-names.js.map +1 -0
- package/dist/shared/chain-registry/configs/arbitrum-sepolia.d.ts +9 -0
- package/dist/shared/chain-registry/configs/arbitrum-sepolia.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/arbitrum-sepolia.js +9 -0
- package/dist/shared/chain-registry/configs/arbitrum-sepolia.js.map +1 -0
- package/dist/shared/chain-registry/configs/base-sepolia.d.ts +9 -0
- package/dist/shared/chain-registry/configs/base-sepolia.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/base-sepolia.js +9 -0
- package/dist/shared/chain-registry/configs/base-sepolia.js.map +1 -0
- package/dist/shared/chain-registry/configs/ethereum.d.ts +7 -0
- package/dist/shared/chain-registry/configs/ethereum.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/ethereum.js +7 -0
- package/dist/shared/chain-registry/configs/ethereum.js.map +1 -0
- package/dist/shared/chain-registry/configs/polygon.d.ts +7 -0
- package/dist/shared/chain-registry/configs/polygon.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/polygon.js +7 -0
- package/dist/shared/chain-registry/configs/polygon.js.map +1 -0
- package/dist/shared/chain-registry/configs/sepolia.d.ts +9 -0
- package/dist/shared/chain-registry/configs/sepolia.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/sepolia.js +9 -0
- package/dist/shared/chain-registry/configs/sepolia.js.map +1 -0
- package/dist/shared/chain-registry/configs/unichain-sepolia.d.ts +9 -0
- package/dist/shared/chain-registry/configs/unichain-sepolia.d.ts.map +1 -0
- package/dist/shared/chain-registry/configs/unichain-sepolia.js +9 -0
- package/dist/shared/chain-registry/configs/unichain-sepolia.js.map +1 -0
- package/dist/shared/chain-registry/registry.d.ts +50 -0
- package/dist/shared/chain-registry/registry.d.ts.map +1 -0
- package/dist/shared/chain-registry/registry.js +72 -0
- package/dist/shared/chain-registry/registry.js.map +1 -0
- package/dist/shared/rpc/provider-manager.d.ts +111 -0
- package/dist/shared/rpc/provider-manager.d.ts.map +1 -0
- package/dist/shared/rpc/provider-manager.js +116 -0
- package/dist/shared/rpc/provider-manager.js.map +1 -0
- package/dist/shared/rpc/viem-provider.d.ts +78 -0
- package/dist/shared/rpc/viem-provider.d.ts.map +1 -0
- package/dist/shared/rpc/viem-provider.js +187 -0
- package/dist/shared/rpc/viem-provider.js.map +1 -0
- package/dist/shared/token-registry/enrichment.d.ts +48 -0
- package/dist/shared/token-registry/enrichment.d.ts.map +1 -0
- package/dist/shared/token-registry/enrichment.js +69 -0
- package/dist/shared/token-registry/enrichment.js.map +1 -0
- package/dist/shared/token-registry/registry.d.ts +119 -0
- package/dist/shared/token-registry/registry.d.ts.map +1 -0
- package/dist/shared/token-registry/registry.js +200 -0
- package/dist/shared/token-registry/registry.js.map +1 -0
- package/dist/shared/utils/erc20-utils.d.ts +24 -0
- package/dist/shared/utils/erc20-utils.d.ts.map +1 -0
- package/dist/shared/utils/erc20-utils.js +31 -0
- package/dist/shared/utils/erc20-utils.js.map +1 -0
- package/dist/shared/utils/retry.d.ts +57 -0
- package/dist/shared/utils/retry.d.ts.map +1 -0
- package/dist/shared/utils/retry.js +104 -0
- package/dist/shared/utils/retry.js.map +1 -0
- package/dist/shared/wallet-manager/viem-signer.d.ts +68 -0
- package/dist/shared/wallet-manager/viem-signer.d.ts.map +1 -0
- package/dist/shared/wallet-manager/viem-signer.js +116 -0
- package/dist/shared/wallet-manager/viem-signer.js.map +1 -0
- package/dist/shared/wallet-manager/wallet-manager.d.ts +96 -0
- package/dist/shared/wallet-manager/wallet-manager.d.ts.map +1 -0
- package/dist/shared/wallet-manager/wallet-manager.js +104 -0
- package/dist/shared/wallet-manager/wallet-manager.js.map +1 -0
- package/dist/solver/agent/agent-config.d.ts +62 -0
- package/dist/solver/agent/agent-config.d.ts.map +1 -0
- package/dist/solver/agent/agent-config.js +59 -0
- package/dist/solver/agent/agent-config.js.map +1 -0
- package/dist/solver/agent/index.d.ts +6 -0
- package/dist/solver/agent/index.d.ts.map +1 -0
- package/dist/solver/agent/index.js +6 -0
- package/dist/solver/agent/index.js.map +1 -0
- package/dist/solver/agent/liquidity-agent.d.ts +118 -0
- package/dist/solver/agent/liquidity-agent.d.ts.map +1 -0
- package/dist/solver/agent/liquidity-agent.js +285 -0
- package/dist/solver/agent/liquidity-agent.js.map +1 -0
- package/dist/solver/contracts/intent-settlement/index.d.ts +2 -0
- package/dist/solver/contracts/intent-settlement/index.d.ts.map +1 -0
- package/dist/solver/contracts/intent-settlement/index.js +2 -0
- package/dist/solver/contracts/intent-settlement/index.js.map +1 -0
- package/dist/solver/contracts/intent-settlement/intent-settlement.d.ts +22 -0
- package/dist/solver/contracts/intent-settlement/intent-settlement.d.ts.map +1 -0
- package/dist/solver/contracts/intent-settlement/intent-settlement.js +58 -0
- package/dist/solver/contracts/intent-settlement/intent-settlement.js.map +1 -0
- package/dist/solver/contracts/intent-settlement/viem-settlement-contract.d.ts +226 -0
- package/dist/solver/contracts/intent-settlement/viem-settlement-contract.d.ts.map +1 -0
- package/dist/solver/contracts/intent-settlement/viem-settlement-contract.js +204 -0
- package/dist/solver/contracts/intent-settlement/viem-settlement-contract.js.map +1 -0
- package/dist/solver/index.d.ts +87 -0
- package/dist/solver/index.d.ts.map +1 -0
- package/dist/solver/index.js +167 -0
- package/dist/solver/index.js.map +1 -0
- package/dist/solver/inventory/index.d.ts +7 -0
- package/dist/solver/inventory/index.d.ts.map +1 -0
- package/dist/solver/inventory/index.js +7 -0
- package/dist/solver/inventory/index.js.map +1 -0
- package/dist/solver/inventory/inventory-manager.d.ts +135 -0
- package/dist/solver/inventory/inventory-manager.d.ts.map +1 -0
- package/dist/solver/inventory/inventory-manager.js +323 -0
- package/dist/solver/inventory/inventory-manager.js.map +1 -0
- package/dist/solver/inventory/inventory-monitor.d.ts +72 -0
- package/dist/solver/inventory/inventory-monitor.d.ts.map +1 -0
- package/dist/solver/inventory/inventory-monitor.js +123 -0
- package/dist/solver/inventory/inventory-monitor.js.map +1 -0
- package/dist/solver/inventory/rebalancer.d.ts +78 -0
- package/dist/solver/inventory/rebalancer.d.ts.map +1 -0
- package/dist/solver/inventory/rebalancer.js +210 -0
- package/dist/solver/inventory/rebalancer.js.map +1 -0
- package/dist/solver/mempool/index.d.ts +8 -0
- package/dist/solver/mempool/index.d.ts.map +1 -0
- package/dist/solver/mempool/index.js +8 -0
- package/dist/solver/mempool/index.js.map +1 -0
- package/dist/solver/mempool/intent-filter.d.ts +49 -0
- package/dist/solver/mempool/intent-filter.d.ts.map +1 -0
- package/dist/solver/mempool/intent-filter.js +75 -0
- package/dist/solver/mempool/intent-filter.js.map +1 -0
- package/dist/solver/mempool/mempool-client.d.ts +105 -0
- package/dist/solver/mempool/mempool-client.d.ts.map +1 -0
- package/dist/solver/mempool/mempool-client.js +161 -0
- package/dist/solver/mempool/mempool-client.js.map +1 -0
- package/dist/solver/mempool/mempool-monitor.d.ts +71 -0
- package/dist/solver/mempool/mempool-monitor.d.ts.map +1 -0
- package/dist/solver/mempool/mempool-monitor.js +127 -0
- package/dist/solver/mempool/mempool-monitor.js.map +1 -0
- package/dist/solver/mempool/solution-submitter.d.ts +41 -0
- package/dist/solver/mempool/solution-submitter.d.ts.map +1 -0
- package/dist/solver/mempool/solution-submitter.js +71 -0
- package/dist/solver/mempool/solution-submitter.js.map +1 -0
- package/dist/solver/monitoring/alert-manager.d.ts +43 -0
- package/dist/solver/monitoring/alert-manager.d.ts.map +1 -0
- package/dist/solver/monitoring/alert-manager.js +69 -0
- package/dist/solver/monitoring/alert-manager.js.map +1 -0
- package/dist/solver/monitoring/health-checker.d.ts +53 -0
- package/dist/solver/monitoring/health-checker.d.ts.map +1 -0
- package/dist/solver/monitoring/health-checker.js +94 -0
- package/dist/solver/monitoring/health-checker.js.map +1 -0
- package/dist/solver/monitoring/index.d.ts +7 -0
- package/dist/solver/monitoring/index.d.ts.map +1 -0
- package/dist/solver/monitoring/index.js +7 -0
- package/dist/solver/monitoring/index.js.map +1 -0
- package/dist/solver/monitoring/profit-tracker.d.ts +47 -0
- package/dist/solver/monitoring/profit-tracker.d.ts.map +1 -0
- package/dist/solver/monitoring/profit-tracker.js +112 -0
- package/dist/solver/monitoring/profit-tracker.js.map +1 -0
- package/dist/solver/pricing/dynamic-pricing.d.ts +86 -0
- package/dist/solver/pricing/dynamic-pricing.d.ts.map +1 -0
- package/dist/solver/pricing/dynamic-pricing.js +189 -0
- package/dist/solver/pricing/dynamic-pricing.js.map +1 -0
- package/dist/solver/pricing/fee-calculator.d.ts +101 -0
- package/dist/solver/pricing/fee-calculator.d.ts.map +1 -0
- package/dist/solver/pricing/fee-calculator.js +149 -0
- package/dist/solver/pricing/fee-calculator.js.map +1 -0
- package/dist/solver/pricing/index.d.ts +7 -0
- package/dist/solver/pricing/index.d.ts.map +1 -0
- package/dist/solver/pricing/index.js +7 -0
- package/dist/solver/pricing/index.js.map +1 -0
- package/dist/solver/pricing/slippage-capture.d.ts +47 -0
- package/dist/solver/pricing/slippage-capture.d.ts.map +1 -0
- package/dist/solver/pricing/slippage-capture.js +63 -0
- package/dist/solver/pricing/slippage-capture.js.map +1 -0
- package/dist/solver/protocols/aggregators/lifi.d.ts +109 -0
- package/dist/solver/protocols/aggregators/lifi.d.ts.map +1 -0
- package/dist/solver/protocols/aggregators/lifi.js +110 -0
- package/dist/solver/protocols/aggregators/lifi.js.map +1 -0
- package/dist/solver/protocols/aggregators/swing.d.ts +67 -0
- package/dist/solver/protocols/aggregators/swing.d.ts.map +1 -0
- package/dist/solver/protocols/aggregators/swing.js +212 -0
- package/dist/solver/protocols/aggregators/swing.js.map +1 -0
- package/dist/solver/protocols/base-protocol.d.ts +42 -0
- package/dist/solver/protocols/base-protocol.d.ts.map +1 -0
- package/dist/solver/protocols/base-protocol.js +16 -0
- package/dist/solver/protocols/base-protocol.js.map +1 -0
- package/dist/solver/protocols/index.d.ts +10 -0
- package/dist/solver/protocols/index.d.ts.map +1 -0
- package/dist/solver/protocols/index.js +10 -0
- package/dist/solver/protocols/index.js.map +1 -0
- package/dist/solver/protocols/lending/aave.d.ts +51 -0
- package/dist/solver/protocols/lending/aave.d.ts.map +1 -0
- package/dist/solver/protocols/lending/aave.js +172 -0
- package/dist/solver/protocols/lending/aave.js.map +1 -0
- package/dist/solver/protocols/protocol-registry.d.ts +28 -0
- package/dist/solver/protocols/protocol-registry.d.ts.map +1 -0
- package/dist/solver/protocols/protocol-registry.js +40 -0
- package/dist/solver/protocols/protocol-registry.js.map +1 -0
- package/dist/solver/settlement/index.d.ts +7 -0
- package/dist/solver/settlement/index.d.ts.map +1 -0
- package/dist/solver/settlement/index.js +7 -0
- package/dist/solver/settlement/index.js.map +1 -0
- package/dist/solver/settlement/live-settlement-manager.d.ts +62 -0
- package/dist/solver/settlement/live-settlement-manager.d.ts.map +1 -0
- package/dist/solver/settlement/live-settlement-manager.js +68 -0
- package/dist/solver/settlement/live-settlement-manager.js.map +1 -0
- package/dist/solver/settlement/proof-generator.d.ts +48 -0
- package/dist/solver/settlement/proof-generator.d.ts.map +1 -0
- package/dist/solver/settlement/proof-generator.js +100 -0
- package/dist/solver/settlement/proof-generator.js.map +1 -0
- package/dist/solver/settlement/proof-verifier.d.ts +31 -0
- package/dist/solver/settlement/proof-verifier.d.ts.map +1 -0
- package/dist/solver/settlement/proof-verifier.js +46 -0
- package/dist/solver/settlement/proof-verifier.js.map +1 -0
- package/dist/solver/settlement/settlement-manager.d.ts +97 -0
- package/dist/solver/settlement/settlement-manager.d.ts.map +1 -0
- package/dist/solver/settlement/settlement-manager.js +220 -0
- package/dist/solver/settlement/settlement-manager.js.map +1 -0
- package/dist/solver/types/agent.d.ts +92 -0
- package/dist/solver/types/agent.d.ts.map +1 -0
- package/dist/solver/types/agent.js +8 -0
- package/dist/solver/types/agent.js.map +1 -0
- package/dist/solver/types/execution.d.ts +70 -0
- package/dist/solver/types/execution.d.ts.map +1 -0
- package/dist/solver/types/execution.js +7 -0
- package/dist/solver/types/execution.js.map +1 -0
- package/dist/solver/types/index.d.ts +13 -0
- package/dist/solver/types/index.d.ts.map +1 -0
- package/dist/solver/types/index.js +13 -0
- package/dist/solver/types/index.js.map +1 -0
- package/dist/solver/types/intent.d.ts +82 -0
- package/dist/solver/types/intent.d.ts.map +1 -0
- package/dist/solver/types/intent.js +33 -0
- package/dist/solver/types/intent.js.map +1 -0
- package/dist/solver/types/inventory.d.ts +83 -0
- package/dist/solver/types/inventory.d.ts.map +1 -0
- package/dist/solver/types/inventory.js +8 -0
- package/dist/solver/types/inventory.js.map +1 -0
- package/dist/solver/types/pricing.d.ts +59 -0
- package/dist/solver/types/pricing.d.ts.map +1 -0
- package/dist/solver/types/pricing.js +8 -0
- package/dist/solver/types/pricing.js.map +1 -0
- package/dist/solver/types/settlement.d.ts +98 -0
- package/dist/solver/types/settlement.d.ts.map +1 -0
- package/dist/solver/types/settlement.js +9 -0
- package/dist/solver/types/settlement.js.map +1 -0
- package/dist/types/chain.d.ts +66 -0
- package/dist/types/chain.d.ts.map +1 -0
- package/dist/types/chain.js +7 -0
- package/dist/types/chain.js.map +1 -0
- package/dist/types/common.d.ts +44 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +8 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/entities.d.ts +61 -0
- package/dist/types/entities.d.ts.map +1 -0
- package/dist/types/entities.js +2 -0
- package/dist/types/entities.js.map +1 -0
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/intent.d.ts +70 -0
- package/dist/types/intent.d.ts.map +1 -0
- package/dist/types/intent.js +2 -0
- package/dist/types/intent.js.map +1 -0
- package/dist/types/templates.d.ts +18 -0
- package/dist/types/templates.d.ts.map +1 -0
- package/dist/types/templates.js +2 -0
- package/dist/types/templates.js.map +1 -0
- package/dist/types/token.d.ts +132 -0
- package/dist/types/token.d.ts.map +1 -0
- package/dist/types/token.js +8 -0
- package/dist/types/token.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebalancer
|
|
3
|
+
*
|
|
4
|
+
* Detects when inventory is unevenly distributed across chains
|
|
5
|
+
* and triggers cross-chain bridging to restore target distribution.
|
|
6
|
+
*
|
|
7
|
+
* Uses the Swing.xyz aggregator (Phase I) to find the best bridge route.
|
|
8
|
+
* Priority order: critical > high > medium > low.
|
|
9
|
+
*
|
|
10
|
+
* EXAMPLE:
|
|
11
|
+
* Target: 50% ETH, 50% Polygon
|
|
12
|
+
* Actual: 80% ETH, 20% Polygon
|
|
13
|
+
* → RebalanceTask { fromChain: 1, toChain: 137, amount: 30% of total }
|
|
14
|
+
*/
|
|
15
|
+
export class Rebalancer {
|
|
16
|
+
inventoryManager;
|
|
17
|
+
bridgeProtocol;
|
|
18
|
+
config;
|
|
19
|
+
agentAddress;
|
|
20
|
+
constructor(inventoryManager, bridgeProtocol, config,
|
|
21
|
+
/** Agent address to receive funds on destination */
|
|
22
|
+
agentAddress) {
|
|
23
|
+
this.inventoryManager = inventoryManager;
|
|
24
|
+
this.bridgeProtocol = bridgeProtocol;
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.agentAddress = agentAddress;
|
|
27
|
+
}
|
|
28
|
+
// ─────────────────────────────────────────────
|
|
29
|
+
// Public API
|
|
30
|
+
// ─────────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Detect chains whose balance deviates from target distribution.
|
|
33
|
+
*
|
|
34
|
+
* Uses **net available balance** (available − locked) per chain so the
|
|
35
|
+
* calculation is consistent with getTotalBalance(), which also uses net.
|
|
36
|
+
*
|
|
37
|
+
* @param token - Token symbol to check. Defaults to "USDC".
|
|
38
|
+
* @returns Array of RebalanceTasks sorted by priority (critical first)
|
|
39
|
+
*/
|
|
40
|
+
needsRebalancing(token = "USDC") {
|
|
41
|
+
const total = this.inventoryManager.getTotalBalance(token);
|
|
42
|
+
if (total === 0n)
|
|
43
|
+
return [];
|
|
44
|
+
const snapshot = this.inventoryManager.getSnapshot();
|
|
45
|
+
const tasks = [];
|
|
46
|
+
// Group balances by chain using NET available (available − locked).
|
|
47
|
+
// Must match getTotalBalance() semantics — both use net — so that
|
|
48
|
+
// per-chain percentages add up to 100%.
|
|
49
|
+
const chainBalances = new Map();
|
|
50
|
+
for (const b of snapshot.balances) {
|
|
51
|
+
if (b.token === token) {
|
|
52
|
+
const net = b.available - b.locked;
|
|
53
|
+
chainBalances.set(b.chainId, net > 0n ? net : 0n);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Clone targetDistribution to avoid mutating the config object.
|
|
57
|
+
// Record<string, number> is used because JS object keys are always strings;
|
|
58
|
+
// chain IDs are coerced to string when used as keys.
|
|
59
|
+
const targets = this.config.targetDistribution
|
|
60
|
+
? { ...this.config.targetDistribution }
|
|
61
|
+
: {};
|
|
62
|
+
const chainIds = Array.from(chainBalances.keys());
|
|
63
|
+
// If no explicit targets, distribute equally among active chains
|
|
64
|
+
if (Object.keys(targets).length === 0 && chainIds.length > 0) {
|
|
65
|
+
const share = 1 / chainIds.length;
|
|
66
|
+
chainIds.forEach(id => {
|
|
67
|
+
targets[String(id)] = share;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Calculate deviations
|
|
71
|
+
const excesses = [];
|
|
72
|
+
const deficits = [];
|
|
73
|
+
// Iterate over the union of chains with a balance and chains with a target
|
|
74
|
+
const allChains = new Set([...chainIds, ...Object.keys(targets).map(Number)]);
|
|
75
|
+
for (const chainId of allChains) {
|
|
76
|
+
const current = chainBalances.get(chainId) ?? 0n;
|
|
77
|
+
// Keys are stored as strings; coerce chainId to string for lookup
|
|
78
|
+
const targetPercent = targets[String(chainId)] ?? 0;
|
|
79
|
+
// Target amount = total * targetPercent using basis-point integer math
|
|
80
|
+
const bps = BigInt(Math.floor(targetPercent * 10000));
|
|
81
|
+
const targetAmount = (total * bps) / 10000n;
|
|
82
|
+
if (current > targetAmount) {
|
|
83
|
+
excesses.push({ chainId, amount: current - targetAmount });
|
|
84
|
+
}
|
|
85
|
+
else if (current < targetAmount) {
|
|
86
|
+
deficits.push({ chainId, amount: targetAmount - current });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Match excesses to deficits.
|
|
90
|
+
// Greedy strategy: pair largest excess with largest deficit first.
|
|
91
|
+
// Use a safe bigint comparator to avoid Number precision loss for very
|
|
92
|
+
// large amounts (> Number.MAX_SAFE_INTEGER ≈ 9 quadrillion raw units).
|
|
93
|
+
const safeCmp = (a, b) => (a > b ? -1 : a < b ? 1 : 0);
|
|
94
|
+
excesses.sort((a, b) => safeCmp(a.amount, b.amount));
|
|
95
|
+
deficits.sort((a, b) => safeCmp(a.amount, b.amount));
|
|
96
|
+
// Pair tasks (token is the parameterised token, not hardcoded)
|
|
97
|
+
let eIdx = 0;
|
|
98
|
+
let dIdx = 0;
|
|
99
|
+
while (eIdx < excesses.length && dIdx < deficits.length) {
|
|
100
|
+
const source = excesses[eIdx];
|
|
101
|
+
const target = deficits[dIdx];
|
|
102
|
+
// Amount to move is min(excess, deficit)
|
|
103
|
+
let amount = source.amount < target.amount ? source.amount : target.amount;
|
|
104
|
+
// Check if this move is significant enough (deviation > threshold)
|
|
105
|
+
// Deviation = amount / total
|
|
106
|
+
const deviation = Number(amount) / Number(total);
|
|
107
|
+
if (deviation > this.config.rebalanceThreshold) {
|
|
108
|
+
let priority = "low";
|
|
109
|
+
if (deviation > 0.5)
|
|
110
|
+
priority = "critical";
|
|
111
|
+
else if (deviation > 0.3)
|
|
112
|
+
priority = "high";
|
|
113
|
+
else if (deviation > this.config.rebalanceThreshold)
|
|
114
|
+
priority = "medium";
|
|
115
|
+
tasks.push({
|
|
116
|
+
fromChain: source.chainId,
|
|
117
|
+
toChain: target.chainId,
|
|
118
|
+
token,
|
|
119
|
+
amount,
|
|
120
|
+
reason: `Deviation ${(deviation * 100).toFixed(1)}% exceeds threshold`,
|
|
121
|
+
priority,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// Update remaining amounts
|
|
125
|
+
source.amount -= amount;
|
|
126
|
+
target.amount -= amount;
|
|
127
|
+
if (source.amount === 0n)
|
|
128
|
+
eIdx++;
|
|
129
|
+
if (target.amount === 0n)
|
|
130
|
+
dIdx++;
|
|
131
|
+
}
|
|
132
|
+
// Sort by priority
|
|
133
|
+
const priorityWeight = { "critical": 4, "high": 3, "medium": 2, "low": 1 };
|
|
134
|
+
return tasks.sort((a, b) => priorityWeight[b.priority] - priorityWeight[a.priority]);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Execute a single rebalance task.
|
|
138
|
+
*/
|
|
139
|
+
async execute(task) {
|
|
140
|
+
console.log(`Executing rebalance: ${task.amount} ${task.token} from ${task.fromChain} to ${task.toChain}`);
|
|
141
|
+
try {
|
|
142
|
+
// 1. Get quote to verify feasibility
|
|
143
|
+
const quote = await this.bridgeProtocol.quote({
|
|
144
|
+
fromChain: task.fromChain,
|
|
145
|
+
toChain: task.toChain,
|
|
146
|
+
token: task.token,
|
|
147
|
+
amount: task.amount,
|
|
148
|
+
});
|
|
149
|
+
console.log(`Bridge quote: Fee ${quote.fee}, Output ${quote.outputAmount}`);
|
|
150
|
+
// 2. Lock funds BEFORE calling bridge.
|
|
151
|
+
// Any concurrent canFulfill() check will immediately see the
|
|
152
|
+
// reservation, preventing double-spending.
|
|
153
|
+
// If lockAmount throws (e.g. insufficient balance), the bridge
|
|
154
|
+
// is never called and the exception propagates to the catch block.
|
|
155
|
+
const rebalanceId = `rebalance-${Date.now()}`;
|
|
156
|
+
this.inventoryManager.lockAmount(task.fromChain, task.token, task.amount, rebalanceId);
|
|
157
|
+
// 3. Execute bridge
|
|
158
|
+
const result = await this.bridgeProtocol.bridge({
|
|
159
|
+
fromChain: task.fromChain,
|
|
160
|
+
toChain: task.toChain,
|
|
161
|
+
token: task.token,
|
|
162
|
+
amount: task.amount,
|
|
163
|
+
recipient: this.agentAddress,
|
|
164
|
+
});
|
|
165
|
+
if (result.success) {
|
|
166
|
+
// 4a. Success — confirm deduction (consumes the lock and reduces available).
|
|
167
|
+
this.inventoryManager.confirmDeduction(task.fromChain, task.token, task.amount, rebalanceId);
|
|
168
|
+
console.log(`Rebalance tx sent: ${result.txHash}`);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// 4b. Failure — release the lock to restore available balance.
|
|
172
|
+
console.error("Rebalance failed execution:", result.error);
|
|
173
|
+
this.inventoryManager.unlockAmount(task.fromChain, task.token, task.amount, rebalanceId);
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error("Rebalance exception:", error);
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
error: error instanceof Error ? error.message : String(error),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Run full auto-rebalance cycle.
|
|
187
|
+
*/
|
|
188
|
+
async autoRebalance() {
|
|
189
|
+
const tasks = this.needsRebalancing();
|
|
190
|
+
if (tasks.length === 0) {
|
|
191
|
+
console.log("Inventory balanced, no rebalancing needed.");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
console.log(`Found ${tasks.length} rebalance tasks`);
|
|
195
|
+
let totalCost = 0n;
|
|
196
|
+
for (const task of tasks) {
|
|
197
|
+
// Double check availability before executing
|
|
198
|
+
if (this.inventoryManager.canFulfill(task.fromChain, task.token, task.amount)) {
|
|
199
|
+
const result = await this.execute(task);
|
|
200
|
+
if (result.success) {
|
|
201
|
+
totalCost += 0n; // TODO: Parse gas cost from result if available
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.warn(`Skipping rebalance task due to insufficient funds: ${task.fromChain} -> ${task.toChain}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=rebalancer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebalancer.js","sourceRoot":"","sources":["../../../src/solver/inventory/rebalancer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/solver/mempool/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/solver/mempool/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Filter — Phase G
|
|
3
|
+
*
|
|
4
|
+
* Decides whether an incoming intent from the mempool should be
|
|
5
|
+
* attempted by this agent. Filters are applied in order from
|
|
6
|
+
* cheapest to most expensive to minimize wasted work.
|
|
7
|
+
*
|
|
8
|
+
* Filter pipeline:
|
|
9
|
+
* 1. Deduplication — Skip if intentId already seen
|
|
10
|
+
* 2. Type check — Only "bridge" intents
|
|
11
|
+
* 3. Agent capability — agent.canSolve(intent)
|
|
12
|
+
*
|
|
13
|
+
* Used by: MempoolMonitor
|
|
14
|
+
*/
|
|
15
|
+
import type { SolverIntent } from "../types/intent";
|
|
16
|
+
import type { LiquidityAgent } from "../agent/liquidity-agent";
|
|
17
|
+
export declare class IntentFilter {
|
|
18
|
+
private readonly agent;
|
|
19
|
+
/** Track seen intentIds to prevent duplicate processing */
|
|
20
|
+
private seen;
|
|
21
|
+
constructor(agent: LiquidityAgent);
|
|
22
|
+
/**
|
|
23
|
+
* Determine whether this agent should attempt solving the intent.
|
|
24
|
+
*
|
|
25
|
+
* Returns false immediately at the first failing check.
|
|
26
|
+
*
|
|
27
|
+
* @param intent - Incoming SolverIntent from the mempool
|
|
28
|
+
* @returns true if the agent should attempt solving, false otherwise
|
|
29
|
+
*/
|
|
30
|
+
shouldSolve(intent: SolverIntent): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Mark an intent as "already solved" so it won't be attempted again
|
|
33
|
+
* if it re-appears in the mempool (e.g., rebroadcast).
|
|
34
|
+
*
|
|
35
|
+
* @param intentId - The intentId to mark as solved
|
|
36
|
+
*/
|
|
37
|
+
markSolved(intentId: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Get count of unique intentIds seen so far.
|
|
40
|
+
* Useful for monitoring / debugging.
|
|
41
|
+
*/
|
|
42
|
+
getSeenCount(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Clear the deduplication cache.
|
|
45
|
+
* Use with caution — only if you intentionally want to reprocess intents.
|
|
46
|
+
*/
|
|
47
|
+
clearCache(): void;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=intent-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-filter.d.ts","sourceRoot":"","sources":["../../../src/solver/mempool/intent-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,qBAAa,YAAY;IAIT,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,2DAA2D;IAC3D,OAAO,CAAC,IAAI,CAA0B;gBAET,KAAK,EAAE,cAAc;IAMlD;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO;IAuB1C;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC;;;OAGG;IACH,YAAY,IAAI,MAAM;IAItB;;;OAGG;IACH,UAAU,IAAI,IAAI;CAGrB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Filter — Phase G
|
|
3
|
+
*
|
|
4
|
+
* Decides whether an incoming intent from the mempool should be
|
|
5
|
+
* attempted by this agent. Filters are applied in order from
|
|
6
|
+
* cheapest to most expensive to minimize wasted work.
|
|
7
|
+
*
|
|
8
|
+
* Filter pipeline:
|
|
9
|
+
* 1. Deduplication — Skip if intentId already seen
|
|
10
|
+
* 2. Type check — Only "bridge" intents
|
|
11
|
+
* 3. Agent capability — agent.canSolve(intent)
|
|
12
|
+
*
|
|
13
|
+
* Used by: MempoolMonitor
|
|
14
|
+
*/
|
|
15
|
+
export class IntentFilter {
|
|
16
|
+
agent;
|
|
17
|
+
/** Track seen intentIds to prevent duplicate processing */
|
|
18
|
+
seen = new Set();
|
|
19
|
+
constructor(agent) {
|
|
20
|
+
this.agent = agent;
|
|
21
|
+
}
|
|
22
|
+
// ─────────────────────────────────────────
|
|
23
|
+
// Public API
|
|
24
|
+
// ─────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether this agent should attempt solving the intent.
|
|
27
|
+
*
|
|
28
|
+
* Returns false immediately at the first failing check.
|
|
29
|
+
*
|
|
30
|
+
* @param intent - Incoming SolverIntent from the mempool
|
|
31
|
+
* @returns true if the agent should attempt solving, false otherwise
|
|
32
|
+
*/
|
|
33
|
+
shouldSolve(intent) {
|
|
34
|
+
// 1. Deduplication — skip already-seen intents
|
|
35
|
+
if (this.seen.has(intent.intentId)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Mark as seen immediately to prevent concurrent processors
|
|
39
|
+
// from racing on the same intent
|
|
40
|
+
this.seen.add(intent.intentId);
|
|
41
|
+
// 2. Type check — only handle bridge intents
|
|
42
|
+
if (intent.parsedIntent.intentType !== "bridge") {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
// 3. Agent capability check — chains, tokens, expiry, inventory
|
|
46
|
+
if (!this.agent.canSolve(intent)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mark an intent as "already solved" so it won't be attempted again
|
|
53
|
+
* if it re-appears in the mempool (e.g., rebroadcast).
|
|
54
|
+
*
|
|
55
|
+
* @param intentId - The intentId to mark as solved
|
|
56
|
+
*/
|
|
57
|
+
markSolved(intentId) {
|
|
58
|
+
this.seen.add(intentId);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get count of unique intentIds seen so far.
|
|
62
|
+
* Useful for monitoring / debugging.
|
|
63
|
+
*/
|
|
64
|
+
getSeenCount() {
|
|
65
|
+
return this.seen.size;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Clear the deduplication cache.
|
|
69
|
+
* Use with caution — only if you intentionally want to reprocess intents.
|
|
70
|
+
*/
|
|
71
|
+
clearCache() {
|
|
72
|
+
this.seen.clear();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=intent-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-filter.js","sourceRoot":"","sources":["../../../src/solver/mempool/intent-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,OAAO,YAAY;IAIQ;IAH7B,2DAA2D;IACnD,IAAI,GAAgB,IAAI,GAAG,EAAE,CAAC;IAEtC,YAA6B,KAAqB;QAArB,UAAK,GAAL,KAAK,CAAgB;IAAI,CAAC;IAEvD,4CAA4C;IAC5C,aAAa;IACb,4CAA4C;IAE5C;;;;;;;OAOG;IACH,WAAW,CAAC,MAAoB;QAC5B,+CAA+C;QAC/C,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,4DAA4D;QAC5D,iCAAiC;QACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE/B,6CAA6C;QAC7C,IAAI,MAAM,CAAC,YAAY,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAgB;QACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,YAAY;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,UAAU;QACN,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACJ"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mempool Client — Phase G
|
|
3
|
+
*
|
|
4
|
+
* WebSocket transport layer for connecting to the Intent Mempool server.
|
|
5
|
+
* Emits typed events when intents arrive or are solved by other solvers.
|
|
6
|
+
*
|
|
7
|
+
* Events:
|
|
8
|
+
* "connected" — WebSocket opened successfully
|
|
9
|
+
* "disconnected" — WebSocket closed (code, reason)
|
|
10
|
+
* "new_intent" — New SolverIntent broadcast from mempool
|
|
11
|
+
* "intent_solved" — Another solver claimed an intent first
|
|
12
|
+
* "error" — Transport-level error
|
|
13
|
+
*
|
|
14
|
+
* Design: Custom lightweight EventEmitter. No external dependencies.
|
|
15
|
+
* WebSocket is injected (or auto-created) so tests can mock it cleanly.
|
|
16
|
+
*
|
|
17
|
+
* Used by: MempoolMonitor
|
|
18
|
+
*/
|
|
19
|
+
import type { SolverIntent } from "../types/intent";
|
|
20
|
+
/** Events emitted by MempoolClient */
|
|
21
|
+
export type MempoolEvent = "connected" | "disconnected" | "new_intent" | "intent_solved" | "error";
|
|
22
|
+
/** Payload for "intent_solved" event */
|
|
23
|
+
export interface IntentSolvedPayload {
|
|
24
|
+
intentId: string;
|
|
25
|
+
solver: string;
|
|
26
|
+
}
|
|
27
|
+
/** Payload for "disconnected" event */
|
|
28
|
+
export interface DisconnectedPayload {
|
|
29
|
+
code: number;
|
|
30
|
+
reason: string;
|
|
31
|
+
}
|
|
32
|
+
/** Union of all event payloads */
|
|
33
|
+
export type MempoolEventPayload = SolverIntent | IntentSolvedPayload | DisconnectedPayload | Error | undefined;
|
|
34
|
+
/** Callback shape for each event */
|
|
35
|
+
export type EventCallback = (payload: any) => void;
|
|
36
|
+
/** Minimal interface for WebSocket — mocked in tests */
|
|
37
|
+
export interface IWebSocket {
|
|
38
|
+
send(data: string): void;
|
|
39
|
+
close(): void;
|
|
40
|
+
onopen?: (() => void) | null;
|
|
41
|
+
onclose?: ((event: {
|
|
42
|
+
code: number;
|
|
43
|
+
reason: string;
|
|
44
|
+
}) => void) | null;
|
|
45
|
+
onmessage?: ((event: {
|
|
46
|
+
data: string;
|
|
47
|
+
}) => void) | null;
|
|
48
|
+
onerror?: ((event: {
|
|
49
|
+
message?: string;
|
|
50
|
+
}) => void) | null;
|
|
51
|
+
}
|
|
52
|
+
/** Factory for creating WebSocket instances */
|
|
53
|
+
export type WebSocketFactory = (url: string) => IWebSocket;
|
|
54
|
+
export declare class MempoolClient {
|
|
55
|
+
private ws;
|
|
56
|
+
private listeners;
|
|
57
|
+
private connected;
|
|
58
|
+
private wsFactory;
|
|
59
|
+
constructor(wsFactory?: WebSocketFactory);
|
|
60
|
+
/**
|
|
61
|
+
* Connect to the mempool WebSocket server.
|
|
62
|
+
*
|
|
63
|
+
* Immediately attaches message handlers. Emits "connected"
|
|
64
|
+
* when the socket opens, or "error" if it fails.
|
|
65
|
+
*
|
|
66
|
+
* @param url - WebSocket URL (e.g. "ws://mempool.example.com/ws")
|
|
67
|
+
*/
|
|
68
|
+
connect(url: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Gracefully close the WebSocket connection.
|
|
71
|
+
*/
|
|
72
|
+
disconnect(): void;
|
|
73
|
+
/** Whether the client is currently connected */
|
|
74
|
+
isConnected(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Send a solution to the mempool server.
|
|
77
|
+
*
|
|
78
|
+
* Payload format: { type: "submit_solution", intentId, txHash, solver, profit }
|
|
79
|
+
*/
|
|
80
|
+
submitSolution(intentId: string, txHash?: string, solverAddress?: string, profit?: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Register a listener for a mempool event.
|
|
83
|
+
*
|
|
84
|
+
* @param event - Event name
|
|
85
|
+
* @param cb - Callback to invoke with the event payload
|
|
86
|
+
*/
|
|
87
|
+
on(event: MempoolEvent, cb: EventCallback): void;
|
|
88
|
+
/**
|
|
89
|
+
* Unregister a previously registered listener.
|
|
90
|
+
*
|
|
91
|
+
* @param event - Event name
|
|
92
|
+
* @param cb - The exact callback reference to remove
|
|
93
|
+
*/
|
|
94
|
+
off(event: MempoolEvent, cb: EventCallback): void;
|
|
95
|
+
/**
|
|
96
|
+
* Remove ALL listeners for all events.
|
|
97
|
+
* Called during disconnect / cleanup.
|
|
98
|
+
*/
|
|
99
|
+
removeAllListeners(): void;
|
|
100
|
+
/** Dispatch incoming server message to the right event */
|
|
101
|
+
private handleMessage;
|
|
102
|
+
/** Emit an event to all registered listeners */
|
|
103
|
+
private emit;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=mempool-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mempool-client.d.ts","sourceRoot":"","sources":["../../../src/solver/mempool/mempool-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAMpD,sCAAsC;AACtC,MAAM,MAAM,YAAY,GAClB,WAAW,GACX,cAAc,GACd,YAAY,GACZ,eAAe,GACf,OAAO,CAAC;AAEd,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,kCAAkC;AAClC,MAAM,MAAM,mBAAmB,GACzB,YAAY,GACZ,mBAAmB,GACnB,mBAAmB,GACnB,KAAK,GACL,SAAS,CAAC;AAEhB,oCAAoC;AAEpC,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;AAEnD,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACvB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACrE,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5D;AAED,+CAA+C;AAC/C,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;AAM3D,qBAAa,aAAa;IACtB,OAAO,CAAC,EAAE,CAA2B;IACrC,OAAO,CAAC,SAAS,CAAoD;IACrE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAmB;gBAExB,SAAS,CAAC,EAAE,gBAAgB;IASxC;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IA+B1B;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB,gDAAgD;IAChD,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAkBhG;;;;;OAKG;IACH,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI;IAOhD;;;;;OAKG;IACH,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI;IAIjD;;;OAGG;IACH,kBAAkB,IAAI,IAAI;IAQ1B,0DAA0D;IAC1D,OAAO,CAAC,aAAa;IAcrB,gDAAgD;IAChD,OAAO,CAAC,IAAI;CAYf"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mempool Client — Phase G
|
|
3
|
+
*
|
|
4
|
+
* WebSocket transport layer for connecting to the Intent Mempool server.
|
|
5
|
+
* Emits typed events when intents arrive or are solved by other solvers.
|
|
6
|
+
*
|
|
7
|
+
* Events:
|
|
8
|
+
* "connected" — WebSocket opened successfully
|
|
9
|
+
* "disconnected" — WebSocket closed (code, reason)
|
|
10
|
+
* "new_intent" — New SolverIntent broadcast from mempool
|
|
11
|
+
* "intent_solved" — Another solver claimed an intent first
|
|
12
|
+
* "error" — Transport-level error
|
|
13
|
+
*
|
|
14
|
+
* Design: Custom lightweight EventEmitter. No external dependencies.
|
|
15
|
+
* WebSocket is injected (or auto-created) so tests can mock it cleanly.
|
|
16
|
+
*
|
|
17
|
+
* Used by: MempoolMonitor
|
|
18
|
+
*/
|
|
19
|
+
// ─────────────────────────────────────────────
|
|
20
|
+
// MempoolClient
|
|
21
|
+
// ─────────────────────────────────────────────
|
|
22
|
+
export class MempoolClient {
|
|
23
|
+
ws = null;
|
|
24
|
+
listeners = new Map();
|
|
25
|
+
connected = false;
|
|
26
|
+
wsFactory;
|
|
27
|
+
constructor(wsFactory) {
|
|
28
|
+
// Default factory uses global WebSocket (Node.js 22+ / browser)
|
|
29
|
+
this.wsFactory = wsFactory ?? ((url) => new WebSocket(url));
|
|
30
|
+
}
|
|
31
|
+
// ─────────────────────────────────────────
|
|
32
|
+
// Connection
|
|
33
|
+
// ─────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Connect to the mempool WebSocket server.
|
|
36
|
+
*
|
|
37
|
+
* Immediately attaches message handlers. Emits "connected"
|
|
38
|
+
* when the socket opens, or "error" if it fails.
|
|
39
|
+
*
|
|
40
|
+
* @param url - WebSocket URL (e.g. "ws://mempool.example.com/ws")
|
|
41
|
+
*/
|
|
42
|
+
connect(url) {
|
|
43
|
+
if (this.ws) {
|
|
44
|
+
this.disconnect();
|
|
45
|
+
}
|
|
46
|
+
this.ws = this.wsFactory(url);
|
|
47
|
+
this.ws.onopen = () => {
|
|
48
|
+
this.connected = true;
|
|
49
|
+
this.emit("connected", undefined);
|
|
50
|
+
};
|
|
51
|
+
this.ws.onclose = (event) => {
|
|
52
|
+
this.connected = false;
|
|
53
|
+
this.emit("disconnected", { code: event.code, reason: event.reason });
|
|
54
|
+
};
|
|
55
|
+
this.ws.onmessage = (event) => {
|
|
56
|
+
try {
|
|
57
|
+
const msg = JSON.parse(event.data);
|
|
58
|
+
this.handleMessage(msg);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
this.emit("error", new Error(`Failed to parse mempool message: ${event.data}`));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
this.ws.onerror = (event) => {
|
|
65
|
+
this.emit("error", new Error(event.message ?? "WebSocket error"));
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Gracefully close the WebSocket connection.
|
|
70
|
+
*/
|
|
71
|
+
disconnect() {
|
|
72
|
+
if (this.ws) {
|
|
73
|
+
this.ws.close();
|
|
74
|
+
this.ws = null;
|
|
75
|
+
}
|
|
76
|
+
this.connected = false;
|
|
77
|
+
}
|
|
78
|
+
/** Whether the client is currently connected */
|
|
79
|
+
isConnected() {
|
|
80
|
+
return this.connected;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Send a solution to the mempool server.
|
|
84
|
+
*
|
|
85
|
+
* Payload format: { type: "submit_solution", intentId, txHash, solver, profit }
|
|
86
|
+
*/
|
|
87
|
+
submitSolution(intentId, txHash, solverAddress, profit) {
|
|
88
|
+
if (!this.ws || !this.connected) {
|
|
89
|
+
console.warn("[MempoolClient] Cannot submit: not connected");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const message = JSON.stringify({
|
|
93
|
+
type: "submit_solution",
|
|
94
|
+
payload: { intentId, txHash, solver: solverAddress, profit },
|
|
95
|
+
});
|
|
96
|
+
this.ws.send(message);
|
|
97
|
+
}
|
|
98
|
+
// ─────────────────────────────────────────
|
|
99
|
+
// Event Emitter
|
|
100
|
+
// ─────────────────────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* Register a listener for a mempool event.
|
|
103
|
+
*
|
|
104
|
+
* @param event - Event name
|
|
105
|
+
* @param cb - Callback to invoke with the event payload
|
|
106
|
+
*/
|
|
107
|
+
on(event, cb) {
|
|
108
|
+
if (!this.listeners.has(event)) {
|
|
109
|
+
this.listeners.set(event, new Set());
|
|
110
|
+
}
|
|
111
|
+
this.listeners.get(event).add(cb);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Unregister a previously registered listener.
|
|
115
|
+
*
|
|
116
|
+
* @param event - Event name
|
|
117
|
+
* @param cb - The exact callback reference to remove
|
|
118
|
+
*/
|
|
119
|
+
off(event, cb) {
|
|
120
|
+
this.listeners.get(event)?.delete(cb);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Remove ALL listeners for all events.
|
|
124
|
+
* Called during disconnect / cleanup.
|
|
125
|
+
*/
|
|
126
|
+
removeAllListeners() {
|
|
127
|
+
this.listeners.clear();
|
|
128
|
+
}
|
|
129
|
+
// ─────────────────────────────────────────
|
|
130
|
+
// Private
|
|
131
|
+
// ─────────────────────────────────────────
|
|
132
|
+
/** Dispatch incoming server message to the right event */
|
|
133
|
+
handleMessage(msg) {
|
|
134
|
+
switch (msg.type) {
|
|
135
|
+
case "new_intent":
|
|
136
|
+
this.emit("new_intent", msg.payload);
|
|
137
|
+
break;
|
|
138
|
+
case "intent_solved":
|
|
139
|
+
this.emit("intent_solved", msg.payload);
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
// Unknown message type — ignore silently
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Emit an event to all registered listeners */
|
|
147
|
+
emit(event, payload) {
|
|
148
|
+
const callbacks = this.listeners.get(event);
|
|
149
|
+
if (!callbacks)
|
|
150
|
+
return;
|
|
151
|
+
for (const cb of callbacks) {
|
|
152
|
+
try {
|
|
153
|
+
cb(payload);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.error(`[MempoolClient] Error in "${event}" listener:`, err);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=mempool-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mempool-client.js","sourceRoot":"","sources":["../../../src/solver/mempool/mempool-client.ts"],"names":[],"mappings":"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"}
|