- Generate seed phrase
- Derivate keys with hierarchical-deterministic features
- Sign
- Verify sign and address
- Bitcoin
- BitcoinSV
- BitcoinCash
- Litecoin
- Dogecoin
- Ethereum (and evm base)
- EOS
- Ripple
- Dashcoin
- TRON
- Terra 20
- Terra classic
const hdwallet = new Keys(Blockchain.ETH, Network.MAINNET)
/** For mainnet/testnet/regtest networks */
const defaultPaths = hdwallet.getDefaultPaths()
const masterKeyPairsWithSeed = await hdwallet.generateSeedPhrase(
24,
SeedPhraseLanguages.ENGLISH,
"m/44'/60'/0'/0",
'simple-password',
)
const isVallidSeedPhrase = await hdwallet.checkSeedPhrase(masterKeyPairsWithSeed.seedPhrase)
if (!isVallidSeedPhrase) {
throw new Error('Validation error: seed phrase is not valid')
}
const derivationFromSeedPhrase = await hdwallet.derivateKeys({
seedPhrase: masterKeyPairsWithSeed.seedPhrase,
password: 'simple-password',
}, { skip: 0, limit: 5, path: "m/44'/60'/0'/0" })
const derivationFromMasterPublicKey = await hdwallet.derivateKeys(
{ masterPublicKey: masterKeyPairsWithSeed.masterPublicKey },
{ skip: 5, limit: 5, path: "m/44'/60'/0'/0" },
)
const derivationFromMasterPrivateKey = await hdwallet.derivateKeys(
{ masterPrivateKey: masterKeyPairsWithSeed.masterPrivateKey },
{ skip: 10, limit: 5, path: "m/44'/60'/0'/0" },
)
const keyPairsWithPath = [
...derivationFromSeedPhrase,
...derivationFromMasterPublicKey,
...derivationFromMasterPrivateKey,
]
for (const keyPairWithPath of keyPairsWithPath) {
console.log(
`Wallet (${keyPairWithPath.path}):\n` +
`${JSON.parse(keyPairWithPath, null, 2)}`,
)
if (keyPairWithPath.privateKey) {
/** keyPairsWithPath.publicKey is equale to publicFromPrivate */
const publicFromPrivate = await hdwallet.getPublicFromPrivate(
keyPairWithPath.privateKey,
)
}
const addressFromPublic = await hdwallet.getAddressFromPublic(
keyPairWithPath.publicKey,
/**
* formats (usually for btc-base):
* - BTC: bech32 | p2tr | p2sh
* - BTC cashe: legacy | bitpay | cashaddr = cashaddr
*/
)
}
import JSON = Mocha.reporters.JSON
interface EthTxData {
to: string
nonce: string | number
gasPrice: string
gasLimit: string
value: string
data: string
from?: string
}
const txData: EthTxData = {
...
}
const jsonTxData = JSON.stringify(txData)
/**
* Key: address
* Value: private key
*/
const keyPairs: Record<string, string> = { 'address': 'private key' }
const hdwallet = new Keys(Blockchain.ETH, Network.MAINNET)
const signedTxJson = hdwallet.sign(
jsonTxData,
keyPairs,
/** is tx */ true,
)
const signedMessageJson = hdwallet.sign(
'Simple text for sign',
keyPairs,
/** is tx */ false,
)
const isValidSignTx = await hdwallet.checkSign(null, null, signedTxJson)
const isValidSignMessage = await hdwallet.checkSign(null, null, signedMessageJson)
if (!isValidSignTx) {
throw new Error('Validation error: signature tx is not valid')
}
if (!isValidSignMessage) {
throw new Error('Validation error: signature message is not valid')
}
console.log(
`SignedTxJson:\n${JSON.parse(signedTxJson, null, 2)}`,
)
console.log(
`SignedMessageJson:\n${JSON.parse(signedMessageJson, null, 2)}`,
)
interface BtcTxData {
sum: string
fee: string
inputs: {
txId: string
hex: string
n: number
value: string
address: string
type: string
scriptPubKeyHex: string
sum: string
}
outputs: {
amount: string
address: string
}
}
const txData: BtcTxData = {
...
}
const jsonTxData = JSON.stringify(txData)
/**
* Key: address
* Value: private key
*/
const keyPairs: Record<string, string> = {
'address first': 'private key first',
'address second': 'private key second',
/** ets */
}
const hdwallet = new Keys(Blockchain.BTC, Network.MAINNET)
const signedTxHex = hdwallet.sign(
jsonTxData,
keyPairs,
/** is tx */ true,
)
const signedMessageHex = hdwallet.sign(
'Simple text for sign',
keyPairs,
/** is tx */ false,
)
const isValidSignTx = await hdwallet.checkSign(
'public key',
jsonTxData,
signedTxHex,
)
const isValidSignMessage = await hdwallet.checkSign(
'public key',
'Simple text for sign',
signedMessageHex,
)
if (!isValidSignTx) {
throw new Error('Validation error: signature tx is not valid')
}
if (!isValidSignMessage) {
throw new Error('Validation error: signature message is not valid')
}
console.log(
`SignedTxHex: "${signedTxHex}"`,
)
console.log(
`SignedMessageHex: "${signedTxHex}"`,
)
interface EOSTxData {
account: string
name: string
authorization: Array<{ actor: string, permission: string }>
data: {
from: string,
to: string,
quantity: string
memo: string,
},
}
const txData: EOSTxData = {
...
}
const jsonTxData = JSON.stringify(txData)
/**
* Key: address
* Value: private key
*/
const keyPairs: Record<string, string> = { 'address': 'private key' }
const hdwallet = new Keys(Blockchain.EOS, Network.MAINNET)
const signedTxJson = hdwallet.sign(
jsonTxData,
keyPairs,
/** is tx */ true,
)
const signedMessageJson = hdwallet.sign(
'Simple text for sign',
keyPairs,
/** is tx */ false,
)
const isValidSignTx = await hdwallet.checkSign(
'public key',
txData,
signedTxJson,
)
const isValidSignMessage = await hdwallet.checkSign(
'public key',
'Simple text for sign',
signedMessageJson,
)
if (!isValidSignTx) {
throw new Error('Validation error: signature tx is not valid')
}
if (!isValidSignMessage) {
throw new Error('Validation error: signature message is not valid')
}
console.log(
`SignedTxJson:\n${JSON.parse(signedTxJson, null, 2)}`,
)
console.log(
`SignedMessageJson:\n${JSON.parse(signedMessageJson, null, 2)}`,
)
- Generate seed phrase
- Derivate keys with deterministic features
- Sign
- Verify sign and address
- TON
- SOL
const dwallet = DeterministicWallets[Blockchain.TON](
'm/0',
config,
)
const seedPhrase = await dwallet.generateSeedPhrase(
24,
'simple-password',
)
const isVallidSeedPhrase = await dwallet.checkSeedPhrase(seedPhrase)
if (!isVallidSeedPhrase) {
throw new Error('Validation error: seed phrase is not valid')
}
const keyPairsWithPath = await dwallet.derivePath(
seedPhrase,
'm/0',
{ skip: 0, limit: 5 },
)
for (const keyPairWithPath of keyPairsWithPath) {
const address = await keyPairWithPath.toAddress()
const wallet = {
address: address.get(),
...keyPairWithPath.toStringPairs('hex'),
}
console.log(
`Wallet (${keyPairWithPath.path}):\n` +
`${JSON.stringify(wallet, null, 2)}`,
)
if (!address.isValid()) {
throw new Error('Validation error: address not valid')
}
/** keyPairWithPath.toAddress().get() is equale addressFromPublicKey.get() */
const addressFromPublicKey = await dwallet.addressFromPublicKey(keyPairWithPath.publicKey)
if (!addressFromPublicKey.isValid()) {
throw new Error('Validation error: address is not valid')
}
}
/** Without using derivation */
const keyPair = await dwallet.keyPairFromSeedPhrase(seedPhrase)
const address = keyPair.toAddress()
const wallet = {
address: address.get(),
...keyPair.toStringPairs('hex'),
}
console.log(
`Wallet:\n${JSON.parse(wallet, null, 2)}`,
)
import JSON = Mocha.reporters.JSON
/** SingTonTransactionType: see in ton types */
const tx: SingTonTransactionType = {
...
}
const privateKey = '...'
const dwallet = DeterministicWallets[Blockchain.TON](
'm/0',
{wc: 0, walletVersion: WalletVersions.TON_V4R2},
)
const signedTxHex = await dwallet.signTransaction(
tx,
privateKey,
)
const signedMessageHex = await dwallet.signMessage(
'Simple text for sign',
privateKey,
)
const isValidSignTx = await dwallet.checkSign(
'public key',
JSON.stringify(tx),
signedTxHex,
)
const isValidSignMessage = await hdwallet.checkSign(
'public key',
'Simple text for sign',
signedMessageHex,
)
if (!isValidSignTx) {
throw new Error('Validation error: signature tx is not valid')
}
if (!isValidSignMessage) {
throw new Error('Validation error: signature message is not valid')
}
console.log(
`SignedTxHex: "${signedTxHex}"`,
)
console.log(
`SignedMessageHex: "${signedTxHex}"`,
)
More information from the sodium-plus library
const backendKeys = await Keys.makeBoxKeys()
const frontendKeys = await Keys.makeBoxKeys()
const seedPhrase =
'december carry bless goose gallery object reduce tomato chef hollow box drill name answer tumble'
/** Frontend get keys pair + backend public key
* then frontend make crypto box.
*/
const box = await Keys.makeBox(
seedPhrase,
frontendKeys.privateKey,
backendKeys.publicKey,
)
const openedBox = await Keys.openBox(
box.box,
box.nonce,
backendKeys.privateKey,
frontendKeys.publicKey,
)
console.log({ openedBox })
const password = '123'
const encrypted = await Keys.encrypt('encrypt test', password)
const decrypted = await Keys.decrypt(encrypted, password)
console.log({ encrypted, decrypted })