@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.
- package/.github/workflows/ci.yml +33 -0
- package/.github/workflows/publish.yml +12 -0
- package/biome.json +23 -0
- package/dist/__tests__/bitcoin-encoder.test.d.ts +2 -0
- package/dist/__tests__/bitcoin-encoder.test.d.ts.map +1 -0
- package/dist/__tests__/bitcoin-encoder.test.js +97 -0
- package/dist/__tests__/bitcoin-encoder.test.js.map +1 -0
- package/dist/__tests__/dogecoin-encoder.test.d.ts +2 -0
- package/dist/__tests__/dogecoin-encoder.test.d.ts.map +1 -0
- package/dist/__tests__/dogecoin-encoder.test.js +57 -0
- package/dist/__tests__/dogecoin-encoder.test.js.map +1 -0
- package/dist/__tests__/litecoin-encoder.test.d.ts +2 -0
- package/dist/__tests__/litecoin-encoder.test.d.ts.map +1 -0
- package/dist/__tests__/litecoin-encoder.test.js +44 -0
- package/dist/__tests__/litecoin-encoder.test.js.map +1 -0
- package/dist/__tests__/registry.test.d.ts +2 -0
- package/dist/__tests__/registry.test.d.ts.map +1 -0
- package/dist/__tests__/registry.test.js +75 -0
- package/dist/__tests__/registry.test.js.map +1 -0
- package/dist/__tests__/rpc.test.d.ts +2 -0
- package/dist/__tests__/rpc.test.d.ts.map +1 -0
- package/dist/__tests__/rpc.test.js +31 -0
- package/dist/__tests__/rpc.test.js.map +1 -0
- package/dist/__tests__/solana-encoder.test.d.ts +2 -0
- package/dist/__tests__/solana-encoder.test.d.ts.map +1 -0
- package/dist/__tests__/solana-encoder.test.js +85 -0
- package/dist/__tests__/solana-encoder.test.js.map +1 -0
- package/dist/__tests__/solana-watcher.test.d.ts +2 -0
- package/dist/__tests__/solana-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/solana-watcher.test.js +281 -0
- package/dist/__tests__/solana-watcher.test.js.map +1 -0
- package/dist/__tests__/sweep-key-parity.test.d.ts +2 -0
- package/dist/__tests__/sweep-key-parity.test.d.ts.map +1 -0
- package/dist/__tests__/sweep-key-parity.test.js +236 -0
- package/dist/__tests__/sweep-key-parity.test.js.map +1 -0
- package/dist/__tests__/tron-encoder.test.d.ts +2 -0
- package/dist/__tests__/tron-encoder.test.d.ts.map +1 -0
- package/dist/__tests__/tron-encoder.test.js +93 -0
- package/dist/__tests__/tron-encoder.test.js.map +1 -0
- package/dist/__tests__/utxo-watcher.test.d.ts +2 -0
- package/dist/__tests__/utxo-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/utxo-watcher.test.js +218 -0
- package/dist/__tests__/utxo-watcher.test.js.map +1 -0
- package/dist/bitcoin/encoder.d.ts +15 -0
- package/dist/bitcoin/encoder.d.ts.map +1 -0
- package/dist/bitcoin/encoder.js +286 -0
- package/dist/bitcoin/encoder.js.map +1 -0
- package/dist/bitcoin/index.d.ts +4 -0
- package/dist/bitcoin/index.d.ts.map +1 -0
- package/dist/bitcoin/index.js +20 -0
- package/dist/bitcoin/index.js.map +1 -0
- package/dist/dogecoin/encoder.d.ts +19 -0
- package/dist/dogecoin/encoder.d.ts.map +1 -0
- package/dist/dogecoin/encoder.js +145 -0
- package/dist/dogecoin/encoder.js.map +1 -0
- package/dist/dogecoin/index.d.ts +4 -0
- package/dist/dogecoin/index.d.ts.map +1 -0
- package/dist/dogecoin/index.js +20 -0
- package/dist/dogecoin/index.js.map +1 -0
- package/dist/evm/encoder.d.ts +7 -0
- package/dist/evm/encoder.d.ts.map +1 -0
- package/dist/evm/encoder.js +43 -0
- package/dist/evm/encoder.js.map +1 -0
- package/dist/evm/eth-watcher.d.ts +38 -0
- package/dist/evm/eth-watcher.d.ts.map +1 -0
- package/dist/evm/eth-watcher.js +138 -0
- package/dist/evm/eth-watcher.js.map +1 -0
- package/dist/evm/index.d.ts +16 -0
- package/dist/evm/index.d.ts.map +1 -0
- package/dist/evm/index.js +34 -0
- package/dist/evm/index.js.map +1 -0
- package/dist/evm/types.d.ts +43 -0
- package/dist/evm/types.d.ts.map +1 -0
- package/dist/evm/types.js +101 -0
- package/dist/evm/types.js.map +1 -0
- package/dist/evm/watcher.d.ts +42 -0
- package/dist/evm/watcher.d.ts.map +1 -0
- package/dist/evm/watcher.js +162 -0
- package/dist/evm/watcher.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/litecoin/encoder.d.ts +8 -0
- package/dist/litecoin/encoder.d.ts.map +1 -0
- package/dist/litecoin/encoder.js +16 -0
- package/dist/litecoin/encoder.js.map +1 -0
- package/dist/litecoin/index.d.ts +4 -0
- package/dist/litecoin/index.d.ts.map +1 -0
- package/dist/litecoin/index.js +20 -0
- package/dist/litecoin/index.js.map +1 -0
- package/dist/shared/test-helpers/index.d.ts +9 -0
- package/dist/shared/test-helpers/index.d.ts.map +1 -0
- package/dist/shared/test-helpers/index.js +30 -0
- package/dist/shared/test-helpers/index.js.map +1 -0
- package/dist/shared/utxo/index.d.ts +5 -0
- package/dist/shared/utxo/index.d.ts.map +1 -0
- package/dist/shared/utxo/index.js +3 -0
- package/dist/shared/utxo/index.js.map +1 -0
- package/dist/shared/utxo/rpc.d.ts +24 -0
- package/dist/shared/utxo/rpc.d.ts.map +1 -0
- package/dist/shared/utxo/rpc.js +75 -0
- package/dist/shared/utxo/rpc.js.map +1 -0
- package/dist/shared/utxo/types.d.ts +40 -0
- package/dist/shared/utxo/types.d.ts.map +1 -0
- package/dist/shared/utxo/types.js +2 -0
- package/dist/shared/utxo/types.js.map +1 -0
- package/dist/shared/utxo/watcher.d.ts +55 -0
- package/dist/shared/utxo/watcher.d.ts.map +1 -0
- package/dist/shared/utxo/watcher.js +150 -0
- package/dist/shared/utxo/watcher.js.map +1 -0
- package/dist/solana/encoder.d.ts +13 -0
- package/dist/solana/encoder.d.ts.map +1 -0
- package/dist/solana/encoder.js +62 -0
- package/dist/solana/encoder.js.map +1 -0
- package/dist/solana/index.d.ts +17 -0
- package/dist/solana/index.d.ts.map +1 -0
- package/dist/solana/index.js +32 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/solana/sweeper.d.ts +47 -0
- package/dist/solana/sweeper.d.ts.map +1 -0
- package/dist/solana/sweeper.js +151 -0
- package/dist/solana/sweeper.js.map +1 -0
- package/dist/solana/types.d.ts +49 -0
- package/dist/solana/types.d.ts.map +1 -0
- package/dist/solana/types.js +2 -0
- package/dist/solana/types.js.map +1 -0
- package/dist/solana/watcher.d.ts +59 -0
- package/dist/solana/watcher.d.ts.map +1 -0
- package/dist/solana/watcher.js +251 -0
- package/dist/solana/watcher.js.map +1 -0
- package/dist/sweep/evm-sweeper.d.ts +31 -0
- package/dist/sweep/evm-sweeper.d.ts.map +1 -0
- package/dist/sweep/evm-sweeper.js +229 -0
- package/dist/sweep/evm-sweeper.js.map +1 -0
- package/dist/sweep/index.d.ts +22 -0
- package/dist/sweep/index.d.ts.map +1 -0
- package/dist/sweep/index.js +290 -0
- package/dist/sweep/index.js.map +1 -0
- package/dist/sweep/tron-sweeper.d.ts +40 -0
- package/dist/sweep/tron-sweeper.d.ts.map +1 -0
- package/dist/sweep/tron-sweeper.js +363 -0
- package/dist/sweep/tron-sweeper.js.map +1 -0
- package/dist/sweep/utxo-sweeper.d.ts +14 -0
- package/dist/sweep/utxo-sweeper.d.ts.map +1 -0
- package/dist/sweep/utxo-sweeper.js +13 -0
- package/dist/sweep/utxo-sweeper.js.map +1 -0
- package/dist/tron/address-convert.d.ts +15 -0
- package/dist/tron/address-convert.d.ts.map +1 -0
- package/dist/tron/address-convert.js +95 -0
- package/dist/tron/address-convert.js.map +1 -0
- package/dist/tron/encoder.d.ts +20 -0
- package/dist/tron/encoder.d.ts.map +1 -0
- package/dist/tron/encoder.js +67 -0
- package/dist/tron/encoder.js.map +1 -0
- package/dist/tron/index.d.ts +6 -0
- package/dist/tron/index.d.ts.map +1 -0
- package/dist/tron/index.js +20 -0
- package/dist/tron/index.js.map +1 -0
- package/dist/tron/sha256.d.ts +6 -0
- package/dist/tron/sha256.d.ts.map +1 -0
- package/dist/tron/sha256.js +90 -0
- package/dist/tron/sha256.js.map +1 -0
- package/dist/tron/watcher.d.ts +42 -0
- package/dist/tron/watcher.d.ts.map +1 -0
- package/dist/tron/watcher.js +168 -0
- package/dist/tron/watcher.js.map +1 -0
- package/package.json +47 -0
- package/src/__tests__/bitcoin-encoder.test.ts +115 -0
- package/src/__tests__/dogecoin-encoder.test.ts +66 -0
- package/src/__tests__/litecoin-encoder.test.ts +51 -0
- package/src/__tests__/registry.test.ts +91 -0
- package/src/__tests__/rpc.test.ts +36 -0
- package/src/__tests__/solana-encoder.test.ts +103 -0
- package/src/__tests__/solana-watcher.test.ts +316 -0
- package/src/__tests__/sweep-key-parity.test.ts +302 -0
- package/src/__tests__/tron-encoder.test.ts +108 -0
- package/src/__tests__/utxo-watcher.test.ts +252 -0
- package/src/bitcoin/encoder.ts +320 -0
- package/src/bitcoin/index.ts +23 -0
- package/src/dogecoin/encoder.ts +161 -0
- package/src/dogecoin/index.ts +23 -0
- package/src/evm/encoder.ts +49 -0
- package/src/evm/eth-watcher.ts +168 -0
- package/src/evm/index.ts +46 -0
- package/src/evm/types.ts +146 -0
- package/src/evm/watcher.ts +189 -0
- package/src/index.ts +21 -0
- package/src/litecoin/encoder.ts +18 -0
- package/src/litecoin/index.ts +23 -0
- package/src/shared/test-helpers/index.ts +36 -0
- package/src/shared/utxo/index.ts +12 -0
- package/src/shared/utxo/rpc.ts +80 -0
- package/src/shared/utxo/types.ts +43 -0
- package/src/shared/utxo/watcher.ts +195 -0
- package/src/solana/encoder.ts +72 -0
- package/src/solana/index.ts +36 -0
- package/src/solana/sweeper.ts +196 -0
- package/src/solana/types.ts +52 -0
- package/src/solana/watcher.ts +282 -0
- package/src/sweep/evm-sweeper.ts +296 -0
- package/src/sweep/index.ts +353 -0
- package/src/sweep/tron-sweeper.ts +467 -0
- package/src/sweep/utxo-sweeper.ts +23 -0
- package/src/tron/address-convert.ts +91 -0
- package/src/tron/encoder.ts +74 -0
- package/src/tron/index.ts +23 -0
- package/src/tron/sha256.ts +100 -0
- package/src/tron/watcher.ts +208 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { hash160 } from "../bitcoin/encoder.js";
|
|
2
|
+
// ---------- Base58Check encoding ----------
|
|
3
|
+
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
4
|
+
function base58encode(data) {
|
|
5
|
+
let num = 0n;
|
|
6
|
+
for (const byte of data)
|
|
7
|
+
num = num * 256n + BigInt(byte);
|
|
8
|
+
let encoded = "";
|
|
9
|
+
while (num > 0n) {
|
|
10
|
+
encoded = BASE58_ALPHABET[Number(num % 58n)] + encoded;
|
|
11
|
+
num = num / 58n;
|
|
12
|
+
}
|
|
13
|
+
for (const byte of data) {
|
|
14
|
+
if (byte !== 0)
|
|
15
|
+
break;
|
|
16
|
+
encoded = `1${encoded}`;
|
|
17
|
+
}
|
|
18
|
+
return encoded;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* SHA-256 (pure implementation, duplicated from bitcoin encoder to avoid
|
|
22
|
+
* re-exporting the internal function — hash160 is already exported).
|
|
23
|
+
*/
|
|
24
|
+
function sha256(data) {
|
|
25
|
+
const K = [
|
|
26
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
|
|
27
|
+
0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
28
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
|
|
29
|
+
0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
30
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
|
31
|
+
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
32
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
|
|
33
|
+
0xc67178f2,
|
|
34
|
+
];
|
|
35
|
+
const msgLen = data.length;
|
|
36
|
+
const bitLen = msgLen * 8;
|
|
37
|
+
const padLen = ((msgLen + 9 + 63) & ~63) - msgLen;
|
|
38
|
+
const padded = new Uint8Array(msgLen + padLen);
|
|
39
|
+
padded.set(data);
|
|
40
|
+
padded[msgLen] = 0x80;
|
|
41
|
+
const view = new DataView(padded.buffer);
|
|
42
|
+
view.setUint32(padded.length - 4, bitLen, false);
|
|
43
|
+
let h0 = 0x6a09e667;
|
|
44
|
+
let h1 = 0xbb67ae85;
|
|
45
|
+
let h2 = 0x3c6ef372;
|
|
46
|
+
let h3 = 0xa54ff53a;
|
|
47
|
+
let h4 = 0x510e527f;
|
|
48
|
+
let h5 = 0x9b05688c;
|
|
49
|
+
let h6 = 0x1f83d9ab;
|
|
50
|
+
let h7 = 0x5be0cd19;
|
|
51
|
+
const w = new Int32Array(64);
|
|
52
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
53
|
+
for (let i = 0; i < 16; i++) {
|
|
54
|
+
w[i] = view.getInt32(offset + i * 4, false);
|
|
55
|
+
}
|
|
56
|
+
for (let i = 16; i < 64; i++) {
|
|
57
|
+
const s0 = (ror32(w[i - 15], 7) ^ ror32(w[i - 15], 18) ^ (w[i - 15] >>> 3)) | 0;
|
|
58
|
+
const s1 = (ror32(w[i - 2], 17) ^ ror32(w[i - 2], 19) ^ (w[i - 2] >>> 10)) | 0;
|
|
59
|
+
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;
|
|
60
|
+
}
|
|
61
|
+
let a = h0;
|
|
62
|
+
let b = h1;
|
|
63
|
+
let c = h2;
|
|
64
|
+
let d = h3;
|
|
65
|
+
let e = h4;
|
|
66
|
+
let f = h5;
|
|
67
|
+
let g = h6;
|
|
68
|
+
let h = h7;
|
|
69
|
+
for (let i = 0; i < 64; i++) {
|
|
70
|
+
const S1 = (ror32(e, 6) ^ ror32(e, 11) ^ ror32(e, 25)) | 0;
|
|
71
|
+
const ch = ((e & f) ^ (~e & g)) | 0;
|
|
72
|
+
const temp1 = (h + S1 + ch + K[i] + w[i]) | 0;
|
|
73
|
+
const S0 = (ror32(a, 2) ^ ror32(a, 13) ^ ror32(a, 22)) | 0;
|
|
74
|
+
const maj = ((a & b) ^ (a & c) ^ (b & c)) | 0;
|
|
75
|
+
const temp2 = (S0 + maj) | 0;
|
|
76
|
+
h = g;
|
|
77
|
+
g = f;
|
|
78
|
+
f = e;
|
|
79
|
+
e = (d + temp1) | 0;
|
|
80
|
+
d = c;
|
|
81
|
+
c = b;
|
|
82
|
+
b = a;
|
|
83
|
+
a = (temp1 + temp2) | 0;
|
|
84
|
+
}
|
|
85
|
+
h0 = (h0 + a) | 0;
|
|
86
|
+
h1 = (h1 + b) | 0;
|
|
87
|
+
h2 = (h2 + c) | 0;
|
|
88
|
+
h3 = (h3 + d) | 0;
|
|
89
|
+
h4 = (h4 + e) | 0;
|
|
90
|
+
h5 = (h5 + f) | 0;
|
|
91
|
+
h6 = (h6 + g) | 0;
|
|
92
|
+
h7 = (h7 + h) | 0;
|
|
93
|
+
}
|
|
94
|
+
const result = new Uint8Array(32);
|
|
95
|
+
const rv = new DataView(result.buffer);
|
|
96
|
+
rv.setInt32(0, h0, false);
|
|
97
|
+
rv.setInt32(4, h1, false);
|
|
98
|
+
rv.setInt32(8, h2, false);
|
|
99
|
+
rv.setInt32(12, h3, false);
|
|
100
|
+
rv.setInt32(16, h4, false);
|
|
101
|
+
rv.setInt32(20, h5, false);
|
|
102
|
+
rv.setInt32(24, h6, false);
|
|
103
|
+
rv.setInt32(28, h7, false);
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
function ror32(x, n) {
|
|
107
|
+
return (x >>> n) | (x << (32 - n));
|
|
108
|
+
}
|
|
109
|
+
// ---------- P2PKH encoding ----------
|
|
110
|
+
/**
|
|
111
|
+
* Encode a compressed public key as a P2PKH (Base58Check) address.
|
|
112
|
+
* Used for DOGE (version 0x1e), etc.
|
|
113
|
+
*
|
|
114
|
+
* Steps:
|
|
115
|
+
* 1. HASH160(pubkey) = RIPEMD-160(SHA-256(pubkey))
|
|
116
|
+
* 2. Prepend version byte
|
|
117
|
+
* 3. Append double-SHA-256 checksum (first 4 bytes)
|
|
118
|
+
* 4. Base58 encode
|
|
119
|
+
*/
|
|
120
|
+
export function encodeP2pkhAddress(publicKey, versionByte) {
|
|
121
|
+
const h = hash160(publicKey);
|
|
122
|
+
const payload = new Uint8Array(21);
|
|
123
|
+
payload[0] = versionByte;
|
|
124
|
+
payload.set(h, 1);
|
|
125
|
+
const checksum = sha256(sha256(payload));
|
|
126
|
+
const full = new Uint8Array(25);
|
|
127
|
+
full.set(payload);
|
|
128
|
+
full.set(checksum.slice(0, 4), 21);
|
|
129
|
+
return base58encode(full);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Dogecoin P2PKH address encoder.
|
|
133
|
+
* Implements IAddressEncoder for the dogecoin plugin.
|
|
134
|
+
* Default version byte is 0x1e (30) for mainnet. Override with params.version.
|
|
135
|
+
*/
|
|
136
|
+
export const p2pkhEncoder = {
|
|
137
|
+
encode(publicKey, params) {
|
|
138
|
+
const versionByte = params.version ? Number(params.version) : 0x1e;
|
|
139
|
+
return encodeP2pkhAddress(publicKey, versionByte);
|
|
140
|
+
},
|
|
141
|
+
encodingType() {
|
|
142
|
+
return "p2pkh";
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=encoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/dogecoin/encoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dogecoin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,2CAA2C,CAAC;AAM3F,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE,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 { p2pkhEncoder } from "./encoder.js";
|
|
4
|
+
export { encodeP2pkhAddress, p2pkhEncoder } from "./encoder.js";
|
|
5
|
+
export const dogecoinPlugin = {
|
|
6
|
+
pluginId: "dogecoin",
|
|
7
|
+
supportedCurve: "secp256k1",
|
|
8
|
+
encoders: {
|
|
9
|
+
p2pkh: p2pkhEncoder,
|
|
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/dogecoin/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC3C,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,WAAW;IAC3B,QAAQ,EAAE;QACT,KAAK,EAAE,YAAY;KACnB;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,7 @@
|
|
|
1
|
+
import type { EncodingParams, IAddressEncoder } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
/** EVM address encoder implementing IAddressEncoder. */
|
|
3
|
+
export declare class EvmAddressEncoder implements IAddressEncoder {
|
|
4
|
+
encode(publicKey: Uint8Array, _params: EncodingParams): string;
|
|
5
|
+
encodingType(): string;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=encoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/evm/encoder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAqCjG,wDAAwD;AACxD,qBAAa,iBAAkB,YAAW,eAAe;IACxD,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM;IAI9D,YAAY,IAAI,MAAM;CAGtB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
2
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
3
|
+
// secp256k1.Point exists at runtime but the ECDSA TS type doesn't expose it.
|
|
4
|
+
// Access via the schnorr sub-object which does have the Point type.
|
|
5
|
+
const Point = secp256k1.Point;
|
|
6
|
+
/**
|
|
7
|
+
* Derive an EVM (0x...) address from a compressed SEC1 public key.
|
|
8
|
+
*
|
|
9
|
+
* Steps:
|
|
10
|
+
* 1. Decompress the 33-byte compressed pubkey to 65-byte uncompressed
|
|
11
|
+
* 2. Take keccak256 of the uncompressed key (without the 0x04 prefix byte)
|
|
12
|
+
* 3. Take the last 20 bytes as the address
|
|
13
|
+
* 4. Apply EIP-55 mixed-case checksum
|
|
14
|
+
*/
|
|
15
|
+
function toHex(bytes) {
|
|
16
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
17
|
+
}
|
|
18
|
+
function encodeEvm(pubkey) {
|
|
19
|
+
const hexKey = toHex(pubkey);
|
|
20
|
+
const uncompressed = Point.fromHex(hexKey).toBytes(false);
|
|
21
|
+
// keccak256 of uncompressed key without the 04 prefix
|
|
22
|
+
const hash = keccak_256(uncompressed.slice(1));
|
|
23
|
+
const addressBytes = hash.slice(-20);
|
|
24
|
+
const rawHex = toHex(addressBytes);
|
|
25
|
+
// EIP-55 checksum
|
|
26
|
+
const hashHex = toHex(keccak_256(new TextEncoder().encode(rawHex)));
|
|
27
|
+
let checksummed = "0x";
|
|
28
|
+
for (let i = 0; i < rawHex.length; i++) {
|
|
29
|
+
const c = rawHex[i];
|
|
30
|
+
checksummed += Number.parseInt(hashHex[i], 16) >= 8 ? c.toUpperCase() : c;
|
|
31
|
+
}
|
|
32
|
+
return checksummed;
|
|
33
|
+
}
|
|
34
|
+
/** EVM address encoder implementing IAddressEncoder. */
|
|
35
|
+
export class EvmAddressEncoder {
|
|
36
|
+
encode(publicKey, _params) {
|
|
37
|
+
return encodeEvm(publicKey);
|
|
38
|
+
}
|
|
39
|
+
encodingType() {
|
|
40
|
+
return "evm";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=encoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/evm/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,6EAA6E;AAC7E,oEAAoE;AACpE,MAAM,KAAK,GAAI,SAA+F,CAAC,KAAK,CAAC;AAErH;;;;;;;;GAQG;AACH,SAAS,KAAK,CAAC,KAAiB;IAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,KAA4B,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1G,CAAC;AAED,SAAS,SAAS,CAAC,MAAkB;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1D,sDAAsD;IACtD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;IAEnC,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,WAAW,GAAG,IAAI,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,WAAW,CAAC;AACpB,CAAC;AAED,wDAAwD;AACxD,MAAM,OAAO,iBAAiB;IAC7B,MAAM,CAAC,SAAqB,EAAE,OAAuB;QACpD,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY;QACX,OAAO,KAAK,CAAC;IACd,CAAC;CACD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { IChainWatcher, PaymentEvent, WatcherOpts } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
/**
|
|
3
|
+
* Native ETH transfer watcher.
|
|
4
|
+
*
|
|
5
|
+
* Unlike the ERC-20 EvmWatcher which uses eth_getLogs for Transfer events,
|
|
6
|
+
* this scans blocks for transactions where `to` matches a watched deposit
|
|
7
|
+
* address and `value > 0`.
|
|
8
|
+
*
|
|
9
|
+
* Scans up to latest block (not just confirmed) to detect pending txs.
|
|
10
|
+
* Emits events on each confirmation increment. Only advances cursor
|
|
11
|
+
* past fully-confirmed blocks.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EthWatcher implements IChainWatcher {
|
|
14
|
+
private _cursor;
|
|
15
|
+
private _stopped;
|
|
16
|
+
private readonly chain;
|
|
17
|
+
private readonly token;
|
|
18
|
+
private readonly rpc;
|
|
19
|
+
private readonly oracle;
|
|
20
|
+
private readonly confirmations;
|
|
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 native ETH transfers to watched addresses, including unconfirmed blocks.
|
|
31
|
+
*
|
|
32
|
+
* Scans from cursor to latest block in batches of 5. Emits events with current
|
|
33
|
+
* confirmation count. Re-emits on each confirmation increment. Only advances
|
|
34
|
+
* cursor past fully-confirmed blocks.
|
|
35
|
+
*/
|
|
36
|
+
poll(): Promise<PaymentEvent[]>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=eth-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eth-watcher.d.ts","sourceRoot":"","sources":["../../src/evm/eth-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EAGb,YAAY,EACZ,WAAW,EACX,MAAM,2CAA2C,CAAC;AAsBnD;;;;;;;;;;GAUG;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,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,iBAAiB,CAAc;gBAE3B,IAAI,EAAE,WAAW;IAYvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAI9C,SAAS,IAAI,MAAM;IAInB,IAAI,IAAI,IAAI;IAIZ;;;;;;OAMG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAgFrC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { createRpcCaller } from "./watcher.js";
|
|
2
|
+
/** Microdollars per cent. Used for oracle price conversion. */
|
|
3
|
+
const MICROS_PER_CENT = 10000n;
|
|
4
|
+
/**
|
|
5
|
+
* Convert native token amount to USD cents using oracle price in microdollars.
|
|
6
|
+
*
|
|
7
|
+
* @param rawAmount - Raw value in smallest unit (e.g. wei)
|
|
8
|
+
* @param priceMicros - Price per whole token in microdollars (10^-6 USD)
|
|
9
|
+
* @param decimals - Token decimals (18 for ETH)
|
|
10
|
+
*/
|
|
11
|
+
function nativeToCents(rawAmount, priceMicros, decimals) {
|
|
12
|
+
if (rawAmount < 0n)
|
|
13
|
+
throw new Error("rawAmount must be non-negative");
|
|
14
|
+
if (!Number.isInteger(priceMicros) || priceMicros <= 0) {
|
|
15
|
+
throw new Error(`priceMicros must be a positive integer, got ${priceMicros}`);
|
|
16
|
+
}
|
|
17
|
+
return Number((rawAmount * BigInt(priceMicros)) / (MICROS_PER_CENT * 10n ** BigInt(decimals)));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Native ETH transfer watcher.
|
|
21
|
+
*
|
|
22
|
+
* Unlike the ERC-20 EvmWatcher which uses eth_getLogs for Transfer events,
|
|
23
|
+
* this scans blocks for transactions where `to` matches a watched deposit
|
|
24
|
+
* address and `value > 0`.
|
|
25
|
+
*
|
|
26
|
+
* Scans up to latest block (not just confirmed) to detect pending txs.
|
|
27
|
+
* Emits events on each confirmation increment. Only advances cursor
|
|
28
|
+
* past fully-confirmed blocks.
|
|
29
|
+
*/
|
|
30
|
+
export class EthWatcher {
|
|
31
|
+
_cursor = 0;
|
|
32
|
+
_stopped = false;
|
|
33
|
+
chain;
|
|
34
|
+
token;
|
|
35
|
+
rpc;
|
|
36
|
+
oracle;
|
|
37
|
+
confirmations;
|
|
38
|
+
cursorStore;
|
|
39
|
+
watcherId;
|
|
40
|
+
_watchedAddresses;
|
|
41
|
+
constructor(opts) {
|
|
42
|
+
this.chain = opts.chain;
|
|
43
|
+
this.token = opts.token;
|
|
44
|
+
this.rpc = createRpcCaller(opts.rpcUrl, opts.rpcHeaders);
|
|
45
|
+
this.oracle = opts.oracle;
|
|
46
|
+
this._cursor = 0;
|
|
47
|
+
this.confirmations = opts.confirmations;
|
|
48
|
+
this.cursorStore = opts.cursorStore;
|
|
49
|
+
this.watcherId = `eth:${opts.chain}`;
|
|
50
|
+
this._watchedAddresses = new Set();
|
|
51
|
+
}
|
|
52
|
+
async init() {
|
|
53
|
+
const saved = await this.cursorStore.get(this.watcherId);
|
|
54
|
+
if (saved !== null)
|
|
55
|
+
this._cursor = saved;
|
|
56
|
+
}
|
|
57
|
+
setWatchedAddresses(addresses) {
|
|
58
|
+
this._watchedAddresses = new Set(addresses.map((a) => a.toLowerCase()));
|
|
59
|
+
}
|
|
60
|
+
getCursor() {
|
|
61
|
+
return this._cursor;
|
|
62
|
+
}
|
|
63
|
+
stop() {
|
|
64
|
+
this._stopped = true;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Poll for native ETH transfers to watched addresses, including unconfirmed blocks.
|
|
68
|
+
*
|
|
69
|
+
* Scans from cursor to latest block in batches of 5. Emits events with current
|
|
70
|
+
* confirmation count. Re-emits on each confirmation increment. Only advances
|
|
71
|
+
* cursor past fully-confirmed blocks.
|
|
72
|
+
*/
|
|
73
|
+
async poll() {
|
|
74
|
+
if (this._stopped || this._watchedAddresses.size === 0)
|
|
75
|
+
return [];
|
|
76
|
+
const latestHex = (await this.rpc("eth_blockNumber", []));
|
|
77
|
+
const latest = Number.parseInt(latestHex, 16);
|
|
78
|
+
const confirmed = latest - this.confirmations;
|
|
79
|
+
if (latest < this._cursor)
|
|
80
|
+
return [];
|
|
81
|
+
const { priceMicros } = await this.oracle.getPrice("ETH");
|
|
82
|
+
const events = [];
|
|
83
|
+
// Fetch blocks in batches to avoid bursting RPC rate limits on fast chains.
|
|
84
|
+
const BATCH_SIZE = 5;
|
|
85
|
+
for (let batchStart = this._cursor; batchStart <= latest; batchStart += BATCH_SIZE) {
|
|
86
|
+
if (this._stopped)
|
|
87
|
+
break;
|
|
88
|
+
const batchEnd = Math.min(batchStart + BATCH_SIZE - 1, latest);
|
|
89
|
+
const blockNums = Array.from({ length: batchEnd - batchStart + 1 }, (_, i) => batchStart + i);
|
|
90
|
+
const blocks = await Promise.all(blockNums.map((bn) => this.rpc("eth_getBlockByNumber", [`0x${bn.toString(16)}`, true]).then((b) => ({ blockNum: bn, block: b, error: null }), (err) => ({ blockNum: bn, block: null, error: err }))));
|
|
91
|
+
// Stop processing at the first failed block so the cursor doesn't advance past it.
|
|
92
|
+
const firstFailIdx = blocks.findIndex((b) => b.error !== null || !b.block);
|
|
93
|
+
const safeBlocks = firstFailIdx === -1 ? blocks : blocks.slice(0, firstFailIdx);
|
|
94
|
+
for (const { blockNum, block } of safeBlocks) {
|
|
95
|
+
if (!block)
|
|
96
|
+
break;
|
|
97
|
+
const confs = latest - blockNum;
|
|
98
|
+
for (const tx of block.transactions) {
|
|
99
|
+
if (!tx.to)
|
|
100
|
+
continue;
|
|
101
|
+
const to = tx.to.toLowerCase();
|
|
102
|
+
if (!this._watchedAddresses.has(to))
|
|
103
|
+
continue;
|
|
104
|
+
const valueWei = BigInt(tx.value);
|
|
105
|
+
if (valueWei === 0n)
|
|
106
|
+
continue;
|
|
107
|
+
// Skip if we already emitted at this confirmation count
|
|
108
|
+
const lastConf = await this.cursorStore.getConfirmationCount(this.watcherId, tx.hash);
|
|
109
|
+
if (lastConf !== null && confs <= lastConf)
|
|
110
|
+
continue;
|
|
111
|
+
const amountUsdCents = nativeToCents(valueWei, priceMicros, 18);
|
|
112
|
+
events.push({
|
|
113
|
+
chain: this.chain,
|
|
114
|
+
token: this.token,
|
|
115
|
+
from: tx.from.toLowerCase(),
|
|
116
|
+
to,
|
|
117
|
+
rawAmount: valueWei.toString(),
|
|
118
|
+
amountUsdCents,
|
|
119
|
+
txHash: tx.hash,
|
|
120
|
+
blockNumber: blockNum,
|
|
121
|
+
confirmations: confs,
|
|
122
|
+
confirmationsRequired: this.confirmations,
|
|
123
|
+
});
|
|
124
|
+
await this.cursorStore.saveConfirmationCount(this.watcherId, tx.hash, confs);
|
|
125
|
+
}
|
|
126
|
+
// Only advance cursor past fully-confirmed blocks
|
|
127
|
+
if (blockNum <= confirmed) {
|
|
128
|
+
this._cursor = blockNum + 1;
|
|
129
|
+
await this.cursorStore.save(this.watcherId, this._cursor);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (firstFailIdx !== -1)
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
return events;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=eth-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eth-watcher.js","sourceRoot":"","sources":["../../src/evm/eth-watcher.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,+DAA+D;AAC/D,MAAM,eAAe,GAAG,MAAO,CAAC;AAEhC;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,SAAiB,EAAE,WAAmB,EAAE,QAAgB;IAC9E,IAAI,SAAS,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,+CAA+C,WAAW,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,MAAM,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,eAAe,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,UAAU;IACd,OAAO,GAAG,CAAC,CAAC;IACZ,QAAQ,GAAG,KAAK,CAAC;IACR,KAAK,CAAS;IACd,KAAK,CAAS;IACd,GAAG,CAAU;IACb,MAAM,CAAe;IACrB,aAAa,CAAS;IACtB,WAAW,CAAsB;IACjC,SAAS,CAAS;IAC3B,iBAAiB,CAAc;IAEvC,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,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,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,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,SAAS;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,IAAI;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI;QACT,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElE,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,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE1D,MAAM,MAAM,GAAmB,EAAE,CAAC;QAElC,4EAA4E;QAC5E,MAAM,UAAU,GAAG,CAAC,CAAC;QACrB,KAAK,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,UAAU,IAAI,UAAU,EAAE,CAAC;YACpF,IAAI,IAAI,CAAC,QAAQ;gBAAE,MAAM;YAEzB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,UAAU,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YAE9F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CACpB,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACpE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAA8C,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAC7F,CAAC,GAAY,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAC7D,CACD,CACD,CAAC;YAEF,mFAAmF;YACnF,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3E,MAAM,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;YAChF,KAAK,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC9C,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAElB,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;gBAEhC,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACrC,IAAI,CAAC,EAAE,CAAC,EAAE;wBAAE,SAAS;oBACrB,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC/B,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;wBAAE,SAAS;oBAE9C,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;oBAClC,IAAI,QAAQ,KAAK,EAAE;wBAAE,SAAS;oBAE9B,wDAAwD;oBACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;oBACtF,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ;wBAAE,SAAS;oBAErD,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;oBAEhE,MAAM,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE;wBAC3B,EAAE;wBACF,SAAS,EAAE,QAAQ,CAAC,QAAQ,EAAE;wBAC9B,cAAc;wBACd,MAAM,EAAE,EAAE,CAAC,IAAI;wBACf,WAAW,EAAE,QAAQ;wBACrB,aAAa,EAAE,KAAK;wBACpB,qBAAqB,EAAE,IAAI,CAAC,aAAa;qBACzC,CAAC,CAAC;oBAEH,MAAM,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC9E,CAAC;gBAED,kDAAkD;gBAClD,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;oBAC3B,IAAI,CAAC,OAAO,GAAG,QAAQ,GAAG,CAAC,CAAC;oBAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC3D,CAAC;YACF,CAAC;YAED,IAAI,YAAY,KAAK,CAAC,CAAC;gBAAE,MAAM;QAChC,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;CACD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IChainPlugin } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
export { EvmAddressEncoder } from "./encoder.js";
|
|
3
|
+
export { EthWatcher } from "./eth-watcher.js";
|
|
4
|
+
export type { ChainConfig, EvmChain, RpcCall, RpcLog, RpcTransaction, StablecoinToken, TokenConfig, } from "./types.js";
|
|
5
|
+
export { DEFAULT_CHAINS, DEFAULT_TOKENS } from "./types.js";
|
|
6
|
+
export { createRpcCaller, EvmWatcher } from "./watcher.js";
|
|
7
|
+
/**
|
|
8
|
+
* EVM chain plugin.
|
|
9
|
+
*
|
|
10
|
+
* Supports ERC-20 stablecoin watching (EvmWatcher) and native ETH watching (EthWatcher).
|
|
11
|
+
* The watcher created depends on whether a contractAddress is provided in opts:
|
|
12
|
+
* - With contractAddress: EvmWatcher (ERC-20 Transfer log scanner)
|
|
13
|
+
* - Without contractAddress: EthWatcher (native ETH block scanner)
|
|
14
|
+
*/
|
|
15
|
+
export declare const evmPlugin: IChainPlugin;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evm/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,2CAA2C,CAAC;AAKxG,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACX,WAAW,EACX,QAAQ,EACR,OAAO,EACP,MAAM,EACN,cAAc,EACd,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI3D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,YAgBvB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EvmAddressEncoder } from "./encoder.js";
|
|
2
|
+
import { EthWatcher } from "./eth-watcher.js";
|
|
3
|
+
import { EvmWatcher } from "./watcher.js";
|
|
4
|
+
export { EvmAddressEncoder } from "./encoder.js";
|
|
5
|
+
export { EthWatcher } from "./eth-watcher.js";
|
|
6
|
+
export { DEFAULT_CHAINS, DEFAULT_TOKENS } from "./types.js";
|
|
7
|
+
export { createRpcCaller, EvmWatcher } from "./watcher.js";
|
|
8
|
+
const encoder = new EvmAddressEncoder();
|
|
9
|
+
/**
|
|
10
|
+
* EVM chain plugin.
|
|
11
|
+
*
|
|
12
|
+
* Supports ERC-20 stablecoin watching (EvmWatcher) and native ETH watching (EthWatcher).
|
|
13
|
+
* The watcher created depends on whether a contractAddress is provided in opts:
|
|
14
|
+
* - With contractAddress: EvmWatcher (ERC-20 Transfer log scanner)
|
|
15
|
+
* - Without contractAddress: EthWatcher (native ETH block scanner)
|
|
16
|
+
*/
|
|
17
|
+
export const evmPlugin = {
|
|
18
|
+
pluginId: "evm",
|
|
19
|
+
supportedCurve: "secp256k1",
|
|
20
|
+
encoders: {
|
|
21
|
+
evm: encoder,
|
|
22
|
+
},
|
|
23
|
+
createWatcher(opts) {
|
|
24
|
+
if (opts.contractAddress) {
|
|
25
|
+
return new EvmWatcher(opts);
|
|
26
|
+
}
|
|
27
|
+
return new EthWatcher(opts);
|
|
28
|
+
},
|
|
29
|
+
createSweeper(_opts) {
|
|
30
|
+
throw new Error("Not implemented — EVM sweeper is planned for Phase 3");
|
|
31
|
+
},
|
|
32
|
+
version: 1,
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/evm/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAU9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiB;IACtC,QAAQ,EAAE,KAAK;IACf,cAAc,EAAE,WAAW;IAC3B,QAAQ,EAAE;QACT,GAAG,EAAE,OAAO;KACZ;IACD,aAAa,CAAC,IAAiB;QAC9B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,aAAa,CAAC,KAAkB;QAC/B,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,EAAE,CAAC;CACV,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Supported EVM chains. */
|
|
2
|
+
export type EvmChain = "base" | "ethereum" | "arbitrum" | "polygon" | (string & {});
|
|
3
|
+
/** Supported stablecoin tokens. */
|
|
4
|
+
export type StablecoinToken = "USDC" | "USDT" | "DAI";
|
|
5
|
+
/** Chain configuration. */
|
|
6
|
+
export interface ChainConfig {
|
|
7
|
+
readonly chain: EvmChain;
|
|
8
|
+
readonly rpcUrl: string;
|
|
9
|
+
readonly confirmations: number;
|
|
10
|
+
readonly blockTimeMs: number;
|
|
11
|
+
readonly chainId: number;
|
|
12
|
+
}
|
|
13
|
+
/** Token configuration on a specific chain. */
|
|
14
|
+
export interface TokenConfig {
|
|
15
|
+
readonly token: StablecoinToken;
|
|
16
|
+
readonly chain: EvmChain;
|
|
17
|
+
readonly contractAddress: `0x${string}`;
|
|
18
|
+
readonly decimals: number;
|
|
19
|
+
}
|
|
20
|
+
/** JSON-RPC call function signature. */
|
|
21
|
+
export type RpcCall = (method: string, params: unknown[]) => Promise<unknown>;
|
|
22
|
+
/** Raw JSON-RPC log entry. */
|
|
23
|
+
export interface RpcLog {
|
|
24
|
+
address: string;
|
|
25
|
+
topics: string[];
|
|
26
|
+
data: string;
|
|
27
|
+
blockNumber: string;
|
|
28
|
+
transactionHash: string;
|
|
29
|
+
logIndex: string;
|
|
30
|
+
}
|
|
31
|
+
/** Raw JSON-RPC transaction entry. */
|
|
32
|
+
export interface RpcTransaction {
|
|
33
|
+
hash: string;
|
|
34
|
+
from: string;
|
|
35
|
+
to: string | null;
|
|
36
|
+
value: string;
|
|
37
|
+
blockNumber: string;
|
|
38
|
+
}
|
|
39
|
+
/** Default chain configurations. */
|
|
40
|
+
export declare const DEFAULT_CHAINS: Record<string, ChainConfig>;
|
|
41
|
+
/** Default stablecoin token configs. */
|
|
42
|
+
export declare const DEFAULT_TOKENS: Record<string, TokenConfig>;
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evm/types.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEpF,mCAAmC;AACnC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtD,2BAA2B;AAC3B,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,wCAAwC;AACxC,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E,8BAA8B;AAC9B,MAAM,WAAW,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,oCAAoC;AACpC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA6BtD,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAmEtD,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Default chain configurations. */
|
|
2
|
+
export const DEFAULT_CHAINS = {
|
|
3
|
+
base: {
|
|
4
|
+
chain: "base",
|
|
5
|
+
rpcUrl: "http://op-geth:8545",
|
|
6
|
+
confirmations: 1,
|
|
7
|
+
blockTimeMs: 2000,
|
|
8
|
+
chainId: 8453,
|
|
9
|
+
},
|
|
10
|
+
ethereum: {
|
|
11
|
+
chain: "ethereum",
|
|
12
|
+
rpcUrl: "http://geth:8545",
|
|
13
|
+
confirmations: 12,
|
|
14
|
+
blockTimeMs: 12000,
|
|
15
|
+
chainId: 1,
|
|
16
|
+
},
|
|
17
|
+
arbitrum: {
|
|
18
|
+
chain: "arbitrum",
|
|
19
|
+
rpcUrl: "http://nitro:8547",
|
|
20
|
+
confirmations: 1,
|
|
21
|
+
blockTimeMs: 250,
|
|
22
|
+
chainId: 42161,
|
|
23
|
+
},
|
|
24
|
+
polygon: {
|
|
25
|
+
chain: "polygon",
|
|
26
|
+
rpcUrl: "http://bor:8545",
|
|
27
|
+
confirmations: 32,
|
|
28
|
+
blockTimeMs: 2000,
|
|
29
|
+
chainId: 137,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
/** Default stablecoin token configs. */
|
|
33
|
+
export const DEFAULT_TOKENS = {
|
|
34
|
+
"USDC:base": {
|
|
35
|
+
token: "USDC",
|
|
36
|
+
chain: "base",
|
|
37
|
+
contractAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
38
|
+
decimals: 6,
|
|
39
|
+
},
|
|
40
|
+
"USDT:base": {
|
|
41
|
+
token: "USDT",
|
|
42
|
+
chain: "base",
|
|
43
|
+
contractAddress: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
|
|
44
|
+
decimals: 6,
|
|
45
|
+
},
|
|
46
|
+
"DAI:base": {
|
|
47
|
+
token: "DAI",
|
|
48
|
+
chain: "base",
|
|
49
|
+
contractAddress: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
50
|
+
decimals: 18,
|
|
51
|
+
},
|
|
52
|
+
"USDC:ethereum": {
|
|
53
|
+
token: "USDC",
|
|
54
|
+
chain: "ethereum",
|
|
55
|
+
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
56
|
+
decimals: 6,
|
|
57
|
+
},
|
|
58
|
+
"USDT:ethereum": {
|
|
59
|
+
token: "USDT",
|
|
60
|
+
chain: "ethereum",
|
|
61
|
+
contractAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
62
|
+
decimals: 6,
|
|
63
|
+
},
|
|
64
|
+
"DAI:ethereum": {
|
|
65
|
+
token: "DAI",
|
|
66
|
+
chain: "ethereum",
|
|
67
|
+
contractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
68
|
+
decimals: 18,
|
|
69
|
+
},
|
|
70
|
+
"USDC:arbitrum": {
|
|
71
|
+
token: "USDC",
|
|
72
|
+
chain: "arbitrum",
|
|
73
|
+
contractAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
74
|
+
decimals: 6,
|
|
75
|
+
},
|
|
76
|
+
"USDT:arbitrum": {
|
|
77
|
+
token: "USDT",
|
|
78
|
+
chain: "arbitrum",
|
|
79
|
+
contractAddress: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
80
|
+
decimals: 6,
|
|
81
|
+
},
|
|
82
|
+
"DAI:arbitrum": {
|
|
83
|
+
token: "DAI",
|
|
84
|
+
chain: "arbitrum",
|
|
85
|
+
contractAddress: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
|
|
86
|
+
decimals: 18,
|
|
87
|
+
},
|
|
88
|
+
"USDC:polygon": {
|
|
89
|
+
token: "USDC",
|
|
90
|
+
chain: "polygon",
|
|
91
|
+
contractAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
92
|
+
decimals: 6,
|
|
93
|
+
},
|
|
94
|
+
"USDT:polygon": {
|
|
95
|
+
token: "USDT",
|
|
96
|
+
chain: "polygon",
|
|
97
|
+
contractAddress: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
98
|
+
decimals: 6,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=types.js.map
|