UNPKG

@thirdweb-dev/wallets

Version:

<p align="center"> <br /> <a href="https://thirdweb.com"><img src="https://github.com/thirdweb-dev/js/blob/main/legacy_packages/sdk/logo.svg?raw=true" width="200" alt=""/></a> <br /> </p> <h1 align="center">thirdweb Wallet SDK</h1> <p align="center"> <a h

294 lines (283 loc) • 7.72 kB
import { _ as _defineProperty } from '../../../../dist/defineProperty-350fc508.browser.esm.js'; import { Contract, utils } from 'ethers'; import EventEmitter from 'eventemitter3'; import { isNativeToken, fetchCurrencyValue, normalizePriceValue, getDefaultGasOverrides, NATIVE_TOKEN_ADDRESS } from '@thirdweb-dev/sdk'; const ERC20WithDecimalsAbi = [{ anonymous: false, inputs: [{ indexed: true, internalType: "address", name: "owner", type: "address" }, { indexed: true, internalType: "address", name: "spender", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }], name: "Approval", type: "event" }, { anonymous: false, inputs: [{ indexed: true, internalType: "address", name: "from", type: "address" }, { indexed: true, internalType: "address", name: "to", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }], name: "Transfer", type: "event" }, { inputs: [{ internalType: "address", name: "owner", type: "address" }, { internalType: "address", name: "spender", type: "address" }], name: "allowance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "spender", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }], name: "approve", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "who", type: "address" }], name: "balanceOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "totalSupply", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }], name: "transfer", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "from", type: "address" }, { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }], name: "transferFrom", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "decimals", outputs: [{ internalType: "uint8", name: "", type: "uint8" }], stateMutability: "view", type: "function" }]; function createErc20(provider, currencyAddress) { return new Contract(currencyAddress, ERC20WithDecimalsAbi, provider); } // TODO improve this function chainIdToThirdwebRpc(chainId, clientId) { return `https://${chainId}.rpc.thirdweb.com${clientId ? `/${clientId}` : ""}${typeof globalThis !== "undefined" && "APP_BUNDLE_ID" in globalThis && !!globalThis.APP_BUNDLE_ID ? `?bundleId=${globalThis.APP_BUNDLE_ID}` : ""}`; } /** * The base class for any wallet in the Wallet SDK, including backend wallets. It contains the functionality common to all wallets. * * This wallet is not meant to be used directly, but instead be extended to [build your own wallet](https://portal.thirdweb.com/wallet-sdk/v2/build) * * @abstractWallet */ class AbstractWallet extends EventEmitter { constructor() { super(...arguments); /** * @internal */ _defineProperty(this, "type", "evm"); } /** * Returns an [ethers Signer](https://docs.ethers.org/v5/api/signer/) object of the connected wallet */ /** * Returns the account address of the connected wallet */ async getAddress() { const signer = await this.getSigner(); return signer.getAddress(); } /** * Returns the balance of the connected wallet for the specified token address. If no token address is specified, it returns the balance of the native token * * @param tokenAddress - The contract address of the token */ async getBalance() { let tokenAddress = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : NATIVE_TOKEN_ADDRESS; const signer = await this.getSigner(); const address = await this.getAddress(); if (!signer.provider) { throw new Error("Please connect a provider"); } let balance; if (isNativeToken(tokenAddress)) { balance = await signer.provider.getBalance(address); } else { const erc20 = createErc20(signer, tokenAddress); balance = await erc20.balanceOf(address); } // Note: assumes that the native currency decimals is 18, which isn't always correct return await fetchCurrencyValue(signer.provider, tokenAddress, balance); } /** * Returns the chain id of the network that the wallet is connected to */ async getChainId() { const signer = await this.getSigner(); return signer.getChainId(); } /** * Transfers some amount of tokens to the specified address * @param to - The address to transfer the amount to * @param amount - The amount to transfer * @param currencyAddress - The contract address of the token to transfer. If not specified, it defaults to the native token * @returns The transaction result */ async transfer(to, amount) { let currencyAddress = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NATIVE_TOKEN_ADDRESS; const signer = await this.getSigner(); const from = await this.getAddress(); if (!signer.provider) { throw new Error("Please connect a provider"); } const value = await normalizePriceValue(signer.provider, amount, currencyAddress); if (isNativeToken(currencyAddress)) { const gas = getDefaultGasOverrides(signer.provider); const tx = await signer.sendTransaction({ from, to, value, ...gas }); return { receipt: await tx.wait() }; } else { const erc20 = createErc20(signer, currencyAddress); const tx = await erc20.transfer(to, value); return { receipt: await tx.wait() }; } } /** * Sign a message with the connected wallet and return the signature * @param message - The message to sign * @returns - The signature */ async signMessage(message) { const signer = await this.getSigner(); return await signer.signMessage(message); } /** * Verify the signature of a message. It returns `true` if the signature is valid, `false` otherwise * @param message - The message to verify * @param signature - The signature to verify * @param address - The address to verify the signature against * @param chainId - The chain id of the network to verify the signature against, If not specified, it defaults to 1 ( Ethereum mainnet ) */ async verifySignature(message, signature, address, // eslint-disable-next-line @typescript-eslint/no-unused-vars _chainId) { try { const messageHash = utils.hashMessage(message); const messageHashBytes = utils.arrayify(messageHash); const recoveredAddress = utils.recoverAddress(messageHashBytes, signature); if (recoveredAddress === address) { return true; } } catch { // no-op } return false; } } export { AbstractWallet, chainIdToThirdwebRpc };