forked from coral-xyz/backpack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
closes coral-xyz#3542
- Loading branch information
Showing
6 changed files
with
312 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import React, { useCallback, useState } from "react"; | ||
import { Button, ScrollBar, Text, TextField, View } from "react-xnft"; | ||
|
||
import type { MnemonicResponse } from "./_types/types"; | ||
import { Blockchain } from "./_types/types"; | ||
import getEthereumPublicKeys from "./_utils/getEthereumPublicKeys"; | ||
import getSolanaPublicKeys from "./_utils/getSolanaPublicKeys"; | ||
|
||
export function MnemonicPrinter() { | ||
const [phrase, setPhrase] = useState(""); | ||
const [mnemonicResponse, setMnemonicResponse] = useState<MnemonicResponse[]>( | ||
[] | ||
); | ||
const [blockChain, setBlockChain] = useState<Blockchain>(Blockchain.SOLANA); | ||
const [message, setMessage] = useState<string>(""); | ||
|
||
const handleSubmit = useCallback(() => { | ||
setMnemonicResponse([]); | ||
setMessage("Loading please wait ..."); | ||
let res = getPaths(blockChain, phrase); | ||
setMnemonicResponse(res); | ||
setMessage(""); | ||
}, [phrase, blockChain]); | ||
|
||
return ( | ||
<View | ||
style={{ | ||
display: "flex", | ||
flexDirection: "column", | ||
height: "100%", | ||
padding: "10px 0px", | ||
cursor: "pointer", | ||
paddingTop: "50px", | ||
}} | ||
> | ||
<View | ||
style={{ | ||
display: "flex", | ||
padding: "0px 16px", | ||
paddingBottom: "10px", | ||
flexDirection: "column", | ||
gap: 5, | ||
}} | ||
> | ||
<TextField | ||
placeholder="Enter secret recovery phrase" | ||
onChange={(e) => { | ||
setPhrase(e.target.value); | ||
}} | ||
value={phrase} | ||
/> | ||
<View | ||
style={{ | ||
display: "flex", | ||
gap: 5, | ||
}} | ||
> | ||
<Button | ||
style={{ | ||
border: | ||
blockChain === Blockchain.SOLANA ? "3px solid" : "3px hidden", | ||
flexGrow: 1, | ||
}} | ||
onClick={() => { | ||
setBlockChain(Blockchain.SOLANA); | ||
}} | ||
> | ||
Solana | ||
</Button> | ||
<Button | ||
style={{ | ||
border: | ||
blockChain === Blockchain.ETHEREUM ? "3px solid" : "3px hidden", | ||
flexGrow: 1, | ||
}} | ||
onClick={() => { | ||
setBlockChain(Blockchain.ETHEREUM); | ||
}} | ||
> | ||
Ethereum | ||
</Button> | ||
</View> | ||
<Button onClick={() => handleSubmit()}> Search </Button> | ||
</View> | ||
<View | ||
style={{ | ||
display: "flex", | ||
flexGrow: 1, | ||
position: "relative", | ||
}} | ||
> | ||
<ScrollBar> | ||
{mnemonicResponse.length > 0 ? ( | ||
mnemonicResponse.map((res) => | ||
renderPublicKeys(res.derivationPath, res.publicKey) | ||
) | ||
) : ( | ||
<Text style={{ padding: "8px" }}>{`${message}`}</Text> | ||
)} | ||
</ScrollBar> | ||
</View> | ||
</View> | ||
); | ||
} | ||
|
||
function renderPublicKeys(derivationPath: string, publicKey: string) { | ||
return ( | ||
<View | ||
style={{ | ||
padding: "8px 16px", | ||
display: "flex", | ||
position: "relative", | ||
}} | ||
> | ||
<View | ||
style={{ | ||
display: "flex", | ||
flexGrow: 1, | ||
flexDirection: "column", | ||
overflow: "hidden", | ||
}} | ||
> | ||
<Text | ||
style={{ | ||
font: "Inter", | ||
lineHeight: "24px", | ||
fontSize: "18px", | ||
whiteSpace: "nowrap", | ||
fontWeight: "bold", | ||
}} | ||
>{`${derivationPath}`}</Text> | ||
<Text | ||
style={{ | ||
font: "Inter", | ||
lineHeight: "24px", | ||
fontSize: "16px", | ||
wordWrap: "break-word", | ||
whiteSpace: "initial", | ||
}} | ||
>{`${publicKey}`}</Text> | ||
</View> | ||
</View> | ||
); | ||
} | ||
|
||
function getPaths(blockChain: string, phrase: string): MnemonicResponse[] { | ||
let res: MnemonicResponse[] = []; | ||
if (blockChain === Blockchain.SOLANA) { | ||
setTimeout(() => { | ||
res = getSolanaPublicKeys(phrase); | ||
}, 25); | ||
} else if (blockChain === Blockchain.ETHEREUM) { | ||
setTimeout(() => { | ||
res = getEthereumPublicKeys(phrase); | ||
}, 25); | ||
} | ||
return res; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export enum Blockchain { | ||
SOLANA = "solana", | ||
ETHEREUM = "ethereum", | ||
} | ||
|
||
export type MnemonicResponse = { | ||
/** Derivation path of the public key */ | ||
derivationPath: string; | ||
/** Public key */ | ||
publicKey: string; | ||
}; |
60 changes: 60 additions & 0 deletions
60
examples/xnft/mnemonic-printer/src/App/_utils/getEthereumPublicKeys.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { ethers } from "ethers"; | ||
|
||
import type { MnemonicResponse } from "../_types/types"; | ||
|
||
self.onmessage = (e: MessageEvent<string>) => { | ||
let res = getEthereumPublicKeys(e.data); | ||
self.postMessage(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; | ||
}; | ||
|
||
export default getEthereumPublicKeys; |
46 changes: 46 additions & 0 deletions
46
examples/xnft/mnemonic-printer/src/App/_utils/getSolanaPublicKeys.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Keypair } from "@solana/web3.js"; | ||
import * as bip39 from "bip39"; | ||
import { HDKey } from "micro-ed25519-hdkey"; | ||
|
||
import type { MnemonicResponse } from "../_types/types"; | ||
|
||
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; | ||
}; | ||
|
||
export default getSolanaPublicKeys; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from "react"; | ||
import ReactXnft, { AnchorDom } from "react-xnft"; | ||
|
||
import { MnemonicPrinter } from "./App/App"; | ||
|
||
ReactXnft.render( | ||
<AnchorDom> | ||
<MnemonicPrinter /> | ||
</AnchorDom> | ||
); |