diff --git a/examples/xnft/mnemonic-printer/package.json b/examples/xnft/mnemonic-printer/package.json new file mode 100644 index 0000000000..f9abdc3498 --- /dev/null +++ b/examples/xnft/mnemonic-printer/package.json @@ -0,0 +1,27 @@ +{ + "name": "mnemonic-printer", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "xnft legacy build", + "start": "xnft legacy start", + "dev": "xnft legacy dev" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@coral-xyz/xnft-cli": "0.2.0-latest.3331", + "@types/d3": "^7.4.0", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "debounce": "^1.2.1", + "micro-ed25519-hdkey": "^0.1.2", + "react": "18.2.0", + "react-xnft": "0.2.0-latest.3318", + "recoil": "^0.7.6", + "reselect": "^4.1.6", + "superstruct": "^0.16.5", + "swr": "^1.3.0" + } +} diff --git a/examples/xnft/mnemonic-printer/src/App/App.tsx b/examples/xnft/mnemonic-printer/src/App/App.tsx new file mode 100644 index 0000000000..e2b778d2a8 --- /dev/null +++ b/examples/xnft/mnemonic-printer/src/App/App.tsx @@ -0,0 +1,248 @@ +import React, { useEffect, useState } from "react"; +import { Button, ScrollBar, Text, TextField, View } from "react-xnft"; +import { Keypair } from "@solana/web3.js"; +import * as bip39 from "bip39"; +import { ethers } from "ethers"; +import { HDKey } from "micro-ed25519-hdkey"; + +export enum Blockchain { + SOLANA = "solana", + ETHEREUM = "ethereum", +} + +export type MnemonicResponse = { + /** Derivation path of the public key */ + derivationPath: string; + /** Public key */ + publicKey: string; +}; + +export function MnemonicPrinter() { + const [mnemonic, setMnemonic] = useState(""); + const [mnemonicResponse, setMnemonicResponse] = useState( + [] + ); + const [blockChain, setBlockChain] = useState(Blockchain.SOLANA); + + const handleSubmit = () => { + setMnemonicResponse([]); + if (blockChain === Blockchain.SOLANA) { + let res = getSolanaPublicKeys(mnemonic); + setMnemonicResponse(res); + } else if (blockChain === Blockchain.ETHEREUM) { + let res = getEthereumPublicKeys(mnemonic); + setMnemonicResponse(res); + } + }; + + useEffect(() => { + console.log(mnemonicResponse); + }, [mnemonicResponse]); + + const getSolanaPublicKeys = (mnemonic: string): MnemonicResponse[] => { + let res: MnemonicResponse[] = []; + const seed = bip39.mnemonicToSeedSync(mnemonic, ""); + const hd = HDKey.fromMasterSeed(seed.toString("hex")); + for (let i = 0; i < 10; i++) { + const path = `m/44'/501'`; + const keypair = Keypair.fromSeed(hd.derive(path).privateKey); + res.push({ + derivationPath: path, + publicKey: keypair.publicKey.toBase58(), + }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/501'/${i}'`; + const keypair = Keypair.fromSeed(hd.derive(path).privateKey); + res.push({ + derivationPath: path, + publicKey: keypair.publicKey.toBase58(), + }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/501'/${i}'/0'`; + const keypair = Keypair.fromSeed(hd.derive(path).privateKey); + res.push({ + derivationPath: path, + publicKey: keypair.publicKey.toBase58(), + }); + for (let j = 0; j < 10; j++) { + const path = `m/44'/501'/${i}'/0'/${j}'`; + const keypair = Keypair.fromSeed(hd.derive(path).privateKey); + res.push({ + derivationPath: path, + publicKey: keypair.publicKey.toBase58(), + }); + } + } + return res; + }; + + const getEthereumPublicKeys = (mnemonic: string): MnemonicResponse[] => { + let res: MnemonicResponse[] = []; + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'/${i}'`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'/0'/${i}`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'/0'/${i}'`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'/${i}'/0`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + for (let j = 0; j < 10; j++) { + const path = `m/44'/60'/${i}'/0'/${j}`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + } + for (let i = 0; i < 10; i++) { + const path = `m/44'/60'/${i}'/0`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + for (let j = 0; j < 10; j++) { + const path = `m/44'/60'/${i}'/0/${j}`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + for (let j = 0; j < 10; j++) { + const path = `m/44'/60'/${i}'/0'/${j}`; + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path); + res.push({ derivationPath: path, publicKey: wallet.address }); + } + } + return res; + }; + + return ( + + + { + setMnemonic(e.target.value); + }} + value={mnemonic} + /> + + + + + + + + + {mnemonicResponse.length + ? mnemonicResponse.map((res) => + renderPublicKeys(res.derivationPath, res.publicKey) + ) + : null} + + + + ); +} + +function renderPublicKeys(derivationPath: string, publicKey: string) { + return ( + + + {`${derivationPath}`} + {`${publicKey}`} + + + ); +} diff --git a/examples/xnft/mnemonic-printer/src/index.tsx b/examples/xnft/mnemonic-printer/src/index.tsx new file mode 100644 index 0000000000..e83c2af7c0 --- /dev/null +++ b/examples/xnft/mnemonic-printer/src/index.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import ReactXnft, { AnchorDom } from "react-xnft"; + +import { MnemonicPrinter } from "./App/App"; + +ReactXnft.render( + + + +);