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
typescriptimport { 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:
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; };
// 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:
// It will trigger `permissionsChanged` event, where `accountInteraction`
// will contain the selected account
await provider.changeAccount();
NOTE:
changeAccount
requiresaccountInteraction
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:
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 returnfalse
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:typescriptThis function will either throw an exception if there are some problems, or wait until the extension/fallback initialization promise is resolved.
await provider.ensureInitialized();
- 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.