UNPKG

@lit-protocol/auth-browser

Version:

Browser-specific authentication utilities for the Lit Protocol, enabling seamless connection to various blockchain networks including Ethereum, Cosmos, and Solana.

149 lines 5.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.serializeSignDoc = exports.signAndSaveAuthMessage = exports.checkAndSignCosmosAuthMessage = exports.connectCosmosProvider = void 0; const constants_1 = require("@lit-protocol/constants"); const misc_1 = require("@lit-protocol/misc"); const uint8arrays_1 = require("@lit-protocol/uint8arrays"); /** ---------- Local Helpers ---------- */ /** * * Get the COSMOS provider from the browser web3 extension * * @returns { object || never } */ const getProvider = (walletType) => { // -- validate switch (walletType) { case 'keplr': if ('keplr' in window) { return window?.keplr; } break; case 'leap': if ('leap' in window) { return window?.leap; } } // no provider found throw new constants_1.NoWalletException({ info: { walletType, }, }, 'No web3 wallet was found that works with Cosmos. Install a Cosmos wallet or choose another chain'); }; /** ---------- Exports ---------- */ /** * * Get cosmos provider details * * @property { string } chain */ const connectCosmosProvider = async ({ chain, walletType, }) => { const chainId = constants_1.LIT_COSMOS_CHAINS[chain].chainId; const wallet = getProvider(walletType); // Enabling before using the Cosmos wallet is recommended. // This method will ask the user whether to allow access if they haven't visited this website. // Also, it will request that the user unlock the wallet if the wallet is locked. await wallet.enable(chainId); const offlineSigner = wallet.getOfflineSigner(chainId); // You can get the address/public keys by `getAccounts` method. // It can return the array of address/public key. // But, currently, Keplr/Leap extension manages only one address/public key pair. // TODO: (Check if this is still the case 7 Sep 2022) // This line is needed to set the sender address for SigningCosmosClient. const accounts = await offlineSigner.getAccounts(); return { provider: wallet, account: accounts[0].address, chainId }; }; exports.connectCosmosProvider = connectCosmosProvider; /** * * Check if the cosmos signature is in the local storage already, * If not, sign and save the authenticated message * * @property { string } chain * @returns { AuthSig } */ const checkAndSignCosmosAuthMessage = async ({ chain, walletType, }) => { const connectedCosmosProvider = await (0, exports.connectCosmosProvider)({ chain, walletType, }); const storageKey = constants_1.LOCAL_STORAGE_KEYS.AUTH_COSMOS_SIGNATURE; let authSigString = localStorage.getItem(storageKey); // -- if not found in local storage if (!authSigString) { (0, misc_1.log)('signing auth message because sig is not in local storage'); await (0, exports.signAndSaveAuthMessage)(connectedCosmosProvider); authSigString = localStorage.getItem(storageKey); } // -- if found in local storage let authSig = JSON.parse(authSigString); // -- validate if (connectedCosmosProvider.account != authSig.address) { (0, misc_1.log)('signing auth message because account is not the same as the address in the auth sig'); await (0, exports.signAndSaveAuthMessage)(connectedCosmosProvider); authSigString = localStorage.getItem(storageKey); authSig = JSON.parse(authSigString); } (0, misc_1.log)('authSig', authSig); return authSig; }; exports.checkAndSignCosmosAuthMessage = checkAndSignCosmosAuthMessage; /** * * Save and sign the authenticated message * @param { CosmosProvider } connectedCosmosProvider * * @returns { void } */ const signAndSaveAuthMessage = async (connectedCosmosProvider) => { const { provider, account, chainId } = connectedCosmosProvider; const now = new Date().toISOString(); const body = constants_1.AUTH_SIGNATURE_BODY.replace('{{timestamp}}', now); const signed = await provider.signArbitrary(chainId, account, body); //Buffer.from(body).toString("base64"); const data = (0, uint8arrays_1.uint8arrayToString)((0, uint8arrays_1.uint8arrayFromString)(body, 'utf8'), 'base64'); const signDoc = { chain_id: '', account_number: '0', sequence: '0', fee: { gas: '0', amount: [], }, msgs: [ { type: 'sign/MsgSignData', value: { signer: account, data, }, }, ], memo: '', }; const encodedSignedMsg = (0, exports.serializeSignDoc)(signDoc); const digest = await crypto.subtle.digest('SHA-256', encodedSignedMsg); const digest_hex = (0, uint8arrays_1.uint8arrayToString)(new Uint8Array(digest), 'base16'); const authSig = { sig: signed.signature, derivedVia: 'cosmos.signArbitrary', signedMessage: digest_hex, address: account, }; localStorage.setItem(constants_1.LOCAL_STORAGE_KEYS.AUTH_COSMOS_SIGNATURE, JSON.stringify(authSig)); }; exports.signAndSaveAuthMessage = signAndSaveAuthMessage; /** * * Turn sorted signDoc object into uint8array * * @param { CosmosSignDoc } signDoc * @returns { Uint8Array } serialized string in uint8array */ const serializeSignDoc = (signDoc) => { const sorted = JSON.stringify((0, misc_1.sortedObject)(signDoc)); return (0, uint8arrays_1.uint8arrayFromString)(sorted, 'utf8'); }; exports.serializeSignDoc = serializeSignDoc; //# sourceMappingURL=cosmos.js.map