Merge pull request #518 from public-awesome/DirectSecp256k1Wallet

Add DirectSecp256k1Wallet
This commit is contained in:
Will Clark 2020-11-12 10:57:26 +01:00 committed by GitHub
commit 2ece7d857a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 316 additions and 165 deletions

View File

@ -1,6 +1,6 @@
import { pathToString } from "@cosmjs/crypto";
import { makeCosmoshubPath, Secp256k1HdWallet, SigningCosmosClient } from "@cosmjs/launchpad";
import { DirectSecp256k1Wallet, isOfflineDirectSigner, OfflineSigner } from "@cosmjs/proto-signing";
import { DirectSecp256k1HdWallet, isOfflineDirectSigner, OfflineSigner } from "@cosmjs/proto-signing";
import { SigningStargateClient } from "@cosmjs/stargate";
import * as constants from "./constants";
@ -12,7 +12,7 @@ export async function createWallets(
stargate = true,
logging = false,
): Promise<ReadonlyArray<readonly [string, OfflineSigner]>> {
const createWallet = stargate ? DirectSecp256k1Wallet.fromMnemonic : Secp256k1HdWallet.fromMnemonic;
const createWallet = stargate ? DirectSecp256k1HdWallet.fromMnemonic : Secp256k1HdWallet.fromMnemonic;
const wallets = new Array<readonly [string, OfflineSigner]>();
// first account is the token holder

View File

@ -0,0 +1,88 @@
import { Secp256k1, Secp256k1Signature, sha256 } from "@cosmjs/crypto";
import { fromBase64, fromHex } from "@cosmjs/encoding";
import { coins } from "@cosmjs/launchpad";
import { DirectSecp256k1HdWallet } from "./directsecp256k1hdwallet";
import { makeAuthInfoBytes, makeSignBytes, makeSignDoc } from "./signing";
import { faucet, testVectors } from "./testutils.spec";
describe("DirectSecp256k1HdWallet", () => {
// m/44'/118'/0'/0/0
// pubkey: 02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6
const defaultMnemonic = "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling";
const defaultPubkey = fromHex("02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6");
const defaultAddress = "cosmos1jhg0e7s6gn44tfc5k37kr04sznyhedtc9rzys5";
describe("fromMnemonic", () => {
it("works", async () => {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(defaultMnemonic);
expect(wallet).toBeTruthy();
expect(wallet.mnemonic).toEqual(defaultMnemonic);
});
});
describe("generate", () => {
it("defaults to 12 words", async () => {
const wallet = await DirectSecp256k1HdWallet.generate();
expect(wallet.mnemonic.split(" ").length).toEqual(12);
});
it("can use different mnemonic lengths", async () => {
expect((await DirectSecp256k1HdWallet.generate(12)).mnemonic.split(" ").length).toEqual(12);
expect((await DirectSecp256k1HdWallet.generate(15)).mnemonic.split(" ").length).toEqual(15);
expect((await DirectSecp256k1HdWallet.generate(18)).mnemonic.split(" ").length).toEqual(18);
expect((await DirectSecp256k1HdWallet.generate(21)).mnemonic.split(" ").length).toEqual(21);
expect((await DirectSecp256k1HdWallet.generate(24)).mnemonic.split(" ").length).toEqual(24);
});
});
describe("getAccounts", () => {
it("resolves to a list of accounts", async () => {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(defaultMnemonic);
const accounts = await wallet.getAccounts();
expect(accounts.length).toEqual(1);
expect(accounts[0]).toEqual({
address: defaultAddress,
algo: "secp256k1",
pubkey: defaultPubkey,
});
});
it("creates the same address as Go implementation", async () => {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(
"oyster design unusual machine spread century engine gravity focus cave carry slot",
);
const [{ address }] = await wallet.getAccounts();
expect(address).toEqual("cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u");
});
});
describe("signDirect", () => {
it("resolves to valid signature", async () => {
const { sequence, bodyBytes } = testVectors[1];
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const pubkey = {
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
value: fromBase64(faucet.pubkey.value),
};
const fee = coins(2000, "ucosm");
const gasLimit = 200000;
const chainId = "simd-testing";
const accountNumber = 1;
const signDoc = makeSignDoc(
fromHex(bodyBytes),
makeAuthInfoBytes([pubkey], fee, gasLimit, sequence),
chainId,
accountNumber,
);
const signDocBytes = makeSignBytes(signDoc);
const { signature } = await wallet.signDirect(faucet.address, signDoc);
const valid = await Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(signDocBytes),
pubkey.value,
);
expect(valid).toEqual(true);
});
});
});

