@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,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inventory Manager
|
|
3
|
+
*
|
|
4
|
+
* Tracks USDC/token balances across all supported chains.
|
|
5
|
+
* Handles locking/unlocking for pending intents and
|
|
6
|
+
* balance snapshots for decision-making.
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle per intent:
|
|
9
|
+
* loadBalances() → canFulfill() → lockAmount()
|
|
10
|
+
* → (success) confirmDeduction() → unlockAmount()
|
|
11
|
+
* → (failure) unlockAmount()
|
|
12
|
+
*/
|
|
13
|
+
import { resolveFromSymbol } from "../../shared/token-registry/registry";
|
|
14
|
+
import { InsufficientInventoryError } from "../../errors/solver-errors";
|
|
15
|
+
import { InventoryLockError } from "../../errors/inventory-errors";
|
|
16
|
+
export class InventoryManager {
|
|
17
|
+
walletManager;
|
|
18
|
+
tokenRegistry;
|
|
19
|
+
chainRegistry;
|
|
20
|
+
providerManager;
|
|
21
|
+
config;
|
|
22
|
+
/**
|
|
23
|
+
* Map of chainId:tokenSymbol → InventoryBalance
|
|
24
|
+
* Format key: `${chainId}:${token}` e.g. "137:USDC"
|
|
25
|
+
*/
|
|
26
|
+
balances = new Map();
|
|
27
|
+
/**
|
|
28
|
+
* Track active locks per intent: intentId → list of lock keys
|
|
29
|
+
* Used to release all locks by intentId on success/failure.
|
|
30
|
+
*/
|
|
31
|
+
locks = new Map();
|
|
32
|
+
constructor(walletManager, tokenRegistry, chainRegistry, providerManager, config) {
|
|
33
|
+
this.walletManager = walletManager;
|
|
34
|
+
this.tokenRegistry = tokenRegistry;
|
|
35
|
+
this.chainRegistry = chainRegistry;
|
|
36
|
+
this.providerManager = providerManager;
|
|
37
|
+
this.config = config;
|
|
38
|
+
}
|
|
39
|
+
// ─────────────────────────────────────────────
|
|
40
|
+
// Private Helpers
|
|
41
|
+
// ─────────────────────────────────────────────
|
|
42
|
+
/** Generate composite map key */
|
|
43
|
+
key(chainId, token) {
|
|
44
|
+
return `${chainId}:${token.toUpperCase()}`;
|
|
45
|
+
}
|
|
46
|
+
// ─────────────────────────────────────────────
|
|
47
|
+
// Public API
|
|
48
|
+
// ─────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* Load on-chain balances for all registered chains and supported tokens.
|
|
51
|
+
*
|
|
52
|
+
* Calls ERC20.balanceOf(agentAddress) on each (chain, token) pair.
|
|
53
|
+
* Safe to call repeatedly (e.g., from InventoryMonitor polling).
|
|
54
|
+
* Preserves existing locked amounts so in-flight intent locks are not lost.
|
|
55
|
+
*/
|
|
56
|
+
async loadBalances() {
|
|
57
|
+
const agentAddress = this.walletManager.getAddress();
|
|
58
|
+
const chains = this.chainRegistry.list();
|
|
59
|
+
let totalLoaded = 0;
|
|
60
|
+
for (const chain of chains) {
|
|
61
|
+
const tokens = this.tokenRegistry.listByChain(chain.id);
|
|
62
|
+
for (const tokenInfo of tokens) {
|
|
63
|
+
try {
|
|
64
|
+
const balance = await this.providerManager.getTokenBalance(chain.id, tokenInfo.address, agentAddress);
|
|
65
|
+
const key = this.key(chain.id, tokenInfo.symbol);
|
|
66
|
+
// Preserve existing locked amount if any, or start at 0
|
|
67
|
+
const existing = this.balances.get(key);
|
|
68
|
+
const locked = existing ? existing.locked : 0n;
|
|
69
|
+
this.balances.set(key, {
|
|
70
|
+
chainId: chain.id,
|
|
71
|
+
token: tokenInfo.symbol,
|
|
72
|
+
available: balance,
|
|
73
|
+
locked,
|
|
74
|
+
lastUpdated: Date.now(),
|
|
75
|
+
});
|
|
76
|
+
totalLoaded++;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`Failed to load balance for ${tokenInfo.symbol} on chain ${chain.id}:`, error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Refresh the balance of a specific token on a specific chain.
|
|
86
|
+
* Useful for targeted updates after a successful transfer without
|
|
87
|
+
* reloading the entire multi-chain inventory.
|
|
88
|
+
*
|
|
89
|
+
* @param chainId - Chain to query
|
|
90
|
+
* @param tokenSymbol - Token symbol to query (e.g. "USDC")
|
|
91
|
+
*/
|
|
92
|
+
async refreshBalance(chainId, tokenSymbol) {
|
|
93
|
+
const agentAddress = this.walletManager.getAddress();
|
|
94
|
+
const tokenAddress = resolveFromSymbol(this.tokenRegistry, tokenSymbol, chainId);
|
|
95
|
+
try {
|
|
96
|
+
const balance = await this.providerManager.getTokenBalance(chainId, tokenAddress, agentAddress);
|
|
97
|
+
const key = this.key(chainId, tokenSymbol);
|
|
98
|
+
const existing = this.balances.get(key);
|
|
99
|
+
const locked = existing ? existing.locked : 0n;
|
|
100
|
+
this.balances.set(key, {
|
|
101
|
+
chainId,
|
|
102
|
+
token: tokenSymbol,
|
|
103
|
+
available: balance,
|
|
104
|
+
locked,
|
|
105
|
+
lastUpdated: Date.now(),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(`Failed to refresh balance for ${tokenSymbol} on chain ${chainId}:`, error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get current available balance (available - locked) for a token on a chain.
|
|
114
|
+
*
|
|
115
|
+
* @param chainId - Chain to query
|
|
116
|
+
* @param token - Token symbol (e.g. "USDC")
|
|
117
|
+
* @returns Available balance in token's smallest unit. Returns 0n if not tracked.
|
|
118
|
+
*/
|
|
119
|
+
getBalance(chainId, token) {
|
|
120
|
+
const key = this.key(chainId, token);
|
|
121
|
+
const balance = this.balances.get(key);
|
|
122
|
+
if (!balance)
|
|
123
|
+
return 0n;
|
|
124
|
+
// Available balance is the raw balance minus reserved/locked funds
|
|
125
|
+
const netAvailable = balance.available - balance.locked;
|
|
126
|
+
return netAvailable > 0n ? netAvailable : 0n;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get total available balance across all chains for a token.
|
|
130
|
+
*
|
|
131
|
+
* Useful for global profitability checks.
|
|
132
|
+
*
|
|
133
|
+
* @param token - Token symbol (e.g. "USDC")
|
|
134
|
+
* @returns Sum of (available - locked) across all chains
|
|
135
|
+
*/
|
|
136
|
+
getTotalBalance(token) {
|
|
137
|
+
let total = 0n;
|
|
138
|
+
const suffix = `:${token.toUpperCase()}`;
|
|
139
|
+
for (const [key, balance] of this.balances) {
|
|
140
|
+
if (key.endsWith(suffix)) {
|
|
141
|
+
const net = balance.available - balance.locked;
|
|
142
|
+
if (net > 0n)
|
|
143
|
+
total += net;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return total;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if we have enough balance to fulfill an intent.
|
|
150
|
+
*
|
|
151
|
+
* Must maintain minReservePercent after the deduction.
|
|
152
|
+
* Formula: available - locked - amount >= total * minReservePercent
|
|
153
|
+
*
|
|
154
|
+
* @param chainId - Target chain for fulfillment
|
|
155
|
+
* @param token - Token to send
|
|
156
|
+
* @param amount - Amount required (in smallest unit)
|
|
157
|
+
* @returns true if we can safely fill without breaching reserve
|
|
158
|
+
*/
|
|
159
|
+
canFulfill(chainId, token, amount) {
|
|
160
|
+
const key = this.key(chainId, token);
|
|
161
|
+
const balance = this.balances.get(key);
|
|
162
|
+
if (!balance)
|
|
163
|
+
return false;
|
|
164
|
+
const netAvailable = balance.available - balance.locked;
|
|
165
|
+
// Basic check
|
|
166
|
+
if (netAvailable < amount)
|
|
167
|
+
return false;
|
|
168
|
+
// Reserve check using integer (basis-points) arithmetic.
|
|
169
|
+
//
|
|
170
|
+
// Semantics: "After sending `amount`, the remaining NET spendable
|
|
171
|
+
// balance must still be >= minReservePercent of that same net balance."
|
|
172
|
+
//
|
|
173
|
+
// Using netAvailable (not raw `available`) keeps the reserve proportional
|
|
174
|
+
// to what we can actually spend, independent of how much is already locked.
|
|
175
|
+
const bps = BigInt(Math.floor(this.config.minReservePercent * 10000));
|
|
176
|
+
const minReserve = (netAvailable * bps) / 10000n;
|
|
177
|
+
// Remaining after deduction must be >= minReserve
|
|
178
|
+
return (netAvailable - amount) >= minReserve;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Lock an amount for a pending intent (reserve it).
|
|
182
|
+
*
|
|
183
|
+
* Throws InsufficientInventoryError if not enough available.
|
|
184
|
+
* Throws InventoryLockError if lock already exists for intentId+token+chain.
|
|
185
|
+
*
|
|
186
|
+
* @param chainId - Chain where funds will be sent
|
|
187
|
+
* @param token - Token to lock
|
|
188
|
+
* @param amount - Amount to lock
|
|
189
|
+
* @param intentId - Intent ID for tracking (used in unlock/confirm)
|
|
190
|
+
*/
|
|
191
|
+
lockAmount(chainId, token, amount, intentId) {
|
|
192
|
+
const key = this.key(chainId, token);
|
|
193
|
+
const balance = this.balances.get(key);
|
|
194
|
+
if (!balance) {
|
|
195
|
+
// Chain/token not tracked
|
|
196
|
+
throw new InsufficientInventoryError(chainId, token, amount.toString(), "0");
|
|
197
|
+
}
|
|
198
|
+
if (!this.canFulfill(chainId, token, amount)) {
|
|
199
|
+
throw new InsufficientInventoryError(chainId, token, amount.toString(), (balance.available - balance.locked).toString());
|
|
200
|
+
}
|
|
201
|
+
// Check for existing lock for this intent/token/chain to prevent double-locking
|
|
202
|
+
const intentLocks = this.locks.get(intentId) || [];
|
|
203
|
+
if (intentLocks.some(l => l.key === key)) {
|
|
204
|
+
throw new InventoryLockError(intentId, `Inventory already locked for ${token} on chain ${chainId}`);
|
|
205
|
+
}
|
|
206
|
+
// Apply lock
|
|
207
|
+
balance.locked += amount;
|
|
208
|
+
balance.lastUpdated = Date.now();
|
|
209
|
+
// Track lock
|
|
210
|
+
intentLocks.push({ key, amount });
|
|
211
|
+
this.locks.set(intentId, intentLocks);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Release a previously locked amount (on success or failure).
|
|
215
|
+
*
|
|
216
|
+
* Safe to call even if intent wasn't locked (idempotent).
|
|
217
|
+
* Throws in dev mode if `amount` does not match the stored lock amount
|
|
218
|
+
* (helps catch accounting bugs early).
|
|
219
|
+
*
|
|
220
|
+
* @param chainId - Chain of the lock
|
|
221
|
+
* @param token - Token to unlock
|
|
222
|
+
* @param amount - Expected amount to unlock (validated against stored lock)
|
|
223
|
+
* @param intentId - Intent ID (must match the original lockAmount call)
|
|
224
|
+
*/
|
|
225
|
+
unlockAmount(chainId, token, amount, intentId) {
|
|
226
|
+
const key = this.key(chainId, token);
|
|
227
|
+
const balance = this.balances.get(key);
|
|
228
|
+
// Remove from locks tracking
|
|
229
|
+
const intentLocks = this.locks.get(intentId);
|
|
230
|
+
if (!intentLocks)
|
|
231
|
+
return; // No locks for this intent (idempotent)
|
|
232
|
+
const lockIndex = intentLocks.findIndex(l => l.key === key);
|
|
233
|
+
if (lockIndex === -1)
|
|
234
|
+
return; // This specific lock not found
|
|
235
|
+
// Remove this specific lock
|
|
236
|
+
const lockedAmount = intentLocks[lockIndex].amount;
|
|
237
|
+
// Validate caller's expected amount matches the stored lock.
|
|
238
|
+
// Mismatch indicates an accounting bug — log a warning instead of silently
|
|
239
|
+
// over- or under-releasing, as the intent runner may have the wrong state.
|
|
240
|
+
if (amount !== lockedAmount) {
|
|
241
|
+
console.warn(`[InventoryManager] unlockAmount mismatch for intent ${intentId} on ${chainId}:${token} ` +
|
|
242
|
+
`— expected ${amount} but lock holds ${lockedAmount}. Using stored value.`);
|
|
243
|
+
}
|
|
244
|
+
intentLocks.splice(lockIndex, 1);
|
|
245
|
+
if (intentLocks.length === 0) {
|
|
246
|
+
this.locks.delete(intentId);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
this.locks.set(intentId, intentLocks);
|
|
250
|
+
}
|
|
251
|
+
// Revert balance state
|
|
252
|
+
if (balance) {
|
|
253
|
+
balance.locked -= lockedAmount;
|
|
254
|
+
if (balance.locked < 0n)
|
|
255
|
+
balance.locked = 0n; // Safety clamp
|
|
256
|
+
balance.lastUpdated = Date.now();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Permanently deduct balance after successfully sending to user.
|
|
261
|
+
*
|
|
262
|
+
* Called after the target chain tx is confirmed. Reduces both
|
|
263
|
+
* available and locked (since we locked it first).
|
|
264
|
+
*
|
|
265
|
+
* @param chainId - Chain where send happened
|
|
266
|
+
* @param token - Token that was sent
|
|
267
|
+
* @param amount - Amount sent
|
|
268
|
+
* @param intentId - Intent ID for tracking
|
|
269
|
+
*/
|
|
270
|
+
confirmDeduction(chainId, token, amount, intentId) {
|
|
271
|
+
const key = this.key(chainId, token);
|
|
272
|
+
const balance = this.balances.get(key);
|
|
273
|
+
// Consume the lock
|
|
274
|
+
const intentLocks = this.locks.get(intentId);
|
|
275
|
+
let lockedAmount = 0n;
|
|
276
|
+
if (intentLocks) {
|
|
277
|
+
const lockIndex = intentLocks.findIndex(l => l.key === key);
|
|
278
|
+
if (lockIndex !== -1) {
|
|
279
|
+
lockedAmount = intentLocks[lockIndex].amount;
|
|
280
|
+
intentLocks.splice(lockIndex, 1);
|
|
281
|
+
if (intentLocks.length === 0) {
|
|
282
|
+
this.locks.delete(intentId);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (balance) {
|
|
287
|
+
// Deduct from available (funds sent away)
|
|
288
|
+
balance.available -= amount;
|
|
289
|
+
// Release the lock (it was consumed)
|
|
290
|
+
balance.locked -= lockedAmount;
|
|
291
|
+
// Safety clamps
|
|
292
|
+
if (balance.available < 0n)
|
|
293
|
+
balance.available = 0n;
|
|
294
|
+
if (balance.locked < 0n)
|
|
295
|
+
balance.locked = 0n;
|
|
296
|
+
balance.lastUpdated = Date.now();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get a full snapshot of all current balances and total USD value.
|
|
301
|
+
*
|
|
302
|
+
* @returns InventorySnapshot with all chain balances and a timestamp
|
|
303
|
+
*/
|
|
304
|
+
getSnapshot() {
|
|
305
|
+
const balances = Array.from(this.balances.values());
|
|
306
|
+
// Calculate estimated USD value.
|
|
307
|
+
// Assumes USDC/USDT = $1 (1:1 peg). Will be replaced by Oracle pricing in Phase I.
|
|
308
|
+
// Uses NET balance (available − locked) so locked funds are not counted as
|
|
309
|
+
// spendable capital — the dashboard value reflects what we can actually use.
|
|
310
|
+
let totalUSD = 0n;
|
|
311
|
+
for (const b of balances) {
|
|
312
|
+
const net = b.available - b.locked;
|
|
313
|
+
if (net > 0n)
|
|
314
|
+
totalUSD += net;
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
balances: [...balances], // Copy array
|
|
318
|
+
totalUSDValue: totalUSD.toString(),
|
|
319
|
+
timestamp: Date.now(),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=inventory-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory-manager.js","sourceRoot":"","sources":["../../../src/solver/inventory/inventory-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inventory Monitor
|
|
3
|
+
*
|
|
4
|
+
* Polls on-chain balances at regular intervals and
|
|
5
|
+
* alerts when unexpected changes are detected
|
|
6
|
+
* (e.g. balance dropped without a corresponding intent).
|
|
7
|
+
*
|
|
8
|
+
* Runs as a background service alongside the main agent loop.
|
|
9
|
+
*/
|
|
10
|
+
import type { InventoryManager } from "./inventory-manager";
|
|
11
|
+
/**
|
|
12
|
+
* Callback invoked when an unexpected balance change is detected.
|
|
13
|
+
*
|
|
14
|
+
* @param chainId - Chain where change was detected
|
|
15
|
+
* @param token - Token symbol
|
|
16
|
+
* @param delta - Balance change (negative = decrease)
|
|
17
|
+
*/
|
|
18
|
+
export type BalanceChangeCallback = (chainId: number, token: string, delta: bigint) => void;
|
|
19
|
+
export declare class InventoryMonitor {
|
|
20
|
+
private readonly inventoryManager;
|
|
21
|
+
/** Polling interval in milliseconds (default: 30_000) */
|
|
22
|
+
private readonly intervalMs;
|
|
23
|
+
/** NodeJS interval handle (null when stopped) */
|
|
24
|
+
private intervalHandle;
|
|
25
|
+
/** Previous snapshot for delta comparison */
|
|
26
|
+
private previousBalances;
|
|
27
|
+
/** Registered alert callbacks */
|
|
28
|
+
private onChangeCallbacks;
|
|
29
|
+
constructor(inventoryManager: InventoryManager,
|
|
30
|
+
/** Polling interval in milliseconds (default: 30_000) */
|
|
31
|
+
intervalMs?: number);
|
|
32
|
+
/**
|
|
33
|
+
* Start polling balances at regular intervals.
|
|
34
|
+
*
|
|
35
|
+
* Calls inventoryManager.loadBalances() on each tick and
|
|
36
|
+
* compares with the previous snapshot to detect changes.
|
|
37
|
+
* Does nothing if already running.
|
|
38
|
+
*/
|
|
39
|
+
start(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Stop the polling interval.
|
|
42
|
+
*
|
|
43
|
+
* Safe to call if not running (idempotent).
|
|
44
|
+
*/
|
|
45
|
+
stop(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Register a callback to be invoked when balance changes are detected.
|
|
48
|
+
*
|
|
49
|
+
* @param callback - Function called with (chainId, token, delta)
|
|
50
|
+
*/
|
|
51
|
+
onChange(callback: BalanceChangeCallback): void;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the monitor is currently running.
|
|
54
|
+
*/
|
|
55
|
+
get isRunning(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* One polling tick.
|
|
58
|
+
*
|
|
59
|
+
* Reloads on-chain balances and fires change callbacks for any delta
|
|
60
|
+
* detected since the last tick.
|
|
61
|
+
*
|
|
62
|
+
* TOCTOU note: there is a brief window between a bridge/send transaction
|
|
63
|
+
* being broadcast and its confirmation on-chain. During that window,
|
|
64
|
+
* loadBalances() will still see the pre-send balance, so a poll firing
|
|
65
|
+
* in this gap will report no change. This self-corrects on the next tick
|
|
66
|
+
* once the tx is mined. The locked amount is preserved across polls so
|
|
67
|
+
* internal solvency checks remain accurate throughout.
|
|
68
|
+
*/
|
|
69
|
+
private poll;
|
|
70
|
+
private notifyChange;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=inventory-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory-monitor.d.ts","sourceRoot":"","sources":["../../../src/solver/inventory/inventory-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACZ,IAAI,CAAC;AAEV,qBAAa,gBAAgB;IAWrB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAZ/B,iDAAiD;IACjD,OAAO,CAAC,cAAc,CAA+C;IAErE,6CAA6C;IAC7C,OAAO,CAAC,gBAAgB,CAAkC;IAE1D,iCAAiC;IACjC,OAAO,CAAC,iBAAiB,CAA+B;gBAGnC,gBAAgB,EAAE,gBAAgB;IACnD,yDAAyD;IACxC,UAAU,GAAE,MAAe;IAOhD;;;;;;OAMG;IACH,KAAK,IAAI,IAAI;IAiBb;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAQZ;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAI/C;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAMD;;;;;;;;;;;;OAYG;YACW,IAAI;IAwBlB,OAAO,CAAC,YAAY;CASvB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inventory Monitor
|
|
3
|
+
*
|
|
4
|
+
* Polls on-chain balances at regular intervals and
|
|
5
|
+
* alerts when unexpected changes are detected
|
|
6
|
+
* (e.g. balance dropped without a corresponding intent).
|
|
7
|
+
*
|
|
8
|
+
* Runs as a background service alongside the main agent loop.
|
|
9
|
+
*/
|
|
10
|
+
export class InventoryMonitor {
|
|
11
|
+
inventoryManager;
|
|
12
|
+
intervalMs;
|
|
13
|
+
/** NodeJS interval handle (null when stopped) */
|
|
14
|
+
intervalHandle = null;
|
|
15
|
+
/** Previous snapshot for delta comparison */
|
|
16
|
+
previousBalances = new Map();
|
|
17
|
+
/** Registered alert callbacks */
|
|
18
|
+
onChangeCallbacks = [];
|
|
19
|
+
constructor(inventoryManager,
|
|
20
|
+
/** Polling interval in milliseconds (default: 30_000) */
|
|
21
|
+
intervalMs = 30_000) {
|
|
22
|
+
this.inventoryManager = inventoryManager;
|
|
23
|
+
this.intervalMs = intervalMs;
|
|
24
|
+
}
|
|
25
|
+
// ─────────────────────────────────────────────
|
|
26
|
+
// Public API
|
|
27
|
+
// ─────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Start polling balances at regular intervals.
|
|
30
|
+
*
|
|
31
|
+
* Calls inventoryManager.loadBalances() on each tick and
|
|
32
|
+
* compares with the previous snapshot to detect changes.
|
|
33
|
+
* Does nothing if already running.
|
|
34
|
+
*/
|
|
35
|
+
start() {
|
|
36
|
+
if (this.intervalHandle !== null)
|
|
37
|
+
return;
|
|
38
|
+
// Initial poll
|
|
39
|
+
this.poll().catch(err => {
|
|
40
|
+
console.error("Initial poll failed:", err);
|
|
41
|
+
});
|
|
42
|
+
this.intervalHandle = setInterval(() => {
|
|
43
|
+
this.poll().catch(err => {
|
|
44
|
+
console.error("Poll failed:", err);
|
|
45
|
+
});
|
|
46
|
+
}, this.intervalMs);
|
|
47
|
+
console.log(`InventoryMonitor started, polling every ${this.intervalMs}ms`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stop the polling interval.
|
|
51
|
+
*
|
|
52
|
+
* Safe to call if not running (idempotent).
|
|
53
|
+
*/
|
|
54
|
+
stop() {
|
|
55
|
+
if (this.intervalHandle !== null) {
|
|
56
|
+
clearInterval(this.intervalHandle);
|
|
57
|
+
this.intervalHandle = null;
|
|
58
|
+
console.log("InventoryMonitor stopped");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Register a callback to be invoked when balance changes are detected.
|
|
63
|
+
*
|
|
64
|
+
* @param callback - Function called with (chainId, token, delta)
|
|
65
|
+
*/
|
|
66
|
+
onChange(callback) {
|
|
67
|
+
this.onChangeCallbacks.push(callback);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether the monitor is currently running.
|
|
71
|
+
*/
|
|
72
|
+
get isRunning() {
|
|
73
|
+
return this.intervalHandle !== null;
|
|
74
|
+
}
|
|
75
|
+
// ─────────────────────────────────────────────
|
|
76
|
+
// Private
|
|
77
|
+
// ─────────────────────────────────────────────
|
|
78
|
+
/**
|
|
79
|
+
* One polling tick.
|
|
80
|
+
*
|
|
81
|
+
* Reloads on-chain balances and fires change callbacks for any delta
|
|
82
|
+
* detected since the last tick.
|
|
83
|
+
*
|
|
84
|
+
* TOCTOU note: there is a brief window between a bridge/send transaction
|
|
85
|
+
* being broadcast and its confirmation on-chain. During that window,
|
|
86
|
+
* loadBalances() will still see the pre-send balance, so a poll firing
|
|
87
|
+
* in this gap will report no change. This self-corrects on the next tick
|
|
88
|
+
* once the tx is mined. The locked amount is preserved across polls so
|
|
89
|
+
* internal solvency checks remain accurate throughout.
|
|
90
|
+
*/
|
|
91
|
+
async poll() {
|
|
92
|
+
try {
|
|
93
|
+
await this.inventoryManager.loadBalances();
|
|
94
|
+
const snapshot = this.inventoryManager.getSnapshot();
|
|
95
|
+
for (const balance of snapshot.balances) {
|
|
96
|
+
// Track raw on-chain balance (`available` as set by loadBalances).
|
|
97
|
+
// Locked amounts are internal state and do not reflect chain movement.
|
|
98
|
+
const key = `${balance.chainId}:${balance.token}`;
|
|
99
|
+
const prev = this.previousBalances.get(key);
|
|
100
|
+
const current = balance.available;
|
|
101
|
+
if (prev !== undefined && prev !== current) {
|
|
102
|
+
const delta = current - prev;
|
|
103
|
+
this.notifyChange(balance.chainId, balance.token, delta);
|
|
104
|
+
}
|
|
105
|
+
this.previousBalances.set(key, current);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error("Error during inventory poll:", error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
notifyChange(chainId, token, delta) {
|
|
113
|
+
for (const cb of this.onChangeCallbacks) {
|
|
114
|
+
try {
|
|
115
|
+
cb(chainId, token, delta);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
console.error("Error in onChange callback:", e);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=inventory-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory-monitor.js","sourceRoot":"","sources":["../../../src/solver/inventory/inventory-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiBH,MAAM,OAAO,gBAAgB;IAWJ;IAEA;IAZrB,iDAAiD;IACzC,cAAc,GAA0C,IAAI,CAAC;IAErE,6CAA6C;IACrC,gBAAgB,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE1D,iCAAiC;IACzB,iBAAiB,GAA4B,EAAE,CAAC;IAExD,YACqB,gBAAkC;IACnD,yDAAyD;IACxC,aAAqB,MAAM;QAF3B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAElC,eAAU,GAAV,UAAU,CAAiB;IAC5C,CAAC;IAEL,gDAAgD;IAChD,aAAa;IACb,gDAAgD;IAEhD;;;;;;OAMG;IACH,KAAK;QACD,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI;YAAE,OAAO;QAEzC,eAAe;QACf,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACpB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACpB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpB,OAAO,CAAC,GAAG,CAAC,2CAA2C,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IAChF,CAAC;IAED;;;;OAIG;IACH,IAAI;QACA,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YAC/B,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAC5C,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAA+B;QACpC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC;IACxC,CAAC;IAED,gDAAgD;IAChD,UAAU;IACV,gDAAgD;IAEhD;;;;;;;;;;;;OAYG;IACK,KAAK,CAAC,IAAI;QACd,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;YAErD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtC,mEAAmE;gBACnE,uEAAuE;gBACvE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;gBAElC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;oBACzC,MAAM,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;oBAC7B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC7D,CAAC;gBAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,OAAe,EAAE,KAAa,EAAE,KAAa;QAC9D,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACtC,IAAI,CAAC;gBACD,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
import type { InventoryManager } from "./inventory-manager";
|
|
16
|
+
import type { RebalanceTask } from "../types/inventory";
|
|
17
|
+
import type { ExecutionResult } from "../types/execution";
|
|
18
|
+
import type { InventoryConfig } from "../types/inventory";
|
|
19
|
+
/**
|
|
20
|
+
* Protocol interface for bridge/rebalancing.
|
|
21
|
+
* Implemented by SwingProtocol in Phase I.
|
|
22
|
+
*/
|
|
23
|
+
export interface IBridgeProtocol {
|
|
24
|
+
/**
|
|
25
|
+
* Get a quote for bridging from one chain to another.
|
|
26
|
+
* Returns estimated output amount and bridge fee.
|
|
27
|
+
*/
|
|
28
|
+
quote(params: {
|
|
29
|
+
fromChain: number;
|
|
30
|
+
toChain: number;
|
|
31
|
+
token: string;
|
|
32
|
+
amount: bigint;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
outputAmount: bigint;
|
|
35
|
+
fee: bigint;
|
|
36
|
+
estimatedTimeMs: number;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Execute the bridge transfer.
|
|
40
|
+
* Returns the execution result with txHash.
|
|
41
|
+
*/
|
|
42
|
+
bridge(params: {
|
|
43
|
+
fromChain: number;
|
|
44
|
+
toChain: number;
|
|
45
|
+
token: string;
|
|
46
|
+
amount: bigint;
|
|
47
|
+
recipient: string;
|
|
48
|
+
}): Promise<ExecutionResult>;
|
|
49
|
+
}
|
|
50
|
+
export declare class Rebalancer {
|
|
51
|
+
private readonly inventoryManager;
|
|
52
|
+
private readonly bridgeProtocol;
|
|
53
|
+
private readonly config;
|
|
54
|
+
/** Agent address to receive funds on destination */
|
|
55
|
+
private readonly agentAddress;
|
|
56
|
+
constructor(inventoryManager: InventoryManager, bridgeProtocol: IBridgeProtocol, config: InventoryConfig,
|
|
57
|
+
/** Agent address to receive funds on destination */
|
|
58
|
+
agentAddress: string);
|
|
59
|
+
/**
|
|
60
|
+
* Detect chains whose balance deviates from target distribution.
|
|
61
|
+
*
|
|
62
|
+
* Uses **net available balance** (available − locked) per chain so the
|
|
63
|
+
* calculation is consistent with getTotalBalance(), which also uses net.
|
|
64
|
+
*
|
|
65
|
+
* @param token - Token symbol to check. Defaults to "USDC".
|
|
66
|
+
* @returns Array of RebalanceTasks sorted by priority (critical first)
|
|
67
|
+
*/
|
|
68
|
+
needsRebalancing(token?: string): RebalanceTask[];
|
|
69
|
+
/**
|
|
70
|
+
* Execute a single rebalance task.
|
|
71
|
+
*/
|
|
72
|
+
execute(task: RebalanceTask): Promise<ExecutionResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Run full auto-rebalance cycle.
|
|
75
|
+
*/
|
|
76
|
+
autoRebalance(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=rebalancer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebalancer.d.ts","sourceRoot":"","sources":["../../../src/solver/inventory/rebalancer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE5E;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAChC;AAED,qBAAa,UAAU;IAEf,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,oDAAoD;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAJZ,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,eAAe,EAC/B,MAAM,EAAE,eAAe;IACxC,oDAAoD;IACnC,YAAY,EAAE,MAAM;IAOzC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,KAAK,SAAS,GAAG,aAAa,EAAE;IA8GjD;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAoD5D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBvC"}
|