A JavaScript client library for interacting with the Radix Distributed Ledger.
npm install @radixdlt/account@radixdlt/accountAccount related APIs for Radix.
We have a WalletT type being a hierchal deterministic wallet (explained by Ledger Acadamy and on BitcoinWiki) capable of deriving all "account"s you will need.
The trailing _T_ in WalletT is a suffix we use for all types (we don't use TypeScript classes at all). We reserve the Wallet name as a "namespaces" for our types, providing static-like factory/constructor methods, e.g. Wallet.create (N.B. the lack of trailing _T_). This decision was taken since we believe you will more often _use the namespace_ Wallet.create than you have to _declare the type_ WalletT.
Here follows the generation of a new mnemonic and the creation of a wallet, via the saving of a keystore.
This outlines the most convenient wallet creation flow using byEncryptingMnemonicAndSavingKeystore.
``typescript
import { Mnemonic, Strength, Language } from '@radixdlt/account'
// ⚠️ Require user to backup mnemonic.
// She will NEVER be able to re-view it.
const mnemonic = Mnemonic.generateNew()
// This will be our "application password" (1️⃣)
// User chooses this, however, please tell her to use a unique, strong randomly generated encryption password. Also urge user to back this up in a safe place. She will need it every time she starts the app.
const keystoreEncryptionPassword = confirmPasswordTextField.value() // or similar
// You need to pass in a function which saves the keystore
// this example uses 'fs' but using a browser you might
// wanna try out https://www.npmjs.com/package/fs-jetpack or similar.
import { PathLike, promises as fsPromises } from 'fs'
const saveKeystoreOnDisk = (keystore: KeystoreT): Promise
const filePath = 'SOME/SUITABLE/PATH/keystore.json'
const json = JSON.stringify(keystore, null, '\t')
return fsPromises.writeFile(filePath, json)
}
// walletResult has type ResultAsyncResultAsync
// : github.com/supermacro/neverthrow (2️⃣)
const walletResult = await Wallet.byEncryptingMnemonicAndSavingKeystore({
mnemonic,
password: keystoreEncryptionPassword,
save: saveKeystoreOnDisk,
})
if (walletResult.isErr()) {
console.log(🤷♂️ Failed to create wallet: ${walletResult.error})`
} else {
const wallet = walletResult.value
// do something with 'wallet'
}
1️⃣: The keystoreEncryptionPassword will be needed everytime the user re-opens the wallet app after having terminated it. It's used to _decrypt_ the encrypted hdMasterSeed. Remember, the keystore is just a JSON file containing an encrypted ciphertext, and metadata about the encryption used to derive said cihpertext. The ciphertext itself is the BIP39 "seed", not the entropy/mnemonic itself.Result
2️⃣ Read more about / ResultAsync
above does. `typescript
const mnemonic = Mnemonic.generateNew()
// ⚠️ Require user backup mnemonic first!
const masterSeed = HDMasterSeed.fromMnemonic({ mnemonic })// Tell user to backup encryption password.
const keystoreEncryptionPassword = confirmPasswordTextField.value() // or similar
const walletResult = await Keystore.encryptSecret({
secret: masterSeed.seed,
password,
})
.map((keystore) => ({ keystore, filePath: keystorePath }))
.andThen((keystore) => {
// Save keystore on file and return an
ResultAsyncif (walletResult.isErr()) {
console.log(🤷♂️ Failed to create wallet: ${walletResult.error})
} else {
const wallet = walletResult.value
// do something with 'wallet'
}
``
`typescript
// Path to where location where the keystore.json file will be saved.
import { Keystore } from "./keystore";
import { PathLike, promises as fsPromises } from 'fs'
// Each time GUI wallet starts ask user for encryption password in GUI
const keystoreEncryptionPassword = passwordTextField.value() // or similar
const loadKeystoreOnDisk = (): Promise
const filePath = 'SOME/SUITABLE/PATH/keystore.json'
return fsPromises.readFile(filePath)
.then(buffer => Keystore.fromBuffer(buffer))
}
const walletResult = await Wallet.byLoadingAndDecryptingKeystore({
password: keystoreEncryptionPassword,
load: loadKeystoreOnDisk
})
if (walletResult.isErr()) {
console.log(🤷♂️ Failed to create wallet: ${walletResult.error})``
} else {
const wallet = walletResult.value
// do something with 'wallet'
}