@eversurf/surfkeeper-provider
Version:
Provider interface for Surf Keeper extension of the Everscale blockchain
201 lines (200 loc) • 6.78 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProviderRpcClient = exports.ProviderNotInitializedException = exports.ProviderNotFoundException = exports.hasSurfKeeperProvider = void 0;
const api_1 = require("./api");
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
const getProvider = () => (isBrowser ? window.surfkeeper : undefined);
let isPageLoaded;
if (!isBrowser || window.document.readyState === 'complete') {
isPageLoaded = Promise.resolve();
}
else {
isPageLoaded = new Promise(resolve => {
const loadEventListener = () => {
// Resolve
resolve();
// Stop listening to the event
window.removeEventListener('load', loadEventListener);
};
window.addEventListener('load', loadEventListener);
});
}
async function hasSurfKeeperProvider() {
if (!isBrowser) {
return false;
}
await isPageLoaded;
return Boolean(window.surfkeeper);
}
exports.hasSurfKeeperProvider = hasSurfKeeperProvider;
class ProviderNotFoundException extends Error {
constructor() {
super('surfkeeper provider was not found');
}
}
exports.ProviderNotFoundException = ProviderNotFoundException;
class ProviderNotInitializedException extends Error {
constructor() {
super('surfkeeper provider was not initialized yet');
}
}
exports.ProviderNotInitializedException = ProviderNotInitializedException;
class ProviderRpcClient {
constructor(network, properties = {}) {
this._network = api_1.ProviderNetwork.everscale;
this._network = network;
this._properties = properties;
// Wrap provider requests
this._api = new Proxy({}, {
get: (_object, method) => (params) => {
if (this._provider != null && this._provider[network] != null) {
return this._provider[network].request({ method, params });
}
else {
throw new ProviderNotInitializedException();
}
},
});
// Wrap provider subscriptions
this._subscribe = new Proxy({}, {
get: (_object) => (params) => {
if (this._provider != null && this._provider[network] != null) {
return this._provider[network].subscribe(params);
}
else {
throw new ProviderNotInitializedException();
}
},
});
if (properties.forceUseFallback === true) {
this._initializationPromise =
properties.fallback != null
? properties.fallback().then(provider => {
this._provider = provider;
})
: Promise.resolve();
}
else {
// Initialize provider with injected object by default
this._provider = getProvider();
if (this._provider != null) {
// Provider is already injected
this._initializationPromise = Promise.resolve();
}
else {
// Wait until page is loaded and initialization complete
this._initializationPromise = hasSurfKeeperProvider()
.then(hasProvider => new Promise((resolve, reject) => {
if (!hasProvider) {
// Fully loaded page doesn't even contain provider flag
return reject('surfkeeper initializations unfortunately went rogue. Please let us know about the details.');
}
// Wait injected provider initialization otherwise
this._provider = getProvider();
if (this._provider != null) {
resolve();
}
else {
reject('surfkeeper initializations unfortunately went rogue. Please let us know about the details.');
}
}))
.then(async () => {
if (this._provider == null && properties.fallback != null) {
this._provider = await properties.fallback();
}
});
}
}
}
/**
* Checks whether this page has injected surfkeeper provider or
* there is a fallback provider.
*/
async hasProvider() {
if (this._properties.fallback != null) {
return true;
}
return hasSurfKeeperProvider();
}
/**
* Waits until provider api will be available. Calls `fallback` if no provider was found
*
* @throws ProviderNotFoundException when no provider found
*/
async ensureInitialized() {
await this._initializationPromise;
if (this._provider == null) {
throw new ProviderNotFoundException();
}
}
/**
* Whether provider api is ready
*/
get isInitialized() {
return this._provider != null;
}
/**
* Raw provider
*/
get getProvider() {
if (this._provider != null) {
return this._provider;
}
else {
throw new ProviderNotInitializedException();
}
}
/**
* Connect extension.
* Shows an approval window to the user.
*/
async connect() {
await this.ensureInitialized();
return await this._provider.connect();
}
/**
* Get connection status.
*/
async connectStatus() {
await this.ensureInitialized();
return await this._provider.checkConnection();
}
/**
* Disconnect extension.
*/
async disconnect() {
await this.ensureInitialized();
return await this._provider.disconnect();
}
/**
* Subscribes on the event and listens to the updates.
*/
subscribe(args) {
return this._subscribe.subscribe(args);
}
/**
* Signs arbitrary data.
* Shows an approval window to the user.
*/
async signData(args) {
await this.ensureInitialized();
return this._api.signData(args);
}
/**
* Sends an internal message from the user account.
* Shows an approval window to the user.
*/
async sendMessage(args) {
await this.ensureInitialized();
return this._api.sendMessage(args);
}
/**
* Sends transaction with provided params.
* Shows an approval window to the user.
*/
async sendTransaction(args) {
await this.ensureInitialized();
return this._api.sendTransaction(args);
}
}
exports.ProviderRpcClient = ProviderRpcClient;