Keys
Contents
Keys¶
To perform actions using an account with Terra.js, you need a Key, which provides an abstraction around signing functions of an account.
Key interface¶
A Key
provides the following interface:
interface Key {
publicKey: Buffer;
accAddress: AccAddress;
valAddress: ValAddress;
accPubKey: AccPubKey;
valPubKey: ValPubKey;
createSignature(tx: StdSignMsg): StdSignature;
signTx(tx: StdSignMsg): Promise<StdTx>;
sign(payload: Buffer): Promise<Buffer>;
}
Key implementations¶
Terra.js provides several standard Key
implementations that provide a variety of ways to load an account with signing features into your program.
RawKey
¶
The most basic implementation of Key
is RawKey
, which is created with a plain private key.
import { RawKey } from '@terra-money/terra.js';
const rk = new RawKey("<private key>");
The private key associated with the RawKey
is available through the instance:
console.log(rk.privateKey);
MnemonicKey
¶
import { MnemonicKey } from '@terra-money/terra.js';
const mk = new MnemonicKey({
mnemonic: "<24-word mnemonic>",
});
Generate random mnemonic¶
If you want to generate a random mnemonic, you can create a MnemonicKey
without any arguments:
const mk = new MnemonicKey();
console.log(mk.mnemonic);
Specifying HD path¶
MnemonicKey
can used to recover a wallet with a particular BIP44 HD path: m/44'/${coinType}'/${account}'/0/${index}
.
const mk = new MnemonicKey({
mnemonic: "<seed-phrase>", // optional, will be random if not provided
coinType: 330, // optional, default
account: 0, // optional, default
index: 0, // optional, default
});
For example, to recover a mnemonic with the old Terra wallet HD path using coin type for ATOM (118):
const mk = new MnemonicKey({
mnemonic: "<seed-phrase>",
coinType: 118
});
CLIKey
¶
NOTE: This requires you to have
terrad
installed.
If you want to use keys stored in your terrad
installation’s keyring to sign transactions, you can use CLIKey
. This also will work for keys that have been registered in your keyring with --ledger
, using a Ledger hardware device.
import { StdFee, MsgSend } from '@terra-money/terra.js';
import { LocalTerra } from '@terra-money/terra.js';
import { CLIKey } from '@terra-money/terra.js';
const terra = new LocalTerra();
const { test1 } = terra.wallets;
const cliKey = new CLIKey('test111');
const cliWallet = terra.wallet(cliKey);
const send = new MsgSend(cliWallet.key.accAddress, test1.key.accAddress, {
uluna: 100000,
});
async function main() {
const tx = await cliWallet.createAndSignTx({
msgs: [send],
fee: new StdFee(100000, { uluna: 100000 }),
});
console.log(await terra.tx.broadcast(tx));
}
main().catch(console.error);
Custom key implementation¶
If you need to write your own key management solution, you will need to subclass the abstract Key
class and provide your own signing function. Note that the key need not expose any details pertaining to the private key – you could specify a sign()
function that forwards the signing request to a server or to a hardware wallet, for instance. The remaining functions related to signing (createSignature()
and signTx()
) are automatically provided and use sign()
underneath.
The following code listing is the implementation of RawKey
, which illustrates how to write a custom Key
:
import SHA256 from 'crypto-js/sha256';
import * as secp256k1 from 'secp256k1';
import { Key } from '@terra-money/terra.js';
/**
* An implementation of the Key interfaces that uses a raw private key.
*/
export class RawKey extends Key {
/**
* Raw private key, in bytes.
*/
public privateKey: Buffer;
constructor(privateKey: Buffer) {
const publicKey = secp256k1.publicKeyCreate(
new Uint8Array(privateKey),
true
);
super(Buffer.from(publicKey));
this.privateKey = privateKey;
}
public sign(payload: Buffer): Promise<Buffer> {
const hash = Buffer.from(SHA256(payload.toString()).toString(), 'hex');
const { signature } = secp256k1.ecdsaSign(
Uint8Array.from(hash),
Uint8Array.from(this.privateKey)
);
return Buffer.from(signature);
}
}
Note that you must call super()
with the public key—this generates the relevant account and validator public keys associated with your key.