diff --git a/docs/api-reference/avm-web-client.mdx b/docs/api-reference/avm-web-client.mdx index eef0f54..00d559b 100644 --- a/docs/api-reference/avm-web-client.mdx +++ b/docs/api-reference/avm-web-client.mdx @@ -39,9 +39,9 @@ import TOCInline from '@theme/TOCInline'; #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | ### `discover([params])` @@ -55,9 +55,9 @@ import TOCInline from '@theme/TOCInline'; #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | ### `enable([params])` @@ -71,9 +71,9 @@ import TOCInline from '@theme/TOCInline'; #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | ### `getConfig()` @@ -86,90 +86,101 @@ import TOCInline from '@theme/TOCInline'; | [`IAVMWebClientConfig`](types#iavmwebclientconfig) | The client's configuration. | -### `onDisable(listener)` +### `onDisable(callback)` -> Listens to `disable` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `disable` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | + +#### Returns +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onDiscover(listener)` +### `onDiscover(callback)` -> Listens to `discover` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `discover` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onEnable(listener)` +### `onEnable(callback)` -> Listens to `enable` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `enable` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onPostTransactions(listener)` +### `onPostTransactions(callback)` -> Listens to `post_transactions` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `post_transactions` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onSignAndPostTransactions(listener)` +### `onSignAndPostTransactions(callback)` -> Listens to `sign_and_post_transactions` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `sign_and_post_transactions` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | -### `onSignTransactions(listener)` +#### Returns + +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -> Listens to `sign_transactions` messages sent from providers. This will replace any previous set listeners. If null is supplied, the listener will be removed. +### `onSignTransactions(callback)` + +> Listens to `sign_transactions` messages sent from providers. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebClientListenerOptions`](types#iavmwebclientlisteneroptions)) => (`void` \| `Promise`) \| `null` | yes | - | The callback is called when a response message is received, or null to remove the listener. If the result was successful, the `error` parameter will be null. | +| Name | Type | Required | Default | Description | +|----------|------------------------------------------------------------------------------------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------| +| callback | (`options`: [`IAVMWebClientCallbackOptions`](types#iavmwebclientcallbackoptions)) => (`void` \| `Promise`) | yes | - | The callback is called when a response message is received. If the result was successful, the `error` parameter will be null. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | ### `postTransactions([params])` @@ -183,29 +194,29 @@ import TOCInline from '@theme/TOCInline'; #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | -### `signAndpostTransactions([params])` +### `removeAllListeners()` -> Request providers to sign and post a list of unsigned transactions to the network. +> Removes all listeners. -#### Parameters +#### Returns -| Name | Type | Required | Default | Description | -|--------|------------------------------------------------------------|----------|---------|-----------------------------------------------------------------| -| params | [`ISignTransactionsParams`](types#isigntransactionsparams) | yes | - | Params that specify the unsigned transactions and the provider. | +| Type | Description | +|--------|-------------| +| `void` | - | -### `signTransactions([params])` +### `removeListener(id)` -> Request providers to sign a list of unsigned transactions. +> Removes the listener, by the ID. #### Parameters -| Name | Type | Required | Default | Description | -|--------|------------------------------------------------------------|----------|---------|-----------------------------------------------------------------| -| params | [`ISignTransactionsParams`](types#isigntransactionsparams) | yes | - | Params that specify the unsigned transactions and the provider. | +| Name | Type | Required | Default | Description | +|------|----------|----------|---------|----------------------------| +| id | `string` | yes | - | The listener ID to remove. | #### Returns @@ -213,34 +224,34 @@ import TOCInline from '@theme/TOCInline'; |--------|-------------| | `void` | - | -### `startListening()` - -> Starts listening to responses from providers. This method should not have to be manually called, as it is called as part of the [initialization](#initoptions) process. his method essentially closes a previous connection and opens a new connection to the BroadcastChannel. +### `signAndpostTransactions([params])` -:::note +> Request providers to sign and post a list of unsigned transactions to the network. -This method must be called if the client needs listen to messages if the [`stopListening()`](#stoplistening) method was previously called. +#### Parameters -::: +| Name | Type | Required | Default | Description | +|--------|------------------------------------------------------------|----------|---------|-----------------------------------------------------------------| +| params | [`ISignTransactionsParams`](types#isigntransactionsparams) | yes | - | Params that specify the unsigned transactions and the provider. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | - -### `stopListening()` +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | -> Stops listening to responses from providers. This method closes the connection to BroadcastChannel. +### `signTransactions([params])` -:::caution +> Request providers to sign a list of unsigned transactions. -It is highly recommended you call this method when you no longer need to listen to provider responses or are cleaning up. +#### Parameters -::: +| Name | Type | Required | Default | Description | +|--------|------------------------------------------------------------|----------|---------|-----------------------------------------------------------------| +| params | [`ISignTransactionsParams`](types#isigntransactionsparams) | yes | - | Params that specify the unsigned transactions and the provider. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|--------------------------------| +| `string` | the ID of the request message. | diff --git a/docs/api-reference/avm-web-provider.mdx b/docs/api-reference/avm-web-provider.mdx index 31b0ad4..5be77e3 100644 --- a/docs/api-reference/avm-web-provider.mdx +++ b/docs/api-reference/avm-web-provider.mdx @@ -38,111 +38,105 @@ import TOCInline from '@theme/TOCInline'; |--------------------------------------------------------|-------------------------------| | [`IAVMWebProviderConfig`](types#iavmwebproviderconfig) | The provider's configuration. | -### `onDisable(listener)` +### `onDisable(callback)` -> Listens to `disable` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. +> Listens to `disable` messages sent from clients. #### Parameters -| Name | Type | Required | Default | Description | -|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`IDisableResult`](types#idisableresult) \| [`Promise`](types#idiscoverresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`IDisableResult`](types#idisableresult) \| [`Promise`](types#idiscoverresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onDiscover(listener)` +### `onDiscover(callback)` > Listens to `discover` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. #### Parameters -| Name | Type | Required | Default | Description | -|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`IDiscoverResult`](types#idiscoverresult) \| [`Promise`](types#idiscoverresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`IDiscoverResult`](types#idiscoverresult) \| [`Promise`](types#idiscoverresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onEnable(listener)` +### `onEnable(callback)` > Listens to `enable` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. #### Parameters -| Name | Type | Required | Default | Description | -|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`IEnableResult`](types#ienableresult) \| [`Promise`](types#ienableresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`IEnableResult`](types#ienableresult) \| [`Promise`](types#ienableresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onPostTransactions(listener)` +### `onPostTransactions(callback)` > Listens to `post_transactions` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`IPostTransactionsResult`](types#iposttransactionsresult) \| [`Promise`](types#iposttransactionsresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`IPostTransactionsResult`](types#iposttransactionsresult) \| [`Promise`](types#iposttransactionsresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onSignAndPostTransactions(listener)` +### `onSignAndPostTransactions(callback)` > Listens to `sign_and_post_transactions` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`IPostTransactionsResult`](types#iposttransactionsresult) \| [`Promise`](types#iposttransactionsresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`IPostTransactionsResult`](types#iposttransactionsresult) \| [`Promise`](types#iposttransactionsresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `onSignTransactions(listener)` +### `onSignTransactions(callback)` > Listens to `sign_transactions` messages sent from clients. This will replace any previous set listeners. If null is supplied, the listener will be removed. #### Parameters -| Name | Type | Required | Default | Description | -|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------| -| listener | (`options`: [`IAVMWebProviderListenerOptions`](types#iavmwebproviderlisteneroptions)) => ([`ISignTransactionsResult`](types#isigntransactionsresult) \| [`Promise`](types#isigntransactionsresult)) \| `null` | yes | - | The listener to call when the request message is sent, or null to remove the listener. | +| Name | Type | Required | Default | Description | +|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|--------------------------------------------------------| +| callback | (`options`: [`IAVMWebProviderCallbackOptions`](types#iavmwebproviderlcallbackoptions)) => ([`ISignTransactionsResult`](types#isigntransactionsresult) \| [`Promise`](types#isigntransactionsresult)) | yes | - | The listener to call when the request message is sent. | #### Returns -| Type | Description | -|--------|-------------| -| `void` | - | +| Type | Description | +|----------|-------------------------| +| `string` | the ID of the listener. | -### `startListening()` +### `removeAllListeners()` -> Starts listening to requests from clients. This method should not have to be manually called, as it is called as part of the [initialization](#initoptions) process. This method essentially closes a previous connection and opens a new connection to the BroadcastChannel. - -:::note - -This method must be called if the client needs listen to messages if the [`stopListening()`](#stoplistening) method was previously called. - -::: +> Removes all listeners. #### Returns @@ -150,15 +144,15 @@ This method must be called if the client needs listen to messages if the [`stopL |--------|-------------| | `void` | - | -### `stopListening()` +### `removeListener(id)` -> Stops listening to requests from clients. This method closes the connection to the BroadcastChannel. +> Removes the listener, by the ID. -:::caution - -It is highly recommended you call this method when you no longer need to listen to client's requests or are cleaning up. +#### Parameters -::: +| Name | Type | Required | Default | Description | +|------|----------|----------|---------|----------------------------| +| id | `string` | yes | - | The listener ID to remove. | #### Returns diff --git a/docs/api-reference/types.mdx b/docs/api-reference/types.mdx index 2b4e910..6667596 100644 --- a/docs/api-reference/types.mdx +++ b/docs/api-reference/types.mdx @@ -17,6 +17,15 @@ import TOCInline from '@theme/TOCInline'; | stxn | `string` | no | - | If this is part of a group of transactions, some of which are already signed you must also provide these signed transactions and the signers array MUST be undefined or empty, as per [ARC-0001](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0001.md#semantic-of-wallettransaction). | | | | | | txn | `string` | yes | - | The base64 encoded unsigned transaction. | +### `IAVMWebClientCallbackOptions` + +| Name | Type | Required | Default | Description | +|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------| +| error | [`IBaseError`](#ibaseerror) \| `null` | yes | - | If an error occured (defined as one of the [errors](errors)), this will be defined. If a request was successful, this will be `null`. | +| id | `string` | yes | - | A unique identifier for the response message. | +| method | `disable` \| `discover` \| `enable` \| `post_transactions` \| `sign_and_post_transactions` \| `sign_transactions` | yes | - | An enum that represents the method of the message. | +| result | [`IDisableResult`](#idisableresult) \| [`IDiscoverResult`](#idiscoverresult) \| [`IEnableResult`](#ienableresult) \| [`IPostTransactionsResult`](#iposttransactionsresult) \| [`ISignTransactionsResult`](#isigntransactionsresult) \| `null` | yes | - | If a request was successful, this will contain the details of the result, otherwise, if an error occurred, this will be `null`. | + ### `IAVMWebClientConfig` | Name | Type | Required | Default | Description | @@ -29,14 +38,13 @@ import TOCInline from '@theme/TOCInline'; |-------|-----------|----------|---------|-------------------------------------------| | debug | `boolean` | no | `false` | Outputs debug information to the console. | -### `IAVMWebClientListenerOptions` +### `IAVMWebProviderCallbackOptions` -| Name | Type | Required | Default | Description | -|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------| -| error | [`IBaseError`](#ibaseerror) \| `null` | yes | - | If an error occured (defined as one of the [errors](errors)), this will be defined. If a request was successful, this will be `null`. | -| id | `string` | yes | - | A unique identifier for the response message. | -| method | `disable` \| `discover` \| `enable` \| `post_transactions` \| `sign_and_post_transactions` \| `sign_transactions` | yes | - | An enum that represents the method of the message. | -| result | [`IDisableResult`](#idisableresult) \| [`IDiscoverResult`](#idiscoverresult) \| [`IEnableResult`](#ienableresult) \| [`IPostTransactionsResult`](#iposttransactionsresult) \| [`ISignTransactionsResult`](#isigntransactionsresult) \| `null` | yes | - | If a request was successful, this will contain the details of the result, otherwise, if an error occurred, this will be `null`. | +| Name | Type | Required | Default | Description | +|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------| +| id | `string` | yes | - | A unique identifier for the request message. | +| method | `disable` \| `discover` \| `enable` \| `post_transactions` \| `sign_and_post_transactions` \| `sign_transactions` | yes | - | An enum that represents the method of the message. | +| params | [`IDisableParams`](#idisableparams) \| [`IDiscoverParams`](#idiscoverparams) \| [`IEnableParams`](#ienableparams) \| [`IPostTransactionsParams`](#iposttransactionsparams) \| [`ISignTransactionsParams`](#isigntransactionsparams) | no | - | Parameters that were sent by the request. | ### `IAVMWebProviderConfig` @@ -51,14 +59,6 @@ import TOCInline from '@theme/TOCInline'; |-------|-----------|----------|---------|-------------------------------------------| | debug | `boolean` | no | `false` | Outputs debug information to the console. | -### `IAVMWebProviderListenerOptions` - -| Name | Type | Required | Default | Description | -|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|----------------------------------------------------| -| id | `string` | yes | - | A unique identifier for the request message. | -| method | `disable` \| `discover` \| `enable` \| `post_transactions` \| `sign_and_post_transactions` \| `sign_transactions` | yes | - | An enum that represents the method of the message. | -| params | [`IDisableParams`](#idisableparams) \| [`IDiscoverParams`](#idiscoverparams) \| [`IEnableParams`](#ienableparams) \| [`IPostTransactionsParams`](#iposttransactionsparams) \| [`ISignTransactionsParams`](#isigntransactionsparams) | no | - | Parameters that were sent by the request. | - ### `IBaseError` | Name | Type | Required | Default | Description | diff --git a/docs/clients/disabling-a-client.mdx b/docs/clients/disabling-a-client.mdx index 8a312af..19b4227 100644 --- a/docs/clients/disabling-a-client.mdx +++ b/docs/clients/disabling-a-client.mdx @@ -46,7 +46,7 @@ client.onDisable(({ error, result }) => { */ }); -// broadcast a disable request +// send a disable request client.disable(); ``` @@ -74,7 +74,7 @@ client.onDisable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast a disable request +// send a disable request client.disable(); ``` @@ -117,7 +117,7 @@ client.onDisable(({ error, result }) => { */ }); -// broadcast an disable request +// send a disable request client.disable({ genesisHash: 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=', providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', @@ -150,7 +150,7 @@ client.onEnable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an disable request +// send a disable request client.disable({ genesisHash: 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=', providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', @@ -198,7 +198,7 @@ client.onDisable(({ error, result }) => { */ }); -// broadcast an disable request +// send a disable request client.disable({ sessionIds: ['ab192498-0c63-4028-80fd-f148710611d8'], }); @@ -229,7 +229,7 @@ client.onEnable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an disable request +// send a disable request client.disable({ sessionIds: ['ab192498-0c63-4028-80fd-f148710611d8'], }); diff --git a/docs/clients/discover-providers.mdx b/docs/clients/discover-providers.mdx index 3781f1b..b0783f2 100644 --- a/docs/clients/discover-providers.mdx +++ b/docs/clients/discover-providers.mdx @@ -68,7 +68,7 @@ client.onDiscover(({ error, result }) => { */ }); -// broadcast a discover request +// send a discover request client.discover(); ``` @@ -120,7 +120,7 @@ client.onDiscover(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast a discover request +// send a discover request client.discover(); ``` @@ -186,7 +186,7 @@ client.onDiscover(({ error, result }) => { */ }); -// broadcast a discover request +// send a discover request client.discover({ providerId }); ``` @@ -240,7 +240,7 @@ client.onDiscover(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast a discover request +// send a discover request client.discover({ providerId }); ``` diff --git a/docs/clients/enabling-a-client.mdx b/docs/clients/enabling-a-client.mdx index c0f5600..8b8c269 100644 --- a/docs/clients/enabling-a-client.mdx +++ b/docs/clients/enabling-a-client.mdx @@ -70,7 +70,7 @@ client.onEnable(({ error, result }) => { */ }); -// broadcast an enable request +// send a enable request client.enable(); ``` @@ -109,7 +109,7 @@ client.onEnable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an enable request +// send a enable request client.enable(); ``` @@ -166,7 +166,7 @@ client.onEnable(({ error, result }) => { */ }); -// broadcast an enable request +// send a enable request client.enable({ providerId }); ``` @@ -207,7 +207,7 @@ client.onEnable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an enable request +// send a enable request client.enable({ providerId }); ``` @@ -258,7 +258,7 @@ client.onEnable(({ error, result }) => { */ }); -// broadcast an enable request +// send a enable request client.enable({ genesisHash }); ``` @@ -299,7 +299,7 @@ client.onEnable(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an enable request +// send a enable request client.enable({ genesisHash }); ``` diff --git a/docs/clients/posting-transactions.mdx b/docs/clients/posting-transactions.mdx index fa6083d..b8a763d 100644 --- a/docs/clients/posting-transactions.mdx +++ b/docs/clients/posting-transactions.mdx @@ -49,7 +49,7 @@ client.onPostTransactions(({ error, result }) => { */ }); -// broadcast an post transactions request +// send a post transactions request client.postTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', stxns: [ @@ -83,7 +83,7 @@ client.onPostTransactions(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast an post transactions request +// send a post transactions request client.postTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', stxns: [ diff --git a/docs/clients/signing-and-posting-transactions.mdx b/docs/clients/signing-and-posting-transactions.mdx index cbe83ae..89b9d52 100644 --- a/docs/clients/signing-and-posting-transactions.mdx +++ b/docs/clients/signing-and-posting-transactions.mdx @@ -72,7 +72,7 @@ client.onSignAndPostTransactions(({ error, result }) => { */ }); -// broadcast a sign and post transactions request +// send a sign and post transactions request client.signAndPostTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -136,7 +136,7 @@ client.onSignAndPostTransactions(({ error, result }: IAVMWebClientListenerOption */ }); -// broadcast a sign and post transactions request +// send a sign and post transactions request client.signAndPostTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ diff --git a/docs/clients/signing-transactions.mdx b/docs/clients/signing-transactions.mdx index 3f4938a..1576cc5 100644 --- a/docs/clients/signing-transactions.mdx +++ b/docs/clients/signing-transactions.mdx @@ -67,7 +67,7 @@ client.onSignTransactions(({ error, result }) => { */ }); -// broadcast a sign transactions request +// send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -131,7 +131,7 @@ client.onSignTransactions(({ error, result }: IAVMWebClientListenerOptions) => { */ }); -// broadcast a sign transactions request +// send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -220,7 +220,7 @@ When sending atomic transactions, all transactions, regardless of whether the wa */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -303,7 +303,7 @@ When sending atomic transactions, all transactions, regardless of whether the wa */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -391,7 +391,7 @@ For example: */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -468,7 +468,7 @@ For example: */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -547,7 +547,7 @@ As you can see from the above example, when the provider skips signing the trans */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -625,7 +625,7 @@ As you can see from the above example, when the provider skips signing the trans */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -716,7 +716,7 @@ The provider may not support multisig accounts, in which case a [`MethodNotSuppo */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -793,7 +793,7 @@ The provider may not support multisig accounts, in which case a [`MethodNotSuppo */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -872,7 +872,7 @@ If you want to only use one address, you can use the `signers` list to instruct */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -952,7 +952,7 @@ If you want to only use one address, you can use the `signers` list to instruct */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -1038,7 +1038,7 @@ The provider may not support re-keyed accounts, in which case a [`MethodNotSuppo */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ @@ -1103,7 +1103,7 @@ The provider may not support re-keyed accounts, in which case a [`MethodNotSuppo */ }); - // broadcast a sign transactions request + // send a sign transactions request client.signTransactions({ providerId: '02657eaf-be17-4efc-b0a4-19d654b2448e', txns: [ diff --git a/docs/overview.mdx b/docs/overview.mdx index 74d8784..10a8e3f 100644 --- a/docs/overview.mdx +++ b/docs/overview.mdx @@ -6,12 +6,6 @@ slug: / import TOCInline from '@theme/TOCInline'; - -import CenteredImage from '@site/docs/components/CenteredImage'; - - -import simpleMessageBusDiagramImage from '@site/docs/static/images/simple_message_bus.png'; - +::: + +The AVM Web Provider leverages the [`EventTarget`][event-target] API as a transport layer to deliver messages and allows clients and web-based providers to securely communicate without interfering with other providers. -[broadcastchannel]: https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel -[post-message]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage +[add-event-listener]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener +[content-scripts]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts +[dispatch-event]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent +[event-target]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget diff --git a/src/controllers/AVMWebClient.test.ts b/src/controllers/AVMWebClient.test.ts index 3e67d20..7f696a7 100644 --- a/src/controllers/AVMWebClient.test.ts +++ b/src/controllers/AVMWebClient.test.ts @@ -26,13 +26,7 @@ describe(AVMWebClient.name, () => { let provider: AVMWebProvider; afterEach(() => { - if (client) { - client.stopListening(); - } - - if (provider) { - provider.stopListening(); - } + provider?.removeAllListeners(); }); describe(`${AVMWebClient.name}#init`, () => { diff --git a/src/controllers/AVMWebClient.ts b/src/controllers/AVMWebClient.ts index 458a74e..bfd1801 100644 --- a/src/controllers/AVMWebClient.ts +++ b/src/controllers/AVMWebClient.ts @@ -9,6 +9,9 @@ import BaseController from './BaseController'; // enums import { ARC0027MessageTypeEnum, ARC0027MethodEnum } from '@app/enums'; +// errors +import { ARC0027UnknownError } from '@app/errors'; + // messages import { RequestMessage, @@ -31,58 +34,88 @@ import type { ISendRequestMessageOptions, ISignTransactionsParams, ISignTransactionsResult, - TAVMWebClientListener, + TAVMWebClientCallback, + TClientCustomEventListener, TRequestParams, + TResponseResults, } from '@app/types'; // utils import { createMessageReference } from '@app/utils'; export default class AVMWebClient extends BaseController { - private readonly listeners: Map; private requestIds: string[]; private constructor(config: IAVMWebClientConfig) { super(config); - this.listeners = new Map(); this.requestIds = []; - - // start listening to response messages - this.startListening(); } /** * private methods */ - private sendRequestMessage({ - method, - params, - }: ISendRequestMessageOptions): void { - const _functionName: string = 'sendRequestMessage'; - let id: string; - let reference: string; + private addListener( + method: ARC0027MethodEnum, + callback: TAVMWebClientCallback + ): string { + const _functionName: string = 'addListener'; + const listener: TClientCustomEventListener = (event) => { + // if the request event is not known, ignore + if (!this.requestIds.includes(event.detail.requestId)) { + return; + } - // if there is no channel, ignore - if (!this.channel) { this.logger.debug( - `${AVMWebClient.name}#${_functionName}: no broadcast channel available, ignoring` + `${AVMWebClient.name}#${_functionName}: received response event:`, + event.detail ); - return; - } + callback({ + ...event.detail, + error: (event.detail as ResponseMessageWithError).error || null, + method, + result: + (event.detail as ResponseMessageWithResult).result || null, + }); + }; + const listenerID: string = uuid(); + const reference: string = createMessageReference( + method, + ARC0027MessageTypeEnum.Response + ); + + // start listening to response events and add the listener to the map + window.addEventListener(reference, listener); + this.listeners.set(listenerID, { + listener, + reference, + }); - id = uuid(); - reference = createMessageReference(method, ARC0027MessageTypeEnum.Request); + return listenerID; + } + + private sendRequestMessage({ + method, + params, + }: ISendRequestMessageOptions): string { + const _functionName: string = 'sendRequestMessage'; + const id: string = uuid(); + const reference: string = createMessageReference( + method, + ARC0027MessageTypeEnum.Request + ); try { - // broadcast the request message - this.channel.postMessage( - new RequestMessage({ - id, - params, - reference, + // dispatch the request message + window.dispatchEvent( + new CustomEvent>(reference, { + detail: new RequestMessage({ + id, + params, + reference, + }), }) ); @@ -92,67 +125,17 @@ export default class AVMWebClient extends BaseController { }, DEFAULT_REQUEST_TIMEOUT); this.logger.debug( - `${AVMWebClient.name}#${_functionName}: posted message "${reference}" with id "${id}"` + `${AVMWebClient.name}#${_functionName}: posted request message "${reference}" with id "${id}"` ); // add the id to the internal state this.requestIds.push(id); + + return id; } catch (error) { this.logger.error(error); - } - } - /** - * protected methods - */ - - protected async onMessage( - message: MessageEvent - ): Promise { - const _functionName: string = 'onMessage'; - const listener: TAVMWebClientListener | null = - this.listeners.get(message.data.reference) || null; - let method: ARC0027MethodEnum | null = null; - - // ensure we have a listener for the response and the request id is known - if (listener && this.requestIds.includes(message.data.requestId)) { - switch (message.data.reference) { - case `${createMessageReference(ARC0027MethodEnum.Disable, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.Disable; - break; - case `${createMessageReference(ARC0027MethodEnum.Discover, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.Discover; - break; - case `${createMessageReference(ARC0027MethodEnum.Enable, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.Enable; - break; - case `${createMessageReference(ARC0027MethodEnum.PostTransactions, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.PostTransactions; - break; - case `${createMessageReference(ARC0027MethodEnum.SignAndPostTransactions, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.SignAndPostTransactions; - break; - case `${createMessageReference(ARC0027MethodEnum.SignTransactions, ARC0027MessageTypeEnum.Response)}`: - method = ARC0027MethodEnum.SignTransactions; - break; - default: - break; - } - - // if we recognize the message, emit the listener - if (method) { - this.logger.debug( - `${AVMWebClient.name}#${_functionName}: received response message "${JSON.stringify(message.data)}"` - ); - - return listener({ - error: (message.data as ResponseMessageWithError).error || null, - id: message.data.id, - method, - requestId: message.data.requestId, - result: (message.data as ResponseMessageWithResult).result || null, - }); - } + throw new ARC0027UnknownError(error.message); } } @@ -174,9 +157,10 @@ export default class AVMWebClient extends BaseController { /** * Sends a request to remove the client from providers. - * @param {IDisableParams} params - [optional] params that specify which provider,network and/or specific session IDs. + * @param {IDisableParams} params - [optional] params that specify which provider, network and/or specific session IDs. + * @returns {string} the ID of the request message. */ - public disable(params?: IDisableParams): void { + public disable(params?: IDisableParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.Disable, params, @@ -187,8 +171,9 @@ export default class AVMWebClient extends BaseController { * Sends a request to get information relating to available providers. This should be called before interacting with * any providers to ensure networks and methods are supported. * @param {IDiscoverParams} params - [optional] params that specify which provider to target. + * @returns {string} the ID of the request message. */ - public discover(params?: IDiscoverParams): void { + public discover(params?: IDiscoverParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.Discover, params, @@ -199,8 +184,9 @@ export default class AVMWebClient extends BaseController { * Enables to a client with providers. If the ID of the provider and/or network is specified, that provider/network is * used, otherwise the all providers available providers are used. * @param {IEnableParams} params - [optional] params that specify the provider and/or the network. + * @returns {string} the ID of the request message. */ - public enable(params?: IEnableParams): void { + public enable(params?: IEnableParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.Enable, params, @@ -208,152 +194,91 @@ export default class AVMWebClient extends BaseController { } /** - * Listens to `disable` messages sent from providers. This will replace any previous set listeners. If null is - * supplied, the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response message - * is received, or null to remove the listener. + * Listens to `disable` messages sent from providers. + * @param {TAVMWebClientCallback} callback - callback that is called when a response message + * is received. + * @returns {string} the ID of the listener. */ - public onDisable( - listener: TAVMWebClientListener | null - ): void { - const responseReference: string = createMessageReference( + public onDisable(callback: TAVMWebClientCallback): string { + return this.addListener( ARC0027MethodEnum.Disable, - ARC0027MessageTypeEnum.Response + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); } /** - * Listens to `discover` messages sent from providers. This will replace any previous set listeners. If null is - * supplied, the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response message - * is received, or null to remove the listener. + * Listens to `discover` messages sent from providers. + * @param {TAVMWebClientCallback} callback - callback that is called when a response message + * is received. + * @returns {string} the ID of the listener. */ - public onDiscover( - listener: TAVMWebClientListener | null - ): void { - const responseReference: string = createMessageReference( + public onDiscover(callback: TAVMWebClientCallback): string { + return this.addListener( ARC0027MethodEnum.Discover, - ARC0027MessageTypeEnum.Response + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); } /** - * Listens to `enable` messages sent from providers. This will replace any previous set listeners. If null is supplied, - * the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response message - * is received, or null to remove the listener. + * Listens to `enable` messages sent from providers. + * @param {TAVMWebClientCallback} callback - callback that is called when a response message + * is received. + * @returns {string} the ID of the listener. */ - public onEnable(listener: TAVMWebClientListener | null): void { - const responseReference: string = createMessageReference( - ARC0027MethodEnum.Enable, - ARC0027MessageTypeEnum.Response - ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); + public onEnable(callback: TAVMWebClientCallback): string { + return this.addListener(ARC0027MethodEnum.Enable, callback); } /** - * Listens to `post_transactions` messages sent from providers. This will replace any previous set listeners. If null - * is supplied, the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response - * message is received, or null to remove the listener. + * Listens to `post_transactions` messages sent from providers. + * @param {TAVMWebClientCallback} callback - callback that is called when a response + * message is received. + * @returns {string} the ID of the listener. */ public onPostTransactions( - listener: TAVMWebClientListener | null - ): void { - const responseReference: string = createMessageReference( + callback: TAVMWebClientCallback + ): string { + return this.addListener( ARC0027MethodEnum.PostTransactions, - ARC0027MessageTypeEnum.Response + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); } /** - * Listens to `sign_and_post_transactions` messages sent from providers. This will replace any previous set listeners. - * If null is supplied, the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response - * message is received, or null to remove the listener. + * Listens to `sign_and_post_transactions` messages sent from providers. + * @param {TAVMWebClientCallback} callback - callback that is called when a response + * message is received. */ public onSignAndPostTransactions( - listener: TAVMWebClientListener | null - ): void { - const responseReference: string = createMessageReference( + callback: TAVMWebClientCallback + ): string { + return this.addListener( ARC0027MethodEnum.SignAndPostTransactions, - ARC0027MessageTypeEnum.Response + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); } /** - * Listens to `sign_transactions` messages sent from providers. This will replace any previous set listeners. If null - * is supplied, the listener will be removed. - * @param {TAVMWebClientListener | null} listener - callback that is called when a response - * message is received, or null to remove the listener. + * Listens to `sign_transactions` messages sent from providers. + * @param {TAVMWebClientCallback | null} callback - callback that is called when a response + * message is received. + * @returns {string} the ID of the listener. */ public onSignTransactions( - listener: TAVMWebClientListener | null - ): void { - const responseReference: string = createMessageReference( + callback: TAVMWebClientCallback + ): string { + return this.addListener( ARC0027MethodEnum.SignTransactions, - ARC0027MessageTypeEnum.Response + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(responseReference); - - return; - } - - this.listeners.set(responseReference, listener); } /** * Request providers to post a list of signed transactions to the network. * @param {IPostTransactionsParams} params - params that specify the provider and the signed transactions. + * @returns {string} the ID of the request message */ - public postTransactions(params: IPostTransactionsParams): void { + public postTransactions(params: IPostTransactionsParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.PostTransactions, params, @@ -363,8 +288,9 @@ export default class AVMWebClient extends BaseController { /** * Sends a list of unsigned transactions to be signed and posted to the network by the provider. * @param {ISignTransactionsParams} params - params that specify the unsigned transactions and the provider. + * @returns {string} the ID of the request message */ - public signAndPostTransactions(params: ISignTransactionsParams): void { + public signAndPostTransactions(params: ISignTransactionsParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.SignAndPostTransactions, params, @@ -374,8 +300,9 @@ export default class AVMWebClient extends BaseController { /** * Sends a list of unsigned transactions to be signed by the provider. * @param {ISignTransactionsParams} params - params that specify the unsigned transactions and the provider. + * @returns {string} the ID of the request message */ - public signTransactions(params: ISignTransactionsParams): void { + public signTransactions(params: ISignTransactionsParams): string { return this.sendRequestMessage({ method: ARC0027MethodEnum.SignTransactions, params, diff --git a/src/controllers/AVMWebProvider.test.ts b/src/controllers/AVMWebProvider.test.ts index 5c338e4..946c6ba 100644 --- a/src/controllers/AVMWebProvider.test.ts +++ b/src/controllers/AVMWebProvider.test.ts @@ -16,13 +16,7 @@ describe(AVMWebProvider.name, () => { let provider: AVMWebProvider; afterEach(() => { - if (client) { - client.stopListening(); - } - - if (provider) { - provider.stopListening(); - } + provider?.removeAllListeners(); }); describe(`${AVMWebProvider.name}#init`, () => { diff --git a/src/controllers/AVMWebProvider.ts b/src/controllers/AVMWebProvider.ts index 9774987..b3248a0 100644 --- a/src/controllers/AVMWebProvider.ts +++ b/src/controllers/AVMWebProvider.ts @@ -31,7 +31,9 @@ import type { ISendResponseMessageOptions, ISignTransactionsParams, ISignTransactionsResult, - TAVMWebProviderListener, + TAVMWebProviderCallback, + TProviderCustomEventListener, + TRequestParams, TResponseResults, } from '@app/types'; @@ -39,131 +41,122 @@ import type { import { createMessageReference } from '@app/utils'; export default class AVMWebProvider extends BaseController { - private readonly listeners: Map; - private constructor(config: IAVMWebProviderConfig) { super(config); - - this.listeners = new Map(); - - // start listening to request messages - this.startListening(); } /** * private methods */ - private async sendResponseMessage({ - method, - listener, - requestMessage, - }: ISendResponseMessageOptions): Promise { - const _functionName: string = 'sendResponseMessage'; - let id: string; - let reference: string; - let result: TResponseResults; - - // if there is no channel, ignore - if (!this.channel) { + private addListener( + method: ARC0027MethodEnum, + callback: TAVMWebProviderCallback + ): string { + const _functionName: string = 'addListener'; + const listener: TProviderCustomEventListener = (event) => { this.logger.debug( - `${AVMWebProvider.name}#${_functionName}: no broadcast channel available, ignoring` + `${AVMWebProvider.name}#${_functionName}: received request event:`, + event.detail ); - return; - } + return this.sendResponseMessage({ + callback, + method, + requestMessage: event.detail as RequestMessage, + }); + }; + const listenerID: string = uuid(); + const reference: string = createMessageReference( + method, + ARC0027MessageTypeEnum.Request + ); + + // start listening to request events and add the listener to the map + window.addEventListener(reference, listener); + this.listeners.set(listenerID, { + listener, + reference, + }); + + return listenerID; + } - id = uuid(); - reference = createMessageReference(method, ARC0027MessageTypeEnum.Response); + private async sendResponseMessage< + Params = TRequestParams, + Result = TResponseResults, + >({ + callback, + method, + requestMessage, + }: ISendResponseMessageOptions): Promise { + const _functionName: string = 'sendResponseMessage'; + const id: string = uuid(); + const reference: string = createMessageReference( + method, + ARC0027MessageTypeEnum.Response + ); + let result: Result; try { - result = await listener({ + result = await callback({ id: requestMessage.id, method, params: requestMessage.params, }); - // post the result message in the broadcast channel - return this.channel.postMessage( - new ResponseMessageWithResult({ - id, - reference, - requestId: requestMessage.id, - result, + // dispatch a response event with the result + window.dispatchEvent( + new CustomEvent>(reference, { + detail: new ResponseMessageWithResult({ + id, + reference, + requestId: requestMessage.id, + result, + }), }) ); + + this.logger.debug( + `${AVMWebProvider.name}#${_functionName}: posted response message "${reference}" with id "${id}"` + ); + + return; } catch (error) { this.logger.error(error); // if we have an arc-0027 error, send it in the response if ((error as BaseARC0027Error).code) { - return this.channel.postMessage( - new ResponseMessageWithError({ - error, - id, - reference, - requestId: requestMessage.id, + window.dispatchEvent( + new CustomEvent(reference, { + detail: new ResponseMessageWithError({ + error, + id, + reference, + requestId: requestMessage.id, + }), }) ); + + return; } // otherwise, wrap the message in an unknown error - return this.channel.postMessage( - new ResponseMessageWithError({ - error: new ARC0027UnknownError({ - message: error.message, - providerId: this.config.providerId, + window.dispatchEvent( + new CustomEvent(reference, { + detail: new ResponseMessageWithError({ + error: new ARC0027UnknownError({ + message: error.message, + providerId: this.config.providerId, + }), + id, + reference, + requestId: requestMessage.id, }), - id, - reference, - requestId: requestMessage.id, }) ); - } - } - - /** - * protected methods - */ - protected async onMessage( - message: MessageEvent - ): Promise { - const listener: TAVMWebProviderListener | null = - this.listeners.get(message.data.reference) || null; - let method: ARC0027MethodEnum | null = null; - - if (listener) { - switch (message.data.reference) { - case `${createMessageReference(ARC0027MethodEnum.Disable, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.Disable; - break; - case `${createMessageReference(ARC0027MethodEnum.Discover, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.Discover; - break; - case `${createMessageReference(ARC0027MethodEnum.Enable, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.Enable; - break; - case `${createMessageReference(ARC0027MethodEnum.PostTransactions, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.PostTransactions; - break; - case `${createMessageReference(ARC0027MethodEnum.SignAndPostTransactions, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.SignAndPostTransactions; - break; - case `${createMessageReference(ARC0027MethodEnum.SignTransactions, ARC0027MessageTypeEnum.Request)}`: - method = ARC0027MethodEnum.SignTransactions; - break; - default: - break; - } - - if (method) { - return await this.sendResponseMessage({ - method, - listener, - requestMessage: message.data, - }); - } + return; } } @@ -186,155 +179,101 @@ export default class AVMWebProvider extends BaseController | null} listener - the listener to call when the - * request message is sent, or null to remove the listener. + * Listens to `disable` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onDisable( - listener: TAVMWebProviderListener | null - ): void { - const requestReference: string = createMessageReference( + callback: TAVMWebProviderCallback + ): string { + return this.addListener( ARC0027MethodEnum.Disable, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } /** - * Listens to `discover` messages sent from clients. This will replace any previous set listeners. If null is - * supplied, the listener will be removed. - * @param {TAVMWebProviderListener | null} listener - the listener to call when the - * request message is sent, or null to remove the listener. + * Listens to `discover` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onDiscover( - listener: TAVMWebProviderListener | null - ): void { - const requestReference: string = createMessageReference( + callback: TAVMWebProviderCallback + ): string { + return this.addListener( ARC0027MethodEnum.Discover, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } /** - * Listens to `enable` messages sent from clients. This will replace any previous set listeners. If null is supplied, - * the listener will be removed. - * @param {TAVMWebProviderListener | null} listener - the listener to call when the - * request message is sent, or null to remove the listener. + * Listens to `enable` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onEnable( - listener: TAVMWebProviderListener | null - ): void { - const requestReference: string = createMessageReference( + callback: TAVMWebProviderCallback + ): string { + return this.addListener( ARC0027MethodEnum.Enable, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } /** - * Listens to `post_transactions` messages sent from clients. This will replace any previous set listeners. If null is - * supplied, the listener will be removed. - * @param {TAVMWebProviderListener | null} listener - the listener - * to call when the request message is sent, or null to remove the listener. + * Listens to `post_transactions` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onPostTransactions( - listener: TAVMWebProviderListener< + callback: TAVMWebProviderCallback< IPostTransactionsParams, IPostTransactionsResult - > | null - ): void { - const requestReference: string = createMessageReference( + > + ): string { + return this.addListener( ARC0027MethodEnum.PostTransactions, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } /** - * Listens to `sign_and_post_transactions` messages sent from clients. This will replace any previous set listeners. - * If null is supplied, the listener will be removed. - * @param {TAVMWebProviderListener | null} listener - the listener - * to call when the request message is sent, or null to remove the listener. + * Listens to `sign_and_post_transactions` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onSignAndPostTransactions( - listener: TAVMWebProviderListener< + callback: TAVMWebProviderCallback< ISignTransactionsParams, IPostTransactionsResult - > | null - ): void { - const requestReference: string = createMessageReference( + > + ): string { + return this.addListener( ARC0027MethodEnum.SignAndPostTransactions, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } /** - * Listens to `sign_transactions` messages sent from clients. This will replace any previous set listeners. If null - * is supplied, the listener will be removed. - * @param {TAVMWebProviderListener | null} listener - the listener - * to call when the request message is sent, or null to remove the listener. + * Listens to `sign_transactions` messages sent from clients. + * @param {TAVMWebProviderCallback} callback - the callback to handle requests from + * the client. + * @returns {string} the ID of the listener. */ public onSignTransactions( - listener: TAVMWebProviderListener< + callback: TAVMWebProviderCallback< ISignTransactionsParams, ISignTransactionsResult - > | null - ): void { - const requestReference: string = createMessageReference( + > + ): string { + return this.addListener( ARC0027MethodEnum.SignTransactions, - ARC0027MessageTypeEnum.Request + callback ); - - // if the listener is null, delete it from the map - if (!listener) { - this.listeners.delete(requestReference); - - return; - } - - this.listeners.set(requestReference, listener); } } diff --git a/src/controllers/BaseController.ts b/src/controllers/BaseController.ts index e676aa7..1983a56 100644 --- a/src/controllers/BaseController.ts +++ b/src/controllers/BaseController.ts @@ -2,27 +2,19 @@ import Logger from './Logger'; // types -import { IBaseConfig } from '@app/types'; - -// utils -import { createChannelName } from '@app/utils'; +import type { IBaseConfig, IListenerItem } from '@app/types'; export default abstract class BaseController { - protected channel: BroadcastChannel | null = null; protected readonly config: Config; + protected readonly listeners: Map; protected logger: Logger; protected constructor(config: Config) { this.config = config; + this.listeners = new Map(); this.logger = new Logger(config.debug ? 'debug' : 'error'); } - /** - * protected abstract methods - */ - - protected abstract onMessage(message: MessageEvent): Promise; - /** * public methods */ @@ -36,26 +28,31 @@ export default abstract class BaseController { } /** - * Starts listening to events. + * Removes all listeners. */ - public startListening(): void { - this.stopListening(); // close any previous channels - - // create a new channel - this.channel = new BroadcastChannel(createChannelName()); - - // start listening to events - this.channel.onmessage = this.onMessage.bind(this); + public removeAllListeners(): void { + // remove all the listeners + this.listeners.forEach(({ listener, reference }) => + window.removeEventListener(reference, listener) + ); + + // clear the map + this.listeners.clear(); } /** - * Stops listening to events. - * - * **NOTE:** this does not clear any event listeners. + * Removes the listener, by the ID. + * @param {string} id - the listener ID to remove. */ - public stopListening(): void { - this.channel && this.channel.close(); + public removeListener(id: string): void { + const item: IListenerItem | null = this.listeners.get(id) || null; + + if (!item) { + return; + } - this.channel = null; + // remove the listener from the dom and the map + window.removeEventListener(item.reference, item.listener); + this.listeners.delete(id); } } diff --git a/src/types/IAVMWebClientListenerOptions.ts b/src/types/IAVMWebClientCallbackOptions.ts similarity index 74% rename from src/types/IAVMWebClientListenerOptions.ts rename to src/types/IAVMWebClientCallbackOptions.ts index 607e30d..40c42c7 100644 --- a/src/types/IAVMWebClientListenerOptions.ts +++ b/src/types/IAVMWebClientCallbackOptions.ts @@ -7,7 +7,7 @@ import { BaseARC0027Error } from '@app/errors'; // types import type TResponseResults from './TResponseResults'; -interface IAVMWebClientListenerOptions { +interface IAVMWebClientCallbackOptions { error: BaseARC0027Error | null; id: string; method: ARC0027MethodEnum; @@ -15,4 +15,4 @@ interface IAVMWebClientListenerOptions { requestId: string; } -export default IAVMWebClientListenerOptions; +export default IAVMWebClientCallbackOptions; diff --git a/src/types/IAVMWebProviderListenerOptions.ts b/src/types/IAVMWebProviderCallbackOptions.ts similarity index 63% rename from src/types/IAVMWebProviderListenerOptions.ts rename to src/types/IAVMWebProviderCallbackOptions.ts index e4acbc6..1cc8285 100644 --- a/src/types/IAVMWebProviderListenerOptions.ts +++ b/src/types/IAVMWebProviderCallbackOptions.ts @@ -4,10 +4,10 @@ import { ARC0027MethodEnum } from '@app/enums'; // types import type TRequestParams from './TRequestParams'; -interface IAVMWebProviderListenerOptions { +interface IAVMWebProviderCallbackOptions { id: string; method: ARC0027MethodEnum; params?: Params; } -export default IAVMWebProviderListenerOptions; +export default IAVMWebProviderCallbackOptions; diff --git a/src/types/IListenerItem.ts b/src/types/IListenerItem.ts new file mode 100644 index 0000000..138b30a --- /dev/null +++ b/src/types/IListenerItem.ts @@ -0,0 +1,10 @@ +// types +import type TClientCustomEventListener from './TClientCustomEventListener'; +import type TProviderCustomEventListener from './TProviderCustomEventListener'; + +interface IListenerItem { + listener: TClientCustomEventListener | TProviderCustomEventListener; + reference: string; +} + +export default IListenerItem; diff --git a/src/types/ISendResponseMessageOptions.ts b/src/types/ISendResponseMessageOptions.ts index db51df4..a0716df 100644 --- a/src/types/ISendResponseMessageOptions.ts +++ b/src/types/ISendResponseMessageOptions.ts @@ -5,13 +5,17 @@ import { ARC0027MethodEnum } from '@app/enums'; import { RequestMessage } from '@app/messages'; // types -import type TAVMWebProviderListener from './TAVMWebProviderListener'; +import type TAVMWebProviderCallback from './TAVMWebProviderCallback'; import type TRequestParams from './TRequestParams'; +import type TResponseResults from './TResponseResults'; -interface ISendResponseMessageOptions { - listener: TAVMWebProviderListener; +interface ISendResponseMessageOptions< + Params = TRequestParams, + Result = TResponseResults, +> { + callback: TAVMWebProviderCallback; method: ARC0027MethodEnum; - requestMessage: RequestMessage; + requestMessage: RequestMessage; } export default ISendResponseMessageOptions; diff --git a/src/types/TAVMWebClientCallback.ts b/src/types/TAVMWebClientCallback.ts new file mode 100644 index 0000000..09e94f0 --- /dev/null +++ b/src/types/TAVMWebClientCallback.ts @@ -0,0 +1,9 @@ +// types +import type IAVMWebClientCallbackOptions from './IAVMWebClientCallbackOptions'; +import type TResponseResults from './TResponseResults'; + +type TAVMWebClientCallback = ( + options: IAVMWebClientCallbackOptions +) => void | Promise; + +export default TAVMWebClientCallback; diff --git a/src/types/TAVMWebClientListener.ts b/src/types/TAVMWebClientListener.ts deleted file mode 100644 index 9d538e9..0000000 --- a/src/types/TAVMWebClientListener.ts +++ /dev/null @@ -1,9 +0,0 @@ -// types -import type IAVMWebClientListenerOptions from './IAVMWebClientListenerOptions'; -import type TResponseResults from './TResponseResults'; - -type TAVMWebClientListener = ( - options: IAVMWebClientListenerOptions -) => void | Promise; - -export default TAVMWebClientListener; diff --git a/src/types/TAVMWebProviderListener.ts b/src/types/TAVMWebProviderCallback.ts similarity index 50% rename from src/types/TAVMWebProviderListener.ts rename to src/types/TAVMWebProviderCallback.ts index 9d71a4c..48c5528 100644 --- a/src/types/TAVMWebProviderListener.ts +++ b/src/types/TAVMWebProviderCallback.ts @@ -1,13 +1,13 @@ // types -import type IAVMWebProviderListenerOptions from './IAVMWebProviderListenerOptions'; +import type IAVMWebProviderCallbackOptions from './IAVMWebProviderCallbackOptions'; import type TRequestParams from './TRequestParams'; import type TResponseResults from './TResponseResults'; -type TAVMWebProviderListener< +type TAVMWebProviderCallback< Params = TRequestParams, Result = TResponseResults, > = ( - options: IAVMWebProviderListenerOptions + options: IAVMWebProviderCallbackOptions ) => Result | Promise; -export default TAVMWebProviderListener; +export default TAVMWebProviderCallback; diff --git a/src/types/TClientCustomEventListener.ts b/src/types/TClientCustomEventListener.ts new file mode 100644 index 0000000..5aae58b --- /dev/null +++ b/src/types/TClientCustomEventListener.ts @@ -0,0 +1,16 @@ +// messages +import { + ResponseMessageWithError, + ResponseMessageWithResult, +} from '@app/messages'; + +// types +import type TResponseResults from './TResponseResults'; + +type TClientCustomEventListener = ( + event: CustomEvent< + ResponseMessageWithError | ResponseMessageWithResult + > +) => Promise | void; + +export default TClientCustomEventListener; diff --git a/src/types/TProviderCustomEventListener.ts b/src/types/TProviderCustomEventListener.ts new file mode 100644 index 0000000..41c15a4 --- /dev/null +++ b/src/types/TProviderCustomEventListener.ts @@ -0,0 +1,11 @@ +// messages +import { RequestMessage } from '@app/messages'; + +// types +import type TRequestParams from './TRequestParams'; + +type TProviderCustomEventListener = ( + event: CustomEvent> +) => Promise | void; + +export default TProviderCustomEventListener; diff --git a/src/types/index.ts b/src/types/index.ts index 5c611d8..9356fd6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,10 +2,10 @@ export type { default as IAccount } from './IAccount'; export type { default as IARC0001Transaction } from './IARC0001Transaction'; export type { default as IAVMWebClientConfig } from './IAVMWebClientConfig'; export type { default as IAVMWebClientInitOptions } from './IAVMWebClientInitOptions'; -export type { default as IAVMWebClientListenerOptions } from './IAVMWebClientListenerOptions'; +export type { default as IAVMWebClientCallbackOptions } from './IAVMWebClientCallbackOptions'; export type { default as IAVMWebProviderConfig } from './IAVMWebProviderConfig'; export type { default as IAVMWebProviderInitOptions } from './IAVMWebProviderInitOptions'; -export type { default as IAVMWebProviderListenerOptions } from './IAVMWebProviderListenerOptions'; +export type { default as IAVMWebProviderCallbackOptions } from './IAVMWebProviderCallbackOptions'; export type { default as IBaseConfig } from './IBaseConfig'; export type { default as IBaseResponseMessage } from './IBaseResponseMessage'; export type { default as IDisableParams } from './IDisableParams'; @@ -15,6 +15,7 @@ export type { default as IDiscoverResult } from './IDiscoverResult'; export type { default as IEnableParams } from './IEnableParams'; export type { default as IEnableResult } from './IEnableResult'; export type { default as INetworkConfiguration } from './INetworkConfiguration'; +export type { default as IListenerItem } from './IListenerItem'; export type { default as IPostTransactionsParams } from './IPostTransactionsParams'; export type { default as IPostTransactionsResult } from './IPostTransactionsResult'; export type { default as IRequestMessage } from './IRequestMessage'; @@ -24,8 +25,10 @@ export type { default as ISendRequestMessageOptions } from './ISendRequestMessag export type { default as ISendResponseMessageOptions } from './ISendResponseMessageOptions'; export type { default as ISignTransactionsParams } from './ISignTransactionsParams'; export type { default as ISignTransactionsResult } from './ISignTransactionsResult'; -export type { default as TAVMWebClientListener } from './TAVMWebClientListener'; -export type { default as TAVMWebProviderListener } from './TAVMWebProviderListener'; +export type { default as TAVMWebClientCallback } from './TAVMWebClientCallback'; +export type { default as TAVMWebProviderCallback } from './TAVMWebProviderCallback'; +export type { default as TClientCustomEventListener } from './TClientCustomEventListener'; +export type { default as TProviderCustomEventListener } from './TProviderCustomEventListener'; export type { default as TLogLevel } from './TLogLevel'; export type { default as TRequestParams } from './TRequestParams'; export type { default as TResponseResults } from './TResponseResults'; diff --git a/src/utils/createChannelName.ts b/src/utils/createChannelName.ts deleted file mode 100644 index 192f3f2..0000000 --- a/src/utils/createChannelName.ts +++ /dev/null @@ -1,11 +0,0 @@ -// constants -import { ARC0027_PREFIX, CHANNEL_NAME_SUFFIX } from '@app/constants'; - -/** - * Convenience function that simply constructs the name of the channel: - * `arc0027:channel` - * @returns {string} the channel name used by the BroadcastChannel API. - */ -export default function createChannelName(): string { - return `${ARC0027_PREFIX}:${CHANNEL_NAME_SUFFIX}`; -} diff --git a/src/utils/index.ts b/src/utils/index.ts index c974934..7213db2 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,2 +1 @@ -export { default as createChannelName } from './createChannelName'; export { default as createMessageReference } from './createMessageReference'; diff --git a/test/setup.ts b/test/setup.ts index 01cd16b..09ffd35 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,7 +1 @@ -import { BroadcastChannel } from 'node:worker_threads'; - -Object.defineProperty(global, 'BroadcastChannel', { - value: BroadcastChannel, -}); - jest.setTimeout(60000);