mainnet-js 3.1.7 → 4.0.0-next.2

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 (83) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/{mainnet-3.1.7.js → mainnet-4.0.0-next.2.js} +66 -166
  3. package/dist/module/cache/walletCache.d.ts +16 -6
  4. package/dist/module/cache/walletCache.d.ts.map +1 -1
  5. package/dist/module/cache/walletCache.js +92 -34
  6. package/dist/module/cache/walletCache.js.map +1 -1
  7. package/dist/module/mine/mine.d.ts.map +1 -1
  8. package/dist/module/mine/mine.js +14 -19
  9. package/dist/module/mine/mine.js.map +1 -1
  10. package/dist/module/network/Connection.d.ts +1 -12
  11. package/dist/module/network/Connection.d.ts.map +1 -1
  12. package/dist/module/network/Connection.js +12 -33
  13. package/dist/module/network/Connection.js.map +1 -1
  14. package/dist/module/network/ElectrumNetworkProvider.d.ts +4 -7
  15. package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
  16. package/dist/module/network/ElectrumNetworkProvider.js +43 -70
  17. package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
  18. package/dist/module/network/configuration.d.ts +2 -4
  19. package/dist/module/network/configuration.d.ts.map +1 -1
  20. package/dist/module/network/configuration.js +25 -50
  21. package/dist/module/network/configuration.js.map +1 -1
  22. package/dist/module/network/constant.d.ts +7 -7
  23. package/dist/module/network/constant.d.ts.map +1 -1
  24. package/dist/module/network/constant.js +20 -24
  25. package/dist/module/network/constant.js.map +1 -1
  26. package/dist/module/network/default.d.ts +3 -2
  27. package/dist/module/network/default.d.ts.map +1 -1
  28. package/dist/module/network/default.js +19 -51
  29. package/dist/module/network/default.js.map +1 -1
  30. package/dist/module/network/index.d.ts +2 -2
  31. package/dist/module/network/index.d.ts.map +1 -1
  32. package/dist/module/network/index.js +2 -2
  33. package/dist/module/network/index.js.map +1 -1
  34. package/dist/module/network/interface.d.ts +0 -6
  35. package/dist/module/network/interface.d.ts.map +1 -1
  36. package/dist/module/wallet/Base.d.ts.map +1 -1
  37. package/dist/module/wallet/Base.js +33 -12
  38. package/dist/module/wallet/Base.js.map +1 -1
  39. package/dist/module/wallet/HDWallet.d.ts.map +1 -1
  40. package/dist/module/wallet/HDWallet.js +16 -35
  41. package/dist/module/wallet/HDWallet.js.map +1 -1
  42. package/dist/module/wallet/Watch.d.ts +22 -1
  43. package/dist/module/wallet/Watch.d.ts.map +1 -1
  44. package/dist/module/wallet/Watch.js +137 -6
  45. package/dist/module/wallet/Watch.js.map +1 -1
  46. package/dist/module/wallet/Wif.d.ts +1 -1
  47. package/dist/module/wallet/Wif.d.ts.map +1 -1
  48. package/dist/module/wallet/Wif.js +0 -4
  49. package/dist/module/wallet/Wif.js.map +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +5 -3
  52. package/src/cache/walletCache.ts +122 -57
  53. package/src/mine/mine.ts +18 -22
  54. package/src/network/Connection.test.ts +8 -7
  55. package/src/network/Connection.ts +16 -42
  56. package/src/network/ElectrumNetworkProvider.ts +54 -88
  57. package/src/network/Rpc.test.ts +6 -5
  58. package/src/network/configuration.test.ts +23 -25
  59. package/src/network/configuration.ts +29 -55
  60. package/src/network/constant.ts +20 -25
  61. package/src/network/default.ts +25 -87
  62. package/src/network/electrum.test.ts +47 -11
  63. package/src/network/index.ts +7 -2
  64. package/src/network/interface.ts +0 -7
  65. package/src/network/subscription.test.ts +268 -0
  66. package/src/wallet/Base.ts +39 -17
  67. package/src/wallet/Cashtokens.test.headless.js +6 -0
  68. package/src/wallet/Cashtokens.test.ts +13 -0
  69. package/src/wallet/HDWallet.test.ts +4 -4
  70. package/src/wallet/HDWallet.ts +19 -35
  71. package/src/wallet/WalletCache.test.ts +6 -2
  72. package/src/wallet/Watch.ts +199 -7
  73. package/src/wallet/Wif.test.ts +6 -0
  74. package/src/wallet/Wif.ts +2 -9
  75. package/tsconfig.browser.json +10 -1
  76. package/tsconfig.json +12 -1
  77. package/webpack.config.cjs +1 -0
  78. package/dist/module/network/util.d.ts +0 -3
  79. package/dist/module/network/util.d.ts.map +0 -1
  80. package/dist/module/network/util.js +0 -27
  81. package/dist/module/network/util.js.map +0 -1
  82. package/src/network/util.test.ts +0 -24
  83. package/src/network/util.ts +0 -30
