@wopr-network/crypto-plugins 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/.github/workflows/ci.yml +33 -0
  2. package/.github/workflows/publish.yml +12 -0
  3. package/biome.json +23 -0
  4. package/dist/__tests__/bitcoin-encoder.test.d.ts +2 -0
  5. package/dist/__tests__/bitcoin-encoder.test.d.ts.map +1 -0
  6. package/dist/__tests__/bitcoin-encoder.test.js +97 -0
  7. package/dist/__tests__/bitcoin-encoder.test.js.map +1 -0
  8. package/dist/__tests__/dogecoin-encoder.test.d.ts +2 -0
  9. package/dist/__tests__/dogecoin-encoder.test.d.ts.map +1 -0
  10. package/dist/__tests__/dogecoin-encoder.test.js +57 -0
  11. package/dist/__tests__/dogecoin-encoder.test.js.map +1 -0
  12. package/dist/__tests__/litecoin-encoder.test.d.ts +2 -0
  13. package/dist/__tests__/litecoin-encoder.test.d.ts.map +1 -0
  14. package/dist/__tests__/litecoin-encoder.test.js +44 -0
  15. package/dist/__tests__/litecoin-encoder.test.js.map +1 -0
  16. package/dist/__tests__/registry.test.d.ts +2 -0
  17. package/dist/__tests__/registry.test.d.ts.map +1 -0
  18. package/dist/__tests__/registry.test.js +75 -0
  19. package/dist/__tests__/registry.test.js.map +1 -0
  20. package/dist/__tests__/rpc.test.d.ts +2 -0
  21. package/dist/__tests__/rpc.test.d.ts.map +1 -0
  22. package/dist/__tests__/rpc.test.js +31 -0
  23. package/dist/__tests__/rpc.test.js.map +1 -0
  24. package/dist/__tests__/solana-encoder.test.d.ts +2 -0
  25. package/dist/__tests__/solana-encoder.test.d.ts.map +1 -0
  26. package/dist/__tests__/solana-encoder.test.js +85 -0
  27. package/dist/__tests__/solana-encoder.test.js.map +1 -0
  28. package/dist/__tests__/solana-watcher.test.d.ts +2 -0
  29. package/dist/__tests__/solana-watcher.test.d.ts.map +1 -0
  30. package/dist/__tests__/solana-watcher.test.js +281 -0
  31. package/dist/__tests__/solana-watcher.test.js.map +1 -0
  32. package/dist/__tests__/sweep-key-parity.test.d.ts +2 -0
  33. package/dist/__tests__/sweep-key-parity.test.d.ts.map +1 -0
  34. package/dist/__tests__/sweep-key-parity.test.js +236 -0
  35. package/dist/__tests__/sweep-key-parity.test.js.map +1 -0
  36. package/dist/__tests__/tron-encoder.test.d.ts +2 -0
  37. package/dist/__tests__/tron-encoder.test.d.ts.map +1 -0
  38. package/dist/__tests__/tron-encoder.test.js +93 -0
  39. package/dist/__tests__/tron-encoder.test.js.map +1 -0
  40. package/dist/__tests__/utxo-watcher.test.d.ts +2 -0
  41. package/dist/__tests__/utxo-watcher.test.d.ts.map +1 -0
  42. package/dist/__tests__/utxo-watcher.test.js +218 -0
  43. package/dist/__tests__/utxo-watcher.test.js.map +1 -0
  44. package/dist/bitcoin/encoder.d.ts +15 -0
  45. package/dist/bitcoin/encoder.d.ts.map +1 -0
  46. package/dist/bitcoin/encoder.js +286 -0
  47. package/dist/bitcoin/encoder.js.map +1 -0
  48. package/dist/bitcoin/index.d.ts +4 -0
  49. package/dist/bitcoin/index.d.ts.map +1 -0
  50. package/dist/bitcoin/index.js +20 -0
  51. package/dist/bitcoin/index.js.map +1 -0
  52. package/dist/dogecoin/encoder.d.ts +19 -0
  53. package/dist/dogecoin/encoder.d.ts.map +1 -0
  54. package/dist/dogecoin/encoder.js +145 -0
  55. package/dist/dogecoin/encoder.js.map +1 -0
  56. package/dist/dogecoin/index.d.ts +4 -0
  57. package/dist/dogecoin/index.d.ts.map +1 -0
  58. package/dist/dogecoin/index.js +20 -0
  59. package/dist/dogecoin/index.js.map +1 -0
  60. package/dist/evm/encoder.d.ts +7 -0
  61. package/dist/evm/encoder.d.ts.map +1 -0
  62. package/dist/evm/encoder.js +43 -0
  63. package/dist/evm/encoder.js.map +1 -0
  64. package/dist/evm/eth-watcher.d.ts +38 -0
  65. package/dist/evm/eth-watcher.d.ts.map +1 -0
  66. package/dist/evm/eth-watcher.js +138 -0
  67. package/dist/evm/eth-watcher.js.map +1 -0
  68. package/dist/evm/index.d.ts +16 -0
  69. package/dist/evm/index.d.ts.map +1 -0
  70. package/dist/evm/index.js +34 -0
  71. package/dist/evm/index.js.map +1 -0
  72. package/dist/evm/types.d.ts +43 -0
  73. package/dist/evm/types.d.ts.map +1 -0
  74. package/dist/evm/types.js +101 -0
  75. package/dist/evm/types.js.map +1 -0
  76. package/dist/evm/watcher.d.ts +42 -0
  77. package/dist/evm/watcher.d.ts.map +1 -0
  78. package/dist/evm/watcher.js +162 -0
  79. package/dist/evm/watcher.js.map +1 -0
  80. package/dist/index.d.ts +7 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +7 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/litecoin/encoder.d.ts +8 -0
  85. package/dist/litecoin/encoder.d.ts.map +1 -0
  86. package/dist/litecoin/encoder.js +16 -0
  87. package/dist/litecoin/encoder.js.map +1 -0
  88. package/dist/litecoin/index.d.ts +4 -0
  89. package/dist/litecoin/index.d.ts.map +1 -0
  90. package/dist/litecoin/index.js +20 -0
  91. package/dist/litecoin/index.js.map +1 -0
  92. package/dist/shared/test-helpers/index.d.ts +9 -0
  93. package/dist/shared/test-helpers/index.d.ts.map +1 -0
  94. package/dist/shared/test-helpers/index.js +30 -0
  95. package/dist/shared/test-helpers/index.js.map +1 -0
  96. package/dist/shared/utxo/index.d.ts +5 -0
  97. package/dist/shared/utxo/index.d.ts.map +1 -0
  98. package/dist/shared/utxo/index.js +3 -0
  99. package/dist/shared/utxo/index.js.map +1 -0
  100. package/dist/shared/utxo/rpc.d.ts +24 -0
  101. package/dist/shared/utxo/rpc.d.ts.map +1 -0
  102. package/dist/shared/utxo/rpc.js +75 -0
  103. package/dist/shared/utxo/rpc.js.map +1 -0
  104. package/dist/shared/utxo/types.d.ts +40 -0
  105. package/dist/shared/utxo/types.d.ts.map +1 -0
  106. package/dist/shared/utxo/types.js +2 -0
  107. package/dist/shared/utxo/types.js.map +1 -0
  108. package/dist/shared/utxo/watcher.d.ts +55 -0
  109. package/dist/shared/utxo/watcher.d.ts.map +1 -0
  110. package/dist/shared/utxo/watcher.js +150 -0
  111. package/dist/shared/utxo/watcher.js.map +1 -0
  112. package/dist/solana/encoder.d.ts +13 -0
  113. package/dist/solana/encoder.d.ts.map +1 -0
  114. package/dist/solana/encoder.js +62 -0
  115. package/dist/solana/encoder.js.map +1 -0
  116. package/dist/solana/index.d.ts +17 -0
  117. package/dist/solana/index.d.ts.map +1 -0
  118. package/dist/solana/index.js +32 -0
  119. package/dist/solana/index.js.map +1 -0
  120. package/dist/solana/sweeper.d.ts +47 -0
  121. package/dist/solana/sweeper.d.ts.map +1 -0
  122. package/dist/solana/sweeper.js +151 -0
  123. package/dist/solana/sweeper.js.map +1 -0
  124. package/dist/solana/types.d.ts +49 -0
  125. package/dist/solana/types.d.ts.map +1 -0
  126. package/dist/solana/types.js +2 -0
  127. package/dist/solana/types.js.map +1 -0
  128. package/dist/solana/watcher.d.ts +59 -0
  129. package/dist/solana/watcher.d.ts.map +1 -0
  130. package/dist/solana/watcher.js +251 -0
  131. package/dist/solana/watcher.js.map +1 -0
  132. package/dist/sweep/evm-sweeper.d.ts +31 -0
  133. package/dist/sweep/evm-sweeper.d.ts.map +1 -0
  134. package/dist/sweep/evm-sweeper.js +229 -0
  135. package/dist/sweep/evm-sweeper.js.map +1 -0
  136. package/dist/sweep/index.d.ts +22 -0
  137. package/dist/sweep/index.d.ts.map +1 -0
  138. package/dist/sweep/index.js +290 -0
  139. package/dist/sweep/index.js.map +1 -0
  140. package/dist/sweep/tron-sweeper.d.ts +40 -0
  141. package/dist/sweep/tron-sweeper.d.ts.map +1 -0
  142. package/dist/sweep/tron-sweeper.js +363 -0
  143. package/dist/sweep/tron-sweeper.js.map +1 -0
  144. package/dist/sweep/utxo-sweeper.d.ts +14 -0
  145. package/dist/sweep/utxo-sweeper.d.ts.map +1 -0
  146. package/dist/sweep/utxo-sweeper.js +13 -0
  147. package/dist/sweep/utxo-sweeper.js.map +1 -0
  148. package/dist/tron/address-convert.d.ts +15 -0
  149. package/dist/tron/address-convert.d.ts.map +1 -0
  150. package/dist/tron/address-convert.js +95 -0
  151. package/dist/tron/address-convert.js.map +1 -0
  152. package/dist/tron/encoder.d.ts +20 -0
  153. package/dist/tron/encoder.d.ts.map +1 -0
  154. package/dist/tron/encoder.js +67 -0
  155. package/dist/tron/encoder.js.map +1 -0
  156. package/dist/tron/index.d.ts +6 -0
  157. package/dist/tron/index.d.ts.map +1 -0
  158. package/dist/tron/index.js +20 -0
  159. package/dist/tron/index.js.map +1 -0
  160. package/dist/tron/sha256.d.ts +6 -0
  161. package/dist/tron/sha256.d.ts.map +1 -0
  162. package/dist/tron/sha256.js +90 -0
  163. package/dist/tron/sha256.js.map +1 -0
  164. package/dist/tron/watcher.d.ts +42 -0
  165. package/dist/tron/watcher.d.ts.map +1 -0
  166. package/dist/tron/watcher.js +168 -0
  167. package/dist/tron/watcher.js.map +1 -0
  168. package/package.json +47 -0
  169. package/src/__tests__/bitcoin-encoder.test.ts +115 -0
  170. package/src/__tests__/dogecoin-encoder.test.ts +66 -0
  171. package/src/__tests__/litecoin-encoder.test.ts +51 -0
  172. package/src/__tests__/registry.test.ts +91 -0
  173. package/src/__tests__/rpc.test.ts +36 -0
  174. package/src/__tests__/solana-encoder.test.ts +103 -0
  175. package/src/__tests__/solana-watcher.test.ts +316 -0
  176. package/src/__tests__/sweep-key-parity.test.ts +302 -0
  177. package/src/__tests__/tron-encoder.test.ts +108 -0
  178. package/src/__tests__/utxo-watcher.test.ts +252 -0
  179. package/src/bitcoin/encoder.ts +320 -0
  180. package/src/bitcoin/index.ts +23 -0
  181. package/src/dogecoin/encoder.ts +161 -0
  182. package/src/dogecoin/index.ts +23 -0
  183. package/src/evm/encoder.ts +49 -0
  184. package/src/evm/eth-watcher.ts +168 -0
  185. package/src/evm/index.ts +46 -0
  186. package/src/evm/types.ts +146 -0
  187. package/src/evm/watcher.ts +189 -0
  188. package/src/index.ts +21 -0
  189. package/src/litecoin/encoder.ts +18 -0
  190. package/src/litecoin/index.ts +23 -0
  191. package/src/shared/test-helpers/index.ts +36 -0
  192. package/src/shared/utxo/index.ts +12 -0
  193. package/src/shared/utxo/rpc.ts +80 -0
  194. package/src/shared/utxo/types.ts +43 -0
  195. package/src/shared/utxo/watcher.ts +195 -0
  196. package/src/solana/encoder.ts +72 -0
  197. package/src/solana/index.ts +36 -0
  198. package/src/solana/sweeper.ts +196 -0
  199. package/src/solana/types.ts +52 -0
  200. package/src/solana/watcher.ts +282 -0
  201. package/src/sweep/evm-sweeper.ts +296 -0
  202. package/src/sweep/index.ts +353 -0
  203. package/src/sweep/tron-sweeper.ts +467 -0
  204. package/src/sweep/utxo-sweeper.ts +23 -0
  205. package/src/tron/address-convert.ts +91 -0
  206. package/src/tron/encoder.ts +74 -0
  207. package/src/tron/index.ts +23 -0
  208. package/src/tron/sha256.ts +100 -0
  209. package/src/tron/watcher.ts +208 -0
  210. package/tsconfig.json +17 -0
  211. package/vitest.config.ts +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/evm/types.ts"],"names":[],"mappings":"AA6CA,oCAAoC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAgC;IAC1D,IAAI,EAAE;QACL,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,qBAAqB;QAC7B,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACT,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,kBAAkB;QAC1B,aAAa,EAAE,EAAE;QACjB,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,CAAC;KACV;IACD,QAAQ,EAAE;QACT,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,mBAAmB;QAC3B,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,GAAG;QAChB,OAAO,EAAE,KAAK;KACd;IACD,OAAO,EAAE;QACR,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,iBAAiB;QACzB,aAAa,EAAE,EAAE;QACjB,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,GAAG;KACZ;CACD,CAAC;AAEF,wCAAwC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAgC;IAC1D,WAAW,EAAE;QACZ,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,MAAM;QACb,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,WAAW,EAAE;QACZ,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,MAAM;QACb,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,UAAU,EAAE;QACX,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,MAAM;QACb,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,EAAE;KACZ;IACD,eAAe,EAAE;QAChB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,eAAe,EAAE;QAChB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,cAAc,EAAE;QACf,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,EAAE;KACZ;IACD,eAAe,EAAE;QAChB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,eAAe,EAAE;QAChB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,cAAc,EAAE;QACf,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,EAAE;KACZ;IACD,cAAc,EAAE;QACf,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,SAAS;QAChB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;IACD,cAAc,EAAE;QACf,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,SAAS;QAChB,eAAe,EAAE,4CAA4C;QAC7D,QAAQ,EAAE,CAAC;KACX;CACD,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { IChainWatcher, PaymentEvent, WatcherOpts } from "@wopr-network/platform-core/crypto-plugin";
