mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
Add SigningCosmosClient.appendSignature
This commit is contained in:
parent
cb752e89d8
commit
4c60f883fa
@ -22,6 +22,8 @@
|
|||||||
remove such functionality from `CosmosClient.searchTx`.
|
remove such functionality from `CosmosClient.searchTx`.
|
||||||
- @cosmjs/launchpad: Add `SigningCosmosClient.sign` method for signing without
|
- @cosmjs/launchpad: Add `SigningCosmosClient.sign` method for signing without
|
||||||
broadcasting.
|
broadcasting.
|
||||||
|
- @cosmjs/launchpad: Add `SigningCosmosClient.appendSignature` method creating
|
||||||
|
transactions with multiple signatures.
|
||||||
- @cosmjs/launchpad: Add support for undefined memo in `makeSignDoc`.
|
- @cosmjs/launchpad: Add support for undefined memo in `makeSignDoc`.
|
||||||
- @cosmjs/launchpad-ledger: `LedgerSigner.sign` method renamed `signAmino`.
|
- @cosmjs/launchpad-ledger: `LedgerSigner.sign` method renamed `signAmino`.
|
||||||
- @cosmjs/proto-signing: Add new package for handling transaction signing with
|
- @cosmjs/proto-signing: Add new package for handling transaction signing with
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
makeRandomAddress,
|
makeRandomAddress,
|
||||||
pendingWithoutLaunchpad,
|
pendingWithoutLaunchpad,
|
||||||
} from "./testutils.spec";
|
} from "./testutils.spec";
|
||||||
|
import { makeCosmoshubPath } from "./wallet";
|
||||||
|
|
||||||
describe("SigningCosmosClient", () => {
|
describe("SigningCosmosClient", () => {
|
||||||
describe("makeReadOnly", () => {
|
describe("makeReadOnly", () => {
|
||||||
@ -222,4 +223,65 @@ describe("SigningCosmosClient", () => {
|
|||||||
assertIsBroadcastTxSuccess(broadcastResult);
|
assertIsBroadcastTxSuccess(broadcastResult);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("appendSignature", () => {
|
||||||
|
it("works", async () => {
|
||||||
|
pendingWithoutLaunchpad();
|
||||||
|
const wallet0 = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||||
|
const wallet1 = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||||
|
const client0 = new SigningCosmosClient(launchpad.endpoint, faucet.address0, wallet0);
|
||||||
|
const client1 = new SigningCosmosClient(launchpad.endpoint, faucet.address1, wallet1);
|
||||||
|
|
||||||
|
const msg1: MsgSend = {
|
||||||
|
type: "cosmos-sdk/MsgSend",
|
||||||
|
value: {
|
||||||
|
from_address: faucet.address0,
|
||||||
|
to_address: makeRandomAddress(),
|
||||||
|
amount: coins(1234567, "ucosm"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const msg2: MsgSend = {
|
||||||
|
type: "cosmos-sdk/MsgSend",
|
||||||
|
value: {
|
||||||
|
from_address: faucet.address1,
|
||||||
|
to_address: makeRandomAddress(),
|
||||||
|
amount: coins(1234567, "ucosm"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const fee = {
|
||||||
|
amount: coins(2000, "ucosm"),
|
||||||
|
gas: "160000", // 2*80k
|
||||||
|
};
|
||||||
|
const memo = "This must be authorized by the two of us";
|
||||||
|
|
||||||
|
const signed = await client0.sign([msg1, msg2], fee, memo);
|
||||||
|
expect(signed.msg).toEqual([msg1, msg2]);
|
||||||
|
expect(signed.fee).toEqual(fee);
|
||||||
|
expect(signed.memo).toEqual(memo);
|
||||||
|
expect(signed.signatures).toEqual([
|
||||||
|
{
|
||||||
|
pub_key: faucet.pubkey0,
|
||||||
|
signature: jasmine.stringMatching(base64Matcher),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const cosigned = await client1.appendSignature(signed);
|
||||||
|
expect(cosigned.msg).toEqual([msg1, msg2]);
|
||||||
|
expect(cosigned.fee).toEqual(fee);
|
||||||
|
expect(cosigned.memo).toEqual(memo);
|
||||||
|
expect(cosigned.signatures).toEqual([
|
||||||
|
{
|
||||||
|
pub_key: faucet.pubkey0,
|
||||||
|
signature: jasmine.stringMatching(base64Matcher),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pub_key: faucet.pubkey1,
|
||||||
|
signature: jasmine.stringMatching(base64Matcher),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const broadcastResult = await client0.broadcastTx(cosigned);
|
||||||
|
assertIsBroadcastTxSuccess(broadcastResult);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
import equals from "fast-deep-equal";
|
||||||
|
|
||||||
import { Coin } from "./coins";
|
import { Coin } from "./coins";
|
||||||
import { Account, BroadcastTxResult, CosmosClient, GetSequenceResult } from "./cosmosclient";
|
import { Account, BroadcastTxResult, CosmosClient, GetSequenceResult } from "./cosmosclient";
|
||||||
import { makeSignDoc } from "./encoding";
|
import { makeSignDoc } from "./encoding";
|
||||||
@ -102,4 +104,25 @@ export class SigningCosmosClient extends CosmosClient {
|
|||||||
const { signed, signature } = await this.signer.signAmino(this.senderAddress, signDoc);
|
const { signed, signature } = await this.signer.signAmino(this.senderAddress, signDoc);
|
||||||
return makeStdTx(signed, signature);
|
return makeStdTx(signed, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets account number and sequence from the API, creates a sign doc,
|
||||||
|
* creates a single signature and appends it to the existing signatures.
|
||||||
|
*/
|
||||||
|
public async appendSignature(signedTx: StdTx): Promise<StdTx> {
|
||||||
|
const { msg: msgs, fee, memo } = signedTx;
|
||||||
|
const { accountNumber, sequence } = await this.getSequence();
|
||||||
|
const chainId = await this.getChainId();
|
||||||
|
const signDoc = makeSignDoc(msgs, fee, chainId, memo, accountNumber, sequence);
|
||||||
|
const { signed, signature: additionalSignature } = await this.signer.signAmino(
|
||||||
|
this.senderAddress,
|
||||||
|
signDoc,
|
||||||
|
);
|
||||||
|
if (!equals(signDoc, signed)) {
|
||||||
|
throw new Error(
|
||||||
|
"The signed document differs from the one of the original transaction. This is not allowed since the resulting transaction will be invalid.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return makeStdTx(signed, [...signedTx.signatures, additionalSignature]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,22 @@ export const faucet = {
|
|||||||
type: "tendermint/PubKeySecp256k1",
|
type: "tendermint/PubKeySecp256k1",
|
||||||
value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ",
|
value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ",
|
||||||
},
|
},
|
||||||
|
pubkey1: {
|
||||||
|
type: "tendermint/PubKeySecp256k1",
|
||||||
|
value: "AiDosfIbBi54XJ1QjCeApumcy/FjdtF+YhywPf3DKTx7",
|
||||||
|
},
|
||||||
|
pubkey2: {
|
||||||
|
type: "tendermint/PubKeySecp256k1",
|
||||||
|
value: "AzQg33JZqH7vSsm09esZY5bZvmzYwE/SY78cA0iLxpD7",
|
||||||
|
},
|
||||||
|
pubkey3: {
|
||||||
|
type: "tendermint/PubKeySecp256k1",
|
||||||
|
value: "A3gOAlB6aiRTCPvWMQg2+ZbGYNsLd8qlvV28m8p2UhY2",
|
||||||
|
},
|
||||||
|
pubkey4: {
|
||||||
|
type: "tendermint/PubKeySecp256k1",
|
||||||
|
value: "Aum2063ub/ErUnIUB36sK55LktGUStgcbSiaAnL1wadu",
|
||||||
|
},
|
||||||
address0: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
|
address0: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
|
||||||
address1: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5",
|
address1: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5",
|
||||||
address2: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k",
|
address2: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k",
|
||||||
|
@ -58,4 +58,9 @@ export declare class SigningCosmosClient extends CosmosClient {
|
|||||||
* creates a single signature and assembles the signed transaction.
|
* creates a single signature and assembles the signed transaction.
|
||||||
*/
|
*/
|
||||||
sign(msgs: readonly Msg[], fee: StdFee, memo?: string): Promise<StdTx>;
|
sign(msgs: readonly Msg[], fee: StdFee, memo?: string): Promise<StdTx>;
|
||||||
|
/**
|
||||||
|
* Gets account number and sequence from the API, creates a sign doc,
|
||||||
|
* creates a single signature and appends it to the existing signatures.
|
||||||
|
*/
|
||||||
|
appendSignature(signedTx: StdTx): Promise<StdTx>;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user