@airgap/beacon-dapp
Version:
Use this package on your dApp to instanciate a DAppClient object and communicate to wallets.
283 lines (282 loc) • 13.1 kB
TypeScript
import { BeaconEvent, BeaconEventHandlerFunction, BeaconEventType } from '../events';
import { AccountInfo, TransportType, BeaconMessageType, RequestPermissionInput, RequestSignPayloadInput, RequestOperationInput, RequestBroadcastInput, PermissionResponseOutput, SignPayloadResponseOutput, OperationResponseOutput, BroadcastResponseOutput, Network, AppMetadata, ExtendedPeerInfo, ColorMode, Blockchain, BlockchainRequestV3, BlockchainResponseV3, PermissionRequestV3, PermissionResponseV3, ProofOfEventChallengeResponse, RequestProofOfEventChallengeInput, PeerInfoType, SimulatedProofOfEventChallengeResponse, RequestSimulatedProofOfEventChallengeInput } from '@airgap/beacon-types';
import { Client, Transport } from '@airgap/beacon-core';
import { BlockExplorer } from '../utils/block-explorer';
import { DAppClientOptions } from './DAppClientOptions';
import { BeaconEventHandler } from '@airgap/beacon-dapp';
import { DappPostMessageTransport } from '../transports/DappPostMessageTransport';
import { DappP2PTransport } from '../transports/DappP2PTransport';
import { DappWalletConnectTransport } from '../transports/DappWalletConnectTransport';
/**
* @publicapi
*
* The DAppClient has to be used in decentralized applications. It handles all the logic related to connecting to beacon-compatible
* wallets and sending requests.
*
* @category DApp
*/
export declare class DAppClient extends Client {
/**
* The description of the app
*/
readonly description?: string;
/**
* The block explorer used by the SDK
*/
readonly blockExplorer: BlockExplorer;
/**
* Automatically switch between apps on Mobile Devices (Enabled by Default)
*/
private enableAppSwitching;
/**
* Enable metrics tracking (Disabled by Default)
*/
private enableMetrics?;
private userId?;
network: Network;
protected readonly events: BeaconEventHandler;
protected postMessageTransport: DappPostMessageTransport | undefined;
protected p2pTransport: DappP2PTransport | undefined;
protected walletConnectTransport: DappWalletConnectTransport | undefined;
protected wcProjectId?: string;
protected wcRelayUrl?: string;
private isGetActiveAccountHandled;
private readonly openRequestsOtherTabs;
/**
* A map of requests that are currently "open", meaning we have sent them to a wallet and are still awaiting a response.
*/
private readonly openRequests;
/**
* The currently active account. For all requests that are associated to a specific request (operation request, signing request),
* the active account is used to determine the network and destination wallet
*/
private _activeAccount;
/**
* The currently active peer. This is used to address a peer in case the active account is not set. (Eg. for permission requests)
*/
private _activePeer;
private _initPromise;
private isInitPending;
private readonly activeAccountLoaded;
private readonly appMetadataManager;
private readonly disclaimerText?;
private readonly errorMessages;
private readonly featuredWallets;
private readonly storageValidator;
private readonly beaconIDB;
private debounceSetActiveAccount;
private multiTabChannel;
constructor(config: DAppClientOptions);
private checkIfBCLeaderExists;
private onElectedLeaderhandler;
private onBCMessageHandler;
private prepareRequest;
private createStateSnapshot;
private initUserID;
initInternalTransports(): Promise<void>;
private initEvents;
private onRelayerError;
private wcToastHandler;
private channelClosedHandler;
/**
* Destroy the instance.
*
* WARNING: Call `destroy` whenever you no longer need dAppClient
* as it frees internal subscriptions to the transport and therefore the instance may no longer work properly.
* If you wish to disconnect your dApp, use `disconnect` instead.
*/
destroy(): Promise<void>;
init(transport?: Transport<any>, substratePairing?: boolean): Promise<TransportType>;
/**
* Returns the active account
*/
getActiveAccount(): Promise<AccountInfo | undefined>;
private isInvalidState;
private resetInvalidState;
/**
* Sets the active account
*
* @param account The account that will be set as the active account
*/
setActiveAccount(account?: AccountInfo): Promise<void>;
/**
* Clear the active account
*/
clearActiveAccount(): Promise<void>;
setColorMode(colorMode: ColorMode): Promise<void>;
getColorMode(): Promise<ColorMode>;
/**
* @deprecated
*
* Use getOwnAppMetadata instead
*/
getAppMetadata(): Promise<AppMetadata>;
showPrepare(): Promise<void>;
hideUI(elements: ('alert' | 'toast')[]): Promise<void>;
private tryToAppSwitch;
private addQueryParam;
private buildPayload;
private updateMetricsStorage;
private sendMetrics;
private checkMakeRequest;
/**
* Will remove the account from the local storage and set a new active account if necessary.
*
* @param accountIdentifier ID of the account
*/
removeAccount(accountIdentifier: string): Promise<void>;
/**
* Remove all accounts and set active account to undefined
*/
removeAllAccounts(): Promise<void>;
/**
* Removes a peer and all the accounts that have been connected through that peer
*
* @param peer Peer to be removed
*/
removePeer(peer: ExtendedPeerInfo, sendDisconnectToPeer?: boolean): Promise<void>;
/**
* Remove all peers and all accounts that have been connected through those peers
*/
removeAllPeers(sendDisconnectToPeers?: boolean): Promise<void>;
/**
* Allows the user to subscribe to specific events that are fired in the SDK
*
* @param internalEvent The event to subscribe to
* @param eventCallback The callback that will be called when the event occurs
*/
subscribeToEvent<K extends BeaconEvent>(internalEvent: K, eventCallback: BeaconEventHandlerFunction<BeaconEventType[K]>): Promise<void>;
/**
* Check if we have permissions to send the specific message type to the active account.
* If no active account is set, only permission requests are allowed.
*
* @param type The type of the message
*/
checkPermissions(type: BeaconMessageType): Promise<boolean>;
sendNotification(title: string, message: string, payload: string, protocolIdentifier: string): Promise<string>;
private blockchains;
addBlockchain(chain: Blockchain): void;
removeBlockchain(chainIdentifier: string): void;
permissionRequest(input: PermissionRequestV3<string>): Promise<PermissionResponseV3<string>>;
request(input: BlockchainRequestV3<string>): Promise<BlockchainResponseV3<string>>;
/**
* Send a permission request to the DApp. This should be done as the first step. The wallet will respond
* with an publicKey and permissions that were given. The account returned will be set as the "activeAccount"
* and will be used for the following requests.
*
* @param input The message details we need to prepare the PermissionRequest message.
*/
requestPermissions(input?: RequestPermissionInput): Promise<PermissionResponseOutput>;
/**
* Send a proof of event request to the wallet. The wallet will either accept or decline the challenge.
* If it is accepted, the challenge will be stored, meaning that even if the user refresh the page, the DAppClient will keep checking if the challenge has been fulfilled.
* Once the challenge is stored, a challenge stored message will be sent to the wallet.
* It's **highly recommended** to run a proof of event challenge to check the identity of an abstracted account
*
* @param input The message details we need to prepare the ProofOfEventChallenge message.
*/
requestProofOfEventChallenge(input: RequestProofOfEventChallengeInput): Promise<ProofOfEventChallengeResponse>;
/**
* Send a simulated proof of event request to the wallet. The wallet will either accept or decline the challenge.
* It's the same than `requestProofOfEventChallenge` but rather than executing operations on the blockchain to prove the identity,
* The wallet will return a list of operations that you'll be able to run on your side to verify the identity of the abstracted account
* It's **highly recommended** to run a proof of event challenge to check the identity of an abstracted account
*
* @param input The message details we need to prepare the SimulatedProofOfEventChallenge message.
*/
requestSimulatedProofOfEventChallenge(input: RequestSimulatedProofOfEventChallengeInput): Promise<SimulatedProofOfEventChallengeResponse>;
/**
* This method will send a "SignPayloadRequest" to the wallet. This method is meant to be used to sign
* arbitrary data (eg. a string). It will return the signature in the format of "edsig..."
*
* @param input The message details we need to prepare the SignPayloadRequest message.
*/
requestSignPayload(input: RequestSignPayloadInput): Promise<SignPayloadResponseOutput>;
/**
* This method will send an "EncryptPayloadRequest" to the wallet. This method is meant to be used to encrypt or decrypt
* arbitrary data (eg. a string). It will return the encrypted or decrypted payload
*
* @param input The message details we need to prepare the EncryptPayloadRequest message.
*/
/**
* This method sends an OperationRequest to the wallet. This method should be used for all kinds of operations,
* eg. transaction or delegation. Not all properties have to be provided. Data like "counter" and fees will be
* fetched and calculated by the wallet (but they can still be provided if required).
*
* @param input The message details we need to prepare the OperationRequest message.
*/
requestOperation(input: RequestOperationInput): Promise<OperationResponseOutput>;
/**
* Sends a "BroadcastRequest" to the wallet. This method can be used to inject an already signed transaction
* to the network.
*
* @param input The message details we need to prepare the BroadcastRequest message.
*/
requestBroadcast(input: RequestBroadcastInput): Promise<BroadcastResponseOutput>;
protected setActivePeer(peer?: PeerInfoType): Promise<void>;
/**
* A "setter" for when the transport needs to be changed.
*/
protected setTransport(transport?: Transport<any>): Promise<void>;
/**
* This method will emit an internal error message.
*
* @param errorMessage The error message to send.
*/
private sendInternalError;
/**
* This method will remove all accounts associated with a specific peer.
*
* @param peersToRemove An array of peers for which accounts should be removed
*/
private removeAccountsForPeers;
private removeAccountsForPeerIds;
/**
* This message handles errors that we receive from the wallet.
*
* @param request The request we sent
* @param beaconError The error we received
*/
private handleRequestError;
/**
* This message will send an event when we receive a successful response to one of the requests we sent.
*
* @param request The request we sent
* @param response The response we received
*/
private notifySuccess;
private getWalletInfoFromStorage;
private updateStorageWallet;
private getWalletInfo;
private getPeer;
/**
* This method handles sending of requests to the DApp. It makes sure that the DAppClient is initialized and connected
* to the transport. After that rate limits and permissions will be checked, an ID is attached and the request is sent
* to the DApp over the transport.
*
* @param requestInput The BeaconMessage to be sent to the wallet
* @param account The account that the message will be sent to
* @param skipResponse If true, the function return as soon as the message is sent
*/
private makeRequest;
/**
* This method handles sending of requests to the DApp. It makes sure that the DAppClient is initialized and connected
* to the transport. After that rate limits and permissions will be checked, an ID is attached and the request is sent
* to the DApp over the transport.
*
* @param requestInput The BeaconMessage to be sent to the wallet
* @param account The account that the message will be sent to
*/
private makeRequestV3;
private makeRequestBC;
disconnect(): Promise<void>;
/**
* Adds a requests to the "openRequests" set so we know what messages have already been answered/handled.
*
* @param id The ID of the message
* @param promise A promise that resolves once the response for that specific message is received
*/
private addOpenRequest;
private sendNotificationWithAccessToken;
private onNewAccount;
}