envoy-pay 0.1.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/CHANGELOG.md +99 -0
- package/LICENSE +200 -0
- package/README.md +529 -0
- package/dist/cjs/adapters/base.js +174 -0
- package/dist/cjs/adapters/base.js.map +1 -0
- package/dist/cjs/adapters/evm.js +339 -0
- package/dist/cjs/adapters/evm.js.map +1 -0
- package/dist/cjs/adapters/index.js +15 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/ows.js +204 -0
- package/dist/cjs/adapters/ows.js.map +1 -0
- package/dist/cjs/adapters/solana.js +210 -0
- package/dist/cjs/adapters/solana.js.map +1 -0
- package/dist/cjs/adapters/stellar.js +173 -0
- package/dist/cjs/adapters/stellar.js.map +1 -0
- package/dist/cjs/adapters/stripe.js +338 -0
- package/dist/cjs/adapters/stripe.js.map +1 -0
- package/dist/cjs/adapters/types.js +3 -0
- package/dist/cjs/adapters/types.js.map +1 -0
- package/dist/cjs/client.js +309 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/contracts/abis/EnvoyFacilitator.js +197 -0
- package/dist/cjs/contracts/abis/EnvoyFacilitator.js.map +1 -0
- package/dist/cjs/contracts/addresses.js +42 -0
- package/dist/cjs/contracts/addresses.js.map +1 -0
- package/dist/cjs/contracts/facilitator.js +225 -0
- package/dist/cjs/contracts/facilitator.js.map +1 -0
- package/dist/cjs/contracts/index.js +21 -0
- package/dist/cjs/contracts/index.js.map +1 -0
- package/dist/cjs/facilitator/facilitator-service.js +305 -0
- package/dist/cjs/facilitator/facilitator-service.js.map +1 -0
- package/dist/cjs/facilitator/fee-calculator.js +134 -0
- package/dist/cjs/facilitator/fee-calculator.js.map +1 -0
- package/dist/cjs/facilitator/index.js +12 -0
- package/dist/cjs/facilitator/index.js.map +1 -0
- package/dist/cjs/facilitator/types.js +99 -0
- package/dist/cjs/facilitator/types.js.map +1 -0
- package/dist/cjs/identity/agent-card.js +143 -0
- package/dist/cjs/identity/agent-card.js.map +1 -0
- package/dist/cjs/identity/agent-identity.js +166 -0
- package/dist/cjs/identity/agent-identity.js.map +1 -0
- package/dist/cjs/identity/did-resolver.js +149 -0
- package/dist/cjs/identity/did-resolver.js.map +1 -0
- package/dist/cjs/identity/erc8004/abis.js +218 -0
- package/dist/cjs/identity/erc8004/abis.js.map +1 -0
- package/dist/cjs/identity/erc8004/identity.js +268 -0
- package/dist/cjs/identity/erc8004/identity.js.map +1 -0
- package/dist/cjs/identity/erc8004/index.js +36 -0
- package/dist/cjs/identity/erc8004/index.js.map +1 -0
- package/dist/cjs/identity/erc8004/reputation.js +110 -0
- package/dist/cjs/identity/erc8004/reputation.js.map +1 -0
- package/dist/cjs/identity/erc8004/types.js +3 -0
- package/dist/cjs/identity/erc8004/types.js.map +1 -0
- package/dist/cjs/identity/index.js +61 -0
- package/dist/cjs/identity/index.js.map +1 -0
- package/dist/cjs/identity/owner-registry.js +140 -0
- package/dist/cjs/identity/owner-registry.js.map +1 -0
- package/dist/cjs/identity/reputation.js +193 -0
- package/dist/cjs/identity/reputation.js.map +1 -0
- package/dist/cjs/identity/types.js +16 -0
- package/dist/cjs/identity/types.js.map +1 -0
- package/dist/cjs/index.js +72 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/logger.js +7 -0
- package/dist/cjs/logger.js.map +1 -0
- package/dist/cjs/monitor/evm-watcher.js +165 -0
- package/dist/cjs/monitor/evm-watcher.js.map +1 -0
- package/dist/cjs/monitor/index.js +32 -0
- package/dist/cjs/monitor/index.js.map +1 -0
- package/dist/cjs/monitor/multi-watcher.js +94 -0
- package/dist/cjs/monitor/multi-watcher.js.map +1 -0
- package/dist/cjs/monitor/solana-watcher.js +172 -0
- package/dist/cjs/monitor/solana-watcher.js.map +1 -0
- package/dist/cjs/monitor/stellar-watcher.js +125 -0
- package/dist/cjs/monitor/stellar-watcher.js.map +1 -0
- package/dist/cjs/mpp.js +187 -0
- package/dist/cjs/mpp.js.map +1 -0
- package/dist/cjs/policy.js +71 -0
- package/dist/cjs/policy.js.map +1 -0
- package/dist/cjs/providers/bridge.js +323 -0
- package/dist/cjs/providers/bridge.js.map +1 -0
- package/dist/cjs/providers/onchainos.js +210 -0
- package/dist/cjs/providers/onchainos.js.map +1 -0
- package/dist/cjs/requests/eip681.js +77 -0
- package/dist/cjs/requests/eip681.js.map +1 -0
- package/dist/cjs/requests/index.js +18 -0
- package/dist/cjs/requests/index.js.map +1 -0
- package/dist/cjs/requests/sep7.js +61 -0
- package/dist/cjs/requests/sep7.js.map +1 -0
- package/dist/cjs/requests/solana-pay.js +51 -0
- package/dist/cjs/requests/solana-pay.js.map +1 -0
- package/dist/cjs/requests/universal.js +40 -0
- package/dist/cjs/requests/universal.js.map +1 -0
- package/dist/cjs/server/index.js +35 -0
- package/dist/cjs/server/index.js.map +1 -0
- package/dist/cjs/server/mpp-gate.js +118 -0
- package/dist/cjs/server/mpp-gate.js.map +1 -0
- package/dist/cjs/server/payment-gate.js +92 -0
- package/dist/cjs/server/payment-gate.js.map +1 -0
- package/dist/cjs/server/receipt.js +52 -0
- package/dist/cjs/server/receipt.js.map +1 -0
- package/dist/cjs/server/webhook.js +122 -0
- package/dist/cjs/server/webhook.js.map +1 -0
- package/dist/cjs/server/x402-gate.js +103 -0
- package/dist/cjs/server/x402-gate.js.map +1 -0
- package/dist/cjs/solana.js +14 -0
- package/dist/cjs/solana.js.map +1 -0
- package/dist/cjs/stellar.js +14 -0
- package/dist/cjs/stellar.js.map +1 -0
- package/dist/cjs/wallet/balance-aggregator.js +149 -0
- package/dist/cjs/wallet/balance-aggregator.js.map +1 -0
- package/dist/cjs/wallet/chain-router.js +254 -0
- package/dist/cjs/wallet/chain-router.js.map +1 -0
- package/dist/cjs/wallet/index.js +15 -0
- package/dist/cjs/wallet/index.js.map +1 -0
- package/dist/cjs/wallet/intent-resolver.js +145 -0
- package/dist/cjs/wallet/intent-resolver.js.map +1 -0
- package/dist/cjs/wallet/session-manager.js +170 -0
- package/dist/cjs/wallet/session-manager.js.map +1 -0
- package/dist/cjs/wallet/types.js +14 -0
- package/dist/cjs/wallet/types.js.map +1 -0
- package/dist/cjs/wallet/unified-wallet.js +253 -0
- package/dist/cjs/wallet/unified-wallet.js.map +1 -0
- package/dist/esm/adapters/base.js +170 -0
- package/dist/esm/adapters/base.js.map +1 -0
- package/dist/esm/adapters/evm.js +334 -0
- package/dist/esm/adapters/evm.js.map +1 -0
- package/dist/esm/adapters/index.js +6 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/ows.js +194 -0
- package/dist/esm/adapters/ows.js.map +1 -0
- package/dist/esm/adapters/solana.js +206 -0
- package/dist/esm/adapters/solana.js.map +1 -0
- package/dist/esm/adapters/stellar.js +136 -0
- package/dist/esm/adapters/stellar.js.map +1 -0
- package/dist/esm/adapters/stripe.js +334 -0
- package/dist/esm/adapters/stripe.js.map +1 -0
- package/dist/esm/adapters/types.js +2 -0
- package/dist/esm/adapters/types.js.map +1 -0
- package/dist/esm/client.js +302 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/contracts/abis/EnvoyFacilitator.js +194 -0
- package/dist/esm/contracts/abis/EnvoyFacilitator.js.map +1 -0
- package/dist/esm/contracts/addresses.js +38 -0
- package/dist/esm/contracts/addresses.js.map +1 -0
- package/dist/esm/contracts/facilitator.js +218 -0
- package/dist/esm/contracts/facilitator.js.map +1 -0
- package/dist/esm/contracts/index.js +8 -0
- package/dist/esm/contracts/index.js.map +1 -0
- package/dist/esm/facilitator/facilitator-service.js +301 -0
- package/dist/esm/facilitator/facilitator-service.js.map +1 -0
- package/dist/esm/facilitator/fee-calculator.js +130 -0
- package/dist/esm/facilitator/fee-calculator.js.map +1 -0
- package/dist/esm/facilitator/index.js +5 -0
- package/dist/esm/facilitator/index.js.map +1 -0
- package/dist/esm/facilitator/types.js +96 -0
- package/dist/esm/facilitator/types.js.map +1 -0
- package/dist/esm/identity/agent-card.js +139 -0
- package/dist/esm/identity/agent-card.js.map +1 -0
- package/dist/esm/identity/agent-identity.js +162 -0
- package/dist/esm/identity/agent-identity.js.map +1 -0
- package/dist/esm/identity/did-resolver.js +145 -0
- package/dist/esm/identity/did-resolver.js.map +1 -0
- package/dist/esm/identity/erc8004/abis.js +215 -0
- package/dist/esm/identity/erc8004/abis.js.map +1 -0
- package/dist/esm/identity/erc8004/identity.js +250 -0
- package/dist/esm/identity/erc8004/identity.js.map +1 -0
- package/dist/esm/identity/erc8004/index.js +13 -0
- package/dist/esm/identity/erc8004/index.js.map +1 -0
- package/dist/esm/identity/erc8004/reputation.js +105 -0
- package/dist/esm/identity/erc8004/reputation.js.map +1 -0
- package/dist/esm/identity/erc8004/types.js +2 -0
- package/dist/esm/identity/erc8004/types.js.map +1 -0
- package/dist/esm/identity/index.js +19 -0
- package/dist/esm/identity/index.js.map +1 -0
- package/dist/esm/identity/owner-registry.js +136 -0
- package/dist/esm/identity/owner-registry.js.map +1 -0
- package/dist/esm/identity/reputation.js +189 -0
- package/dist/esm/identity/reputation.js.map +1 -0
- package/dist/esm/identity/types.js +15 -0
- package/dist/esm/identity/types.js.map +1 -0
- package/dist/esm/index.js +37 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger.js +3 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/monitor/evm-watcher.js +162 -0
- package/dist/esm/monitor/evm-watcher.js.map +1 -0
- package/dist/esm/monitor/index.js +25 -0
- package/dist/esm/monitor/index.js.map +1 -0
- package/dist/esm/monitor/multi-watcher.js +91 -0
- package/dist/esm/monitor/multi-watcher.js.map +1 -0
- package/dist/esm/monitor/solana-watcher.js +169 -0
- package/dist/esm/monitor/solana-watcher.js.map +1 -0
- package/dist/esm/monitor/stellar-watcher.js +122 -0
- package/dist/esm/monitor/stellar-watcher.js.map +1 -0
- package/dist/esm/mpp.js +175 -0
- package/dist/esm/mpp.js.map +1 -0
- package/dist/esm/policy.js +67 -0
- package/dist/esm/policy.js.map +1 -0
- package/dist/esm/providers/bridge.js +319 -0
- package/dist/esm/providers/bridge.js.map +1 -0
- package/dist/esm/providers/onchainos.js +172 -0
- package/dist/esm/providers/onchainos.js.map +1 -0
- package/dist/esm/requests/eip681.js +74 -0
- package/dist/esm/requests/eip681.js.map +1 -0
- package/dist/esm/requests/index.js +11 -0
- package/dist/esm/requests/index.js.map +1 -0
- package/dist/esm/requests/sep7.js +58 -0
- package/dist/esm/requests/sep7.js.map +1 -0
- package/dist/esm/requests/solana-pay.js +48 -0
- package/dist/esm/requests/solana-pay.js.map +1 -0
- package/dist/esm/requests/universal.js +37 -0
- package/dist/esm/requests/universal.js.map +1 -0
- package/dist/esm/server/index.js +27 -0
- package/dist/esm/server/index.js.map +1 -0
- package/dist/esm/server/mpp-gate.js +115 -0
- package/dist/esm/server/mpp-gate.js.map +1 -0
- package/dist/esm/server/payment-gate.js +89 -0
- package/dist/esm/server/payment-gate.js.map +1 -0
- package/dist/esm/server/receipt.js +48 -0
- package/dist/esm/server/receipt.js.map +1 -0
- package/dist/esm/server/webhook.js +119 -0
- package/dist/esm/server/webhook.js.map +1 -0
- package/dist/esm/server/x402-gate.js +100 -0
- package/dist/esm/server/x402-gate.js.map +1 -0
- package/dist/esm/solana.js +8 -0
- package/dist/esm/solana.js.map +1 -0
- package/dist/esm/stellar.js +8 -0
- package/dist/esm/stellar.js.map +1 -0
- package/dist/esm/wallet/balance-aggregator.js +145 -0
- package/dist/esm/wallet/balance-aggregator.js.map +1 -0
- package/dist/esm/wallet/chain-router.js +250 -0
- package/dist/esm/wallet/chain-router.js.map +1 -0
- package/dist/esm/wallet/index.js +7 -0
- package/dist/esm/wallet/index.js.map +1 -0
- package/dist/esm/wallet/intent-resolver.js +141 -0
- package/dist/esm/wallet/intent-resolver.js.map +1 -0
- package/dist/esm/wallet/session-manager.js +166 -0
- package/dist/esm/wallet/session-manager.js.map +1 -0
- package/dist/esm/wallet/types.js +13 -0
- package/dist/esm/wallet/types.js.map +1 -0
- package/dist/esm/wallet/unified-wallet.js +249 -0
- package/dist/esm/wallet/unified-wallet.js.map +1 -0
- package/dist/types/adapters/base.d.ts +53 -0
- package/dist/types/adapters/base.d.ts.map +1 -0
- package/dist/types/adapters/evm.d.ts +93 -0
- package/dist/types/adapters/evm.d.ts.map +1 -0
- package/dist/types/adapters/index.d.ts +7 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/ows.d.ts +123 -0
- package/dist/types/adapters/ows.d.ts.map +1 -0
- package/dist/types/adapters/solana.d.ts +77 -0
- package/dist/types/adapters/solana.d.ts.map +1 -0
- package/dist/types/adapters/stellar.d.ts +67 -0
- package/dist/types/adapters/stellar.d.ts.map +1 -0
- package/dist/types/adapters/stripe.d.ts +206 -0
- package/dist/types/adapters/stripe.d.ts.map +1 -0
- package/dist/types/adapters/types.d.ts +110 -0
- package/dist/types/adapters/types.d.ts.map +1 -0
- package/dist/types/client.d.ts +89 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/contracts/abis/EnvoyFacilitator.d.ts +296 -0
- package/dist/types/contracts/abis/EnvoyFacilitator.d.ts.map +1 -0
- package/dist/types/contracts/addresses.d.ts +24 -0
- package/dist/types/contracts/addresses.d.ts.map +1 -0
- package/dist/types/contracts/facilitator.d.ts +172 -0
- package/dist/types/contracts/facilitator.d.ts.map +1 -0
- package/dist/types/contracts/index.d.ts +6 -0
- package/dist/types/contracts/index.d.ts.map +1 -0
- package/dist/types/facilitator/facilitator-service.d.ts +69 -0
- package/dist/types/facilitator/facilitator-service.d.ts.map +1 -0
- package/dist/types/facilitator/fee-calculator.d.ts +48 -0
- package/dist/types/facilitator/fee-calculator.d.ts.map +1 -0
- package/dist/types/facilitator/index.d.ts +5 -0
- package/dist/types/facilitator/index.d.ts.map +1 -0
- package/dist/types/facilitator/types.d.ts +221 -0
- package/dist/types/facilitator/types.d.ts.map +1 -0
- package/dist/types/identity/agent-card.d.ts +83 -0
- package/dist/types/identity/agent-card.d.ts.map +1 -0
- package/dist/types/identity/agent-identity.d.ts +102 -0
- package/dist/types/identity/agent-identity.d.ts.map +1 -0
- package/dist/types/identity/did-resolver.d.ts +70 -0
- package/dist/types/identity/did-resolver.d.ts.map +1 -0
- package/dist/types/identity/erc8004/abis.d.ts +336 -0
- package/dist/types/identity/erc8004/abis.d.ts.map +1 -0
- package/dist/types/identity/erc8004/identity.d.ts +109 -0
- package/dist/types/identity/erc8004/identity.d.ts.map +1 -0
- package/dist/types/identity/erc8004/index.d.ts +15 -0
- package/dist/types/identity/erc8004/index.d.ts.map +1 -0
- package/dist/types/identity/erc8004/reputation.d.ts +52 -0
- package/dist/types/identity/erc8004/reputation.d.ts.map +1 -0
- package/dist/types/identity/erc8004/types.d.ts +31 -0
- package/dist/types/identity/erc8004/types.d.ts.map +1 -0
- package/dist/types/identity/index.d.ts +10 -0
- package/dist/types/identity/index.d.ts.map +1 -0
- package/dist/types/identity/owner-registry.d.ts +68 -0
- package/dist/types/identity/owner-registry.d.ts.map +1 -0
- package/dist/types/identity/reputation.d.ts +66 -0
- package/dist/types/identity/reputation.d.ts.map +1 -0
- package/dist/types/identity/types.d.ts +182 -0
- package/dist/types/identity/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logger.d.ts +10 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/monitor/evm-watcher.d.ts +40 -0
- package/dist/types/monitor/evm-watcher.d.ts.map +1 -0
- package/dist/types/monitor/index.d.ts +25 -0
- package/dist/types/monitor/index.d.ts.map +1 -0
- package/dist/types/monitor/multi-watcher.d.ts +48 -0
- package/dist/types/monitor/multi-watcher.d.ts.map +1 -0
- package/dist/types/monitor/solana-watcher.d.ts +36 -0
- package/dist/types/monitor/solana-watcher.d.ts.map +1 -0
- package/dist/types/monitor/stellar-watcher.d.ts +34 -0
- package/dist/types/monitor/stellar-watcher.d.ts.map +1 -0
- package/dist/types/mpp.d.ts +153 -0
- package/dist/types/mpp.d.ts.map +1 -0
- package/dist/types/policy.d.ts +40 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/providers/bridge.d.ts +162 -0
- package/dist/types/providers/bridge.d.ts.map +1 -0
- package/dist/types/providers/onchainos.d.ts +128 -0
- package/dist/types/providers/onchainos.d.ts.map +1 -0
- package/dist/types/requests/eip681.d.ts +51 -0
- package/dist/types/requests/eip681.d.ts.map +1 -0
- package/dist/types/requests/index.d.ts +11 -0
- package/dist/types/requests/index.d.ts.map +1 -0
- package/dist/types/requests/sep7.d.ts +56 -0
- package/dist/types/requests/sep7.d.ts.map +1 -0
- package/dist/types/requests/solana-pay.d.ts +50 -0
- package/dist/types/requests/solana-pay.d.ts.map +1 -0
- package/dist/types/requests/universal.d.ts +28 -0
- package/dist/types/requests/universal.d.ts.map +1 -0
- package/dist/types/server/index.d.ts +27 -0
- package/dist/types/server/index.d.ts.map +1 -0
- package/dist/types/server/mpp-gate.d.ts +66 -0
- package/dist/types/server/mpp-gate.d.ts.map +1 -0
- package/dist/types/server/payment-gate.d.ts +33 -0
- package/dist/types/server/payment-gate.d.ts.map +1 -0
- package/dist/types/server/receipt.d.ts +52 -0
- package/dist/types/server/receipt.d.ts.map +1 -0
- package/dist/types/server/webhook.d.ts +46 -0
- package/dist/types/server/webhook.d.ts.map +1 -0
- package/dist/types/server/x402-gate.d.ts +70 -0
- package/dist/types/server/x402-gate.d.ts.map +1 -0
- package/dist/types/solana.d.ts +7 -0
- package/dist/types/solana.d.ts.map +1 -0
- package/dist/types/stellar.d.ts +7 -0
- package/dist/types/stellar.d.ts.map +1 -0
- package/dist/types/wallet/balance-aggregator.d.ts +51 -0
- package/dist/types/wallet/balance-aggregator.d.ts.map +1 -0
- package/dist/types/wallet/chain-router.d.ts +44 -0
- package/dist/types/wallet/chain-router.d.ts.map +1 -0
- package/dist/types/wallet/index.d.ts +7 -0
- package/dist/types/wallet/index.d.ts.map +1 -0
- package/dist/types/wallet/intent-resolver.d.ts +39 -0
- package/dist/types/wallet/intent-resolver.d.ts.map +1 -0
- package/dist/types/wallet/session-manager.d.ts +57 -0
- package/dist/types/wallet/session-manager.d.ts.map +1 -0
- package/dist/types/wallet/types.d.ts +161 -0
- package/dist/types/wallet/types.d.ts.map +1 -0
- package/dist/types/wallet/unified-wallet.d.ts +122 -0
- package/dist/types/wallet/unified-wallet.d.ts.map +1 -0
- package/package.json +194 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEvmWatcher = createEvmWatcher;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
/**
|
|
6
|
+
* ERC-20 Transfer event topic hash.
|
|
7
|
+
* keccak256('Transfer(address,address,uint256)')
|
|
8
|
+
*/
|
|
9
|
+
const TRANSFER_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
|
10
|
+
/**
|
|
11
|
+
* Creates an EVM payment watcher using JSON-RPC polling.
|
|
12
|
+
*
|
|
13
|
+
* Monitors:
|
|
14
|
+
* 1. ERC-20 Transfer events TO the target address (USDC)
|
|
15
|
+
* 2. Native ETH transfers TO the target address (via block scanning)
|
|
16
|
+
*
|
|
17
|
+
* @returns Unsubscribe function to stop watching.
|
|
18
|
+
*/
|
|
19
|
+
function createEvmWatcher(config) {
|
|
20
|
+
const log = config.logger ?? logger_1.noopLogger;
|
|
21
|
+
const pollInterval = config.pollIntervalMs ?? 12000;
|
|
22
|
+
const chainName = config.chainName ?? 'EVM';
|
|
23
|
+
const chainId = config.chainId ?? 'eip155:1';
|
|
24
|
+
let running = true;
|
|
25
|
+
let lastBlock = 0;
|
|
26
|
+
let timer = null;
|
|
27
|
+
async function rpcCall(method, params) {
|
|
28
|
+
const response = await fetch(config.rpcUrl, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: { 'Content-Type': 'application/json' },
|
|
31
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
|
|
32
|
+
});
|
|
33
|
+
const json = await response.json();
|
|
34
|
+
if (json.error)
|
|
35
|
+
throw new Error(`RPC error: ${json.error.message}`);
|
|
36
|
+
return json.result;
|
|
37
|
+
}
|
|
38
|
+
async function getLatestBlock() {
|
|
39
|
+
const hex = await rpcCall('eth_blockNumber', []);
|
|
40
|
+
return parseInt(hex, 16);
|
|
41
|
+
}
|
|
42
|
+
async function getErc20Transfers(fromBlock, toBlock) {
|
|
43
|
+
if (!config.usdcContractAddress)
|
|
44
|
+
return [];
|
|
45
|
+
const paddedAddress = '0x' + config.address.slice(2).toLowerCase().padStart(64, '0');
|
|
46
|
+
const logs = await rpcCall('eth_getLogs', [{
|
|
47
|
+
fromBlock: '0x' + fromBlock.toString(16),
|
|
48
|
+
toBlock: '0x' + toBlock.toString(16),
|
|
49
|
+
address: config.usdcContractAddress,
|
|
50
|
+
topics: [TRANSFER_TOPIC, null, paddedAddress],
|
|
51
|
+
}]);
|
|
52
|
+
if (!Array.isArray(logs))
|
|
53
|
+
return [];
|
|
54
|
+
return logs.map((logEntry) => {
|
|
55
|
+
const amount = BigInt(logEntry.data).toString();
|
|
56
|
+
const from = '0x' + logEntry.topics[1].slice(26);
|
|
57
|
+
return {
|
|
58
|
+
amount,
|
|
59
|
+
amountFormatted: formatUsdc(amount),
|
|
60
|
+
asset: 'USDC',
|
|
61
|
+
from,
|
|
62
|
+
transactionHash: logEntry.transactionHash,
|
|
63
|
+
chain: chainName,
|
|
64
|
+
caip2Id: chainId,
|
|
65
|
+
timestamp: new Date(),
|
|
66
|
+
confirmations: 1,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async function getNativeTransfers(fromBlock, toBlock) {
|
|
71
|
+
const payments = [];
|
|
72
|
+
const targetLower = config.address.toLowerCase();
|
|
73
|
+
for (let blockNum = fromBlock; blockNum <= toBlock; blockNum++) {
|
|
74
|
+
try {
|
|
75
|
+
const block = await rpcCall('eth_getBlockByNumber', ['0x' + blockNum.toString(16), true]);
|
|
76
|
+
if (!block?.transactions)
|
|
77
|
+
continue;
|
|
78
|
+
for (const tx of block.transactions) {
|
|
79
|
+
if (tx.to?.toLowerCase() === targetLower &&
|
|
80
|
+
tx.value && tx.value !== '0x0' && tx.value !== '0x') {
|
|
81
|
+
const amount = BigInt(tx.value).toString();
|
|
82
|
+
payments.push({
|
|
83
|
+
amount,
|
|
84
|
+
amountFormatted: formatEth(amount),
|
|
85
|
+
asset: 'ETH',
|
|
86
|
+
from: tx.from,
|
|
87
|
+
transactionHash: tx.hash,
|
|
88
|
+
chain: chainName,
|
|
89
|
+
caip2Id: chainId,
|
|
90
|
+
timestamp: new Date(parseInt(block.timestamp, 16) * 1000),
|
|
91
|
+
confirmations: 1,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
log(`[evm-watcher] β οΈ Error scanning block ${blockNum}: ${err.message}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return payments;
|
|
101
|
+
}
|
|
102
|
+
async function poll() {
|
|
103
|
+
if (!running)
|
|
104
|
+
return;
|
|
105
|
+
try {
|
|
106
|
+
const currentBlock = await getLatestBlock();
|
|
107
|
+
if (lastBlock === 0) {
|
|
108
|
+
lastBlock = currentBlock;
|
|
109
|
+
log(`[evm-watcher] π Started watching from block ${currentBlock} on ${chainName}`);
|
|
110
|
+
schedulePoll();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (currentBlock <= lastBlock) {
|
|
114
|
+
schedulePoll();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const fromBlock = lastBlock + 1;
|
|
118
|
+
const toBlock = currentBlock;
|
|
119
|
+
log(`[evm-watcher] π¦ Scanning blocks ${fromBlock}β${toBlock} on ${chainName}`);
|
|
120
|
+
// Scan for ERC-20 and native transfers in parallel
|
|
121
|
+
const [erc20Payments, nativePayments] = await Promise.all([
|
|
122
|
+
getErc20Transfers(fromBlock, toBlock),
|
|
123
|
+
getNativeTransfers(fromBlock, toBlock),
|
|
124
|
+
]);
|
|
125
|
+
const allPayments = [...erc20Payments, ...nativePayments];
|
|
126
|
+
for (const payment of allPayments) {
|
|
127
|
+
log(`[evm-watcher] π° Incoming: ${payment.amountFormatted} ${payment.asset} from ${payment.from.slice(0, 10)}β¦`);
|
|
128
|
+
config.onPayment(payment);
|
|
129
|
+
}
|
|
130
|
+
lastBlock = toBlock;
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
log(`[evm-watcher] β Poll error: ${err.message}`);
|
|
134
|
+
config.onError?.(err);
|
|
135
|
+
}
|
|
136
|
+
schedulePoll();
|
|
137
|
+
}
|
|
138
|
+
function schedulePoll() {
|
|
139
|
+
if (running && pollInterval > 0) {
|
|
140
|
+
timer = setTimeout(poll, pollInterval);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Start polling
|
|
144
|
+
poll();
|
|
145
|
+
// Return unsubscribe function
|
|
146
|
+
return () => {
|
|
147
|
+
running = false;
|
|
148
|
+
if (timer)
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
log(`[evm-watcher] π Stopped watching on ${chainName}`);
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function formatUsdc(atomicAmount) {
|
|
154
|
+
const n = BigInt(atomicAmount);
|
|
155
|
+
const whole = n / 1000000n;
|
|
156
|
+
const frac = (n % 1000000n).toString().padStart(6, '0');
|
|
157
|
+
return `${whole}.${frac}`;
|
|
158
|
+
}
|
|
159
|
+
function formatEth(weiAmount) {
|
|
160
|
+
const n = BigInt(weiAmount);
|
|
161
|
+
const whole = n / 10n ** 18n;
|
|
162
|
+
const frac = ((n % 10n ** 18n) / 10n ** 12n).toString().padStart(6, '0');
|
|
163
|
+
return `${whole}.${frac}`;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=evm-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm-watcher.js","sourceRoot":"","sources":["../../../src/monitor/evm-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMultiChainWatcher = exports.createSolanaWatcher = exports.createStellarWatcher = exports.createEvmWatcher = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* envoy β Real-Time Payment Monitoring
|
|
6
|
+
*
|
|
7
|
+
* Chain-specific watchers that detect incoming payments
|
|
8
|
+
* and invoke callbacks in real-time.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { createEvmWatcher, createStellarWatcher } from 'envoy-pay/monitor';
|
|
13
|
+
*
|
|
14
|
+
* const unsub = createEvmWatcher({
|
|
15
|
+
* address: '0xYOUR_WALLET',
|
|
16
|
+
* rpcUrl: 'https://mainnet.base.org',
|
|
17
|
+
* onPayment: (event) => console.log('Received:', event),
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Stop watching
|
|
21
|
+
* unsub();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
var evm_watcher_1 = require("./evm-watcher");
|
|
25
|
+
Object.defineProperty(exports, "createEvmWatcher", { enumerable: true, get: function () { return evm_watcher_1.createEvmWatcher; } });
|
|
26
|
+
var stellar_watcher_1 = require("./stellar-watcher");
|
|
27
|
+
Object.defineProperty(exports, "createStellarWatcher", { enumerable: true, get: function () { return stellar_watcher_1.createStellarWatcher; } });
|
|
28
|
+
var solana_watcher_1 = require("./solana-watcher");
|
|
29
|
+
Object.defineProperty(exports, "createSolanaWatcher", { enumerable: true, get: function () { return solana_watcher_1.createSolanaWatcher; } });
|
|
30
|
+
var multi_watcher_1 = require("./multi-watcher");
|
|
31
|
+
Object.defineProperty(exports, "createMultiChainWatcher", { enumerable: true, get: function () { return multi_watcher_1.createMultiChainWatcher; } });
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/monitor/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CAAwE;AAA/D,+GAAA,gBAAgB,OAAA;AACzB,qDAAoF;AAA3E,uHAAA,oBAAoB,OAAA;AAC7B,mDAAiF;AAAxE,qHAAA,mBAAmB,OAAA;AAC5B,iDAAwF;AAA/E,wHAAA,uBAAuB,OAAA"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMultiChainWatcher = createMultiChainWatcher;
|
|
4
|
+
const evm_watcher_1 = require("./evm-watcher");
|
|
5
|
+
const stellar_watcher_1 = require("./stellar-watcher");
|
|
6
|
+
const solana_watcher_1 = require("./solana-watcher");
|
|
7
|
+
const logger_1 = require("../logger");
|
|
8
|
+
/**
|
|
9
|
+
* Creates a multi-chain payment watcher.
|
|
10
|
+
*
|
|
11
|
+
* @returns Unsubscribe function that stops ALL chain watchers.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const unsub = createMultiChainWatcher({
|
|
16
|
+
* evm: [
|
|
17
|
+
* { address: '0x...', rpcUrl: 'https://mainnet.base.org', chainName: 'Base', usdcContractAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
|
|
18
|
+
* { address: '0x...', rpcUrl: 'https://arb1.arbitrum.io/rpc', chainName: 'Arbitrum' },
|
|
19
|
+
* ],
|
|
20
|
+
* stellar: { accountId: 'GABCD...' },
|
|
21
|
+
* solana: { address: '7abc...' },
|
|
22
|
+
* onPayment: (event) => console.log(`${event.chain}: ${event.amountFormatted} ${event.asset}`),
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Stop all watchers
|
|
26
|
+
* unsub();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function createMultiChainWatcher(config) {
|
|
30
|
+
const log = config.logger ?? logger_1.noopLogger;
|
|
31
|
+
const unsubscribers = [];
|
|
32
|
+
log('[multi-watcher] π Starting multi-chain payment monitorβ¦');
|
|
33
|
+
// Start EVM watchers
|
|
34
|
+
if (config.evm) {
|
|
35
|
+
for (const evmConfig of config.evm) {
|
|
36
|
+
const unsub = (0, evm_watcher_1.createEvmWatcher)({
|
|
37
|
+
...evmConfig,
|
|
38
|
+
onPayment: (event) => {
|
|
39
|
+
config.onPayment(event);
|
|
40
|
+
evmConfig.onPayment?.(event);
|
|
41
|
+
},
|
|
42
|
+
onError: (err) => {
|
|
43
|
+
config.onError?.(err);
|
|
44
|
+
evmConfig.onError?.(err);
|
|
45
|
+
},
|
|
46
|
+
logger: evmConfig.logger ?? log,
|
|
47
|
+
});
|
|
48
|
+
unsubscribers.push(unsub);
|
|
49
|
+
}
|
|
50
|
+
log(`[multi-watcher] βοΈ ${config.evm.length} EVM chain(s) active`);
|
|
51
|
+
}
|
|
52
|
+
// Start Stellar watcher
|
|
53
|
+
if (config.stellar) {
|
|
54
|
+
const unsub = (0, stellar_watcher_1.createStellarWatcher)({
|
|
55
|
+
...config.stellar,
|
|
56
|
+
onPayment: (event) => {
|
|
57
|
+
config.onPayment(event);
|
|
58
|
+
config.stellar.onPayment?.(event);
|
|
59
|
+
},
|
|
60
|
+
onError: (err) => {
|
|
61
|
+
config.onError?.(err);
|
|
62
|
+
config.stellar.onError?.(err);
|
|
63
|
+
},
|
|
64
|
+
logger: config.stellar.logger ?? log,
|
|
65
|
+
});
|
|
66
|
+
unsubscribers.push(unsub);
|
|
67
|
+
log('[multi-watcher] β Stellar watcher active');
|
|
68
|
+
}
|
|
69
|
+
// Start Solana watcher
|
|
70
|
+
if (config.solana) {
|
|
71
|
+
const unsub = (0, solana_watcher_1.createSolanaWatcher)({
|
|
72
|
+
...config.solana,
|
|
73
|
+
onPayment: (event) => {
|
|
74
|
+
config.onPayment(event);
|
|
75
|
+
config.solana.onPayment?.(event);
|
|
76
|
+
},
|
|
77
|
+
onError: (err) => {
|
|
78
|
+
config.onError?.(err);
|
|
79
|
+
config.solana.onError?.(err);
|
|
80
|
+
},
|
|
81
|
+
logger: config.solana.logger ?? log,
|
|
82
|
+
});
|
|
83
|
+
unsubscribers.push(unsub);
|
|
84
|
+
log('[multi-watcher] β Solana watcher active');
|
|
85
|
+
}
|
|
86
|
+
log(`[multi-watcher] β
${unsubscribers.length} watcher(s) running`);
|
|
87
|
+
return () => {
|
|
88
|
+
for (const unsub of unsubscribers) {
|
|
89
|
+
unsub();
|
|
90
|
+
}
|
|
91
|
+
log('[multi-watcher] π All watchers stopped');
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=multi-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-watcher.js","sourceRoot":"","sources":["../../../src/monitor/multi-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSolanaWatcher = createSolanaWatcher;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
/** Mainnet USDC mint address. */
|
|
6
|
+
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a Solana payment watcher using JSON-RPC polling.
|
|
9
|
+
*
|
|
10
|
+
* Polls `getSignaturesForAddress` for new transactions, then
|
|
11
|
+
* inspects each transaction to detect:
|
|
12
|
+
* 1. Native SOL transfers TO the target address
|
|
13
|
+
* 2. SPL USDC transfers TO the target's Associated Token Account
|
|
14
|
+
*
|
|
15
|
+
* @returns Unsubscribe function to stop watching.
|
|
16
|
+
*/
|
|
17
|
+
function createSolanaWatcher(config) {
|
|
18
|
+
const log = config.logger ?? logger_1.noopLogger;
|
|
19
|
+
const rpcUrl = config.rpcUrl ?? 'https://api.mainnet-beta.solana.com';
|
|
20
|
+
const pollInterval = config.pollIntervalMs ?? 5000;
|
|
21
|
+
const usdcMint = config.usdcMint ?? USDC_MINT;
|
|
22
|
+
let running = true;
|
|
23
|
+
let lastSignature = null;
|
|
24
|
+
let timer = null;
|
|
25
|
+
async function rpcCall(method, params) {
|
|
26
|
+
const response = await fetch(rpcUrl, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: { 'Content-Type': 'application/json' },
|
|
29
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
|
|
30
|
+
});
|
|
31
|
+
const json = await response.json();
|
|
32
|
+
if (json.error)
|
|
33
|
+
throw new Error(`Solana RPC error: ${json.error.message}`);
|
|
34
|
+
return json.result;
|
|
35
|
+
}
|
|
36
|
+
async function getNewSignatures() {
|
|
37
|
+
const params = [
|
|
38
|
+
config.address,
|
|
39
|
+
{ limit: 20, ...(lastSignature ? { until: lastSignature } : {}) },
|
|
40
|
+
];
|
|
41
|
+
const result = await rpcCall('getSignaturesForAddress', params);
|
|
42
|
+
if (!Array.isArray(result) || result.length === 0)
|
|
43
|
+
return [];
|
|
44
|
+
// Return newest first
|
|
45
|
+
return result
|
|
46
|
+
.filter((r) => r.confirmationStatus === 'confirmed' || r.confirmationStatus === 'finalized')
|
|
47
|
+
.map((r) => r.signature);
|
|
48
|
+
}
|
|
49
|
+
async function inspectTransaction(signature) {
|
|
50
|
+
try {
|
|
51
|
+
const tx = await rpcCall('getTransaction', [signature, { encoding: 'jsonParsed', maxSupportedTransactionVersion: 0 }]);
|
|
52
|
+
if (!tx?.meta || tx.meta.err)
|
|
53
|
+
return null;
|
|
54
|
+
const targetLower = config.address;
|
|
55
|
+
// Check parsed instructions for SOL transfers and SPL token transfers
|
|
56
|
+
const instructions = tx.transaction?.message?.instructions || [];
|
|
57
|
+
const innerInstructions = tx.meta?.innerInstructions || [];
|
|
58
|
+
const allInstructions = [
|
|
59
|
+
...instructions,
|
|
60
|
+
...innerInstructions.flatMap((inner) => inner.instructions || []),
|
|
61
|
+
];
|
|
62
|
+
for (const ix of allInstructions) {
|
|
63
|
+
const parsed = ix.parsed;
|
|
64
|
+
if (!parsed)
|
|
65
|
+
continue;
|
|
66
|
+
// Native SOL transfer
|
|
67
|
+
if (parsed.type === 'transfer' && ix.program === 'system') {
|
|
68
|
+
if (parsed.info?.destination === targetLower) {
|
|
69
|
+
const lamports = parsed.info.lamports.toString();
|
|
70
|
+
return {
|
|
71
|
+
amount: lamports,
|
|
72
|
+
amountFormatted: formatSol(lamports),
|
|
73
|
+
asset: 'SOL',
|
|
74
|
+
from: parsed.info.source || 'unknown',
|
|
75
|
+
transactionHash: signature,
|
|
76
|
+
chain: 'Solana',
|
|
77
|
+
caip2Id: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
|
|
78
|
+
timestamp: new Date((tx.blockTime || Date.now() / 1000) * 1000),
|
|
79
|
+
confirmations: 1,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// SPL Token transfer (including USDC)
|
|
84
|
+
if ((parsed.type === 'transfer' || parsed.type === 'transferChecked') &&
|
|
85
|
+
ix.program === 'spl-token') {
|
|
86
|
+
const info = parsed.info;
|
|
87
|
+
// Check if this is USDC (by mint address in transferChecked)
|
|
88
|
+
const isUsdc = info?.mint === usdcMint;
|
|
89
|
+
const amount = info?.amount || info?.tokenAmount?.amount;
|
|
90
|
+
if (amount && info?.destination) {
|
|
91
|
+
// We need to check if the destination ATA belongs to our address
|
|
92
|
+
// For simplicity, we check pre/post token balances
|
|
93
|
+
return {
|
|
94
|
+
amount: amount.toString(),
|
|
95
|
+
amountFormatted: isUsdc ? formatUsdc(amount.toString()) : amount.toString(),
|
|
96
|
+
asset: isUsdc ? 'USDC' : 'SPL',
|
|
97
|
+
from: info.source || info.authority || 'unknown',
|
|
98
|
+
transactionHash: signature,
|
|
99
|
+
chain: 'Solana',
|
|
100
|
+
caip2Id: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
|
|
101
|
+
timestamp: new Date((tx.blockTime || Date.now() / 1000) * 1000),
|
|
102
|
+
confirmations: 1,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
log(`[solana-watcher] β οΈ Failed to inspect tx ${signature.slice(0, 16)}β¦: ${err.message}`);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function poll() {
|
|
115
|
+
if (!running)
|
|
116
|
+
return;
|
|
117
|
+
try {
|
|
118
|
+
const signatures = await getNewSignatures();
|
|
119
|
+
if (signatures.length > 0 && !lastSignature) {
|
|
120
|
+
// First poll β just record the latest signature
|
|
121
|
+
lastSignature = signatures[0];
|
|
122
|
+
log(`[solana-watcher] π Started watching from signature ${lastSignature.slice(0, 16)}β¦ on Solana`);
|
|
123
|
+
schedulePoll();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (signatures.length === 0) {
|
|
127
|
+
schedulePoll();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
log(`[solana-watcher] π¦ Processing ${signatures.length} new transactions`);
|
|
131
|
+
for (const sig of signatures.reverse()) { // Oldest first
|
|
132
|
+
const payment = await inspectTransaction(sig);
|
|
133
|
+
if (payment) {
|
|
134
|
+
log(`[solana-watcher] π° Incoming: ${payment.amountFormatted} ${payment.asset} from ${payment.from.slice(0, 10)}β¦`);
|
|
135
|
+
config.onPayment(payment);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
lastSignature = signatures[0]; // Most recent
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
log(`[solana-watcher] β Poll error: ${err.message}`);
|
|
142
|
+
config.onError?.(err);
|
|
143
|
+
}
|
|
144
|
+
schedulePoll();
|
|
145
|
+
}
|
|
146
|
+
function schedulePoll() {
|
|
147
|
+
if (running && pollInterval > 0) {
|
|
148
|
+
timer = setTimeout(poll, pollInterval);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Start polling
|
|
152
|
+
poll();
|
|
153
|
+
return () => {
|
|
154
|
+
running = false;
|
|
155
|
+
if (timer)
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
log(`[solana-watcher] π Stopped watching on Solana`);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function formatSol(lamports) {
|
|
161
|
+
const n = BigInt(lamports);
|
|
162
|
+
const whole = n / 1000000000n;
|
|
163
|
+
const frac = ((n % 1000000000n) / 1000n).toString().padStart(6, '0');
|
|
164
|
+
return `${whole}.${frac}`;
|
|
165
|
+
}
|
|
166
|
+
function formatUsdc(atomicAmount) {
|
|
167
|
+
const n = BigInt(atomicAmount);
|
|
168
|
+
const whole = n / 1000000n;
|
|
169
|
+
const frac = (n % 1000000n).toString().padStart(6, '0');
|
|
170
|
+
return `${whole}.${frac}`;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=solana-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana-watcher.js","sourceRoot":"","sources":["../../../src/monitor/solana-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStellarWatcher = createStellarWatcher;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
/**
|
|
6
|
+
* Creates a Stellar payment watcher using Horizon SSE streaming.
|
|
7
|
+
*
|
|
8
|
+
* Listens for `payment` and `create_account` operations directed
|
|
9
|
+
* to the target account. Supports asset-based filtering.
|
|
10
|
+
*
|
|
11
|
+
* @returns Unsubscribe function to stop watching.
|
|
12
|
+
*/
|
|
13
|
+
function createStellarWatcher(config) {
|
|
14
|
+
const log = config.logger ?? logger_1.noopLogger;
|
|
15
|
+
const horizonUrl = config.horizonUrl ?? 'https://horizon.stellar.org';
|
|
16
|
+
const assetFilter = config.asset ?? 'all';
|
|
17
|
+
const cursor = config.cursor ?? 'now';
|
|
18
|
+
let abortController = null;
|
|
19
|
+
let running = true;
|
|
20
|
+
let reconnectTimer = null;
|
|
21
|
+
async function startStream() {
|
|
22
|
+
if (!running)
|
|
23
|
+
return;
|
|
24
|
+
const url = `${horizonUrl}/accounts/${config.accountId}/payments?cursor=${cursor}&order=asc`;
|
|
25
|
+
log(`[stellar-watcher] π Connecting to Horizon SSE: ${config.accountId.slice(0, 10)}β¦`);
|
|
26
|
+
abortController = new AbortController();
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
headers: { Accept: 'text/event-stream' },
|
|
30
|
+
signal: abortController.signal,
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new Error(`Horizon HTTP ${response.status}: ${response.statusText}`);
|
|
34
|
+
}
|
|
35
|
+
if (!response.body) {
|
|
36
|
+
throw new Error('No response body for SSE stream');
|
|
37
|
+
}
|
|
38
|
+
const reader = response.body.getReader();
|
|
39
|
+
const decoder = new TextDecoder();
|
|
40
|
+
let buffer = '';
|
|
41
|
+
log(`[stellar-watcher] β
SSE connected, watching for paymentsβ¦`);
|
|
42
|
+
while (running) {
|
|
43
|
+
const { done, value } = await reader.read();
|
|
44
|
+
if (done)
|
|
45
|
+
break;
|
|
46
|
+
buffer += decoder.decode(value, { stream: true });
|
|
47
|
+
// Parse SSE events
|
|
48
|
+
const lines = buffer.split('\n');
|
|
49
|
+
buffer = lines.pop() || '';
|
|
50
|
+
let currentData = '';
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (line.startsWith('data: ')) {
|
|
53
|
+
currentData += line.slice(6);
|
|
54
|
+
}
|
|
55
|
+
else if (line === '' && currentData) {
|
|
56
|
+
// End of event β process
|
|
57
|
+
if (currentData !== '"hello"' && currentData !== 'hello') {
|
|
58
|
+
processEvent(currentData);
|
|
59
|
+
}
|
|
60
|
+
currentData = '';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err.name === 'AbortError') {
|
|
67
|
+
log('[stellar-watcher] π Stream aborted');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
log(`[stellar-watcher] β Stream error: ${err.message}`);
|
|
71
|
+
config.onError?.(err);
|
|
72
|
+
// Reconnect after 5s
|
|
73
|
+
if (running) {
|
|
74
|
+
log('[stellar-watcher] π Reconnecting in 5sβ¦');
|
|
75
|
+
reconnectTimer = setTimeout(startStream, 5000);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function processEvent(data) {
|
|
80
|
+
try {
|
|
81
|
+
const record = JSON.parse(data);
|
|
82
|
+
// Only process payments TO this account
|
|
83
|
+
if (record.to !== config.accountId)
|
|
84
|
+
return;
|
|
85
|
+
// Only process payment operations
|
|
86
|
+
if (record.type !== 'payment' && record.type !== 'create_account')
|
|
87
|
+
return;
|
|
88
|
+
// Determine asset
|
|
89
|
+
const asset = record.asset_type === 'native'
|
|
90
|
+
? 'XLM'
|
|
91
|
+
: record.asset_code || 'unknown';
|
|
92
|
+
// Apply asset filter
|
|
93
|
+
if (assetFilter !== 'all' && asset !== assetFilter)
|
|
94
|
+
return;
|
|
95
|
+
// Convert amount to atomic units (stroops = amount * 10^7)
|
|
96
|
+
const atomicAmount = Math.round(parseFloat(record.amount) * 10_000_000).toString();
|
|
97
|
+
const payment = {
|
|
98
|
+
amount: atomicAmount,
|
|
99
|
+
amountFormatted: record.amount,
|
|
100
|
+
asset,
|
|
101
|
+
from: record.from,
|
|
102
|
+
transactionHash: record.transaction_hash,
|
|
103
|
+
chain: 'Stellar',
|
|
104
|
+
caip2Id: 'stellar:pubnet',
|
|
105
|
+
timestamp: new Date(record.created_at),
|
|
106
|
+
};
|
|
107
|
+
log(`[stellar-watcher] π° Incoming: ${record.amount} ${asset} from ${record.from.slice(0, 10)}β¦`);
|
|
108
|
+
config.onPayment(payment);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
log(`[stellar-watcher] β οΈ Failed to parse event: ${err.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Start the stream
|
|
115
|
+
startStream();
|
|
116
|
+
// Return unsubscribe
|
|
117
|
+
return () => {
|
|
118
|
+
running = false;
|
|
119
|
+
abortController?.abort();
|
|
120
|
+
if (reconnectTimer)
|
|
121
|
+
clearTimeout(reconnectTimer);
|
|
122
|
+
log(`[stellar-watcher] π Stopped watching ${config.accountId.slice(0, 10)}β¦`);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=stellar-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stellar-watcher.js","sourceRoot":"","sources":["../../../src/monitor/stellar-watcher.ts"],"names":[],"mappings":"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"}
|