threshold-network / token-dashboard

22 stars 23 forks source link

Improve tBTC SDK initialization #751

Closed michalsmiarowski closed 2 months ago

michalsmiarowski commented 4 months ago

Closes: #749

Here we use lazy loading for tbtc sdk initialization in our threshold-ts lib. Instead of keeping the sdk object in _sdk property we actually store the promise itself in _sdkPromise property. This promise is set during the construction of the SDK class and is meant to be resolved once the SDK is fully initialized. The promise is used to ensure that the SDK is initialized only once and that all subsequent retrievals of the SDK instance await this promise, thereby ensuring that the SDK is ready for use before any operations are performed.

The promise also facilitates updating the SDK instance dynamically: if a new initialization is triggered (e.g., when a user logs in and provides a new signer), it ensures that the new SDK object replaces any previously pending SDK object, even if the original promise has not yet resolved.

To retrieve the SDK object, use the getSdk() method. This method will either return the already resolved SDK object or wait until the promise resolves before returning the SDK.

Additionally I've changed the getTransactionConfirmations method implementation - it does not have to use SDK. The IsSdkInitializingContext is also not neede anymore so I've removed it completely.

Further explanation of the flow (based on https://github.com/threshold-network/token-dashboard/pull/751#discussion_r1575410420):

  1. Instead of storing sdk object in a property and add some helping variables (like isSdkInitalized) that will tell if the sdk is initialized or not, we now store the promise itself:
  /**
   * Holds the promise for the asynchronously initialized SDK instance.
   * This promise is set during the construction of the SDK class and is meant
   * to be resolved once the SDK is fully initialized. The promise is used to
   * ensure that the SDK is initialized only once and that all subsequent
   * retrievals of the SDK instance await this promise, thereby ensuring that
   * the SDK is ready for use before any operations are performed.
   *
   * The promise also facilitates updating the SDK instance dynamically: if a
   * new initialization is triggered (e.g., when a user logs in and provides a
   * new signer), it ensures that the new SDK object replaces any previously
   * pending SDK object, even if the original promise has not yet resolved.
   *
   * To retrieve the SDK object, use the `getSdk()` method. This method will
   * either return the already resolved SDK object or wait until the promise
   * resolves before returning the SDK.
   */

  private _sdkPromise: Promise<SDK | undefined>
  1. We retrieve the SDK object by using _getSDK method which will wait for the promise mentioned above to be resolved:
private _getSdk = async (): Promise<SDK> => {
    const sdk = await this._sdkPromise
    if (!sdk) throw new EmptySdkObjectError()

    return sdk
  }

So, there are few cases that can happen:

a) User interacts with tbtc contract but the SDK is not initialized yet:

b) User interacts with tbtc contract and SDK is already initialied:

github-actions[bot] commented 4 months ago

Preview uploaded to https://preview.dashboard.test.threshold.network/improve-tbtc-sdk-initialization/index.html.

github-actions[bot] commented 4 months ago

Preview uploaded to https://preview.dashboard.test.threshold.network/improve-tbtc-sdk-initialization/index.html.

github-actions[bot] commented 2 months ago

Preview uploaded to https://preview.dashboard.test.threshold.network/improve-tbtc-sdk-initialization/index.html.