View File

@ -0,0 +1,133 @@
import {
Bip39,
EnglishMnemonic,
HdPath,
Random,
Secp256k1,
sha256,
Slip10,
Slip10Curve,
} from "@cosmjs/crypto";
import {
AccountData,
encodeSecp256k1Signature,
makeCosmoshubPath,
rawSecp256k1PubkeyToAddress,
} from "@cosmjs/launchpad";
import { cosmos } from "./codec";
import { DirectSignResponse, OfflineDirectSigner } from "./signer";
import { makeSignBytes } from "./signing";
/**
* Derivation information required to derive a keypair and an address from a mnemonic.
*/
interface Secp256k1Derivation {
readonly hdPath: HdPath;
readonly prefix: string;
}
/** A wallet for protobuf based signing using SIGN_MODE_DIRECT */
export class DirectSecp256k1HdWallet implements OfflineDirectSigner {
/**
* Restores a wallet from the given BIP39 mnemonic.
*
* @param mnemonic Any valid English mnemonic.
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
public static async fromMnemonic(
mnemonic: string,
hdPath: HdPath = makeCosmoshubPath(0),
prefix = "cosmos",
): Promise<DirectSecp256k1HdWallet> {
const mnemonicChecked = new EnglishMnemonic(mnemonic);
const seed = await Bip39.mnemonicToSeed(mnemonicChecked);
const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);
const uncompressed = (await Secp256k1.makeKeypair(privkey)).pubkey;
return new DirectSecp256k1HdWallet(
mnemonicChecked,
hdPath,
privkey,
Secp256k1.compressPubkey(uncompressed),
prefix,
);
}
/**
* Generates a new wallet with a BIP39 mnemonic of the given length.
*
* @param length The number of words in the mnemonic (12, 15, 18, 21 or 24).
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
public static async generate(
length: 12 | 15 | 18 | 21 | 24 = 12,
hdPath: HdPath = makeCosmoshubPath(0),
prefix = "cosmos",
): Promise<DirectSecp256k1HdWallet> {
const entropyLength = 4 * Math.floor((11 * length) / 33);
const entropy = Random.getBytes(entropyLength);
const mnemonic = Bip39.encode(entropy);
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic.toString(), hdPath, prefix);
}
/** Base secret */
private readonly secret: EnglishMnemonic;
/** Derivation instruction */
private readonly accounts: readonly Secp256k1Derivation[];
/** Derived data */
private readonly pubkey: Uint8Array;
private readonly privkey: Uint8Array;
private constructor(
mnemonic: EnglishMnemonic,
hdPath: HdPath,
privkey: Uint8Array,
pubkey: Uint8Array,
prefix: string,
) {
this.secret = mnemonic;
this.accounts = [
{
hdPath: hdPath,
prefix: prefix,
},
];
this.privkey = privkey;
this.pubkey = pubkey;
}
public get mnemonic(): string {
return this.secret.toString();
}
private get address(): string {
return rawSecp256k1PubkeyToAddress(this.pubkey, this.accounts[0].prefix);
}
public async getAccounts(): Promise<readonly AccountData[]> {
return [
{
algo: "secp256k1",
address: this.address,
pubkey: this.pubkey,
},
];
}
public async signDirect(address: string, signDoc: cosmos.tx.v1beta1.ISignDoc): Promise<DirectSignResponse> {
const signBytes = makeSignBytes(signDoc);
if (address !== this.address) {
throw new Error(`Address ${address} not found in wallet`);
}
const hashedMessage = sha256(signBytes);
const signature = await Secp256k1.createSignature(hashedMessage, this.privkey);
const signatureBytes = new Uint8Array([...signature.r(32), ...signature.s(32)]);
const stdSignature = encodeSecp256k1Signature(this.pubkey, signatureBytes);
return {
signed: signDoc,
signature: stdSignature,
};
}
}

View File

