@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,320 @@
|
|
|
1
|
+
import type { EncodingParams, IAddressEncoder } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
|
|
3
|
+
// ---------- bech32 encoding (pure implementation, no external deps) ----------
|
|
4
|
+
|
|
5
|
+
const BECH32_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
6
|
+
|
|
7
|
+
const BECH32_GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
|
8
|
+
|
|
9
|
+
function bech32Polymod(values: number[]): number {
|
|
10
|
+
let chk = 1;
|
|
11
|
+
for (const v of values) {
|
|
12
|
+
const top = chk >> 25;
|
|
13
|
+
chk = ((chk & 0x1ffffff) << 5) ^ v;
|
|
14
|
+
for (let i = 0; i < 5; i++) {
|
|
15
|
+
if ((top >> i) & 1) {
|
|
16
|
+
chk ^= BECH32_GENERATOR[i]!;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return chk;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function bech32HrpExpand(hrp: string): number[] {
|
|
24
|
+
const result: number[] = [];
|
|
25
|
+
for (let i = 0; i < hrp.length; i++) {
|
|
26
|
+
result.push(hrp.charCodeAt(i) >> 5);
|
|
27
|
+
}
|
|
28
|
+
result.push(0);
|
|
29
|
+
for (let i = 0; i < hrp.length; i++) {
|
|
30
|
+
result.push(hrp.charCodeAt(i) & 31);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function bech32CreateChecksum(hrp: string, data: number[]): number[] {
|
|
36
|
+
const values = [...bech32HrpExpand(hrp), ...data, 0, 0, 0, 0, 0, 0];
|
|
37
|
+
const polymod = bech32Polymod(values) ^ 1;
|
|
38
|
+
const checksum: number[] = [];
|
|
39
|
+
for (let i = 0; i < 6; i++) {
|
|
40
|
+
checksum.push((polymod >> (5 * (5 - i))) & 31);
|
|
41
|
+
}
|
|
42
|
+
return checksum;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function bech32Encode(hrp: string, data: number[]): string {
|
|
46
|
+
const combined = [...data, ...bech32CreateChecksum(hrp, data)];
|
|
47
|
+
let result = `${hrp}1`;
|
|
48
|
+
for (const d of combined) {
|
|
49
|
+
result += BECH32_CHARSET[d];
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Convert a byte array to 5-bit words (bech32 encoding). */
|
|
55
|
+
function toWords(bytes: Uint8Array): number[] {
|
|
56
|
+
let value = 0;
|
|
57
|
+
let bits = 0;
|
|
58
|
+
const words: number[] = [];
|
|
59
|
+
for (const byte of bytes) {
|
|
60
|
+
value = (value << 8) | byte;
|
|
61
|
+
bits += 8;
|
|
62
|
+
while (bits >= 5) {
|
|
63
|
+
bits -= 5;
|
|
64
|
+
words.push((value >> bits) & 31);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (bits > 0) {
|
|
68
|
+
words.push((value << (5 - bits)) & 31);
|
|
69
|
+
}
|
|
70
|
+
return words;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ---------- hash160 (SHA-256 + RIPEMD-160) pure implementation ----------
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* SHA-256 implementation (pure TypeScript).
|
|
77
|
+
* Used for hash160 in address derivation.
|
|
78
|
+
*/
|
|
79
|
+
function sha256(data: Uint8Array): Uint8Array {
|
|
80
|
+
const K: number[] = [
|
|
81
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
|
|
82
|
+
0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
83
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
|
|
84
|
+
0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
85
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
|
86
|
+
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
87
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
|
|
88
|
+
0xc67178f2,
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
// Pre-processing: padding
|
|
92
|
+
const msgLen = data.length;
|
|
93
|
+
const bitLen = msgLen * 8;
|
|
94
|
+
// Padding: 1 bit, then zeros, then 64-bit length
|
|
95
|
+
const padLen = ((msgLen + 9 + 63) & ~63) - msgLen;
|
|
96
|
+
const padded = new Uint8Array(msgLen + padLen);
|
|
97
|
+
padded.set(data);
|
|
98
|
+
padded[msgLen] = 0x80;
|
|
99
|
+
// Write bit length as big-endian 64-bit at the end
|
|
100
|
+
const view = new DataView(padded.buffer);
|
|
101
|
+
view.setUint32(padded.length - 4, bitLen, false);
|
|
102
|
+
|
|
103
|
+
let h0 = 0x6a09e667;
|
|
104
|
+
let h1 = 0xbb67ae85;
|
|
105
|
+
let h2 = 0x3c6ef372;
|
|
106
|
+
let h3 = 0xa54ff53a;
|
|
107
|
+
let h4 = 0x510e527f;
|
|
108
|
+
let h5 = 0x9b05688c;
|
|
109
|
+
let h6 = 0x1f83d9ab;
|
|
110
|
+
let h7 = 0x5be0cd19;
|
|
111
|
+
|
|
112
|
+
const w = new Int32Array(64);
|
|
113
|
+
|
|
114
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
115
|
+
for (let i = 0; i < 16; i++) {
|
|
116
|
+
w[i] = view.getInt32(offset + i * 4, false);
|
|
117
|
+
}
|
|
118
|
+
for (let i = 16; i < 64; i++) {
|
|
119
|
+
const s0 = (ror32(w[i - 15]!, 7) ^ ror32(w[i - 15]!, 18) ^ (w[i - 15]! >>> 3)) | 0;
|
|
120
|
+
const s1 = (ror32(w[i - 2]!, 17) ^ ror32(w[i - 2]!, 19) ^ (w[i - 2]! >>> 10)) | 0;
|
|
121
|
+
w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) | 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let a = h0;
|
|
125
|
+
let b = h1;
|
|
126
|
+
let c = h2;
|
|
127
|
+
let d = h3;
|
|
128
|
+
let e = h4;
|
|
129
|
+
let f = h5;
|
|
130
|
+
let g = h6;
|
|
131
|
+
let h = h7;
|
|
132
|
+
|
|
133
|
+
for (let i = 0; i < 64; i++) {
|
|
134
|
+
const S1 = (ror32(e, 6) ^ ror32(e, 11) ^ ror32(e, 25)) | 0;
|
|
135
|
+
const ch = ((e & f) ^ (~e & g)) | 0;
|
|
136
|
+
const temp1 = (h + S1 + ch + K[i]! + w[i]!) | 0;
|
|
137
|
+
const S0 = (ror32(a, 2) ^ ror32(a, 13) ^ ror32(a, 22)) | 0;
|
|
138
|
+
const maj = ((a & b) ^ (a & c) ^ (b & c)) | 0;
|
|
139
|
+
const temp2 = (S0 + maj) | 0;
|
|
140
|
+
|
|
141
|
+
h = g;
|
|
142
|
+
g = f;
|
|
143
|
+
f = e;
|
|
144
|
+
e = (d + temp1) | 0;
|
|
145
|
+
d = c;
|
|
146
|
+
c = b;
|
|
147
|
+
b = a;
|
|
148
|
+
a = (temp1 + temp2) | 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
h0 = (h0 + a) | 0;
|
|
152
|
+
h1 = (h1 + b) | 0;
|
|
153
|
+
h2 = (h2 + c) | 0;
|
|
154
|
+
h3 = (h3 + d) | 0;
|
|
155
|
+
h4 = (h4 + e) | 0;
|
|
156
|
+
h5 = (h5 + f) | 0;
|
|
157
|
+
h6 = (h6 + g) | 0;
|
|
158
|
+
h7 = (h7 + h) | 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const result = new Uint8Array(32);
|
|
162
|
+
const rv = new DataView(result.buffer);
|
|
163
|
+
rv.setInt32(0, h0, false);
|
|
164
|
+
rv.setInt32(4, h1, false);
|
|
165
|
+
rv.setInt32(8, h2, false);
|
|
166
|
+
rv.setInt32(12, h3, false);
|
|
167
|
+
rv.setInt32(16, h4, false);
|
|
168
|
+
rv.setInt32(20, h5, false);
|
|
169
|
+
rv.setInt32(24, h6, false);
|
|
170
|
+
rv.setInt32(28, h7, false);
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function ror32(x: number, n: number): number {
|
|
175
|
+
return (x >>> n) | (x << (32 - n));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* RIPEMD-160 implementation (pure TypeScript).
|
|
180
|
+
* Used for hash160 in address derivation.
|
|
181
|
+
*/
|
|
182
|
+
function ripemd160(data: Uint8Array): Uint8Array {
|
|
183
|
+
const msgLen = data.length;
|
|
184
|
+
const bitLen = msgLen * 8;
|
|
185
|
+
const padLen = ((msgLen + 9 + 63) & ~63) - msgLen;
|
|
186
|
+
const padded = new Uint8Array(msgLen + padLen);
|
|
187
|
+
padded.set(data);
|
|
188
|
+
padded[msgLen] = 0x80;
|
|
189
|
+
const view = new DataView(padded.buffer);
|
|
190
|
+
view.setUint32(padded.length - 8, bitLen, true); // little-endian for RIPEMD
|
|
191
|
+
|
|
192
|
+
let h0 = 0x67452301;
|
|
193
|
+
let h1 = 0xefcdab89;
|
|
194
|
+
let h2 = 0x98badcfe;
|
|
195
|
+
let h3 = 0x10325476;
|
|
196
|
+
let h4 = 0xc3d2e1f0;
|
|
197
|
+
|
|
198
|
+
const RL = [
|
|
199
|
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10,
|
|
200
|
+
14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7,
|
|
201
|
+
12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
const RR = [
|
|
205
|
+
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5,
|
|
206
|
+
1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4,
|
|
207
|
+
1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
|
|
208
|
+
];
|
|
209
|
+
|
|
210
|
+
const SL = [
|
|
211
|
+
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11,
|
|
212
|
+
13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15,
|
|
213
|
+
5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
const SR = [
|
|
217
|
+
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9,
|
|
218
|
+
7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5,
|
|
219
|
+
12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
const KL = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e];
|
|
223
|
+
const KR = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000];
|
|
224
|
+
|
|
225
|
+
function f(j: number, x: number, y: number, z: number): number {
|
|
226
|
+
if (j < 16) return x ^ y ^ z;
|
|
227
|
+
if (j < 32) return (x & y) | (~x & z);
|
|
228
|
+
if (j < 48) return (x | ~y) ^ z;
|
|
229
|
+
if (j < 64) return (x & z) | (y & ~z);
|
|
230
|
+
return x ^ (y | ~z);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function rol32(x: number, n: number): number {
|
|
234
|
+
return (x << n) | (x >>> (32 - n));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
238
|
+
const x: number[] = [];
|
|
239
|
+
for (let i = 0; i < 16; i++) {
|
|
240
|
+
x.push(view.getInt32(offset + i * 4, true)); // little-endian
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
let al = h0;
|
|
244
|
+
let bl = h1;
|
|
245
|
+
let cl = h2;
|
|
246
|
+
let dl = h3;
|
|
247
|
+
let el = h4;
|
|
248
|
+
let ar = h0;
|
|
249
|
+
let br = h1;
|
|
250
|
+
let cr = h2;
|
|
251
|
+
let dr = h3;
|
|
252
|
+
let er = h4;
|
|
253
|
+
|
|
254
|
+
for (let j = 0; j < 80; j++) {
|
|
255
|
+
const round = j >> 4;
|
|
256
|
+
let t = (al + f(j, bl, cl, dl) + x[RL[j]!]! + KL[round]!) | 0;
|
|
257
|
+
t = (rol32(t, SL[j]!) + el) | 0;
|
|
258
|
+
al = el;
|
|
259
|
+
el = dl;
|
|
260
|
+
dl = rol32(cl, 10);
|
|
261
|
+
cl = bl;
|
|
262
|
+
bl = t;
|
|
263
|
+
|
|
264
|
+
t = (ar + f(79 - j, br, cr, dr) + x[RR[j]!]! + KR[round]!) | 0;
|
|
265
|
+
t = (rol32(t, SR[j]!) + er) | 0;
|
|
266
|
+
ar = er;
|
|
267
|
+
er = dr;
|
|
268
|
+
dr = rol32(cr, 10);
|
|
269
|
+
cr = br;
|
|
270
|
+
br = t;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const t = (h1 + cl + dr) | 0;
|
|
274
|
+
h1 = (h2 + dl + er) | 0;
|
|
275
|
+
h2 = (h3 + el + ar) | 0;
|
|
276
|
+
h3 = (h4 + al + br) | 0;
|
|
277
|
+
h4 = (h0 + bl + cr) | 0;
|
|
278
|
+
h0 = t;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const result = new Uint8Array(20);
|
|
282
|
+
const rv = new DataView(result.buffer);
|
|
283
|
+
rv.setInt32(0, h0, true);
|
|
284
|
+
rv.setInt32(4, h1, true);
|
|
285
|
+
rv.setInt32(8, h2, true);
|
|
286
|
+
rv.setInt32(12, h3, true);
|
|
287
|
+
rv.setInt32(16, h4, true);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** HASH160 = RIPEMD-160(SHA-256(data)). Standard Bitcoin address hash. */
|
|
292
|
+
export function hash160(data: Uint8Array): Uint8Array {
|
|
293
|
+
return ripemd160(sha256(data));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Encode a compressed public key as a bech32 (SegWit v0) address.
|
|
298
|
+
* Used for BTC (hrp="bc"), LTC (hrp="ltc"), etc.
|
|
299
|
+
*/
|
|
300
|
+
export function encodeBech32Address(publicKey: Uint8Array, hrp: string): string {
|
|
301
|
+
const h = hash160(publicKey);
|
|
302
|
+
const words = toWords(h);
|
|
303
|
+
// witness version 0 prefix
|
|
304
|
+
return bech32Encode(hrp, [0, ...words]);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Bitcoin bech32 address encoder.
|
|
309
|
+
* Implements IAddressEncoder for the bitcoin plugin.
|
|
310
|
+
* Default HRP is "bc" (mainnet). Override with params.hrp for testnet ("tb").
|
|
311
|
+
*/
|
|
312
|
+
export const bech32Encoder: IAddressEncoder = {
|
|
313
|
+
encode(publicKey: Uint8Array, params: EncodingParams): string {
|
|
314
|
+
const hrp = params.hrp ?? "bc";
|
|
315
|
+
return encodeBech32Address(publicKey, hrp);
|
|
316
|
+
},
|
|
317
|
+
encodingType(): string {
|
|
318
|
+
return "bech32";
|
|
319
|
+
},
|
|
320
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IChainPlugin, WatcherOpts } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
|
|
3
|
+
import { createRpcFromOpts } from "../shared/utxo/index.js";
|
|
4
|
+
import { createUtxoWatcher } from "../shared/utxo/watcher.js";
|
|
5
|
+
import { bech32Encoder } from "./encoder.js";
|
|
6
|
+
|
|
7
|
+
export { bech32Encoder, encodeBech32Address, hash160 } from "./encoder.js";
|
|
8
|
+
|
|
9
|
+
export const bitcoinPlugin: IChainPlugin = {
|
|
10
|
+
pluginId: "bitcoin",
|
|
11
|
+
supportedCurve: "secp256k1",
|
|
12
|
+
encoders: {
|
|
13
|
+
bech32: bech32Encoder,
|
|
14
|
+
},
|
|
15
|
+
createWatcher(opts: WatcherOpts) {
|
|
16
|
+
const rpc = createRpcFromOpts(opts.rpcUrl, opts.rpcHeaders);
|
|
17
|
+
return createUtxoWatcher(opts, rpc);
|
|
18
|
+
},
|
|
19
|
+
createSweeper() {
|
|
20
|
+
throw new Error("Not implemented");
|
|
21
|
+
},
|
|
22
|
+
version: 1,
|
|
23
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { EncodingParams, IAddressEncoder } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
|
|
3
|
+
import { hash160 } from "../bitcoin/encoder.js";
|
|
4
|
+
|
|
5
|
+
// ---------- Base58Check encoding ----------
|
|
6
|
+
|
|
7
|
+
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
8
|
+
|
|
9
|
+
function base58encode(data: Uint8Array): string {
|
|
10
|
+
let num = 0n;
|
|
11
|
+
for (const byte of data) num = num * 256n + BigInt(byte);
|
|
12
|
+
let encoded = "";
|
|
13
|
+
while (num > 0n) {
|
|
14
|
+
encoded = BASE58_ALPHABET[Number(num % 58n)] + encoded;
|
|
15
|
+
num = num / 58n;
|
|
16
|
+
}
|
|
17
|
+
for (const byte of data) {
|
|
18
|
+
if (byte !== 0) break;
|
|
19
|
+
encoded = `1${encoded}`;
|
|
20
|
+
}
|
|
21
|
+
return encoded;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* SHA-256 (pure implementation, duplicated from bitcoin encoder to avoid
|
|
26
|
+
* re-exporting the internal function — hash160 is already exported).
|
|
27
|
+
*/
|
|
28
|
+
function sha256(data: Uint8Array): Uint8Array {
|
|
29
|
+
const K: number[] = [
|
|
30
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
|
|
31
|
+
0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
32
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
|
|
33
|
+
0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
34
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
|
35
|
+
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
36
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
|
|
37
|
+
0xc67178f2,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const msgLen = data.length;
|
|
41
|
+
const bitLen = msgLen * 8;
|
|
42
|
+
const padLen = ((msgLen + 9 + 63) & ~63) - msgLen;
|
|
43
|
+
const padded = new Uint8Array(msgLen + padLen);
|
|
44
|
+
padded.set(data);
|
|
45
|
+
padded[msgLen] = 0x80;
|
|
46
|
+
const view = new DataView(padded.buffer);
|
|
47
|
+
view.setUint32(padded.length - 4, bitLen, false);
|
|
48
|
+
|
|
49
|
+
let h0 = 0x6a09e667;
|
|
50
|
+
let h1 = 0xbb67ae85;
|
|
51
|
+
let h2 = 0x3c6ef372;
|
|
52
|
+
let h3 = 0xa54ff53a;
|
|
53
|
+
let h4 = 0x510e527f;
|
|
54
|
+
let h5 = 0x9b05688c;
|
|
55
|
+
let h6 = 0x1f83d9ab;
|
|
56
|
+
let h7 = 0x5be0cd19;
|
|
57
|
+
|
|
58
|
+
const w = new Int32Array(64);
|
|
59
|
+
|
|
60
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
61
|
+
for (let i = 0; i < 16; i++) {
|
|
62
|
+
w[i] = view.getInt32(offset + i * 4, false);
|
|
63
|
+
}
|
|
64
|
+
for (let i = 16; i < 64; i++) {
|
|
65
|
+
const s0 = (ror32(w[i - 15]!, 7) ^ ror32(w[i - 15]!, 18) ^ (w[i - 15]! >>> 3)) | 0;
|
|
66
|
+
const s1 = (ror32(w[i - 2]!, 17) ^ ror32(w[i - 2]!, 19) ^ (w[i - 2]! >>> 10)) | 0;
|
|
67
|
+
w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) | 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let a = h0;
|
|
71
|
+
let b = h1;
|
|
72
|
+
let c = h2;
|
|
73
|
+
let d = h3;
|
|
74
|
+
let e = h4;
|
|
75
|
+
let f = h5;
|
|
76
|
+
let g = h6;
|
|
77
|
+
let h = h7;
|
|
78
|
+
|
|
79
|
+
for (let i = 0; i < 64; i++) {
|
|
80
|
+
const S1 = (ror32(e, 6) ^ ror32(e, 11) ^ ror32(e, 25)) | 0;
|
|
81
|
+
const ch = ((e & f) ^ (~e & g)) | 0;
|
|
82
|
+
const temp1 = (h + S1 + ch + K[i]! + w[i]!) | 0;
|
|
83
|
+
const S0 = (ror32(a, 2) ^ ror32(a, 13) ^ ror32(a, 22)) | 0;
|
|
84
|
+
const maj = ((a & b) ^ (a & c) ^ (b & c)) | 0;
|
|
85
|
+
const temp2 = (S0 + maj) | 0;
|
|
86
|
+
|
|
87
|
+
h = g;
|
|
88
|
+
g = f;
|
|
89
|
+
f = e;
|
|
90
|
+
e = (d + temp1) | 0;
|
|
91
|
+
d = c;
|
|
92
|
+
c = b;
|
|
93
|
+
b = a;
|
|
94
|
+
a = (temp1 + temp2) | 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
h0 = (h0 + a) | 0;
|
|
98
|
+
h1 = (h1 + b) | 0;
|
|
99
|
+
h2 = (h2 + c) | 0;
|
|
100
|
+
h3 = (h3 + d) | 0;
|
|
101
|
+
h4 = (h4 + e) | 0;
|
|
102
|
+
h5 = (h5 + f) | 0;
|
|
103
|
+
h6 = (h6 + g) | 0;
|
|
104
|
+
h7 = (h7 + h) | 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const result = new Uint8Array(32);
|
|
108
|
+
const rv = new DataView(result.buffer);
|
|
109
|
+
rv.setInt32(0, h0, false);
|
|
110
|
+
rv.setInt32(4, h1, false);
|
|
111
|
+
rv.setInt32(8, h2, false);
|
|
112
|
+
rv.setInt32(12, h3, false);
|
|
113
|
+
rv.setInt32(16, h4, false);
|
|
114
|
+
rv.setInt32(20, h5, false);
|
|
115
|
+
rv.setInt32(24, h6, false);
|
|
116
|
+
rv.setInt32(28, h7, false);
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function ror32(x: number, n: number): number {
|
|
121
|
+
return (x >>> n) | (x << (32 - n));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ---------- P2PKH encoding ----------
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Encode a compressed public key as a P2PKH (Base58Check) address.
|
|
128
|
+
* Used for DOGE (version 0x1e), etc.
|
|
129
|
+
*
|
|
130
|
+
* Steps:
|
|
131
|
+
* 1. HASH160(pubkey) = RIPEMD-160(SHA-256(pubkey))
|
|
132
|
+
* 2. Prepend version byte
|
|
133
|
+
* 3. Append double-SHA-256 checksum (first 4 bytes)
|
|
134
|
+
* 4. Base58 encode
|
|
135
|
+
*/
|
|
136
|
+
export function encodeP2pkhAddress(publicKey: Uint8Array, versionByte: number): string {
|
|
137
|
+
const h = hash160(publicKey);
|
|
138
|
+
const payload = new Uint8Array(21);
|
|
139
|
+
payload[0] = versionByte;
|
|
140
|
+
payload.set(h, 1);
|
|
141
|
+
const checksum = sha256(sha256(payload));
|
|
142
|
+
const full = new Uint8Array(25);
|
|
143
|
+
full.set(payload);
|
|
144
|
+
full.set(checksum.slice(0, 4), 21);
|
|
145
|
+
return base58encode(full);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Dogecoin P2PKH address encoder.
|
|
150
|
+
* Implements IAddressEncoder for the dogecoin plugin.
|
|
151
|
+
* Default version byte is 0x1e (30) for mainnet. Override with params.version.
|
|
152
|
+
*/
|
|
153
|
+
export const p2pkhEncoder: IAddressEncoder = {
|
|
154
|
+
encode(publicKey: Uint8Array, params: EncodingParams): string {
|
|
155
|
+
const versionByte = params.version ? Number(params.version) : 0x1e;
|
|
156
|
+
return encodeP2pkhAddress(publicKey, versionByte);
|
|
157
|
+
},
|
|
158
|
+
encodingType(): string {
|
|
159
|
+
return "p2pkh";
|
|
160
|
+
},
|
|
161
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IChainPlugin, WatcherOpts } from "@wopr-network/platform-core/crypto-plugin";
|
|
2
|
+
|
|
3
|
+
import { createRpcFromOpts } from "../shared/utxo/index.js";
|
|
4
|
+
import { createUtxoWatcher } from "../shared/utxo/watcher.js";
|
|
5
|
+
import { p2pkhEncoder } from "./encoder.js";
|
|
6
|
+
|
|
7
|
+
export { encodeP2pkhAddress, p2pkhEncoder } from "./encoder.js";
|
|
8
|
+
|
|
9
|
+
export const dogecoinPlugin: IChainPlugin = {
|
|
10
|
+
pluginId: "dogecoin",
|
|
11
|
+
supportedCurve: "secp256k1",
|
|
12
|
+
encoders: {
|
|
13
|
+
p2pkh: p2pkhEncoder,
|
|
14
|
+
},
|
|
15
|
+
createWatcher(opts: WatcherOpts) {
|
|
16
|
+
const rpc = createRpcFromOpts(opts.rpcUrl, opts.rpcHeaders);
|
|
17
|
+
return createUtxoWatcher(opts, rpc);
|
|
18
|
+
},
|
|
19
|
+
createSweeper() {
|
|
20
|
+
throw new Error("Not implemented");
|
|
21
|
+
},
|
|
22
|
+
version: 1,
|
|
23
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
2
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
3
|
+
import type { EncodingParams, IAddressEncoder } from "@wopr-network/platform-core/crypto-plugin";
|
|
4
|
+
|
|
5
|
+
// secp256k1.Point exists at runtime but the ECDSA TS type doesn't expose it.
|
|
6
|
+
// Access via the schnorr sub-object which does have the Point type.
|
|
7
|
+
const Point = (secp256k1 as unknown as { Point: { fromHex(h: string): { toBytes(c: boolean): Uint8Array } } }).Point;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Derive an EVM (0x...) address from a compressed SEC1 public key.
|
|
11
|
+
*
|
|
12
|
+
* Steps:
|
|
13
|
+
* 1. Decompress the 33-byte compressed pubkey to 65-byte uncompressed
|
|
14
|
+
* 2. Take keccak256 of the uncompressed key (without the 0x04 prefix byte)
|
|
15
|
+
* 3. Take the last 20 bytes as the address
|
|
16
|
+
* 4. Apply EIP-55 mixed-case checksum
|
|
17
|
+
*/
|
|
18
|
+
function toHex(bytes: Uint8Array): string {
|
|
19
|
+
return Array.from(bytes as unknown as number[], (b: number) => b.toString(16).padStart(2, "0")).join("");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function encodeEvm(pubkey: Uint8Array): string {
|
|
23
|
+
const hexKey = toHex(pubkey);
|
|
24
|
+
const uncompressed = Point.fromHex(hexKey).toBytes(false);
|
|
25
|
+
// keccak256 of uncompressed key without the 04 prefix
|
|
26
|
+
const hash = keccak_256(uncompressed.slice(1));
|
|
27
|
+
const addressBytes = hash.slice(-20);
|
|
28
|
+
const rawHex = toHex(addressBytes);
|
|
29
|
+
|
|
30
|
+
// EIP-55 checksum
|
|
31
|
+
const hashHex = toHex(keccak_256(new TextEncoder().encode(rawHex)));
|
|
32
|
+
let checksummed = "0x";
|
|
33
|
+
for (let i = 0; i < rawHex.length; i++) {
|
|
34
|
+
const c = rawHex[i];
|
|
35
|
+
checksummed += Number.parseInt(hashHex[i], 16) >= 8 ? c.toUpperCase() : c;
|
|
36
|
+
}
|
|
37
|
+
return checksummed;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** EVM address encoder implementing IAddressEncoder. */
|
|
41
|
+
export class EvmAddressEncoder implements IAddressEncoder {
|
|
42
|
+
encode(publicKey: Uint8Array, _params: EncodingParams): string {
|
|
43
|
+
return encodeEvm(publicKey);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
encodingType(): string {
|
|
47
|
+
return "evm";
|
|
48
|
+
}
|
|
49
|
+
}
|