Skip to content
On this page

Installation & Setup

Basic Setup

Depending on your use case, you can use different kinds of providers:

  • Extension only:

    This default usage pattern requires injected provider object. This means extension must be installed or website is opened inside some webview with prepared runtime. Library will wait until this object is ready and will not require any other assets to load.

    > npm install --save everscale-inpage-provider
    typescript
    import { ProviderRpcClient } from 'everscale-inpage-provider';
    
    const ever = new ProviderRpcClient();
  • With everscale-standalone-client:

    In case your app doesn't require user interaction, it can use some kind of fallback provider. Depending on forceUseFallback parameter it will either always use fallback or only when injected rpc object was not found.

    For more information on setting up and using the Everscale Standalone Client, please refer to the Standalone Client Guide.

Right after provider is initialized its state can be retrieved:

typescript
const currentProviderState = await provider.getProviderState();

You need to install an extension to be able to play with the demos.

Permissions

Each RPC method requires some set of permissions to be executed. Therefore, the website must request a required subset of them to be able to execute these methods. Each permission can have some data assigned to it.

At the moment there are only two permissions:

  • basic - needed for all simple methods like calculating account address or getting transactions. This permission doesn't have any data assigned to it.
  • accountInteraction - any request which requires user interaction (e.g. through popup) requires this permission.
    typescript
    // Assigned data:
    type AccountInteractionData = {
      // Address of the selected wallet
      address: Address;
      // Preferred public key (usually a public key from the selected wallet)
      publicKey: string;
      // Hint about wallet contract type
      contractType: WalletContractType;
    };
typescript
// You can subscribe to permission changes in one place
(await provider.subscribe('permissionsChanged')).on(
  'data',
  permissions => {
    // You can update component state here
    console.log(permissions);
  },
);

// NOTE: subscription object can be used during the disposal:
//   const subscription = await provider.subscribe('permissionsChanged');
//   subscription.on('data', data => { ... });
//   ...
//   await subscription.unsubscribe();

// Request all permissions
const permissions = await provider.requestPermissions({
  permissions: ['basic', 'accountInteraction'],
});

// ...

// Log out and disable all permissions
await provider.disconnect();

INFO

You don't need to request permissions while using standalone client with NodeJS. requestPermissions will not give errors, but it will not do anything either.

NOTE: You can check current provider state using getProviderState demo.

Changing account

Quite often there may be a situation in which the user works with your app through several accounts. In order to change your account, you can either simply log out and log in, but then all subscriptions will be reset. Therefore, to change the account there is a separate method that is preferable to use:

typescript
// It will trigger `permissionsChanged` event, where `accountInteraction`
// will contain the selected account
await provider.changeAccount();

NOTE: changeAccount requires accountInteraction permissions

Detecting Provider

To determine whether your browser has an Provider, you can use the hasEverscaleProvider() function. Here's an example of how to use it:

typescript
import { hasEverscaleProvider } from 'everscale-inpage-provider';

const hasProvider = await hasEverscaleProvider();
if (hasProvider) {
  console.log('Provider is detected');
} else {
  console.log('Provider is not detected');
}

Additional notes:

  • hasEverscaleProvider() will always return false in Web Workers or NodeJS environment. Otherwise, it will wait until the page is loaded and check whether the RPC object is injected.
  • You can explicitly wait until the provider is fully initialized using:
    typescript
    await provider.ensureInitialized();
    This function will either throw an exception if there are some problems, or wait until the extension/fallback initialization promise is resolved.
  • There are several lifecycle events to provide better error messages or state info:
    • connected - Called every time when provider connection is established.
    • disconnected - Called when inpage provider disconnects from extension.
    • networkChanged - Called each time the user changes network.
    • permissionsChanged - Called when permissions are changed.
    • loggedOut - Called when the user logs out of the extension (completely).

What's next?

At this point, you should have understood roughly the basic structure of a provider. However, we have not yet interacted with the blockchain in any way! Let's fix it in the next sections, in which we will cover all popular use cases.