diff --git a/packages/cashscript/package.json b/packages/cashscript/package.json index b5fde331..f6372471 100644 --- a/packages/cashscript/package.json +++ b/packages/cashscript/package.json @@ -45,10 +45,10 @@ "dependencies": { "@bitauth/libauth": "^3.1.0-next.2", "@cashscript/utils": "^0.11.0-next.1", + "@electrum-cash/network": "^4.1.1", "@mr-zwets/bchn-api-wrapper": "^1.0.1", "change-case": "^5.4.4", "delay": "^6.0.0", - "electrum-cash": "^2.0.10", "fast-deep-equal": "^3.1.3", "pako": "^2.1.0", "semver": "^7.6.3" diff --git a/packages/cashscript/src/network/ElectrumNetworkProvider.ts b/packages/cashscript/src/network/ElectrumNetworkProvider.ts index 789b7ef9..49ae4478 100644 --- a/packages/cashscript/src/network/ElectrumNetworkProvider.ts +++ b/packages/cashscript/src/network/ElectrumNetworkProvider.ts @@ -1,55 +1,58 @@ import { binToHex } from '@bitauth/libauth'; import { sha256 } from '@cashscript/utils'; import { - ElectrumCluster, - ElectrumTransport, - ClusterOrder, - RequestResponse, -} from 'electrum-cash'; + ElectrumClient, + type RequestResponse, + type ElectrumClientEvents, +} from '@electrum-cash/network'; import { Utxo, Network } from '../interfaces.js'; import NetworkProvider from './NetworkProvider.js'; import { addressToLockScript } from '../utils.js'; + +interface OptionsBase { + manualConnectionManagement?: boolean; +} + +interface CustomHostNameOptions extends OptionsBase { + hostname: string; +} + +interface CustomElectrumOptions extends OptionsBase { + electrum: ElectrumClient; +} + +type Options = OptionsBase | CustomHostNameOptions | CustomElectrumOptions; + export default class ElectrumNetworkProvider implements NetworkProvider { - private electrum: ElectrumCluster; + private electrum: ElectrumClient; private concurrentRequests: number = 0; + private manualConnectionManagement: boolean; - constructor( - public network: Network = Network.MAINNET, - electrum?: ElectrumCluster, - private manualConnectionManagement?: boolean, - ) { - // If a custom Electrum Cluster is passed, we use it instead of the default. - if (electrum) { - this.electrum = electrum; - return; - } + constructor(public network: Network = Network.MAINNET, options: Options = {}) { + this.electrum = this.instantiateElectrumClient(network, options); + this.manualConnectionManagement = options?.manualConnectionManagement ?? false; + } + + private instantiateElectrumClient(network: Network, options: Options): ElectrumClient { + if ('electrum' in options) return options.electrum; + const server = 'hostname' in options ? options.hostname : this.getServerForNetwork(network); + return new ElectrumClient('CashScript Application', '1.4.1', server); + } - if (network === Network.MAINNET) { - // Initialise a 2-of-3 Electrum Cluster with 6 reliable hardcoded servers - // using the first three servers as "priority" servers - this.electrum = new ElectrumCluster('CashScript Application', '1.4.1', 2, 3, ClusterOrder.PRIORITY); - this.electrum.addServer('bch.imaginary.cash', 50004, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('blackie.c3-soft.com', 50004, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('electroncash.de', 60002, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('electroncash.dk', 50004, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('bch.loping.net', 50004, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('electrum.imaginary.cash', 50004, ElectrumTransport.WSS.Scheme, false); - } else if (network === Network.TESTNET3) { - // Initialise a 1-of-2 Electrum Cluster with 2 hardcoded servers - this.electrum = new ElectrumCluster('CashScript Application', '1.4.1', 1, 2, ClusterOrder.PRIORITY); - this.electrum.addServer('blackie.c3-soft.com', 60004, ElectrumTransport.WSS.Scheme, false); - this.electrum.addServer('electroncash.de', 60004, ElectrumTransport.WSS.Scheme, false); - // this.electrum.addServer('bch.loping.net', 60004, ElectrumTransport.WSS.Scheme, false); - // this.electrum.addServer('testnet.imaginary.cash', 50004, ElectrumTransport.WSS.Scheme); - } else if (network === Network.TESTNET4) { - this.electrum = new ElectrumCluster('CashScript Application', '1.4.1', 1, 1, ClusterOrder.PRIORITY); - this.electrum.addServer('testnet4.imaginary.cash', 50004, ElectrumTransport.WSS.Scheme, false); - } else if (network === Network.CHIPNET) { - this.electrum = new ElectrumCluster('CashScript Application', '1.4.1', 1, 1, ClusterOrder.PRIORITY); - this.electrum.addServer('chipnet.bch.ninja', 50004, ElectrumTransport.WSS.Scheme, false); - } else { - throw new Error(`Tried to instantiate an ElectrumNetworkProvider for unsupported network ${network}`); + // Get Electrum server based on network + private getServerForNetwork(network: Network): string { + switch (network) { + case Network.MAINNET: + return 'bch.imaginary.cash'; + case Network.TESTNET3: + return 'testnet.imaginary.cash'; + case Network.TESTNET4: + return 'testnet4.imaginary.cash'; + case Network.CHIPNET: + return 'chipnet.bch.ninja'; + default: + throw new Error(`Unsupported network: ${network}`); } } @@ -85,39 +88,41 @@ export default class ElectrumNetworkProvider implements NetworkProvider { return await this.performRequest('blockchain.transaction.broadcast', txHex) as string; } - async connectCluster(): Promise { - try { - return await this.electrum.startup(); - } catch (e) { - return []; + async connect(): Promise { + if (!this.manualConnectionManagement) { + throw new Error('Manual connection management is disabled'); } + + return this.electrum.connect(); } - async disconnectCluster(): Promise { - return this.electrum.shutdown(); + async disconnect(): Promise { + if (!this.manualConnectionManagement) { + throw new Error('Manual connection management is disabled'); + } + + return this.electrum.disconnect(); } async performRequest( name: string, ...parameters: (string | number | boolean)[] ): Promise { - // Only connect the cluster when no concurrent requests are running + // Only connect the electrum client when no concurrent requests are running if (this.shouldConnect()) { - this.connectCluster(); + await this.electrum.connect(); } this.concurrentRequests += 1; - await this.electrum.ready(); - let result; try { result = await this.electrum.request(name, ...parameters); } finally { - // Always disconnect the cluster, also if the request fails + // Always disconnect the electrum client, also if the request fails // as long as no other concurrent requests are running if (this.shouldDisconnect()) { - await this.disconnectCluster(); + await this.electrum.disconnect(); } } diff --git a/packages/cashscript/test/e2e/network/ElectrumNetworkProvider.test.ts b/packages/cashscript/test/e2e/network/ElectrumNetworkProvider.test.ts new file mode 100644 index 00000000..653b1a56 --- /dev/null +++ b/packages/cashscript/test/e2e/network/ElectrumNetworkProvider.test.ts @@ -0,0 +1,61 @@ +import { describeOrSkip } from '../../../test/test-util.js'; +import { ElectrumNetworkProvider, Network } from '../../../src/index.js'; +import { ElectrumClient } from '@electrum-cash/network'; + +describeOrSkip(!process.env.TESTS_USE_MOCKNET, 'ElectrumNetworkProvider', () => { + // TODO: Test more of the API + it('should be able to request data', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET); + const blockHeight = await provider.getBlockHeight(); + expect(blockHeight).toBeDefined(); + }); + + it('should be able to handle multiple concurrent requests', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET); + + const transactionPromise = provider.getRawTransaction('d72923b7cf345d2a90f951d66f437d4fbb941fcbd87bb54d8d88e51ecb3e3b9f'); + const blockHeightPromise = provider.getBlockHeight(); + + const transaction = await transactionPromise; + const blockHeight = await blockHeightPromise; + + expect(blockHeight).toBeDefined(); + expect(transaction).toBeDefined(); + }); + + it('should be able to pass in a custom electrum client', async () => { + const electrum = new ElectrumClient('CashScript Application', '1.4.1', 'chipnet.bch.ninja'); + const provider = new ElectrumNetworkProvider(Network.CHIPNET, { electrum }); + const blockHeight = await provider.getBlockHeight(); + expect(blockHeight).toBeDefined(); + }); + + it('should be able to pass in a custom host name', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET, { hostname: 'chipnet.bch.ninja' }); + const blockHeight = await provider.getBlockHeight(); + expect(blockHeight).toBeDefined(); + }); + + describe('manual connection management', () => { + it('should throw an error if trying to use connect/disconnect without specifying manualConnectionManagement', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET); + expect(provider.connect()).rejects.toThrow('Manual connection management is disabled'); + }); + + it('should throw an error if client is not connected', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET, { manualConnectionManagement: true }); + expect(provider.getBlockHeight()).rejects.toThrow('Unable to send request to a disconnected server'); + }); + + it('should be able to send requests after connecting', async () => { + const provider = new ElectrumNetworkProvider(Network.CHIPNET, { manualConnectionManagement: true }); + + await provider.connect(); + const blockHeight = await provider.getBlockHeight(); + await provider.disconnect(); + + expect(blockHeight).toBeDefined(); + }); + }); +}); + diff --git a/packages/cashscript/test/e2e/network/FullStack.test.ts b/packages/cashscript/test/e2e/network/FullStackNetworkProvider.test.ts similarity index 100% rename from packages/cashscript/test/e2e/network/FullStack.test.ts rename to packages/cashscript/test/e2e/network/FullStackNetworkProvider.test.ts diff --git a/website/docs/releases/migration-notes.md b/website/docs/releases/migration-notes.md index 881a1ab0..04d704dc 100644 --- a/website/docs/releases/migration-notes.md +++ b/website/docs/releases/migration-notes.md @@ -4,7 +4,9 @@ title: Migration Notes ## v0.10 to v0.11 -### CashScript SDK +There are several breaking changes to the SDK in this release. They are listed below in their own sections. + +### CashScript SDK (Transaction Builder) The 'Simple Transaction builder' has been marked as deprecated and the 'Advanced Transaction Builder' is now simply referred to as the CashScript `Transaction Builder`, as there is only one supported for the future. @@ -69,6 +71,42 @@ const txDetails = await new TransactionBuilder({ provider }) With the new transaction builder, all inputs and outputs are explicitly specified. This means that there are no automatic change outputs added (for BCH or tokens). This means that there are also no `.withMinChange()`, `.withoutChange()`, `.withoutTokenChange()`, `withHardcodedFee()`, or `.withFeePerByte()` methods. The developer is responsible for manually adding change outputs. There is still an option to use `.setMaxFee()` as a security measure to prevent the transaction from being too expensive. +### CashScript SDK (ElectrumNetworkProvider) + +The underlying `electrum-cash` library has been mgrated to the new `@electrum-cash/network` package. This drops support for electrum cluster functionality. We reworked the second parameter of the `ElectrumNetworkProvider` constructor to be an options object, which can contain a custom electrum client or a custom hostname. + +If you were not using custom clusters, there is no need to change anything. If you were using custom clusters, you will need to update your code to use the new `@electrum-cash/network` package and use a single client instead of a cluster. + +#### Example + +Before: + +```ts +import { ElectrumCluster, ClusterOrder } from 'electrum-cash'; +import { ElectrumNetworkProvider } from 'cashscript'; + +const customCluster = new ElectrumCluster('CashScript Application', '1.4.1', 2, 3, ClusterOrder.PRIORITY); +customCluster.addServer('bch.imaginary.cash', 50004, ElectrumTransport.WSS.Scheme, false); +customCluster.addServer('blackie.c3-soft.com', 50004, ElectrumTransport.WSS.Scheme, false); +customCluster.addServer('electroncash.dk', 50004, ElectrumTransport.WSS.Scheme, false); + +const provider = new ElectrumNetworkProvider('mainnet', customCluster); +``` + +After: + +```ts +import { ElectrumClient } from '@electrum-cash/network'; +import { ElectrumNetworkProvider } from 'cashscript'; + +const customClient = new ElectrumClient('CashScript Application', '1.4.1', 'bch.imaginary.cash'); +const provider = new ElectrumNetworkProvider('mainnet', { electrum: customClient }); + +// or + +const provider = new ElectrumNetworkProvider('mainnet', { hostname: 'bch.imaginary.cash' }); +``` + ## v0.9 to v0.10 ### CashScript SDK diff --git a/website/docs/releases/release-notes.md b/website/docs/releases/release-notes.md index bb560464..482ffae7 100644 --- a/website/docs/releases/release-notes.md +++ b/website/docs/releases/release-notes.md @@ -2,10 +2,12 @@ title: Release Notes --- -## v0.11.0-next.1 +## v0.11.0-next.2 This update adds CashScript support for the new BCH 2025 network upgrade. To read more about the upgrade, see [this blog post](https://blog.bitjson.com/2025-chips/). +This release also contains several breaking changes, please refer to the [migration notes](/docs/releases/migration-notes) for more information. + #### cashc compiler - :hammer_and_wrench: Remove warning for opcount and update warning for byte size to match new limits. @@ -16,6 +18,7 @@ This update adds CashScript support for the new BCH 2025 network upgrade. To rea - Libauth template generation and debugging for multi-contract transactions - :hammer_and_wrench: Deprecate the simple transaction builder. You can still use the simple transaction builder with the current SDK, but this support will be removed in a future release. - :hammer_and_wrench: Update debug tooling to use the new `BCH_2025_05` instruction set. +- :boom: **BREAKING**: Remove support for custom Clusters from `ElectrumNetworkProvider` and added a configuration object to the constructor. - :boom: **BREAKING**: Remove support for old contracts compiled with CashScript v0.6.x or earlier. ## v0.10.5 diff --git a/website/docs/sdk/network-provider.md b/website/docs/sdk/network-provider.md index 7e7e83b2..48fd1de3 100644 --- a/website/docs/sdk/network-provider.md +++ b/website/docs/sdk/network-provider.md @@ -6,30 +6,43 @@ The CashScript SDK needs to connect to the BCH network to perform certain operat ## ElectrumNetworkProvider -The ElectrumNetworkProvider uses [electrum-cash][electrum-cash] to connect to the BCH network. Both `network` and `electrum` parameters are optional, and they default to mainnet and a 2-of-3 ElectrumCluster with a number of reliable electrum servers. +The ElectrumNetworkProvider uses [@electrum-cash/network][electrum-cash] to connect to the BCH network. Both `network` and `options` parameters are optional, and they default to mainnet with the `bch.imaginary.cash` electrum server. ```ts -new ElectrumNetworkProvider(network?: Network, electrum?: ElectrumCluster) +new ElectrumNetworkProvider(network?: Network, options?: Options) ``` -:::note -In some cases it might be desirable to overwrite the 2-of-3 ElectrumCluster default to use only a 1-of-1 cluster because of network latency. -::: - +Using the `network` parameter, you can specify the network to connect to. The network parameter can be one of 5 different options: -### Network ```ts type Network = 'mainnet' | 'chipnet' | 'testnet3' | 'testnet4' | 'regtest'; ``` -The network parameter can be one of 5 different options. +Using the `options` parameter, you can specify a custom electrum client or hostname, and enable manual connection management. + +```ts +type Options = OptionsBase | CustomHostNameOptions | CustomElectrumOptions; + +interface OptionsBase { + manualConnectionManagement?: boolean; +} + +interface CustomHostNameOptions extends OptionsBase { + hostname: string; +} + +interface CustomElectrumOptions extends OptionsBase { + electrum: ElectrumClient; +} +``` #### Example ```ts -const provider = new ElectrumProvider('chipnet'); +const hostname = 'chipnet.bch.ninja'; +const provider = new ElectrumNetworkProvider('chipnet', { hostname }); ``` -### getUtxos +### getUtxos() ```ts async provider.getUtxos(address: string): Promise; ``` @@ -49,7 +62,7 @@ interface Utxo { const userUtxos = await provider.getUtxos(userAddress) ``` -### getBlockHeight +### getBlockHeight() ```ts async provider.getBlockHeight(): Promise; ``` @@ -60,7 +73,7 @@ Get the current blockHeight. const currentBlockHeight = await provider.getBlockHeight() ``` -### getRawTransaction +### getRawTransaction() ```ts async provider.getRawTransaction(txid: string): Promise; ``` @@ -72,7 +85,7 @@ Retrieve the Hex transaction details for a given transaction ID. const rawTransaction = await provider.getRawTransaction(txid) ``` -### sendRawTransaction +### sendRawTransaction() ```ts async provider.sendRawTransaction(txHex: string): Promise; ``` @@ -83,7 +96,7 @@ Broadcast a raw hex transaction to the network. const txId = await provider.sendRawTransaction(txHex) ``` -### performRequest +### performRequest() Perform an arbitrary electrum request, refer to the docs at [electrum-cash-protocol](https://electrum-cash-protocol.readthedocs.io/en/latest/). @@ -93,6 +106,29 @@ const verbose = true // get parsed transaction as json result const txId = await provider.performRequest('blockchain.transaction.get', txid, verbose) ``` +### Manual Connection Management + +By default, the ElectrumNetworkProvider will automatically connect and disconnect to the electrum client as needed. However, you can enable manual connection management by setting the `manualConnectionManagement` option to `true`. This can be useful if you are passing a custom electrum client and are using that client for other purposes, such as subscribing to events. + +```ts +const provider = new ElectrumNetworkProvider('chipnet', { manualConnectionManagement: true }); +``` + +#### connect() +```ts +provider.connect(): Promise; +``` + +Connects to the electrum client. + +#### disconnect() +```ts +provider.disconnect(): Promise; +``` + +Disconnects from the electrum client, returns `true` if the client was connected, `false` if it was already disconnected. + + ## Advanced Options All network functionality that the CashScript SDK needs is encapsulated in a network provider. This allows different network providers to be used and makes it easy to swap out dependencies. @@ -127,6 +163,6 @@ To implement a Custom NetworkProvider, refer to the [NetworkProvider interface]( ::: -[electrum-cash]: https://www.npmjs.com/package/electrum-cash +[electrum-cash]: https://www.npmjs.com/package/@electrum-cash/network [fullstack]: https://fullstack.cash/ [bchjs]: https://bchjs.fullstack.cash/ diff --git a/yarn.lock b/yarn.lock index 9a1a8d22..5e08360e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1056,6 +1056,38 @@ resolved "https://registry.yarnpkg.com/@cspell/url/-/url-8.17.2.tgz#81f8cd7d31b7d160971a207da5b6486eebc5aecb" integrity sha512-yy4eYWNX2iutXmy4Igbn/hL/NYaNt94DylohPtgVr0Zxnn/AAArt9Bv1KXPpjB8VFy2wzzPzWmZ+MWDUVpHCbg== +"@electrum-cash/debug-logs@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@electrum-cash/debug-logs/-/debug-logs-1.0.0.tgz#7d021515f1b881f477176cb640f2178d094181e5" + integrity sha512-GU/CvRR9lZ0d8gy9CXGW7f//OHCIydBavv9q+JcxjGj8Xr7HwlGqHx+Wzhx9y3YmJrXfExpgClcd++gTjdEmzA== + dependencies: + debug "^4.3.7" + +"@electrum-cash/network@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@electrum-cash/network/-/network-4.1.1.tgz#1f9571c783f613ce960374b4bffb73c27b28c429" + integrity sha512-v5abF2qGRTnBoi9tcS/iz7j82D8HYsK9iY0NM5v8/Qu8SnlMGGNz8UDFl+YzRPFXb4SUL3K0uf3Oydy82DB3oA== + dependencies: + "@electrum-cash/debug-logs" "^1.0.0" + "@electrum-cash/web-socket" "^1.0.0" + async-mutex "^0.5.0" + debug "^4.3.2" + eventemitter3 "^5.0.1" + lossless-json "^4.0.1" + +"@electrum-cash/web-socket@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@electrum-cash/web-socket/-/web-socket-1.0.0.tgz#0ab57e46d41e941ffb57deff86afea3ae1379d5d" + integrity sha512-+VQ6aPE7nUysyDn9SB7/uqKuVJmjrhvr0LRK2ANTeR1DfmXBnv5z29e/0zK5A7ZoAz0gdZZuLDzN46r8S5Cxig== + dependencies: + "@electrum-cash/debug-logs" "^1.0.0" + "@monsterbitar/isomorphic-ws" "^5.3.0" + "@types/ws" "^8.5.5" + async-mutex "^0.5.0" + eventemitter3 "^5.0.1" + lossless-json "^4.0.1" + ws "^8.13.0" + "@esbuild/aix-ppc64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" @@ -2385,6 +2417,11 @@ npmlog "^4.1.2" write-file-atomic "^2.3.0" +"@monsterbitar/isomorphic-ws@^5.3.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@monsterbitar/isomorphic-ws/-/isomorphic-ws-5.3.1.tgz#acd6be86c7568682d8146f8b5fadbec74bf8789e" + integrity sha512-BWfWUffbg3uO4K6Cyokg9ff43lPaXAOZcCnNe1lcjCjUMDVrRAb5qEHG5qeJp3ud2SPYbORaNsls5as6SR3oig== + "@mr-zwets/bchn-api-wrapper@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@mr-zwets/bchn-api-wrapper/-/bchn-api-wrapper-1.0.1.tgz#1ecd9fca91ed7e33df9769e243ae04871d2d356f" @@ -2778,10 +2815,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/ws@^7.4.6": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.5": + version "8.5.14" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.14.tgz#93d44b268c9127d96026cf44353725dd9b6c3c21" + integrity sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw== dependencies: "@types/node" "*" @@ -3250,12 +3287,12 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -async-mutex@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.2.tgz#1485eda5bda1b0ec7c8df1ac2e815757ad1831df" - integrity sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA== +async-mutex@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.5.0.tgz#353c69a0b9e75250971a64ac203b0ebfddd75482" + integrity sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA== dependencies: - tslib "^2.3.1" + tslib "^2.4.0" asynckit@^0.4.0: version "0.4.0" @@ -4543,6 +4580,13 @@ debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.7: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -4823,17 +4867,6 @@ electron-to-chromium@^1.5.73: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz#8e334ca206bb293a20b16418bf454783365b0a95" integrity sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g== -electrum-cash@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/electrum-cash/-/electrum-cash-2.0.10.tgz#0b2831d01b214bff1dfee7b90022f36126cb6945" - integrity sha512-xxKXWyDsnUR2pkqzb7r7ANf6yzlHO8+Rkq8HOFkKiH1tF1BJwyh6sDhGAy4lkTv2sU8Uv1em/itYZ5n2Cr6zaA== - dependencies: - "@types/ws" "^7.4.6" - async-mutex "^0.3.1" - debug "^4.3.2" - isomorphic-ws "^4.0.1" - ws "^7.5.2" - elliptic@^6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" @@ -5325,6 +5358,11 @@ eventemitter3@^3.1.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -6979,11 +7017,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -7837,6 +7870,11 @@ lodash@^4.17.12, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.2.1: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lossless-json@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-4.0.2.tgz#f00c52815805d1421930a87e2670e27350958a3f" + integrity sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA== + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -8210,7 +8248,7 @@ ms@2.1.2, ms@^2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -10614,10 +10652,10 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== -tslib@^2.3.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.4.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tsx@^4.19.2: version "4.19.2" @@ -11198,10 +11236,10 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" -ws@^7.5.2: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +ws@^8.13.0: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== xdg-basedir@^5.1.0: version "5.1.0"