@@ -6,6 +6,8 @@ import {
6
6
  encodeCashAddress,
7
7
  assertSuccess,
8
8
  hash160,
9
+ sha256,
10
+ utf8ToBin,
9
11
  decodeCashAddressFormatWithoutPrefix,
10
12
  } from "@bitauth/libauth";
11
13
  import {
@@ -19,12 +21,17 @@ import { WalletTypeEnum } from "./enum.js";
19
21
  import { DUST_UTXO_THRESHOLD } from "../constant.js";
20
22
  import { TxI, Utxo } from "../interface.js";
21
23
  import { derivePrefix } from "../util/derivePublicKeyHash.js";
22
- import { SignedMessage } from "../message/signed.js";
23
24
  import { VerifyMessageResponseI } from "../message/interface.js";
24
25
  import { TransactionHistoryItem } from "../history/interface.js";
25
26
  import { getHistory } from "../history/getHistory.js";
26
- import { WalletInfoI } from "./interface.js";
27
+ import { CancelFn, WalletInfoI } from "./interface.js";
27
28
  import { toCashaddr, toTokenaddr } from "../util/deriveCashaddr.js";
29
+ import { sumUtxoValue } from "../util/sumUtxoValue.js";
30
+ import {
31
+ SingleAddressWalletCache,
32
+ WalletCacheEntry,
33
+ WalletCacheI,
34
+ } from "../cache/walletCache.js";
28
35
 
29
36
  export interface WatchWalletOptions {
30
37
  name?: string;
@@ -38,6 +45,7 @@ export interface WatchWalletOptions {
38
45
  * Class to manage a mainnet watch wallet.
39
46
  */
40
47
  export class WatchWallet extends BaseWallet {
48
+ declare readonly walletCache: WalletCacheI;
41
49
  readonly publicKeyCompressed?: Uint8Array;
42
50
  readonly publicKey?: Uint8Array;
43
51
  readonly publicKeyHash!: Uint8Array;
@@ -47,6 +55,20 @@ export class WatchWallet extends BaseWallet {
47
55
  static networkPrefix = CashAddressNetworkPrefix.mainnet;
48
56
  static walletType = WalletTypeEnum.Watch;
49
57
 
58
+ // Subscription-first infrastructure: single subscription shared by all watchers
59
+ private watchCallbacks: Array<
60
+ (status: string | null, address: string) => void
61
+ > = [];
62
+ private baseCancelFn?: CancelFn;
63
+ watchPromise?: Promise<void>;
64
+ updatePromise?: Promise<void>;
65
+
66
+ // Live state — updated by subscription notifications
67
+ private status: string | null = null;
68
+ private utxos: Utxo[] = [];
69
+ private rawHistory: TxI[] = [];
70
+ private lastConfirmedHeight: number = 0;
71
+
50
72
  constructor(
51
73
  name = "",
52
74
  network = NetworkType.Mainnet,
@@ -141,9 +163,159 @@ export class WatchWallet extends BaseWallet {
141
163
 
142
164
  this.name = name;
143
165
 
166
+ // Initialize persistent cache and load saved state
167
+ await this.initWalletCache();
168
+ const cached = this.getCacheEntry();
169
+ this.status = cached.status;
170
+ this.utxos = cached.utxos;
171
+ this.rawHistory = cached.rawHistory;
172
+ this.lastConfirmedHeight = cached.lastConfirmedHeight;
173
+
174
+ // Start subscription immediately (subscription-first approach)
175
+ this.watchPromise = this.makeWatchPromise().catch(() => {});
176
+
144
177
  return this;
145
178
  }
146
179
 
180
+ protected deriveWalletId(): string {
181
+ return binToHex(sha256.hash(utf8ToBin(`${this.cashaddr}-${this.network}`)));
182
+ }
183
+
184
+ protected async initWalletCache(): Promise<void> {
185
+ const cache = new SingleAddressWalletCache(
186
+ this.deriveWalletId(),
187
+ this.cashaddr,
188
+ this.tokenaddr
189
+ );
190
+ await cache.init();
191
+ const wallet = this as any;
192
+ if (wallet.privateKey) {
193
+ cache.get(this.cashaddr)!.privateKey = wallet.privateKey;
194
+ }
195
+ // @ts-ignore
196
+ this.walletCache = cache;
197
+ }
198
+
199
+ protected getCacheEntry(): WalletCacheEntry {
200
+ return this.walletCache.get(this.cashaddr)!;
201
+ }
202
+
203
+ /// Subscribe to the single address for status change notifications
204
+ private async makeWatchPromise(): Promise<void> {
205
+ const addr = this.cashaddr;
206
+ let resolved = false;
207
+
208
+ return new Promise<void>(async (resolve) => {
209
+ this.baseCancelFn = await this.provider.subscribeToAddress(
210
+ addr,
211
+ async (args: [address: string, status: string | null]) => {
212
+ const [address, status] = args;
213
+ if (address !== addr) return;
214
+
215
+ if (status !== null && status !== this.status) {
216
+ this.updatePromise = this.fetchData(status);
217
+ }
218
+ this.status = status;
219
+ this.notifyWatchCallbacks(status, addr);
220
+
221
+ if (!resolved) {
222
+ resolved = true;
223
+ resolve();
224
+ }
225
+ }
226
+ );
227
+ });
228
+ }
229
+
230
+ private async fetchData(status: string | null): Promise<void> {
231
+ const addr = this.cashaddr;
232
+ const fromHeight = this.lastConfirmedHeight;
233
+
234
+ const [utxos, newHistory] = await Promise.all([
235
+ this.provider.getUtxos(addr),
236
+ this.provider.getHistory(addr, fromHeight),
237
+ ]);
238
+
239
+ // Merge: keep confirmed items below fromHeight, add new items
240
+ const confirmedFromHistory = this.rawHistory.filter(
241
+ (tx) => tx.height > 0 && tx.height < fromHeight
242
+ );
243
+ const seen = new Set(confirmedFromHistory.map((tx) => tx.tx_hash));
244
+ const merged = [...confirmedFromHistory];
245
+ for (const tx of newHistory) {
246
+ if (!seen.has(tx.tx_hash)) {
247
+ seen.add(tx.tx_hash);
248
+ merged.push(tx);
249
+ }
250
+ }
251
+
252
+ this.lastConfirmedHeight = merged.reduce(
253
+ (max, tx) => (tx.height > 0 ? Math.max(max, tx.height) : max),
254
+ fromHeight
255
+ );
256
+
257
+ // Update live state
258
+ this.utxos = utxos;
259
+ this.rawHistory = merged;
260
+
261
+ // Persist to cache
262
+ this.walletCache.setStatusAndUtxos(
263
+ addr,
264
+ status,
265
+ utxos,
266
+ merged,
267
+ this.lastConfirmedHeight
268
+ );
269
+ }
270
+
271
+ private notifyWatchCallbacks(status: string | null, address: string) {
272
+ for (const callback of this.watchCallbacks) {
273
+ try {
274
+ callback(status, address);
275
+ } catch (_e) {
276
+ // Ignore callback errors to not break other watchers
277
+ }
278
+ }
279
+ }
280
+
281
+ public override async watchStatus(
282
+ callback: (status: string | null, address: string) => void
283
+ ): Promise<CancelFn> {
284
+ await this.watchPromise;
285
+
286
+ this.watchCallbacks.push(callback);
287
+
288
+ return async () => {
289
+ const index = this.watchCallbacks.indexOf(callback);
290
+ if (index > -1) {
291
+ this.watchCallbacks.splice(index, 1);
292
+ }
293
+ };
294
+ }
295
+
296
+ public override async waitForUpdate(
297
+ options: { timeout?: number } = {}
298
+ ): Promise<void> {
299
+ const timeout = options.timeout ?? 100;
300
+
301
+ let cancel: CancelFn;
302
+ const statusChange = new Promise<void>(async (resolve) => {
303
+ cancel = await this.watchStatus(() => resolve());
304
+ });
305
+
306
+ const timer = new Promise<void>((resolve) => setTimeout(resolve, timeout));
307
+
308
+ await Promise.race([statusChange, timer]);
309
+ await cancel!();
310
+ }
311
+
312
+ public override async stop() {
313
+ await super.stop();
314
+ await this.baseCancelFn?.();
315
+ this.baseCancelFn = undefined;
316
+ this.watchCallbacks = [];
317
+ }
318
+
147
319
  /**
148
320
  * getDepositAddress - get a wallet deposit address
149
321
  *
@@ -227,16 +399,20 @@ export class WatchWallet extends BaseWallet {
227
399
  *
228
400
  */
229
401
  public async getUtxos(): Promise<Utxo[]> {
230
- const bchUtxos: Utxo[] = await this.provider.getUtxos(this.cashaddr);
402
+ await this.watchPromise;
403
+ await this.updatePromise;
404
+
231
405
  return this._slpSemiAware
232
- ? bchUtxos.filter((u) => u.satoshis > DUST_UTXO_THRESHOLD)
233
- : bchUtxos;
406
+ ? this.utxos.filter((u) => u.satoshis > DUST_UTXO_THRESHOLD)
407
+ : this.utxos;
234
408
  }
235
409
 
236
410
  // Gets balance by summing value in all utxos in sats
237
411
  // Balance includes DUST utxos which could be slp tokens and also cashtokens with BCH amounts
238
412
  public async getBalance(): Promise<bigint> {
239
- return this.provider.getBalance(this.cashaddr);
413
+ await this.watchPromise;
414
+ await this.updatePromise;
415
+ return sumUtxoValue(this.utxos);
240
416
  }
241
417
 
242
418
  // gets transaction history of this wallet
@@ -244,7 +420,23 @@ export class WatchWallet extends BaseWallet {
244
420
  fromHeight: number = 0,
245
421
  toHeight: number = -1
246
422
  ): Promise<TxI[]> {
247
- return await this.provider.getHistory(this.cashaddr, fromHeight, toHeight);
423
+ await this.watchPromise;
424
+ await this.updatePromise;
425
+
426
+ let history = this.rawHistory;
427
+
428
+ if (fromHeight > 0 || toHeight !== -1) {
429
+ history = history.filter((tx) => {
430
+ if (tx.height <= 0) {
431
+ return toHeight === -1;
432
+ }
433
+ const aboveFrom = tx.height >= fromHeight;
434
+ const belowTo = toHeight === -1 || tx.height <= toHeight;
435
+ return aboveFrom && belowTo;
436
+ });
437
+ }
438
+
439
+ return history;
248
440
  }
249
441
 
250
442
  /**
@@ -891,6 +891,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
891
891
  cashaddr: charlieWallet.cashaddr!,
892
892
  value: DUST,
893
893
  });
894
+ await charlieWallet.waitForUpdate();
894
895
  expect(await charlieWallet.getBalance()).toBe(DUST);
895
896
  });
896
897
 
@@ -911,6 +912,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
911
912
  cashaddr: charlieWallet.cashaddr!,
912
913
  value: DUST,
913
914
  });
915
+ await charlieWallet.waitForUpdate();
914
916
  expect(await charlieWallet.getBalance()).toBe(DUST);
915
917
  });
916
918
 
@@ -928,6 +930,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
928
930
  ]);
929
931
 
930
932
  await bobWallet.send([{ cashaddr: charlieWallet.cashaddr!, value: DUST }]);
933
+ await charlieWallet.waitForUpdate();
931
934
  expect(await charlieWallet.getBalance()).toBe(DUST);
932
935
  });
933
936
 
@@ -945,6 +948,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
945
948
  ]);
946
949
 
947
950
  await bobWallet.send([{ cashaddr: charlieWallet.cashaddr!, value: DUST }]);
951
+ await charlieWallet.waitForUpdate();
948
952
  expect(await charlieWallet.getBalance()).toBe(DUST);
949
953
  });
950
954
 
@@ -960,6 +964,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
960
964
  ]);
961
965
 
962
966
  await bobWallet.send([{ cashaddr: charlieWallet.cashaddr!, value: DUST }]);
967
+ await charlieWallet.waitForUpdate();
963
968
  expect(await charlieWallet.getBalance()).toBe(DUST);
964
969
  });
965
970
  test(`Should throw error with dust amounts (${
@@ -1033,6 +1038,7 @@ describe(`Wallet extrema behavior regression testing`, () => {
1033
1038
  { cashaddr: bob.getDepositAddress(), value: 546n },
1034
1039
  { cashaddr: bob.getDepositAddress(), value: 1000n },
1035
1040
  ]);
1041
+ await bob.waitForUpdate();
1036
1042
  expect(sumUtxoValue(await bob.getUtxos())).toBe(1546n);
1037
1043
  bob.slpSemiAware();
1038
1044
  expect(sumUtxoValue(await bob.getUtxos())).toBe(1000n);
package/src/wallet/Wif.ts CHANGED
@@ -65,7 +65,7 @@ export interface WalletOptions {
65
65
  * Class to manage a bitcoin cash wallet.
66
66
  */
67
67
  export class Wallet extends WatchWallet {
68
- declare readonly provider: ElectrumNetworkProvider;
68
+ declare provider: ElectrumNetworkProvider;
69
69
 
70
70
  readonly derivationPath: string = Config.DefaultParentDerivationPath + "/0/0";
71
71
  readonly parentDerivationPath: string = Config.DefaultParentDerivationPath;
@@ -223,16 +223,9 @@ export class Wallet extends WatchWallet {
223
223
  address,
224
224
  });
225
225
 
226
- if (this.privateKey) {
227
- // @ts-ignore
228
- this.walletCache = new Map<string, { privateKey: Uint8Array }>().set(
229
- this.cashaddr,
230
- { privateKey: this.privateKey }
231
- );
232
- }
233
-
234
226
  return this;
235
227
  }
228
+
236
229
  //#endregion Constructors and Statics
237
230
 
238
231
  //#region Accessors
@@ -3,7 +3,16 @@
3
3
  "compilerOptions": {
4
4
  "baseUrl": "src",
5
5
  "paths": {
6
- "pg": ["false*"]
6
+ "pg": ["false*"],
7
+ "@rpckit/core/electrum-cash": [
8
+ "../../../node_modules/@rpckit/core/dist/electrum-cash/index.d.ts"
9
+ ],
10
+ "@rpckit/websocket/electrum-cash": [
11
+ "../../../node_modules/@rpckit/websocket/dist/electrum-cash/index.d.ts"
12
+ ],
13
+ "@rpckit/fallback/electrum-cash": [
14
+ "../../../node_modules/@rpckit/fallback/dist/electrum-cash/index.d.ts"
15
+ ]
7
16
  }
8
17
  },
9
18
  "include": ["src/**/*.ts"],
package/tsconfig.json CHANGED
@@ -25,7 +25,18 @@
25
25
  "sourceMap": true,
26
26
  "noEmit": false,
27
27
  "strictPropertyInitialization": false,
28
- "useDefineForClassFields": false
28
+ "useDefineForClassFields": false,
29
+ "paths": {
30
+ "@rpckit/core/electrum-cash": [
31
+ "../../node_modules/@rpckit/core/dist/electrum-cash/index.d.ts"
32
+ ],
33
+ "@rpckit/websocket/electrum-cash": [
34
+ "../../node_modules/@rpckit/websocket/dist/electrum-cash/index.d.ts"
35
+ ],
36
+ "@rpckit/fallback/electrum-cash": [
37
+ "../../node_modules/@rpckit/fallback/dist/electrum-cash/index.d.ts"
38
+ ]
39
+ }
29
40
  },
30
41
  "include": ["src/**/*.ts"],
31
42
  "exclude": ["node_modules/**", "src/**/*test.ts"],
@@ -15,6 +15,7 @@ const baseConfig = {
15
15
  extensionAlias: {
16
16
  ".js": [".ts", ".js"],
17
17
  },
18
+ symlinks: true,
18
19
  },
19
20
  optimization: {
20
21
  minimize: false,
@@ -1,3 +0,0 @@
1
- import { ElectrumHostParams } from "./interface.js";
2
- export declare function parseElectrumUrl(givenUrl: string): ElectrumHostParams;
3
- //# sourceMappingURL=util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/network/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAMrE"}
@@ -1,27 +0,0 @@
1
- export function parseElectrumUrl(givenUrl) {
2
- let url = new URL(givenUrl);
3
- let port = parseInt(url.port || "443");
4
- let scheme = getElectrumScheme(url.protocol);
5
- return { host: url.hostname, port: port, scheme: scheme };
6
- }
7
- function getElectrumScheme(protocol) {
8
- let transport;
9
- switch (protocol) {
10
- case "http:":
11
- transport = "tcp";
12
- break;
13
- case "https:":
14
- transport = "tcp_tls";
15
- break;
16
- case "ws:":
17
- transport = "ws";
18
- break;
19
- case "wss:":
20
- transport = "wss";
21
- break;
22
- default:
23
- throw Error("Electrum transport protocol not understood.");
24
- }
25
- return transport;
26
- }
27
- //# sourceMappingURL=util.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/network/util.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;IACvC,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE7C,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5D,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,IAAI,SAAiB,CAAC;IACtB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM;QACR,KAAK,QAAQ;YACX,SAAS,GAAG,SAAS,CAAC;YACtB,MAAM;QACR,KAAK,KAAK;YACR,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM;QACR,KAAK,MAAM;YACT,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM;QACR;YACE,MAAM,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,SAA6C,CAAC;AACvD,CAAC"}
@@ -1,24 +0,0 @@
1
- import { parseElectrumUrl } from "./util";
2
-
3
- test("Should parse various electrum urls", async () => {
4
- expect(parseElectrumUrl("https://localhost:1")).toEqual({
5
- host: "localhost",
6
- port: 1,
7
- scheme: "tcp_tls",
8
- });
9
- expect(parseElectrumUrl("http://127.0.0.1:1")).toEqual({
10
- host: "127.0.0.1",
11
- port: 1,
12
- scheme: "tcp",
13
- });
14
- expect(parseElectrumUrl("ws://1.2.3.4:10001")).toEqual({
15
- host: "1.2.3.4",
16
- port: 10001,
17
- scheme: "ws",
18
- });
19
- expect(parseElectrumUrl("wss://example.space:1")).toEqual({
20
- host: "example.space",
21
- port: 1,
22
- scheme: "wss",
23
- });
24
- });
@@ -1,30 +0,0 @@
1
- import { ElectrumHostParams } from "./interface.js";
2
-
3
- export function parseElectrumUrl(givenUrl: string): ElectrumHostParams {
4
- let url = new URL(givenUrl);
5
- let port = parseInt(url.port || "443");
6
- let scheme = getElectrumScheme(url.protocol);
7
-
8
- return { host: url.hostname, port: port, scheme: scheme };
9
- }
10
-
11
- function getElectrumScheme(protocol: string) {
12
- let transport: string;
13
- switch (protocol) {
14
- case "http:":
15
- transport = "tcp";
16
- break;
17
- case "https:":
18
- transport = "tcp_tls";
19
- break;
20
- case "ws:":
21
- transport = "ws";
22
- break;
23
- case "wss:":
24
- transport = "wss";
25
- break;
26
- default:
27
- throw Error("Electrum transport protocol not understood.");
28
- }
29
- return transport as "tcp" | "tcp_tls" | "ws" | "wss";
30
- }