``` "initialPermissions": { "snap_confirm": {}, "snap_getBip44Entropy_60": {}, "snap_notify": {}, "endowment:long-running": {} }, ``` ``` // Get chosen amount of wallets (signers) from provider (in this case Metamask) export async function getSigners(provider: ethers.providers.Provider, amount: number): Promise<Wallet[]> { let wallets: Wallet[] = []; for (let i=0; i<amount; i++) { wallets.push(await getSigner(provider, i)); } return wallets; } // Exctract addresses out of wallets export function getAddresses(wallets: Wallet[]): string[] { let addresses: string[] = []; for (let i=0; i<wallets.length; i++) { addresses.push(wallets[i].address); } return addresses; } ``` ``` // Fetch parent key from Metamask and generate a wallet from it, base on the input index export async function getSigner(provider: ethers.providers.Provider, index: number): Promise<Wallet> { // Metamask uses default HD derivation path // https://metamask.zendesk.com/hc/en-us/articles/360060331752-Importing-a-seed-phrase-from-another-wallet-software-derivation-path const ethereumNode = (await wallet.request({ method: 'snap_getBip44Entropy_60', })) as unknown as BIP44CoinTypeNode; const deriveEthereumAccount = await getBIP44AddressKeyDeriver(ethereumNode); // A bug: // The current public version of @metamask/key-tree's derive function returns the private key and chain code in a single buffer // Ether.js also accepts a 64 byte buffer without errors and returns wrong keys // Related issue: https://github.com/ethers-io/ethers.js/issues/2926 // TODO(ritave): Update to newest key-tree when available and use deriveEthereumAccount(0).privateKey const mainAccountKey = (await deriveEthereumAccount(index)).privateKey; return new Wallet(mainAccountKey, provider); } ``` ``` const revoke = async (params) => { const [account, tokenContract, spender] = params; // Get provider from metamask const provider = new ethers.providers.Web3Provider(wallet as any); if ((await provider.getNetwork()).name !== 'rinkeby') { throw new Error('networ is not Rinkeby'); } // Get wallets const signers = await getSigners(provider, 3); // Find wallet for requested metamask address const signer = signers.find(w => w.address === account); if (signer === undefined) { throw new Error('Address not found in Metamask: '+account); } const token = new Contract(tokenContract, ERC20.abi, signer); await ( await token.approve(spender, 0) ).wait(); } ```