Merge pull request #618 from cosmos/spike-ledger-stargate

Demonstrate Stargate Ledger compatibility via Amino signing
This commit is contained in:
Will Clark 2021-01-14 14:32:44 +01:00 committed by GitHub
commit 11e159e4ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 14 deletions

View File

@ -2,20 +2,33 @@
import { Secp256k1, Secp256k1Signature, sha256 } from "@cosmjs/crypto";
import { fromBase64 } from "@cosmjs/encoding";
import {
assertIsBroadcastTxSuccess as assertIsBroadcastTxSuccessLaunchpad,
coins,
isBroadcastTxSuccess,
makeCosmoshubPath,
makeSignDoc,
Msg,
Secp256k1HdWallet,
serializeSignDoc,
SigningCosmosClient,
StdFee,
} from "@cosmjs/launchpad";
import { assert, sleep } from "@cosmjs/utils";
import {
assertIsBroadcastTxSuccess as assertIsBroadcastTxSuccessStargate,
SigningStargateClient,
} from "@cosmjs/stargate";
import { sleep } from "@cosmjs/utils";
import Transport from "@ledgerhq/hw-transport";
import { LedgerSigner } from "./ledgersigner";
import { launchpad, pendingWithoutLaunchpad, pendingWithoutLedger } from "./testutils.spec";
import {
faucet,
launchpad,
pendingWithoutLaunchpad,
pendingWithoutLedger,
pendingWithoutSimapp,
simapp,
simappEnabled,
} from "./testutils.spec";
const interactiveTimeout = 120_000;
@ -44,9 +57,20 @@ describe("LedgerSigner", () => {
const defaultMemo = "Some memo";
const defaultSequence = "0";
const defaultAccountNumber = "42";
const defaultRecipient = "cosmos1p6xs63q4g7np99ttv5nd3yzkt8n4qxa47w8aea";
const defaultLedgerAddress = "cosmos1p6xs63q4g7np99ttv5nd3yzkt8n4qxa47w8aea";
let transport: Transport;
beforeAll(async () => {
if (simappEnabled()) {
const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const client = await SigningStargateClient.connectWithSigner(simapp.endpoint, wallet);
const amount = coins(226644, "ucosm");
const memo = "Ensure chain has my pubkey";
const sendResult = await client.sendTokens(faucet.address, defaultLedgerAddress, amount, memo);
assertIsBroadcastTxSuccessStargate(sendResult);
}
});
beforeEach(async () => {
transport = await createTransport();
});
@ -100,15 +124,15 @@ describe("LedgerSigner", () => {
hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)],
});
const [fistAccount] = await signer.getAccounts();
const [firstAccount] = await signer.getAccounts();
const msgs: readonly Msg[] = [
{
type: "cosmos-sdk/MsgSend",
value: {
amount: coins(1234567, "ucosm"),
from_address: fistAccount.address,
to_address: defaultRecipient,
from_address: firstAccount.address,
to_address: defaultLedgerAddress,
},
},
];
@ -120,12 +144,12 @@ describe("LedgerSigner", () => {
defaultAccountNumber,
defaultSequence,
);
const { signed, signature } = await signer.signAmino(fistAccount.address, signDoc);
const { signed, signature } = await signer.signAmino(firstAccount.address, signDoc);
expect(signed).toEqual(signDoc);
const valid = await Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(serializeSignDoc(signed)),
fistAccount.pubkey,
firstAccount.pubkey,
);
expect(valid).toEqual(true);
},
@ -133,7 +157,7 @@ describe("LedgerSigner", () => {
);
it(
"creates signature accepted by launchpad backend",
"creates signature accepted by Launchpad backend",
async () => {
pendingWithoutLedger();
pendingWithoutLaunchpad();
@ -141,11 +165,33 @@ describe("LedgerSigner", () => {
testModeAllowed: true,
hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)],
});
const [fistAccount] = await signer.getAccounts();
const [firstAccount] = await signer.getAccounts();
const client = new SigningCosmosClient(launchpad.endpoint, fistAccount.address, signer);
const result = await client.sendTokens(defaultRecipient, coins(1234567, "ucosm"));
assert(isBroadcastTxSuccess(result));
const client = new SigningCosmosClient(launchpad.endpoint, firstAccount.address, signer);
const result = await client.sendTokens(defaultLedgerAddress, coins(1234567, "ucosm"));
assertIsBroadcastTxSuccessLaunchpad(result);
},
interactiveTimeout,
);
it(
"creates signature accepted by Stargate backend",
async () => {
pendingWithoutLedger();
pendingWithoutSimapp();
const signer = new LedgerSigner(transport, {
testModeAllowed: true,
hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)],
});
const [firstAccount] = await signer.getAccounts();
const client = await SigningStargateClient.connectWithSigner(simapp.endpoint, signer);
const result = await client.sendTokens(
firstAccount.address,
defaultLedgerAddress,
coins(1234, "ucosm"),
);
assertIsBroadcastTxSuccessStargate(result);
},
interactiveTimeout,
);

View File

@ -1,3 +1,13 @@
export const faucet = {
mnemonic:
"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone",
pubkey: {
type: "tendermint/PubKeySecp256k1",
value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ",
},
address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
};
export function ledgerEnabled(): boolean {
return !!process.env.LEDGER_ENABLED;
}
@ -18,7 +28,22 @@ export function pendingWithoutLaunchpad(): void {
}
}
export function simappEnabled(): boolean {
return !!process.env.SIMAPP_ENABLED;
}
export function pendingWithoutSimapp(): void {
if (!simappEnabled()) {
return pending("Set SIMAPP_ENABLED to enable Simapp-based tests");
}
}
export const launchpad = {
endpoint: "http://localhost:1317",
chainId: "testing",
};
export const simapp = {
endpoint: "ws://localhost:26658",
chainId: "simd-testing",
};