``` /** * Detection and global state for sporran wallet * * Detect wallet in a component's mounted() and updated() hooks with: this.$wallet.checkForExtension() * * Use the wallet with: this.$wallet.getInstance() */ import Vue from "vue"; // import { DidPublicKey, IEncryptedMessage } from '@kiltprotocol/sdk-js' function walletSetup() { let instance = null; // #region helpers /** * Helpers for getting extension object from window * * @docs https://hackmd.io/@dTGKTsAWSxi6eYV5aeFnXA/ryH5JVCd5 */ const apiWindow = window; /** * @param {() => Promise<T>} creator * @returns {Promise<T>} */ function documentReadyPromise(creator) { return new Promise((resolve) => { if (document.readyState === "complete") { resolve(creator()); } else { window.addEventListener("load", () => resolve(creator())); } }); } /** * @returns {Promise<[{ name?: string; signWithDid: ( plaintext: string ) => Promise<{ signature: string; didKeyUri: string }>; startSession: ( dAppName: string, dAppEncryptionKeyId: DidPublicKey['id'], challenge: string ) => Promise<{ listen: ( callback: (message: IEncryptedMessage) => Promise<void> ) => Promise<void>; close: () => Promise<void>; send: (message: IEncryptedMessage) => Promise<void>; encryptionKeyId: DidPublicKey['id']; encryptedChallenge: string; nonce: string; }>; specVersion: '0.1'; version: string; }][]>} */ function getWindowExtensions() { return Promise.all( Object.entries(apiWindow.kilt).map( ([name, { version, signWithDid, startSession, specVersion }]) => Promise.all([ Promise.resolve({ name, version, signWithDid, startSession, specVersion, }), ]) ) ); } /** * @returns {Promise<{ name?: string; signWithDid: ( plaintext: string ) => Promise<{ signature: string; didKeyUri: string }>; startSession: ( dAppName: string, dAppEncryptionKeyId: DidPublicKey['id'], challenge: string ) => Promise<{ listen: ( callback: (message: IEncryptedMessage) => Promise<void> ) => Promise<void>; close: () => Promise<void>; send: (message: IEncryptedMessage) => Promise<void>; encryptionKeyId: DidPublicKey['id']; encryptedChallenge: string; nonce: string; }>; specVersion: '0.1'; version: string; }[]>}} */ function getExtensions() { apiWindow.kilt = apiWindow.kilt || {}; return documentReadyPromise(() => getWindowExtensions() .then((values) => values.filter((value) => !!value[0]).map(([info]) => info) ) .catch(() => []) .then((values) => values) ); } // #endregion async function checkForExtension() { const allInjected = await getExtensions(); if (Array.isArray(allInjected) && allInjected.length) { allInjected.forEach((x) => { if (x.name === "sporran") { instance = x; } }); } } function getInstance() { return instance; } return { checkForExtension, getInstance, }; } export default function (app) { Vue.prototype.$wallet = walletSetup(); } ```