@ -1,45 +1,28 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Secp256k1, Secp256k1Signature, sha256 } from "@cosmjs/crypto";
import { fromBase64, fromHex } from "@cosmjs/encoding";
import { coins } from "@cosmjs/launchpad";
import { DirectSecp256k1Wallet } from "./directsecp256k1wallet";
import { makeAuthInfoBytes, makeSignBytes, makeSignDoc } from "./signing";
import { faucet, testVectors } from "./testutils.spec";
import { testVectors } from "./testutils.spec";
describe("DirectSecp256k1Wallet", () => {
// m/44'/118'/0'/0/0
// pubkey: 02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6
const defaultMnemonic = "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling";
const defaultPubkey = fromHex("02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6");
const defaultAddress = "cosmos1jhg0e7s6gn44tfc5k37kr04sznyhedtc9rzys5";
const defaultPrivkey = fromHex("b8c462d2bb0c1a92edf44f735021f16c270f28ee2c3d1cb49943a5e70a3c763e");
const defaultAddress = "cosmos1kxt5x5q2l57ma2d434pqpafxdm0mgeg9c8cvtx";
const defaultPubkey = fromHex("03f146c27639179e5b67b8646108f48e1a78b146c74939e34afaa5414ad5c93f8a");
describe("fromMnemonic", () => {
describe("fromKey", () => {
it("works", async () => {
const wallet = await DirectSecp256k1Wallet.fromMnemonic(defaultMnemonic);
expect(wallet).toBeTruthy();
expect(wallet.mnemonic).toEqual(defaultMnemonic);
});
});
describe("generate", () => {
it("defaults to 12 words", async () => {
const wallet = await DirectSecp256k1Wallet.generate();
expect(wallet.mnemonic.split(" ").length).toEqual(12);
});
it("can use different mnemonic lengths", async () => {
expect((await DirectSecp256k1Wallet.generate(12)).mnemonic.split(" ").length).toEqual(12);
expect((await DirectSecp256k1Wallet.generate(15)).mnemonic.split(" ").length).toEqual(15);
expect((await DirectSecp256k1Wallet.generate(18)).mnemonic.split(" ").length).toEqual(18);
expect((await DirectSecp256k1Wallet.generate(21)).mnemonic.split(" ").length).toEqual(21);
expect((await DirectSecp256k1Wallet.generate(24)).mnemonic.split(" ").length).toEqual(24);
const signer = await DirectSecp256k1Wallet.fromKey(defaultPrivkey);
expect(signer).toBeTruthy();
});
});
describe("getAccounts", () => {
it("resolves to a list of accounts", async () => {
const wallet = await DirectSecp256k1Wallet.fromMnemonic(defaultMnemonic);
const accounts = await wallet.getAccounts();
const signer = await DirectSecp256k1Wallet.fromKey(defaultPrivkey);
const accounts = await signer.getAccounts();
expect(accounts.length).toEqual(1);
expect(accounts[0]).toEqual({
address: defaultAddress,
@ -47,23 +30,16 @@ describe("DirectSecp256k1Wallet", () => {
pubkey: defaultPubkey,
});
});
it("creates the same address as Go implementation", async () => {
const wallet = await DirectSecp256k1Wallet.fromMnemonic(
"oyster design unusual machine spread century engine gravity focus cave carry slot",
);
const [{ address }] = await wallet.getAccounts();
expect(address).toEqual("cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u");
});
});
describe("signDirect", () => {
it("resolves to valid signature", async () => {
const { sequence, bodyBytes } = testVectors[1];
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1Wallet.fromKey(defaultPrivkey);
const accounts = await wallet.getAccounts();
const pubkey = {
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
value: fromBase64(faucet.pubkey.value),
value: accounts[0].pubkey,
};
const fee = coins(2000, "ucosm");
const gasLimit = 200000;
@ -76,7 +52,7 @@ describe("DirectSecp256k1Wallet", () => {
accountNumber,
);
const signDocBytes = makeSignBytes(signDoc);
const { signature } = await wallet.signDirect(faucet.address, signDoc);
const { signature } = await wallet.signDirect(accounts[0].address, signDoc);
const valid = await Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(signDocBytes),

View File

@ -1,109 +1,39 @@
import {
Bip39,
EnglishMnemonic,
HdPath,
Random,
Secp256k1,
sha256,
Slip10,
Slip10Curve,
} from "@cosmjs/crypto";
import {
AccountData,
encodeSecp256k1Signature,
makeCosmoshubPath,
rawSecp256k1PubkeyToAddress,
} from "@cosmjs/launchpad";
import { Secp256k1, sha256 } from "@cosmjs/crypto";
import { AccountData, encodeSecp256k1Signature, rawSecp256k1PubkeyToAddress } from "@cosmjs/launchpad";
import { cosmos } from "./codec";
import { DirectSignResponse, OfflineDirectSigner } from "./signer";
import { makeSignBytes } from "./signing";
/**
* Derivation information required to derive a keypair and an address from a mnemonic.
* A wallet that holds a single secp256k1 keypair.
*
* If you want to work with BIP39 mnemonics and multiple accounts, use DirectSecp256k1HdWallet.
*/
interface Secp256k1Derivation {
readonly hdPath: HdPath;
readonly prefix: string;
}
/** A wallet for protobuf based signing using SIGN_MODE_DIRECT */
export class DirectSecp256k1Wallet implements OfflineDirectSigner {
/**
* Restores a wallet from the given BIP39 mnemonic.
* Creates a DirectSecp256k1Wallet from the given private key
*
* @param mnemonic Any valid English mnemonic.
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param privkey The private key.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
public static async fromMnemonic(
mnemonic: string,
hdPath: HdPath = makeCosmoshubPath(0),
prefix = "cosmos",
): Promise<DirectSecp256k1Wallet> {
const mnemonicChecked = new EnglishMnemonic(mnemonic);
const seed = await Bip39.mnemonicToSeed(mnemonicChecked);
const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);
public static async fromKey(privkey: Uint8Array, prefix = "cosmos"): Promise<DirectSecp256k1Wallet> {
const uncompressed = (await Secp256k1.makeKeypair(privkey)).pubkey;
return new DirectSecp256k1Wallet(
mnemonicChecked,
hdPath,
privkey,
Secp256k1.compressPubkey(uncompressed),
prefix,
);
return new DirectSecp256k1Wallet(privkey, Secp256k1.compressPubkey(uncompressed), prefix);
}
/**
* Generates a new wallet with a BIP39 mnemonic of the given length.
*
* @param length The number of words in the mnemonic (12, 15, 18, 21 or 24).
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
public static async generate(
length: 12 | 15 | 18 | 21 | 24 = 12,
hdPath: HdPath = makeCosmoshubPath(0),
prefix = "cosmos",
): Promise<DirectSecp256k1Wallet> {
const entropyLength = 4 * Math.floor((11 * length) / 33);
const entropy = Random.getBytes(entropyLength);
const mnemonic = Bip39.encode(entropy);
return DirectSecp256k1Wallet.fromMnemonic(mnemonic.toString(), hdPath, prefix);
}
/** Base secret */
private readonly secret: EnglishMnemonic;
/** Derivation instruction */
private readonly accounts: readonly Secp256k1Derivation[];
/** Derived data */
private readonly pubkey: Uint8Array;
private readonly privkey: Uint8Array;
private readonly prefix: string;
private constructor(
mnemonic: EnglishMnemonic,
hdPath: HdPath,
privkey: Uint8Array,
pubkey: Uint8Array,
prefix: string,
) {
this.secret = mnemonic;
this.accounts = [
{
hdPath: hdPath,
prefix: prefix,
},
];
private constructor(privkey: Uint8Array, pubkey: Uint8Array, prefix: string) {
this.privkey = privkey;
this.pubkey = pubkey;
}
public get mnemonic(): string {
return this.secret.toString();
this.prefix = prefix;
}
private get address(): string {
return rawSecp256k1PubkeyToAddress(this.pubkey, this.accounts[0].prefix);
return rawSecp256k1PubkeyToAddress(this.pubkey, this.prefix);
}
public async getAccounts(): Promise<readonly AccountData[]> {

View File

@ -1,7 +1,7 @@
export { Coin } from "./msgs";
export { cosmosField, registered } from "./decorator";
export { EncodeObject, Registry } from "./registry";
export { DirectSecp256k1Wallet } from "./directsecp256k1wallet";
export { DirectSecp256k1HdWallet } from "./directsecp256k1hdwallet";
export { decodePubkey, encodePubkey } from "./pubkey";
export { isOfflineDirectSigner, OfflineDirectSigner, OfflineSigner } from "./signer";
export { makeAuthInfoBytes, makeSignBytes, makeSignDoc } from "./signing";

View File

@ -2,7 +2,7 @@
import { fromBase64, fromHex, toHex } from "@cosmjs/encoding";
import { cosmos, google } from "./codec";
import { DirectSecp256k1Wallet } from "./directsecp256k1wallet";
import { DirectSecp256k1HdWallet } from "./directsecp256k1hdwallet";
import { defaultRegistry } from "./msgs";
import { Registry, TxBodyValue } from "./registry";
import { makeAuthInfoBytes, makeSignBytes, makeSignDoc } from "./signing";
@ -27,7 +27,7 @@ describe("signing", () => {
const gasLimit = 200000;
it("correctly parses test vectors", async () => {
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts();
const prefixedPubkeyBytes = Uint8Array.from([0x0a, pubkeyBytes.length, ...pubkeyBytes]);
@ -61,7 +61,7 @@ describe("signing", () => {
it("correctly generates test vectors", async () => {
const myRegistry = new Registry();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts();
const publicKey = PubKey.create({
key: pubkeyBytes,

View File

@ -0,0 +1,39 @@
import { HdPath } from "@cosmjs/crypto";
import { AccountData } from "@cosmjs/launchpad";
import { cosmos } from "./codec";
import { DirectSignResponse, OfflineDirectSigner } from "./signer";
/** A wallet for protobuf based signing using SIGN_MODE_DIRECT */
export declare class DirectSecp256k1HdWallet implements OfflineDirectSigner {
/**
* Restores a wallet from the given BIP39 mnemonic.
*
* @param mnemonic Any valid English mnemonic.
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
static fromMnemonic(mnemonic: string, hdPath?: HdPath, prefix?: string): Promise<DirectSecp256k1HdWallet>;
/**
* Generates a new wallet with a BIP39 mnemonic of the given length.
*
* @param length The number of words in the mnemonic (12, 15, 18, 21 or 24).
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
static generate(
length?: 12 | 15 | 18 | 21 | 24,
hdPath?: HdPath,
prefix?: string,
): Promise<DirectSecp256k1HdWallet>;
/** Base secret */
private readonly secret;
/** Derivation instruction */
private readonly accounts;
/** Derived data */
private readonly pubkey;
private readonly privkey;
private constructor();
get mnemonic(): string;
private get address();
getAccounts(): Promise<readonly AccountData[]>;
signDirect(address: string, signDoc: cosmos.tx.v1beta1.ISignDoc): Promise<DirectSignResponse>;
}

View File

@ -1,38 +1,23 @@
import { HdPath } from "@cosmjs/crypto";
import { AccountData } from "@cosmjs/launchpad";
import { cosmos } from "./codec";
import { DirectSignResponse, OfflineDirectSigner } from "./signer";
/** A wallet for protobuf based signing using SIGN_MODE_DIRECT */
/**
* A wallet that holds a single secp256k1 keypair.
*
* If you want to work with BIP39 mnemonics and multiple accounts, use DirectSecp256k1HdWallet.
*/
export declare class DirectSecp256k1Wallet implements OfflineDirectSigner {
/**
* Restores a wallet from the given BIP39 mnemonic.
* Creates a DirectSecp256k1Wallet from the given private key
*
* @param mnemonic Any valid English mnemonic.
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param privkey The private key.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
static fromMnemonic(mnemonic: string, hdPath?: HdPath, prefix?: string): Promise<DirectSecp256k1Wallet>;
/**
* Generates a new wallet with a BIP39 mnemonic of the given length.
*
* @param length The number of words in the mnemonic (12, 15, 18, 21 or 24).
* @param hdPath The BIP-32/SLIP-10 derivation path. Defaults to the Cosmos Hub/ATOM path `m/44'/118'/0'/0/0`.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
static generate(
length?: 12 | 15 | 18 | 21 | 24,
hdPath?: HdPath,
prefix?: string,
): Promise<DirectSecp256k1Wallet>;
/** Base secret */
private readonly secret;
/** Derivation instruction */
private readonly accounts;
/** Derived data */
static fromKey(privkey: Uint8Array, prefix?: string): Promise<DirectSecp256k1Wallet>;
private readonly pubkey;
private readonly privkey;
private readonly prefix;
private constructor();
get mnemonic(): string;
private get address();
getAccounts(): Promise<readonly AccountData[]>;
signDirect(address: string, signDoc: cosmos.tx.v1beta1.ISignDoc): Promise<DirectSignResponse>;

View File

@ -1,7 +1,7 @@
export { Coin } from "./msgs";
export { cosmosField, registered } from "./decorator";
export { EncodeObject, Registry } from "./registry";
export { DirectSecp256k1Wallet } from "./directsecp256k1wallet";
export { DirectSecp256k1HdWallet } from "./directsecp256k1hdwallet";
export { decodePubkey, encodePubkey } from "./pubkey";
export { isOfflineDirectSigner, OfflineDirectSigner, OfflineSigner } from "./signer";
export { makeAuthInfoBytes, makeSignBytes, makeSignDoc } from "./signing";

View File

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { coin, coins, GasPrice, Secp256k1HdWallet } from "@cosmjs/launchpad";
import { Coin, cosmosField, DirectSecp256k1Wallet, registered, Registry } from "@cosmjs/proto-signing";
import { Coin, cosmosField, DirectSecp256k1HdWallet, registered, Registry } from "@cosmjs/proto-signing";
import { assert } from "@cosmjs/utils";
import { Message } from "protobufjs";
@ -13,7 +13,7 @@ describe("SigningStargateClient", () => {
describe("constructor", () => {
it("can be constructed with default fees", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const client = await SigningStargateClient.connectWithWallet(simapp.tendermintUrl, wallet);
const openedClient = (client as unknown) as PrivateSigningStargateClient;
expect(openedClient.fees).toEqual({
@ -31,7 +31,7 @@ describe("SigningStargateClient", () => {
it("can be constructed with custom registry", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const registry = new Registry();
registry.register("/custom.MsgCustom", cosmos.bank.v1beta1.MsgSend);
const options = { registry: registry };
@ -42,7 +42,7 @@ describe("SigningStargateClient", () => {
it("can be constructed with custom gas price", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const gasPrice = GasPrice.fromString("3.14utest");
const options = { gasPrice: gasPrice };
const client = await SigningStargateClient.connectWithWallet(simapp.tendermintUrl, wallet, options);
@ -62,7 +62,7 @@ describe("SigningStargateClient", () => {
it("can be constructed with custom gas limits", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const gasLimits = {
send: 160000,
};
@ -84,7 +84,7 @@ describe("SigningStargateClient", () => {
it("can be constructed with custom gas price and gas limits", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const gasPrice = GasPrice.fromString("3.14utest");
const gasLimits = {
send: 160000,
@ -109,7 +109,7 @@ describe("SigningStargateClient", () => {
describe("sendTokens", () => {
it("works", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const client = await SigningStargateClient.connectWithWallet(simapp.tendermintUrl, wallet);
const transferAmount = coins(7890, "ucosm");
@ -135,7 +135,7 @@ describe("SigningStargateClient", () => {
describe("signAndBroadcast", () => {
it("works with direct mode", async () => {
pendingWithoutSimapp();
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate";
const registry = new Registry();
registry.register(msgDelegateTypeUrl, cosmos.staking.v1beta1.MsgDelegate);

View File

@ -2,7 +2,7 @@
import { fromBase64, toBase64 } from "@cosmjs/encoding";
import { Coin, coins } from "@cosmjs/launchpad";
import {
DirectSecp256k1Wallet,
DirectSecp256k1HdWallet,
encodePubkey,
makeAuthInfoBytes,
makeSignDoc,
@ -32,7 +32,7 @@ interface TestTxSend {
async function sendTokens(
client: StargateClient,
registry: Registry,
wallet: DirectSecp256k1Wallet,
wallet: DirectSecp256k1HdWallet,
recipient: string,
amount: readonly Coin[],
memo: string,
@ -96,7 +96,7 @@ describe("StargateClient.searchTx", () => {
beforeAll(async () => {
if (simappEnabled()) {
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const client = await StargateClient.connect(simapp.tendermintUrl);
const unsuccessfulRecipient = makeRandomAddress();
const successfulRecipient = makeRandomAddress();

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { fromBase64, toBase64 } from "@cosmjs/encoding";
import {
DirectSecp256k1Wallet,
DirectSecp256k1HdWallet,
encodePubkey,
makeAuthInfoBytes,
makeSignDoc,
@ -256,7 +256,7 @@ describe("StargateClient", () => {
it("broadcasts a transaction", async () => {
pendingWithoutSimapp();
const client = await StargateClient.connect(simapp.tendermintUrl);
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts();
const pubkey = encodePubkey({
type: "tendermint/PubKeySecp256k1",