Skip to content

Library for manage d-wallets and hd-wallets for given set of blockchains.

Notifications You must be signed in to change notification settings

wallet-verse/crypto-api-keys-lib

Repository files navigation

Crypto keys lib

HD Wallets

Features:

  • Generate seed phrase
  • Derivate keys with hierarchical-deterministic features
  • Sign
  • Verify sign and address

Support blockchains

  • Bitcoin
  • BitcoinSV
  • BitcoinCash
  • Litecoin
  • Dogecoin
  • Ethereum (and evm base)
  • EOS
  • Ripple
  • Dashcoin
  • TRON
  • Terra 20
  • Terra classic

Overview derivation features example

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
         */
    )
}

Overview sign features for EVM-base example

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)}`,
)

Overview sign features for BTC-base example

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}"`,
)

Overview sign features for EOS example

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)}`,
)

Deterministic Wallets

Features:

  • Generate seed phrase
  • Derivate keys with deterministic features
  • Sign
  • Verify sign and address

Support blockchains

  • TON
  • SOL

Overview derivation features example

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)}`,
)

Overview sign features for TON example

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}"`,
)

Other features

Crypto box

More information from the sodium-plus library

Overview make and open box example

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 })

Encryption

Overview encrypt and decrypt example

    const password = '123'

    const encrypted = await Keys.encrypt('encrypt test', password)
    const decrypted = await Keys.decrypt(encrypted, password)

    console.log({ encrypted, decrypted })

Roadmap

About

Library for manage d-wallets and hd-wallets for given set of blockchains.

Resources

Stars

Watchers

Forks

Packages

No packages published