UNPKG

@creit.tech/stellar-wallets-kit

Version:
228 lines (225 loc) 8.25 kB
import { store, setNetwork, setModalTheme, seButtonTheme, setAllowedWallets, setSelectedModuleId, setAddress, removeAddress, setHorizonUrl } from './state/store.mjs'; class StellarWalletsKit { get selectedModule() { const target = this.modules.find( (mod) => mod.productId === store.getValue().selectedModuleId ); if (!target) { throw { code: -3, message: "Please set the wallet first" }; } return target; } constructor(params) { this.modules = params.modules; this.setWallet(params.selectedWalletId); setNetwork(params.network); const modalTheme = params.theme || params.modalTheme; if (modalTheme) { setModalTheme(modalTheme); } if (params.buttonTheme) { seButtonTheme(params.buttonTheme); } this.getSupportedWallets().then((value) => { setAllowedWallets(value); }); } /** * This method will return an array with all wallets supported by this kit but will let you know those the user have already installed/has access to * There are wallets that are by default available since they either don't need to be installed or have a fallback */ async getSupportedWallets() { return Promise.all( this.modules.map(async (mod) => { const timer = new Promise((r) => setTimeout(() => r(false), 500)); return { id: mod.productId, name: mod.productName, type: mod.moduleType, icon: mod.productIcon, isAvailable: await Promise.race([timer, mod.isAvailable()]), url: mod.productUrl }; }) ); } setWallet(id) { const target = this.modules.find( (mod) => mod.productId === id ); if (!target) { throw new Error(`Wallet id "${id}" is not supported`); } setSelectedModuleId(target.productId); } async getAddress(params) { const { address } = await this.selectedModule.getAddress(params); setAddress(address); return { address }; } async signTransaction(xdr, opts) { return this.selectedModule.signTransaction(xdr, { ...opts, networkPassphrase: opts?.networkPassphrase || store.getValue().selectedNetwork }); } async signAuthEntry(authEntry, opts) { return this.selectedModule.signAuthEntry(authEntry, { ...opts, networkPassphrase: opts?.networkPassphrase || store.getValue().selectedNetwork }); } async signMessage(message, opts) { return this.selectedModule.signMessage(message, { ...opts, networkPassphrase: opts?.networkPassphrase || store.getValue().selectedNetwork }); } async getNetwork() { return this.selectedModule.getNetwork(); } async disconnect() { removeAddress(); } // ---- Button methods isButtonCreated() { return !!this.buttonElement; } /** * This method allows developers to set their own buttons (for connection and disconnection) on their website * while letting the kit handle the logic behind opening the modal, setting and removing the address from the storage, etc */ assignButtons(params) { const connectEl = typeof params.connectEl === "string" ? document.querySelector(params.connectEl) : params.connectEl; if (!connectEl) throw new Error("connectEl is not available"); connectEl.addEventListener( "click", () => { this.openModal({ onWalletSelected: (option) => { setSelectedModuleId(option.id); this.getAddress().then((r) => params.onConnect(r)); } }).then(); }, false ); if (!params.disconnectEl) return; const disconnectEl = typeof params.disconnectEl === "string" ? document.querySelector(params.disconnectEl) : params.disconnectEl; if (!disconnectEl) throw new Error("disconnectEl is not available"); disconnectEl.addEventListener( "click", () => { params.onDisconnect(); removeAddress(); if (this.selectedModule.disconnect) { this.selectedModule.disconnect().then(); } }, false ); } /** * * @param params {Object} * @param params.container {HTMLElement} - The container where the button should be rendered. * @param params.onConnect {Function} - This callback is called after the user has clicked the button and selected a wallet * @param params.onClosed {Function} - This callback is called if the user closes the modal without selecting any wallet. * @param params.onError {Function} - This callback is called if there is an error while trying to get the address once the user has selected the wallet from the modal. * @param params.onDisconnect {Function} - This callback is called once the user disconnects from the dropdown modal * @param params.horizonUrl {String} - If this url is set, the dropdown modal will show the current XLM balance of the address fetched from the wallet * @param params.buttonText {String} - A custom text to set inside the button. */ async createButton(params) { if (this.buttonElement) { throw new Error(`Stellar Wallets Kit button is already created`); } this.buttonElement = document.createElement("stellar-wallets-button"); if (params.buttonText) { this.buttonElement.setAttribute("buttonText", params.buttonText); } if (params.horizonUrl) { setHorizonUrl(params.horizonUrl); } params.container.appendChild(this.buttonElement); this.buttonElement.addEventListener( "button-clicked", () => { this.openModal({ onWalletSelected: (option) => { setSelectedModuleId(option.id); this.getAddress().then((r) => params.onConnect(r)).catch((err) => { if (params.onError) params.onError(err); }); }, onClosed: (err) => { if (params.onClosed) params.onClosed(err); } }); }, false ); this.buttonElement.addEventListener( "disconnect-wallet", () => { params.onDisconnect(); if (this.selectedModule.disconnect) { this.selectedModule.disconnect(); } }, false ); } /** * Removes the button elements from the HTML and from the kit's instance. * * @param params.skipDisconnect - Set this to `true` if you want to prevent that we disconnect (for example, disconnecting WalletConnect or removing the address) */ async removeButton(params) { if (!this.buttonElement) { throw new Error(`Stellar Wallets Kit button hasn't been created yet`); } if (params?.skipDisconnect !== true) { this.buttonElement.disconnect(); } this.buttonElement.remove(); delete this.buttonElement; } // ---- END Button methods // ---- Modal methods async openModal(params) { if (this.modalElement && !this.buttonElement) { throw new Error(`Stellar Wallets Kit modal is already open`); } else { this.modalElement = document.createElement("stellar-wallets-modal"); } this.modalElement.setAttribute("showModal", ""); if (params.modalTitle) { this.modalElement.setAttribute("modalTitle", params.modalTitle); } if (params.notAvailableText) { this.modalElement.setAttribute("notAvailableText", params.notAvailableText); } document.body.appendChild(this.modalElement); const listener = (event) => { params.onWalletSelected(event.detail); this.modalElement.removeEventListener("wallet-selected", listener, false); document.body.removeChild(this.modalElement); this.modalElement = void 0; }; this.modalElement.addEventListener("wallet-selected", listener, false); const errorListener = (event) => { if (params.onClosed) { params.onClosed(event.detail); } this.modalElement.removeEventListener("wallet-selected", listener, false); this.modalElement.removeEventListener("modal-closed", errorListener, false); document.body.removeChild(this.modalElement); this.modalElement = void 0; }; this.modalElement.addEventListener("modal-closed", errorListener, false); } // ---- END Modal methods } export { StellarWalletsKit }; //# sourceMappingURL=stellar-wallets-kit.mjs.map