@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
JavaScript
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
;