@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
157 lines (154 loc) • 5.84 kB
JavaScript
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
import { EIP_5792_METHODS } from '@toruslabs/ethereum-controllers';
import { getAccountsFromNamespaces, parseAccountId } from '@walletconnect/utils';
import { providerErrors, rpcErrors } from '@web3auth/auth';
import { EVM_METHOD_TYPES } from '@web3auth/ws-embed';
import { formatChainId } from './utils.js';
import { WalletLoginError } from '../../base/errors/index.js';
import { log } from '../../base/loglevel.js';
async function getLastActiveSession(signClient) {
if (signClient.session.length) {
const lastKeyIndex = signClient.session.keys.length - 1;
return signClient.session.get(signClient.session.keys[lastKeyIndex]);
}
return null;
}
function isMobileDevice() {
return /Mobi|Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(window.navigator.userAgent);
}
function isSolanaChain(chainId) {
return chainId.startsWith("solana:");
}
async function sendJrpcRequest(signClient, chainId, method, params) {
const session = await getLastActiveSession(signClient);
if (!session) {
throw providerErrors.disconnected();
}
if (typeof window !== "undefined" && isMobileDevice()) {
if (session.peer.metadata.redirect && session.peer.metadata.redirect.native) {
const redirectUrl = session.peer.metadata.redirect.native;
try {
const parsedUrl = new URL(redirectUrl);
if (["javascript:", "data:", "vbscript:"].includes(parsedUrl.protocol)) {
throw new Error("Invalid redirect scheme");
}
window.open(parsedUrl.href, "_blank");
} catch (e) {
log.error("Invalid redirect URL", e);
}
}
}
return signClient.request({
topic: session.topic,
chainId,
request: {
method,
params: isSolanaChain(chainId) ? _objectSpread(_objectSpread({}, params), {}, {
pubkey: session.self.publicKey
}) : params
}
});
}
async function getAccounts(signClient) {
const session = await getLastActiveSession(signClient);
if (!session) {
throw providerErrors.disconnected();
}
const accounts = getAccountsFromNamespaces(session.namespaces);
if (accounts && accounts.length) {
return [...new Set(accounts.map(add => {
return parseAccountId(add).address;
}))];
}
throw WalletLoginError.connectionError("Failed to get accounts");
}
async function getSolanaAccounts(signClient) {
const session = await getLastActiveSession(signClient);
if (!session) {
throw providerErrors.disconnected();
}
const accounts = getAccountsFromNamespaces(session.namespaces);
return [...new Set(accounts.filter(add => add.startsWith("solana:")).map(add => parseAccountId(add).address))];
}
function getEthProviderHandlers({
connector,
chainId
}) {
return {
getPrivateKey: async () => {
throw rpcErrors.methodNotSupported();
},
getPublicKey: async () => {
throw rpcErrors.methodNotSupported();
},
getAccounts: async _ => {
return getAccounts(connector);
},
processTransaction: async (txParams, _) => {
const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, EVM_METHOD_TYPES.ETH_TRANSACTION, [txParams]);
return methodRes;
},
processSignTransaction: async (txParams, _) => {
const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "eth_signTransaction", [txParams]);
return methodRes;
},
processEthSignMessage: async (msgParams, _) => {
const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, EVM_METHOD_TYPES.ETH_SIGN, [msgParams.from, msgParams.data]);
return methodRes;
},
processPersonalMessage: async (msgParams, _) => {
const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, EVM_METHOD_TYPES.PERSONAL_SIGN, [msgParams.data, msgParams.from]);
return methodRes;
},
processTypedMessageV4: async msgParams => {
const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, EVM_METHOD_TYPES.ETH_SIGN_TYPED_DATA_V4, [msgParams.from, msgParams.data]);
return methodRes;
},
// EIP-5792: wallet_getCapabilities
processGetCapabilities: async params => {
const capabilities = await sendJrpcRequest(connector, `eip155:${chainId}`, EIP_5792_METHODS.WALLET_GET_CAPABILITIES, params);
return capabilities;
},
// EIP-5792: wallet_sendCalls
processSendCalls: async params => {
const results = await sendJrpcRequest(connector, `eip155:${chainId}`, EIP_5792_METHODS.WALLET_SEND_CALLS, [params]);
return results;
},
// EIP-5792: wallet_getCallsStatus
processGetCallsStatus: async batchId => {
const results = await sendJrpcRequest(connector, `eip155:${chainId}`, EIP_5792_METHODS.WALLET_GET_CALLS_STATUS, [batchId]);
return results;
},
// EIP-5792: wallet_showCallsStatus
processShowCallsStatus: async batchId => {
await sendJrpcRequest(connector, `eip155:${chainId}`, EIP_5792_METHODS.WALLET_SHOW_CALLS_STATUS, [batchId]);
}
};
}
async function switchChain({
connector,
chainId,
newChainId
}) {
await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_switchEthereumChain", [{
chainId: newChainId
}]);
}
async function addChain({
connector,
chainId,
chainConfig
}) {
if (!chainConfig) {
throw providerErrors.custom({
message: "Chain config is required",
code: 4902
});
}
const formattedChainId = formatChainId(chainConfig.chainId);
const formattedChainConfig = _objectSpread(_objectSpread({}, chainConfig), {}, {
chainId: formattedChainId
});
await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_addEthereumChain", [formattedChainConfig]);
}
export { addChain, getAccounts, getEthProviderHandlers, getSolanaAccounts, sendJrpcRequest, switchChain };