diff --git a/CHANGELOG.md b/CHANGELOG.md index 39c01ae8..e9b9f68e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ - @cosmjs/launchpad: Create `WrappedTx`, `WrappedStdTx` and `isWrappedStdTx` to better represent the Amino tx interface. Deprecate `CosmosSdkTx`, which is an alias for `WrappedStdTx`. +- @cosmjs/launchpad: Add `makeStdTx` to create an `StdTx`. - @cosmjs/launchpad-ledger: Add package supporting Ledger device integration for Launchpad. Two new classes are provided: `LedgerSigner` (for most use cases) and `LaunchpadLedger` for more fine-grained access. diff --git a/packages/cli/README.md b/packages/cli/README.md index 8c5fbdfb..47818805 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -74,13 +74,8 @@ const signDoc = makeSignDoc( account_number, sequence, ); -const { signature } = await wallet.sign(faucetAddress, signDoc); -const signedTx: StdTx = { - msg: [sendTokensMsg], - fee: defaultFee, - memo: memo, - signatures: [signature], -}; +const { signed, signature } = await wallet.sign(faucetAddress, signDoc); +const signedTx = makeStdTx(signed, signature); const broadcastResult = await client.broadcastTx(signedTx); ``` diff --git a/packages/cli/examples/delegate.ts b/packages/cli/examples/delegate.ts index 199ed2b6..edcdfcfb 100644 --- a/packages/cli/examples/delegate.ts +++ b/packages/cli/examples/delegate.ts @@ -28,13 +28,8 @@ const { accountNumber, sequence } = await client.getSequence(senderAddress); console.log("Account/sequence:", accountNumber, sequence); const signDoc = makeSignDoc([msg], fee, chainId, memo, accountNumber, sequence); -const { signature } = await wallet.sign(senderAddress, signDoc); -const signedTx: StdTx = { - msg: [msg], - fee: fee, - memo: memo, - signatures: [signature], -}; +const { signed, signature } = await wallet.sign(senderAddress, signDoc); +const signedTx = makeStdTx(signed, signature); const result = await client.broadcastTx(signedTx); console.log("Broadcast result:", result); diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index 32b0ac14..cc3ad5e9 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -99,6 +99,7 @@ export async function main(originalArgs: readonly string[]): Promise { "logs", "makeCosmoshubPath", "makeSignDoc", + "makeStdTx", "IndexedTx", "BroadcastTxResult", "Coin", diff --git a/packages/cosmwasm/src/cosmwasmclient.searchtx.spec.ts b/packages/cosmwasm/src/cosmwasmclient.searchtx.spec.ts index db6af67a..9c386d77 100644 --- a/packages/cosmwasm/src/cosmwasmclient.searchtx.spec.ts +++ b/packages/cosmwasm/src/cosmwasmclient.searchtx.spec.ts @@ -6,6 +6,7 @@ import { isMsgSend, LcdClient, makeSignDoc, + makeStdTx, MsgSend, Secp256k1Wallet, WrappedStdTx, @@ -104,15 +105,10 @@ describe("CosmWasmClient.searchTx", () => { const { accountNumber, sequence } = await client.getSequence(); const chainId = await client.getChainId(); const signDoc = makeSignDoc([sendMsg], fee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(alice.address0, signDoc); + const { signed, signature } = await wallet.sign(alice.address0, signDoc); const tx: WrappedStdTx = { type: "cosmos-sdk/StdTx", - value: { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }, + value: makeStdTx(signed, signature), }; const transactionId = await client.getIdentifier(tx); const result = await client.broadcastTx(tx.value); diff --git a/packages/cosmwasm/src/cosmwasmclient.spec.ts b/packages/cosmwasm/src/cosmwasmclient.spec.ts index ec0f895b..1e1143d1 100644 --- a/packages/cosmwasm/src/cosmwasmclient.spec.ts +++ b/packages/cosmwasm/src/cosmwasmclient.spec.ts @@ -5,10 +5,10 @@ import { assertIsBroadcastTxSuccess, isWrappedStdTx, makeSignDoc, + makeStdTx, MsgSend, Secp256k1Wallet, StdFee, - StdTx, } from "@cosmjs/launchpad"; import { assert, sleep } from "@cosmjs/utils"; import { ReadonlyDate } from "readonly-date"; @@ -240,13 +240,8 @@ describe("CosmWasmClient", () => { const chainId = await client.getChainId(); const { accountNumber, sequence } = await client.getSequence(alice.address0); const signDoc = makeSignDoc([sendMsg], fee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(alice.address0, signDoc); - const signedTx: StdTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(alice.address0, signDoc); + const signedTx = makeStdTx(signed, signature); const result = await client.broadcastTx(signedTx); assertIsBroadcastTxSuccess(result); const { logs, transactionHash } = result; diff --git a/packages/cosmwasm/src/lcdapi/wasm.spec.ts b/packages/cosmwasm/src/lcdapi/wasm.spec.ts index 199d915a..459ecdf7 100644 --- a/packages/cosmwasm/src/lcdapi/wasm.spec.ts +++ b/packages/cosmwasm/src/lcdapi/wasm.spec.ts @@ -11,6 +11,7 @@ import { coins, LcdClient, makeSignDoc, + makeStdTx, OfflineSigner, Secp256k1Wallet, setupAuthExtension, @@ -36,7 +37,6 @@ import { fromOneElementArray, getHackatom, makeRandomAddress, - makeSignedTx, pendingWithoutWasmd, wasmd, wasmdEnabled, @@ -126,8 +126,8 @@ async function executeContract( const { account_number, sequence } = (await client.auth.account(alice.address0)).result.value; const signDoc = makeSignDoc([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const { signature } = await signer.sign(alice.address0, signDoc); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); + const { signed, signature } = await signer.sign(alice.address0, signDoc); + const signedTx = makeStdTx(signed, signature); return client.broadcastTx(signedTx); } diff --git a/packages/cosmwasm/src/signingcosmwasmclient.ts b/packages/cosmwasm/src/signingcosmwasmclient.ts index 07ff9fa8..1930deb7 100644 --- a/packages/cosmwasm/src/signingcosmwasmclient.ts +++ b/packages/cosmwasm/src/signingcosmwasmclient.ts @@ -12,11 +12,11 @@ import { GasPrice, isBroadcastTxFailure, makeSignDoc, + makeStdTx, Msg, MsgSend, OfflineSigner, StdFee, - StdTx, } from "@cosmjs/launchpad"; import { Uint53 } from "@cosmjs/math"; import pako from "pako"; @@ -361,13 +361,8 @@ export class SigningCosmWasmClient extends CosmWasmClient { const { accountNumber, sequence } = await this.getSequence(); const chainId = await this.getChainId(); const signDoc = makeSignDoc(msgs, fee, chainId, memo, accountNumber, sequence); - const { signature } = await this.signer.sign(this.senderAddress, signDoc); - const signedTx: StdTx = { - msg: msgs, - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await this.signer.sign(this.senderAddress, signDoc); + const signedTx = makeStdTx(signed, signature); return this.broadcastTx(signedTx); } } diff --git a/packages/cosmwasm/src/testutils.spec.ts b/packages/cosmwasm/src/testutils.spec.ts index 765d2e8a..fd780bf6 100644 --- a/packages/cosmwasm/src/testutils.spec.ts +++ b/packages/cosmwasm/src/testutils.spec.ts @@ -1,6 +1,5 @@ import { Random } from "@cosmjs/crypto"; import { Bech32, fromBase64 } from "@cosmjs/encoding"; -import { Msg, StdFee, StdSignature, StdTx } from "@cosmjs/launchpad"; import hackatom from "./testdata/contract.json"; @@ -89,12 +88,3 @@ export function fromOneElementArray(elements: ArrayLike): T { if (elements.length !== 1) throw new Error(`Expected exactly one element but got ${elements.length}`); return elements[0]; } - -export function makeSignedTx(firstMsg: Msg, fee: StdFee, memo: string, firstSignature: StdSignature): StdTx { - return { - msg: [firstMsg], - fee: fee, - memo: memo, - signatures: [firstSignature], - }; -} diff --git a/packages/launchpad/README.md b/packages/launchpad/README.md index 9015b820..3ecedbf0 100644 --- a/packages/launchpad/README.md +++ b/packages/launchpad/README.md @@ -206,13 +206,8 @@ const { account_number, sequence } = ( await client.auth.account(myAddress) ).result.value; const signDoc = makeSignDoc([msg], fee, apiUrl, memo, account_number, sequence); -const { signature } = await signer.sign(myAddress, signDoc); -const signedTx: StdTx = { - msg: [msg], - fee: fee, - memo: memo, - signatures: [signature], -}; +const { signed, signature } = await signer.sign(myAddress, signDoc); +const signedTx = makeStdTx(signed, signature); const result = await client.postTx(signedTx); assertIsPostTxSuccess(result); ``` diff --git a/packages/launchpad/src/cosmosclient.searchtx.spec.ts b/packages/launchpad/src/cosmosclient.searchtx.spec.ts index e6f06067..5ff15c3a 100644 --- a/packages/launchpad/src/cosmosclient.searchtx.spec.ts +++ b/packages/launchpad/src/cosmosclient.searchtx.spec.ts @@ -16,7 +16,7 @@ import { wasmd, wasmdEnabled, } from "./testutils.spec"; -import { WrappedStdTx } from "./tx"; +import { makeStdTx, WrappedStdTx } from "./tx"; interface TestTxSend { readonly sender: string; @@ -56,15 +56,10 @@ describe("CosmosClient.searchTx", () => { const { accountNumber, sequence } = await client.getSequence(); const chainId = await client.getChainId(); const signDoc = makeSignDoc([sendMsg], fee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(walletAddress, signDoc); + const { signed, signature } = await wallet.sign(walletAddress, signDoc); const tx: WrappedStdTx = { type: "cosmos-sdk/StdTx", - value: { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }, + value: makeStdTx(signed, signature), }; const transactionId = await client.getIdentifier(tx); const result = await client.broadcastTx(tx.value); diff --git a/packages/launchpad/src/cosmosclient.spec.ts b/packages/launchpad/src/cosmosclient.spec.ts index 4cf1deba..95ee11b3 100644 --- a/packages/launchpad/src/cosmosclient.spec.ts +++ b/packages/launchpad/src/cosmosclient.spec.ts @@ -16,7 +16,7 @@ import { unused, wasmd, } from "./testutils.spec"; -import { isWrappedStdTx, StdTx } from "./tx"; +import { isWrappedStdTx, makeStdTx } from "./tx"; import { StdFee } from "./types"; const blockTime = 1_000; // ms @@ -232,13 +232,8 @@ describe("CosmosClient", () => { const chainId = await client.getChainId(); const { accountNumber, sequence } = await client.getSequence(faucet.address); const signDoc = makeSignDoc([sendMsg], fee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(walletAddress, signDoc); - const signedTx: StdTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(walletAddress, signDoc); + const signedTx = makeStdTx(signed, signature); const txResult = await client.broadcastTx(signedTx); assertIsBroadcastTxSuccess(txResult); const { logs, transactionHash } = txResult; diff --git a/packages/launchpad/src/encoding.ts b/packages/launchpad/src/encoding.ts index 970d69b1..81bafa2f 100644 --- a/packages/launchpad/src/encoding.ts +++ b/packages/launchpad/src/encoding.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { toUtf8 } from "@cosmjs/encoding"; +import { Uint53 } from "@cosmjs/math"; -import { uint64ToString } from "./lcdapi"; import { Msg } from "./msgs"; import { StdFee } from "./types"; @@ -47,8 +47,8 @@ export function makeSignDoc( ): StdSignDoc { return { chain_id: chainId, - account_number: uint64ToString(accountNumber), - sequence: uint64ToString(sequence), + account_number: Uint53.fromString(accountNumber.toString()).toString(), + sequence: Uint53.fromString(sequence.toString()).toString(), fee: fee, msgs: msgs, memo: memo, diff --git a/packages/launchpad/src/index.ts b/packages/launchpad/src/index.ts index ed8aa4ad..a703e61f 100644 --- a/packages/launchpad/src/index.ts +++ b/packages/launchpad/src/index.ts @@ -100,7 +100,7 @@ export { findSequenceForSignedTx } from "./sequence"; export { encodeSecp256k1Signature, decodeSignature } from "./signature"; export { AccountData, Algo, OfflineSigner, SignResponse } from "./signer"; export { CosmosFeeTable, SigningCosmosClient } from "./signingcosmosclient"; -export { isStdTx, isWrappedStdTx, CosmosSdkTx, StdTx, WrappedStdTx, WrappedTx } from "./tx"; +export { isStdTx, isWrappedStdTx, makeStdTx, CosmosSdkTx, StdTx, WrappedStdTx, WrappedTx } from "./tx"; export { pubkeyType, PubKey, StdFee, StdSignature } from "./types"; export { makeCosmoshubPath, executeKdf, KdfConfiguration } from "./wallet"; export { extractKdfConfiguration, Secp256k1Wallet } from "./secp256k1wallet"; diff --git a/packages/launchpad/src/lcdapi/distribution.spec.ts b/packages/launchpad/src/lcdapi/distribution.spec.ts index df624284..dc9f402e 100644 --- a/packages/launchpad/src/lcdapi/distribution.spec.ts +++ b/packages/launchpad/src/lcdapi/distribution.spec.ts @@ -16,6 +16,7 @@ import { wasmd, wasmdEnabled, } from "../testutils.spec"; +import { makeStdTx } from "../tx"; import { DistributionExtension, setupDistributionExtension } from "./distribution"; import { LcdClient } from "./lcdclient"; @@ -46,15 +47,10 @@ describe("DistributionExtension", () => { const memo = "Test delegation for wasmd"; const { accountNumber, sequence } = await client.getSequence(); const signDoc = makeSignDoc([msg], defaultFee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(faucet.address, signDoc); - const tx = { - msg: [msg], - fee: defaultFee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(faucet.address, signDoc); + const signedTx = makeStdTx(signed, signature); - const result = await client.broadcastTx(tx); + const result = await client.broadcastTx(signedTx); assertIsBroadcastTxSuccess(result); await sleep(75); // wait until transactions are indexed diff --git a/packages/launchpad/src/lcdapi/lcdclient.spec.ts b/packages/launchpad/src/lcdapi/lcdclient.spec.ts index b971823b..051d8d86 100644 --- a/packages/launchpad/src/lcdapi/lcdclient.spec.ts +++ b/packages/launchpad/src/lcdapi/lcdclient.spec.ts @@ -12,7 +12,6 @@ import cosmoshub from "../testdata/cosmoshub.json"; import { faucet, makeRandomAddress, - makeSignedTx, nonNegativeIntegerMatcher, pendingWithoutWasmd, tendermintIdMatcher, @@ -20,7 +19,7 @@ import { wasmd, wasmdEnabled, } from "../testutils.spec"; -import { isWrappedStdTx, StdTx } from "../tx"; +import { isWrappedStdTx, makeStdTx, StdTx } from "../tx"; import { StdFee } from "../types"; import { makeCosmoshubPath } from "../wallet"; import { setupAuthExtension } from "./auth"; @@ -241,13 +240,8 @@ describe("LcdClient", () => { const { accountNumber, sequence } = await client.getSequence(); const chainId = await client.getChainId(); const signDoc = makeSignDoc([sendMsg], fee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(walletAddress, signDoc); - const signedTx: StdTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(walletAddress, signDoc); + const signedTx = makeStdTx(signed, signature); const transactionId = await client.getIdentifier({ type: "cosmos-sdk/StdTx", value: signedTx }); const result = await client.broadcastTx(signedTx); assert(isBroadcastTxFailure(result)); @@ -540,8 +534,8 @@ describe("LcdClient", () => { const { account_number, sequence } = (await client.auth.account(faucet.address)).result.value; const signDoc = makeSignDoc([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const { signature } = await wallet.sign(walletAddress, signDoc); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); + const { signed, signature } = await wallet.sign(walletAddress, signDoc); + const signedTx = makeStdTx(signed, signature); const result = await client.broadcastTx(signedTx); expect(result.code).toBeUndefined(); expect(result).toEqual({ @@ -661,13 +655,8 @@ describe("LcdClient", () => { const { account_number, sequence } = (await client.auth.account(walletAddress)).result.value; const signDoc = makeSignDoc([msg1, msg2], fee, wasmd.chainId, memo, account_number, sequence); - const { signature } = await wallet.sign(walletAddress, signDoc); - const signedTx: StdTx = { - msg: [msg1, msg2], - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(walletAddress, signDoc); + const signedTx = makeStdTx(signed, signature); const broadcastResult = await client.broadcastTx(signedTx); expect(broadcastResult.code).toBeUndefined(); }); diff --git a/packages/launchpad/src/lcdapi/staking.spec.ts b/packages/launchpad/src/lcdapi/staking.spec.ts index a188fa89..c7e1439a 100644 --- a/packages/launchpad/src/lcdapi/staking.spec.ts +++ b/packages/launchpad/src/lcdapi/staking.spec.ts @@ -16,6 +16,7 @@ import { wasmd, wasmdEnabled, } from "../testutils.spec"; +import { makeStdTx } from "../tx"; import { LcdClient } from "./lcdclient"; import { BondStatus, setupStakingExtension, StakingExtension } from "./staking"; @@ -47,15 +48,10 @@ describe("StakingExtension", () => { const memo = "Test delegation for wasmd"; const { accountNumber, sequence } = await client.getSequence(); const signDoc = makeSignDoc([msg], defaultFee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(faucet.address, signDoc); - const tx = { - msg: [msg], - fee: defaultFee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(faucet.address, signDoc); + const signedTx = makeStdTx(signed, signature); - const result = await client.broadcastTx(tx); + const result = await client.broadcastTx(signedTx); assertIsBroadcastTxSuccess(result); } { @@ -70,15 +66,10 @@ describe("StakingExtension", () => { const memo = "Test undelegation for wasmd"; const { accountNumber, sequence } = await client.getSequence(); const signDoc = makeSignDoc([msg], defaultFee, chainId, memo, accountNumber, sequence); - const { signature } = await wallet.sign(faucet.address, signDoc); - const tx = { - msg: [msg], - fee: defaultFee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await wallet.sign(faucet.address, signDoc); + const signedTx = makeStdTx(signed, signature); - const result = await client.broadcastTx(tx); + const result = await client.broadcastTx(signedTx); assertIsBroadcastTxSuccess(result); } diff --git a/packages/launchpad/src/secp256k1wallet.spec.ts b/packages/launchpad/src/secp256k1wallet.spec.ts index 87d6c7a9..f7f6f867 100644 --- a/packages/launchpad/src/secp256k1wallet.spec.ts +++ b/packages/launchpad/src/secp256k1wallet.spec.ts @@ -120,10 +120,11 @@ describe("Secp256k1Wallet", () => { account_number: "7", sequence: "54", }; - const { signature } = await wallet.sign(defaultAddress, signDoc); + const { signed, signature } = await wallet.sign(defaultAddress, signDoc); + expect(signed).toEqual(signDoc); const valid = await Secp256k1.verifySignature( Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)), - new Sha256(serializeSignDoc(signDoc)).digest(), + new Sha256(serializeSignDoc(signed)).digest(), defaultPubkey, ); expect(valid).toEqual(true); diff --git a/packages/launchpad/src/signingcosmosclient.ts b/packages/launchpad/src/signingcosmosclient.ts index 0c1edd5c..77090274 100644 --- a/packages/launchpad/src/signingcosmosclient.ts +++ b/packages/launchpad/src/signingcosmosclient.ts @@ -6,7 +6,7 @@ import { buildFeeTable, FeeTable, GasLimits, GasPrice } from "./gas"; import { BroadcastMode } from "./lcdapi"; import { Msg, MsgSend } from "./msgs"; import { OfflineSigner } from "./signer"; -import { StdTx } from "./tx"; +import { makeStdTx } from "./tx"; import { StdFee } from "./types"; /** @@ -90,13 +90,8 @@ export class SigningCosmosClient extends CosmosClient { const { accountNumber, sequence } = await this.getSequence(); const chainId = await this.getChainId(); const signDoc = makeSignDoc(msgs, fee, chainId, memo, accountNumber, sequence); - const { signature } = await this.signer.sign(this.senderAddress, signDoc); - const signedTx: StdTx = { - msg: msgs, - fee: fee, - memo: memo, - signatures: [signature], - }; + const { signed, signature } = await this.signer.sign(this.senderAddress, signDoc); + const signedTx = makeStdTx(signed, signature); return this.broadcastTx(signedTx); } } diff --git a/packages/launchpad/src/testutils.spec.ts b/packages/launchpad/src/testutils.spec.ts index 335880b1..66a0f592 100644 --- a/packages/launchpad/src/testutils.spec.ts +++ b/packages/launchpad/src/testutils.spec.ts @@ -1,10 +1,6 @@ import { Random } from "@cosmjs/crypto"; import { Bech32 } from "@cosmjs/encoding"; -import { Msg } from "./msgs"; -import { StdTx } from "./tx"; -import { StdFee, StdSignature } from "./types"; - export function makeRandomAddress(): string { return Bech32.encode("cosmos", Random.getBytes(20)); } @@ -75,12 +71,3 @@ export function fromOneElementArray(elements: ArrayLike): T { if (elements.length !== 1) throw new Error(`Expected exactly one element but got ${elements.length}`); return elements[0]; } - -export function makeSignedTx(firstMsg: Msg, fee: StdFee, memo: string, firstSignature: StdSignature): StdTx { - return { - msg: [firstMsg], - fee: fee, - memo: memo, - signatures: [firstSignature], - }; -} diff --git a/packages/launchpad/src/tx.spec.ts b/packages/launchpad/src/tx.spec.ts new file mode 100644 index 00000000..21bf834f --- /dev/null +++ b/packages/launchpad/src/tx.spec.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { coins } from "./coins"; +import { makeSignDoc } from "./encoding"; +import { makeStdTx } from "./tx"; +import { StdFee, StdSignature } from "./types"; + +describe("tx", () => { + describe("makeStdTx", () => { + it("can make an StdTx from a SignDoc and one signature", () => { + const fee: StdFee = { amount: coins(123, "ucosm"), gas: "22" }; + const signDoc = makeSignDoc([], fee, "chain-xy", "hello", 3, 4); + const signature: StdSignature = { + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }; + const signedTx = makeStdTx(signDoc, signature); + expect(signedTx).toEqual({ + msg: [], + memo: "hello", + fee: fee, + signatures: [signature], + }); + }); + + it("can make an StdTx from a SignDoc and multiple signatures", () => { + const fee: StdFee = { amount: coins(123, "ucosm"), gas: "22" }; + const signDoc = makeSignDoc([], fee, "chain-xy", "hello", 3, 4); + const signature1: StdSignature = { + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }; + const signature2: StdSignature = { + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "A5qFcJBJvEK/fOmEAY0DHNWwSRZ9TEfNZyH8VoVvDtAq", + }, + signature: "NK1Oy4EUGAsoC03c1wi9GG03JC/39LEdautC5Jk643oIbEPqeXHMwaqbdvO/Jws0X/NAXaN8SAy2KNY5Qml+5Q==", + }; + const signedTx = makeStdTx(signDoc, [signature1, signature2]); + expect(signedTx).toEqual({ + msg: [], + memo: "hello", + fee: fee, + signatures: [signature1, signature2], + }); + }); + }); +}); diff --git a/packages/launchpad/src/tx.ts b/packages/launchpad/src/tx.ts index 53c0198c..a466c9f4 100644 --- a/packages/launchpad/src/tx.ts +++ b/packages/launchpad/src/tx.ts @@ -1,3 +1,4 @@ +import { StdSignDoc } from "./encoding"; import { Msg } from "./msgs"; import { StdFee, StdSignature } from "./types"; @@ -20,6 +21,18 @@ export function isStdTx(txValue: unknown): txValue is StdTx { ); } +export function makeStdTx( + content: Pick, + signatures: StdSignature | readonly StdSignature[], +): StdTx { + return { + msg: content.msgs, + fee: content.fee, + memo: content.memo, + signatures: Array.isArray(signatures) ? signatures : [signatures], + }; +} + /** * An Amino JSON wrapper around the Tx interface */ diff --git a/packages/launchpad/types/index.d.ts b/packages/launchpad/types/index.d.ts index 4a87457a..196653ce 100644 --- a/packages/launchpad/types/index.d.ts +++ b/packages/launchpad/types/index.d.ts @@ -98,7 +98,7 @@ export { findSequenceForSignedTx } from "./sequence"; export { encodeSecp256k1Signature, decodeSignature } from "./signature"; export { AccountData, Algo, OfflineSigner, SignResponse } from "./signer"; export { CosmosFeeTable, SigningCosmosClient } from "./signingcosmosclient"; -export { isStdTx, isWrappedStdTx, CosmosSdkTx, StdTx, WrappedStdTx, WrappedTx } from "./tx"; +export { isStdTx, isWrappedStdTx, makeStdTx, CosmosSdkTx, StdTx, WrappedStdTx, WrappedTx } from "./tx"; export { pubkeyType, PubKey, StdFee, StdSignature } from "./types"; export { makeCosmoshubPath, executeKdf, KdfConfiguration } from "./wallet"; export { extractKdfConfiguration, Secp256k1Wallet } from "./secp256k1wallet"; diff --git a/packages/launchpad/types/tx.d.ts b/packages/launchpad/types/tx.d.ts index 8bf6134e..501dc880 100644 --- a/packages/launchpad/types/tx.d.ts +++ b/packages/launchpad/types/tx.d.ts @@ -1,3 +1,4 @@ +import { StdSignDoc } from "./encoding"; import { Msg } from "./msgs"; import { StdFee, StdSignature } from "./types"; /** @@ -12,6 +13,10 @@ export interface StdTx { readonly memo: string | undefined; } export declare function isStdTx(txValue: unknown): txValue is StdTx; +export declare function makeStdTx( + content: Pick, + signatures: StdSignature | readonly StdSignature[], +): StdTx; /** * An Amino JSON wrapper around the Tx interface */