2
+ import type { RpcCall } from "./types.js";
3
+ /** Create an RPC caller for a given URL (plain JSON-RPC over fetch). */
4
+ export declare function createRpcCaller(rpcUrl: string, extraHeaders?: Record<string, string>): RpcCall;
5
+ /**
6
+ * ERC-20 Transfer log scanner.
7
+ *
8
+ * Scans from cursor to latest block for Transfer events matching watched
9
+ * deposit addresses. Emits events with current confirmation count. Re-emits
10
+ * on each confirmation increment. Only advances cursor past fully-confirmed blocks.
11
+ */
12
+ export declare class EvmWatcher implements IChainWatcher {
13
+ private _cursor;
14
+ private _stopped;
15
+ private readonly chain;
16
+ private readonly token;
17
+ private readonly rpc;
18
+ private readonly confirmations;
19
+ private readonly contractAddress;
20
+ private readonly decimals;
21
+ private readonly cursorStore;
22
+ private readonly watcherId;
23
+ private _watchedAddresses;
24
+ constructor(opts: WatcherOpts);
25
+ init(): Promise<void>;
26
+ setWatchedAddresses(addresses: string[]): void;
27
+ getCursor(): number;
28
+ stop(): void;
29
+ /**
30
+ * Poll for ERC-20 Transfer events, including pending (unconfirmed) blocks.
31
+ *
32
+ * Two-phase scan:
33
+ * 1. Scan cursor..latest for new/updated txs, emit with current confirmation count
34
+ * 2. Re-check pending txs automatically since cursor doesn't advance past unconfirmed blocks
35
+ *
36
+ * Cursor only advances past fully-confirmed blocks.
37
+ *
38
+ * Returns PaymentEvent[] instead of using callbacks.
39
+ */
40
+ poll(): Promise<PaymentEvent[]>;
41
+ }
42
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/evm/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EAEb,YAAY,EACZ,WAAW,EACX,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,YAAY,CAAC;AAIlD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAqB9F;AAUD;;;;;;GAMG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC/C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,iBAAiB,CAAW;gBAExB,IAAI,EAAE,WAAW;IAavB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAI9C,SAAS,IAAI,MAAM;IAInB,IAAI,IAAI,IAAI;IAIZ;;;;;;;;;;OAUG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAqFrC"}
@@ -0,0 +1,162 @@
1
+ const TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
2
+ /** Create an RPC caller for a given URL (plain JSON-RPC over fetch). */
3
+ export function createRpcCaller(rpcUrl, extraHeaders) {
4
+ let id = 0;
5
+ const headers = { "Content-Type": "application/json", ...extraHeaders };
6
+ return async (method, params) => {
7
+ const res = await fetch(rpcUrl, {
8
+ method: "POST",
9
+ headers,
10
+ body: JSON.stringify({ jsonrpc: "2.0", id: ++id, method, params }),
11
+ });
12
+ if (!res.ok) {
13
+ const body = await res.text().catch(() => "");
14
+ const hasApiKey = "TRON-PRO-API-KEY" in headers;
15
+ console.error(`[rpc] ${method} ${res.status} auth=${hasApiKey} url=${rpcUrl.replace(/apikey=[^&]+/, "apikey=***")} body=${body.slice(0, 200)}`);
16
+ throw new Error(`RPC ${method} failed: ${res.status}`);
17
+ }
18
+ const data = (await res.json());
19
+ if (data.error)
20
+ throw new Error(`RPC ${method} error: ${data.error.message}`);
21
+ return data.result;
22
+ };
23
+ }
24
+ /**
25
+ * Convert token raw amount (BigInt) to USD cents (integer).
26
+ * Stablecoins are 1:1 USD. Truncates fractional cents.
27
+ */
28
+ function centsFromTokenAmount(rawAmount, decimals) {
29
+ return Number((rawAmount * 100n) / 10n ** BigInt(decimals));
30
+ }
31
+ /**
32
+ * ERC-20 Transfer log scanner.
33
+ *
34
+ * Scans from cursor to latest block for Transfer events matching watched
35
+ * deposit addresses. Emits events with current confirmation count. Re-emits
36
+ * on each confirmation increment. Only advances cursor past fully-confirmed blocks.
37
+ */
38
+ export class EvmWatcher {
39
+ _cursor = 0;
40
+ _stopped = false;
41
+ chain;
42
+ token;
43
+ rpc;
44
+ confirmations;
45
+ contractAddress;
46
+ decimals;
47
+ cursorStore;
48
+ watcherId;
49
+ _watchedAddresses;
50
+ constructor(opts) {
51
+ this.chain = opts.chain;
52
+ this.token = opts.token;
53
+ this.rpc = createRpcCaller(opts.rpcUrl, opts.rpcHeaders);
54
+ this._cursor = 0;
55
+ this.confirmations = opts.confirmations;
56
+ this.contractAddress = (opts.contractAddress ?? "").toLowerCase();
57
+ this.decimals = opts.decimals;
58
+ this.cursorStore = opts.cursorStore;
59
+ this.watcherId = `evm:${opts.chain}:${opts.token}`;
60
+ this._watchedAddresses = [];
61
+ }
62
+ async init() {
63
+ const saved = await this.cursorStore.get(this.watcherId);
64
+ if (saved !== null)
65
+ this._cursor = saved;
66
+ }
67
+ setWatchedAddresses(addresses) {
68
+ this._watchedAddresses = addresses.map((a) => a.toLowerCase());
69
+ }
70
+ getCursor() {
71
+ return this._cursor;
72
+ }
73
+ stop() {
74
+ this._stopped = true;
75
+ }
76
+ /**
77
+ * Poll for ERC-20 Transfer events, including pending (unconfirmed) blocks.
78
+ *
79
+ * Two-phase scan:
80
+ * 1. Scan cursor..latest for new/updated txs, emit with current confirmation count
81
+ * 2. Re-check pending txs automatically since cursor doesn't advance past unconfirmed blocks
82
+ *
83
+ * Cursor only advances past fully-confirmed blocks.
84
+ *
85
+ * Returns PaymentEvent[] instead of using callbacks.
86
+ */
87
+ async poll() {
88
+ if (this._stopped || this._watchedAddresses.length === 0)
89
+ return [];
90
+ const latestHex = (await this.rpc("eth_blockNumber", []));
91
+ const latest = Number.parseInt(latestHex, 16);
92
+ const confirmed = latest - this.confirmations;
93
+ if (latest < this._cursor)
94
+ return [];
95
+ // Filter by topic[2] (to address) when watched addresses are set.
96
+ const toFilter = this._watchedAddresses.length > 0
97
+ ? this._watchedAddresses.map((a) => `0x000000000000000000000000${a.slice(2)}`)
98
+ : null;
99
+ // Scan from cursor to latest (not just confirmed) to detect pending txs
100
+ const logs = (await this.rpc("eth_getLogs", [
101
+ {
102
+ address: this.contractAddress,
103
+ topics: [TRANSFER_TOPIC, null, toFilter],
104
+ fromBlock: `0x${this._cursor.toString(16)}`,
105
+ toBlock: `0x${latest.toString(16)}`,
106
+ },
107
+ ]));
108
+ // Group logs by block
109
+ const logsByBlock = new Map();
110
+ for (const log of logs) {
111
+ const bn = Number.parseInt(log.blockNumber, 16);
112
+ const arr = logsByBlock.get(bn);
113
+ if (arr)
114
+ arr.push(log);
115
+ else
116
+ logsByBlock.set(bn, [log]);
117
+ }
118
+ const events = [];
119
+ // Process all blocks (including unconfirmed), emit with confirmation count
120
+ const blockNums = [...logsByBlock.keys()].sort((a, b) => a - b);
121
+ for (const blockNum of blockNums) {
122
+ const confs = latest - blockNum;
123
+ for (const log of logsByBlock.get(blockNum) ?? []) {
124
+ const txKey = `${log.transactionHash}:${log.logIndex}`;
125
+ // Skip if we already emitted at this confirmation count
126
+ const lastConf = await this.cursorStore.getConfirmationCount(this.watcherId, txKey);
127
+ if (lastConf !== null && confs <= lastConf)
128
+ continue;
129
+ const to = `0x${log.topics[2].slice(26)}`.toLowerCase();
130
+ const from = `0x${log.topics[1].slice(26)}`.toLowerCase();
131
+ const rawAmount = BigInt(log.data);
132
+ const amountUsdCents = centsFromTokenAmount(rawAmount, this.decimals);
133
+ events.push({
134
+ chain: this.chain,
135
+ token: this.token,
136
+ from,
137
+ to,
138
+ rawAmount: rawAmount.toString(),
139
+ amountUsdCents,
140
+ txHash: log.transactionHash,
141
+ blockNumber: blockNum,
142
+ confirmations: confs,
143
+ confirmationsRequired: this.confirmations,
144
+ });
145
+ // Track confirmation count
146
+ await this.cursorStore.saveConfirmationCount(this.watcherId, txKey, confs);
147
+ }
148
+ // Only advance cursor past fully-confirmed blocks
149
+ if (blockNum <= confirmed) {
150
+ this._cursor = blockNum + 1;
151
+ await this.cursorStore.save(this.watcherId, this._cursor);
152
+ }
153
+ }
154
+ // Advance cursor if no logs found but confirmed blocks exist
155
+ if (blockNums.length === 0 && confirmed >= this._cursor) {
156
+ this._cursor = confirmed + 1;
157
+ await this.cursorStore.save(this.watcherId, this._cursor);
158
+ }
159
+ return events;
160
+ }
161
+ }
162
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/evm/watcher.ts"],"names":[],"mappings":"AAQA,MAAM,cAAc,GAAG,oEAAoE,CAAC;AAE5F,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,YAAqC;IACpF,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,YAAY,EAAE,CAAC;IAChG,OAAO,KAAK,EAAE,MAAc,EAAE,MAAiB,EAAoB,EAAE;QACpE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;YAC/B,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;SAClE,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,kBAAkB,IAAI,OAAO,CAAC;YAChD,OAAO,CAAC,KAAK,CACZ,SAAS,MAAM,IAAI,GAAG,CAAC,MAAM,SAAS,SAAS,QAAQ,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAChI,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsD,CAAC;QACrF,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,SAAiB,EAAE,QAAgB;IAChE,OAAO,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,UAAU;IACd,OAAO,GAAG,CAAC,CAAC;IACZ,QAAQ,GAAG,KAAK,CAAC;IACR,KAAK,CAAS;IACd,KAAK,CAAS;IACd,GAAG,CAAU;IACb,aAAa,CAAS;IACtB,eAAe,CAAS;IACxB,QAAQ,CAAS;IACjB,WAAW,CAAsB;IACjC,SAAS,CAAS;IAC3B,iBAAiB,CAAW;IAEpC,YAAY,IAAiB;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAClE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACnD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI;QACT,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IAC1C,CAAC;IAED,mBAAmB,CAAC,SAAmB;QACtC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,SAAS;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,IAAI;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,IAAI;QACT,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEpE,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAW,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;QAE9C,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAErC,kEAAkE;QAClE,MAAM,QAAQ,GACb,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC;YAChC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,6BAA6B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,CAAC,CAAC,IAAI,CAAC;QAET,wEAAwE;QACxE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;YAC3C;gBACC,OAAO,EAAE,IAAI,CAAC,eAAe;gBAC7B,MAAM,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,QAAQ,CAAC;gBACxC,SAAS,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBAC3C,OAAO,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;aACnC;SACD,CAAC,CAAa,CAAC;QAEhB,sBAAsB;QACtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;QAChD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChC,IAAI,GAAG;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;gBAClB,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAmB,EAAE,CAAC;QAElC,2EAA2E;QAC3E,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;YAEhC,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAEvD,wDAAwD;gBACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBACpF,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ;oBAAE,SAAS;gBAErD,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;gBACxD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC1D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACnC,MAAM,cAAc,GAAG,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAEtE,MAAM,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,IAAI;oBACJ,EAAE;oBACF,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE;oBAC/B,cAAc;oBACd,MAAM,EAAE,GAAG,CAAC,eAAe;oBAC3B,WAAW,EAAE,QAAQ;oBACrB,aAAa,EAAE,KAAK;oBACpB,qBAAqB,EAAE,IAAI,CAAC,aAAa;iBACzC,CAAC,CAAC;gBAEH,2BAA2B;gBAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5E,CAAC;YAED,kDAAkD;YAClD,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,GAAG,QAAQ,GAAG,CAAC,CAAC;gBAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3D,CAAC;QACF,CAAC;QAED,6DAA6D;QAC7D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACzD,IAAI,CAAC,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC;YAC7B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;CACD"}
@@ -0,0 +1,7 @@
1
+ export { bitcoinPlugin } from "./bitcoin/index.js";
2
+ export { dogecoinPlugin, encodeP2pkhAddress, p2pkhEncoder } from "./dogecoin/index.js";
3
+ export { evmPlugin } from "./evm/index.js";
4
+ export { bech32Encoder as ltcBech32Encoder, litecoinPlugin } from "./litecoin/index.js";
5
+ export { base58Encode, createSolanaRpcCaller, SolanaAddressEncoder, SolanaSweeper, SolanaWatcher, solanaPlugin, } from "./solana/index.js";
6
+ export { encodeKeccakB58Address, hexToTron, isTronAddress, keccakB58Encoder, TronEvmWatcher, tronPlugin, tronToHex, } from "./tron/index.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EACN,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,SAAS,GACT,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { bitcoinPlugin } from "./bitcoin/index.js";
2
+ export { dogecoinPlugin, encodeP2pkhAddress, p2pkhEncoder } from "./dogecoin/index.js";
3
+ export { evmPlugin } from "./evm/index.js";
4
+ export { bech32Encoder as ltcBech32Encoder, litecoinPlugin } from "./litecoin/index.js";
5
+ export { base58Encode, createSolanaRpcCaller, SolanaAddressEncoder, SolanaSweeper, SolanaWatcher, solanaPlugin, } from "./solana/index.js";
6
+ export { encodeKeccakB58Address, hexToTron, isTronAddress, keccakB58Encoder, TronEvmWatcher, tronPlugin, tronToHex, } from "./tron/index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EACN,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,SAAS,GACT,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { IAddressEncoder } from "@wopr-network/platform-core/crypto-plugin";
2
+ /**
3
+ * Litecoin bech32 address encoder.
4
+ * Implements IAddressEncoder for the litecoin plugin.
5
+ * Default HRP is "ltc" (mainnet). Override with params.hrp for testnet ("tltc").
6
+ */
7
+ export declare const bech32Encoder: IAddressEncoder;
8
+ //# sourceMappingURL=encoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/litecoin/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAIjG;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,eAQ3B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { encodeBech32Address } from "../bitcoin/encoder.js";
2
+ /**
3
+ * Litecoin bech32 address encoder.
4
+ * Implements IAddressEncoder for the litecoin plugin.
5
+ * Default HRP is "ltc" (mainnet). Override with params.hrp for testnet ("tltc").
6
+ */
7
+ export const bech32Encoder = {
8
+ encode(publicKey, params) {
9
+ const hrp = params.hrp ?? "ltc";
10
+ return encodeBech32Address(publicKey, hrp);
11
+ },
12
+ encodingType() {
13
+ return "bech32";
14
+ },
15
+ };
16
+ //# sourceMappingURL=encoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/litecoin/encoder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC7C,MAAM,CAAC,SAAqB,EAAE,MAAsB;QACnD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC;QAChC,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC;IACD,YAAY;QACX,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { IChainPlugin } from "@wopr-network/platform-core/crypto-plugin";
2
+ export { bech32Encoder } from "./encoder.js";
3
+ export declare const litecoinPlugin: IChainPlugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/litecoin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,2CAA2C,CAAC;AAM3F,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,eAAO,MAAM,cAAc,EAAE,YAc5B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { createRpcFromOpts } from "../shared/utxo/index.js";
2
+ import { createUtxoWatcher } from "../shared/utxo/watcher.js";
3
+ import { bech32Encoder } from "./encoder.js";
4
+ export { bech32Encoder } from "./encoder.js";
5
+ export const litecoinPlugin = {
6
+ pluginId: "litecoin",
7
+ supportedCurve: "secp256k1",
8
+ encoders: {
9
+ bech32: bech32Encoder,
10
+ },
11
+ createWatcher(opts) {
12
+ const rpc = createRpcFromOpts(opts.rpcUrl, opts.rpcHeaders);
13
+ return createUtxoWatcher(opts, rpc);
14
+ },
15
+ createSweeper() {
16
+ throw new Error("Not implemented");
17
+ },
18
+ version: 1,
19
+ };
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/litecoin/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC3C,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,WAAW;IAC3B,QAAQ,EAAE;QACT,MAAM,EAAE,aAAa;KACrB;IACD,aAAa,CAAC,IAAiB;QAC9B,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5D,OAAO,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,aAAa;QACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,EAAE,CAAC;CACV,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { IPriceOracle, IWatcherCursorStore } from "@wopr-network/platform-core/crypto-plugin";
2
+ /** In-memory mock cursor store for testing UTXO watchers. */
3
+ export declare function createMockCursorStore(): IWatcherCursorStore & {
4
+ _cursors: Map<string, number>;
5
+ _confirmations: Map<string, number>;
6
+ };
7
+ /** Mock price oracle that returns a fixed price. */
8
+ export declare function createMockOracle(priceMicros?: number): IPriceOracle;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/test-helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAEnG,6DAA6D;AAC7D,wBAAgB,qBAAqB,IAAI,mBAAmB,GAAG;IAC9D,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAoBA;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,WAAW,SAAkB,GAAG,YAAY,CAM5E"}
@@ -0,0 +1,30 @@
1
+ /** In-memory mock cursor store for testing UTXO watchers. */
2
+ export function createMockCursorStore() {
3
+ const cursors = new Map();
4
+ const confirmations = new Map();
5
+ return {
6
+ _cursors: cursors,
7
+ _confirmations: confirmations,
8
+ async get(watcherId) {
9
+ return cursors.get(watcherId) ?? null;
10
+ },
11
+ async save(watcherId, cursor) {
12
+ cursors.set(watcherId, cursor);
13
+ },
14
+ async getConfirmationCount(watcherId, txKey) {
15
+ return confirmations.get(`${watcherId}:${txKey}`) ?? null;
16
+ },
17
+ async saveConfirmationCount(watcherId, txKey, count) {
18
+ confirmations.set(`${watcherId}:${txKey}`, count);
19
+ },
20
+ };
21
+ }
22
+ /** Mock price oracle that returns a fixed price. */
23
+ export function createMockOracle(priceMicros = 100_000_000_000) {
24
+ return {
25
+ async getPrice(_token) {
26
+ return { priceMicros };
27
+ },
28
+ };
29
+ }
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/test-helpers/index.ts"],"names":[],"mappings":"AAEA,6DAA6D;AAC7D,MAAM,UAAU,qBAAqB;IAIpC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEhD,OAAO;QACN,QAAQ,EAAE,OAAO;QACjB,cAAc,EAAE,aAAa;QAC7B,KAAK,CAAC,GAAG,CAAC,SAAiB;YAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAc;YAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,oBAAoB,CAAC,SAAiB,EAAE,KAAa;YAC1D,OAAO,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;QAC3D,CAAC;QACD,KAAK,CAAC,qBAAqB,CAAC,SAAiB,EAAE,KAAa,EAAE,KAAa;YAC1E,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;KACD,CAAC;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,WAAW,GAAG,eAAe;IAC7D,OAAO;QACN,KAAK,CAAC,QAAQ,CAAC,MAAc;YAC5B,OAAO,EAAE,WAAW,EAAE,CAAC;QACxB,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { createBitcoindRpc, createRpcFromOpts, parseRpcUrl } from "./rpc.js";
2
+ export type { DescriptorInfo, GetTransactionResponse, ImportDescriptorResult, ReceivedByAddress, RpcCall, TxDetail, UtxoNodeConfig, } from "./types.js";
3
+ export type { UtxoWatcherConfig } from "./watcher.js";
4
+ export { createUtxoWatcher, UtxoWatcher } from "./watcher.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utxo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC7E,YAAY,EACX,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,cAAc,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createBitcoindRpc, createRpcFromOpts, parseRpcUrl } from "./rpc.js";
2
+ export { createUtxoWatcher, UtxoWatcher } from "./watcher.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/utxo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAW7E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { RpcCall } from "./types.js";
2
+ interface RpcConfig {
3
+ rpcUrl: string;
4
+ rpcUser: string;
5
+ rpcPassword: string;
6
+ }
7
+ /**
8
+ * Parse RPC credentials from a URL with embedded basic auth.
9
+ * e.g. "http://user:pass@host:8332" -> { rpcUrl: "http://host:8332", rpcUser: "user", rpcPassword: "pass" }
10
+ * If no auth in URL, returns the URL as-is with empty credentials.
11
+ */
12
+ export declare function parseRpcUrl(url: string): RpcConfig;
13
+ /**
14
+ * Create a JSON-RPC caller for a bitcoind-compatible node (BTC, LTC, DOGE).
15
+ * Uses basic auth and JSON-RPC 1.0 protocol.
16
+ */
17
+ export declare function createBitcoindRpc(rpcUrl: string, rpcUser: string, rpcPassword: string): RpcCall;
18
+ /**
19
+ * Create a bitcoind-compatible RPC caller from WatcherOpts-style config.
20
+ * Parses rpcUrl for embedded credentials, falls back to rpcHeaders Authorization.
21
+ */
22
+ export declare function createRpcFromOpts(rpcUrl: string, rpcHeaders: Record<string, string>): RpcCall;
23
+ export {};
24
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/shared/utxo/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,UAAU,SAAS;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAclD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAiB/F;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAuB7F"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Parse RPC credentials from a URL with embedded basic auth.
3
+ * e.g. "http://user:pass@host:8332" -> { rpcUrl: "http://host:8332", rpcUser: "user", rpcPassword: "pass" }
4
+ * If no auth in URL, returns the URL as-is with empty credentials.
5
+ */
6
+ export function parseRpcUrl(url) {
7
+ try {
8
+ const parsed = new URL(url);
9
+ if (parsed.username) {
10
+ const rpcUser = decodeURIComponent(parsed.username);
11
+ const rpcPassword = decodeURIComponent(parsed.password);
12
+ parsed.username = "";
13
+ parsed.password = "";
14
+ return { rpcUrl: parsed.toString().replace(/\/$/, ""), rpcUser, rpcPassword };
15
+ }
16
+ }
17
+ catch {
18
+ // Not a valid URL with auth, return as-is
19
+ }
20
+ return { rpcUrl: url, rpcUser: "", rpcPassword: "" };
21
+ }
22
+ /**
23
+ * Create a JSON-RPC caller for a bitcoind-compatible node (BTC, LTC, DOGE).
24
+ * Uses basic auth and JSON-RPC 1.0 protocol.
25
+ */
26
+ export function createBitcoindRpc(rpcUrl, rpcUser, rpcPassword) {
27
+ let id = 0;
28
+ const auth = btoa(`${rpcUser}:${rpcPassword}`);
29
+ return async (method, params) => {
30
+ const res = await fetch(rpcUrl, {
31
+ method: "POST",
32
+ headers: {
33
+ "Content-Type": "application/json",
34
+ Authorization: `Basic ${auth}`,
35
+ },
36
+ body: JSON.stringify({ jsonrpc: "1.0", id: ++id, method, params }),
37
+ });
38
+ if (!res.ok)
39
+ throw new Error(`RPC ${method} failed: ${res.status}`);
40
+ const data = (await res.json());
41
+ if (data.error)
42
+ throw new Error(`RPC ${method}: ${data.error.message}`);
43
+ return data.result;
44
+ };
45
+ }
46
+ /**
47
+ * Create a bitcoind-compatible RPC caller from WatcherOpts-style config.
48
+ * Parses rpcUrl for embedded credentials, falls back to rpcHeaders Authorization.
49
+ */
50
+ export function createRpcFromOpts(rpcUrl, rpcHeaders) {
51
+ // Try parsing credentials from URL
52
+ const parsed = parseRpcUrl(rpcUrl);
53
+ if (parsed.rpcUser) {
54
+ return createBitcoindRpc(parsed.rpcUrl, parsed.rpcUser, parsed.rpcPassword);
55
+ }
56
+ // Fall back to rpcHeaders (may contain Authorization header)
57
+ let id = 0;
58
+ return async (method, params) => {
59
+ const res = await fetch(rpcUrl, {
60
+ method: "POST",
61
+ headers: {
62
+ "Content-Type": "application/json",
63
+ ...rpcHeaders,
64
+ },
65
+ body: JSON.stringify({ jsonrpc: "1.0", id: ++id, method, params }),
66
+ });
67
+ if (!res.ok)
68
+ throw new Error(`RPC ${method} failed: ${res.status}`);
69
+ const data = (await res.json());
70
+ if (data.error)
71
+ throw new Error(`RPC ${method}: ${data.error.message}`);
72
+ return data.result;
73
+ };
74
+ }
75
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../../src/shared/utxo/rpc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** Configuration for a bitcoind-compatible JSON-RPC node (BTC, LTC, DOGE). */
2
+ export interface UtxoNodeConfig {
3
+ readonly rpcUrl: string;
4
+ readonly rpcUser: string;
5
+ readonly rpcPassword: string;
6
+ readonly network: "mainnet" | "testnet" | "regtest";
7
+ readonly confirmations: number;
8
+ }
9
+ /** A single "received by address" entry from listreceivedbyaddress. */
10
+ export interface ReceivedByAddress {
11
+ address: string;
12
+ amount: number;
13
+ confirmations: number;
14
+ txids: string[];
15
+ }
16
+ /** Transaction detail from gettransaction. */
17
+ export interface TxDetail {
18
+ address: string;
19
+ amount: number;
20
+ category: string;
21
+ }
22
+ /** Response from gettransaction RPC call. */
23
+ export interface GetTransactionResponse {
24
+ details: TxDetail[];
25
+ confirmations: number;
26
+ }
27
+ /** Descriptor info response from getdescriptorinfo. */
28
+ export interface DescriptorInfo {
29
+ descriptor: string;
30
+ }
31
+ /** Result of importdescriptors RPC call. */
32
+ export interface ImportDescriptorResult {
33
+ success: boolean;
34
+ error?: {
35
+ message: string;
36
+ };
37
+ }
38
+ /** JSON-RPC call signature for bitcoind-compatible nodes. */
39
+ export type RpcCall = (method: string, params: unknown[]) => Promise<unknown>;
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shared/utxo/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B;AAED,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC9B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAED,6DAA6D;AAC7D,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/shared/utxo/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import type { IChainWatcher, IPriceOracle, IWatcherCursorStore, PaymentEvent, WatcherOpts } from "@wopr-network/platform-core/crypto-plugin";
2
+ import type { RpcCall } from "./types.js";
3
+ export interface UtxoWatcherConfig {
4
+ /** JSON-RPC call function for the node. */
5
+ rpc: RpcCall;
6
+ /** Chain identifier for the price oracle (e.g. "BTC", "LTC", "DOGE"). */
7
+ token: string;
8
+ /** Chain name for PaymentEvent (e.g. "bitcoin", "litecoin", "dogecoin"). */
9
+ chain: string;
10
+ /** Number of decimal places for this chain's native unit (8 for BTC/LTC/DOGE). */
11
+ decimals: number;
12
+ /** Required confirmations before marking fully processed. */
13
+ confirmations: number;
14
+ /** Price oracle for USD conversion. */
15
+ oracle: IPriceOracle;
16
+ /** Cursor store for dedup and confirmation tracking. */
17
+ cursorStore: IWatcherCursorStore;
18
+ }
19
+ /**
20
+ * Generic UTXO chain watcher that works with any bitcoind-compatible node.
21
+ * Polls listreceivedbyaddress for payments and tracks confirmations.
22
+ *
23
+ * Reusable for BTC, LTC, and DOGE.
24
+ */
25
+ export declare class UtxoWatcher implements IChainWatcher {
26
+ private readonly rpc;
27
+ private readonly addresses;
28
+ private readonly token;
29
+ private readonly chain;
30
+ private readonly decimals;
31
+ private readonly minConfirmations;
32
+ private readonly oracle;
33
+ private readonly cursorStore;
34
+ private readonly watcherId;
35
+ private cursor;
36
+ private stopped;
37
+ constructor(config: UtxoWatcherConfig);
38
+ init(): Promise<void>;
39
+ setWatchedAddresses(addresses: string[]): void;
40
+ getCursor(): number;
41
+ stop(): void;
42
+ /**
43
+ * Import an address into the node's wallet (watch-only).
44
+ * Uses importdescriptors (modern) with fallback to importaddress (legacy).
45
+ */
46
+ importAddress(address: string): Promise<void>;
47
+ /**
48
+ * Poll for payments to watched addresses.
49
+ * Returns PaymentEvent[] for each new or updated confirmation.
50
+ */
51
+ poll(): Promise<PaymentEvent[]>;
52
+ }
53
+ /** Create a UtxoWatcher from the standard WatcherOpts interface. */
54
+ export declare function createUtxoWatcher(opts: WatcherOpts, rpc: RpcCall): IChainWatcher;
55
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../src/shared/utxo/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,MAAM,2CAA2C,CAAC;AAEnD,OAAO,KAAK,EAKX,OAAO,EACP,MAAM,YAAY,CAAC;AAqBpB,MAAM,WAAW,iBAAiB;IACjC,2CAA2C;IAC3C,GAAG,EAAE,OAAO,CAAC;IACb,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,MAAM,EAAE,YAAY,CAAC;IACrB,wDAAwD;IACxD,WAAW,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;GAKG;AACH,qBAAa,WAAY,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,iBAAiB;IAW/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAK9C,SAAS,IAAI,MAAM;IAInB,IAAI,IAAI,IAAI;IAIZ;;;OAGG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAwDrC;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,aAAa,CAUhF"}