diff --git a/packages/sdk/src/cosmwasmclient.spec.ts b/packages/sdk/src/cosmwasmclient.spec.ts index 740b00aa..27ff42e3 100644 --- a/packages/sdk/src/cosmwasmclient.spec.ts +++ b/packages/sdk/src/cosmwasmclient.spec.ts @@ -1,5 +1,5 @@ import { CosmWasmClient } from "./cosmwasmclient"; -import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding"; +import { makeSignBytes, marshalTx } from "./encoding"; import { findAttribute } from "./logs"; import { Secp256k1Pen } from "./pen"; import { RestClient } from "./restclient"; @@ -95,7 +95,7 @@ describe("CosmWasmClient", () => { const chainId = await client.chainId(); const { accountNumber, sequence } = await client.getNonce(faucet.address); const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence); - const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signature = await pen.sign(signBytes); const signedTx = { msg: [sendMsg], fee: fee, @@ -113,9 +113,7 @@ describe("CosmWasmClient", () => { it("works", async () => { pendingWithoutCosmos(); const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { - return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); - }); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); const codeId = await client.upload(getRandomizedHackatom()); expect(codeId).toBeGreaterThanOrEqual(1); }); @@ -125,9 +123,7 @@ describe("CosmWasmClient", () => { it("works with transfer amount", async () => { pendingWithoutCosmos(); const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { - return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); - }); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); const codeId = await client.upload(getRandomizedHackatom()); const transferAmount: readonly Coin[] = [ @@ -159,9 +155,7 @@ describe("CosmWasmClient", () => { it("can instantiate one code multiple times", async () => { pendingWithoutCosmos(); const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { - return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); - }); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); const codeId = await client.upload(getRandomizedHackatom()); const contractAddress1 = await client.instantiate(codeId, { @@ -180,9 +174,7 @@ describe("CosmWasmClient", () => { it("works", async () => { pendingWithoutCosmos(); const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { - return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); - }); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); const codeId = await client.upload(getRandomizedHackatom()); // instantiate diff --git a/packages/sdk/src/encoding.spec.ts b/packages/sdk/src/encoding.spec.ts index 6aeb8f61..ccdb8a4a 100644 --- a/packages/sdk/src/encoding.spec.ts +++ b/packages/sdk/src/encoding.spec.ts @@ -1,59 +1 @@ -import { Encoding } from "@iov/encoding"; - -import { encodeSecp256k1Signature } from "./encoding"; - -const { fromBase64 } = Encoding; - -describe("encoding", () => { - describe("encodeSecp256k1Signature", () => { - it("encodes a full signature", () => { - const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); - const signature = fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ); - expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }); - }); - - it("compresses uncompressed public keys", () => { - const pubkey = fromBase64( - "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", - ); - const signature = fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ); - expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }); - }); - - it("removes recovery values from signature data", () => { - const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); - const signature = Uint8Array.from([ - ...fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ), - 99, - ]); - expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }); - }); - }); -}); +describe("encoding", () => {}); diff --git a/packages/sdk/src/encoding.ts b/packages/sdk/src/encoding.ts index c8045b36..8a782944 100644 --- a/packages/sdk/src/encoding.ts +++ b/packages/sdk/src/encoding.ts @@ -1,10 +1,8 @@ -import { Secp256k1 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; -import { encodeSecp256k1Pubkey } from "./pubkey"; -import { Msg, StdFee, StdSignature, StdTx } from "./types"; +import { Msg, StdFee, StdTx } from "./types"; -const { toBase64, toUtf8 } = Encoding; +const { toUtf8 } = Encoding; function sortJson(json: any): any { if (typeof json !== "object" || json === null) { @@ -59,12 +57,3 @@ export function makeSignBytes( const signMsg = sortJson(signJson); return toUtf8(JSON.stringify(signMsg)); } - -export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature { - return { - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: encodeSecp256k1Pubkey(pubkey), - // Recovery seems to be unused - signature: toBase64(Secp256k1.trimRecoveryByte(signature)), - }; -} diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index a3331203..294c81f8 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -4,8 +4,9 @@ export { logs, types }; export { CosmosAddressBech32Prefix, encodeAddress, isValidAddress } from "./address"; export { unmarshalTx } from "./decoding"; -export { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding"; +export { makeSignBytes, marshalTx } from "./encoding"; export { RestClient, TxsResponse } from "./restclient"; +export { encodeSecp256k1Signature } from "./signature"; export { CosmWasmClient, ExecuteResult, GetNonceResult, PostTxResult } from "./cosmwasmclient"; export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen"; export { diff --git a/packages/sdk/src/pen.spec.ts b/packages/sdk/src/pen.spec.ts index 7ea39cee..57c71c78 100644 --- a/packages/sdk/src/pen.spec.ts +++ b/packages/sdk/src/pen.spec.ts @@ -2,6 +2,7 @@ import { Secp256k1, Secp256k1Signature, Sha256 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; import { Secp256k1Pen } from "./pen"; +import { decodeSignature } from "./signature"; const { fromHex } = Encoding; @@ -33,12 +34,12 @@ describe("Sec256k1Pen", () => { "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling", ); const data = Encoding.toAscii("foo bar"); - const signature = await pen.createSignature(data); + const { pubkey, signature } = decodeSignature(await pen.sign(data)); const valid = await Secp256k1.verifySignature( new Secp256k1Signature(signature.slice(0, 32), signature.slice(32, 64)), new Sha256(data).digest(), - pen.pubkey, + pubkey, ); expect(valid).toEqual(true); }); diff --git a/packages/sdk/src/pen.ts b/packages/sdk/src/pen.ts index f50d2465..86037fe2 100644 --- a/packages/sdk/src/pen.ts +++ b/packages/sdk/src/pen.ts @@ -9,6 +9,9 @@ import { Slip10RawIndex, } from "@iov/crypto"; +import { encodeSecp256k1Signature } from "./signature"; +import { StdSignature } from "./types"; + export type PrehashType = "sha256" | "sha512" | null; /** @@ -23,7 +26,7 @@ export type PrehashType = "sha256" | "sha512" | null; */ export interface Pen { readonly pubkey: Uint8Array; - readonly createSignature: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; + readonly sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; } function prehash(bytes: Uint8Array, type: PrehashType): Uint8Array { @@ -73,14 +76,12 @@ export class Secp256k1Pen implements Pen { } /** - * Creates a fixed length encoding of the signature parameters r (32 bytes) and s (32 bytes). + * Creates and returns a signature */ - public async createSignature( - signBytes: Uint8Array, - prehashType: PrehashType = "sha256", - ): Promise { + public async sign(signBytes: Uint8Array, prehashType: PrehashType = "sha256"): Promise { const message = prehash(signBytes, prehashType); const signature = await Secp256k1.createSignature(message, this.privkey); - return new Uint8Array([...signature.r(32), ...signature.s(32)]); + const fixedLengthSignature = new Uint8Array([...signature.r(32), ...signature.s(32)]); + return encodeSecp256k1Signature(this.pubkey, fixedLengthSignature); } } diff --git a/packages/sdk/src/restclient.spec.ts b/packages/sdk/src/restclient.spec.ts index 26a654b7..9862d178 100644 --- a/packages/sdk/src/restclient.spec.ts +++ b/packages/sdk/src/restclient.spec.ts @@ -3,7 +3,7 @@ import { Sha256 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; import { assert } from "@iov/utils"; -import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding"; +import { makeSignBytes, marshalTx } from "./encoding"; import { findAttribute, parseLogs } from "./logs"; import { Pen, Secp256k1Pen } from "./pen"; import { encodeBech32Pubkey } from "./pubkey"; @@ -86,7 +86,7 @@ async function uploadCustomContract( const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence); - const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signature = await pen.sign(signBytes); const signedTx = makeSignedTx(theMsg, fee, memo, signature); return client.postTx(marshalTx(signedTx)); } @@ -127,7 +127,7 @@ async function instantiateContract( const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence); - const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signature = await pen.sign(signBytes); const signedTx = makeSignedTx(theMsg, fee, memo, signature); return client.postTx(marshalTx(signedTx)); } @@ -159,7 +159,7 @@ async function executeContract( const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence); - const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signature = await pen.sign(signBytes); const signedTx = makeSignedTx(theMsg, fee, memo, signature); return client.postTx(marshalTx(signedTx)); } @@ -261,7 +261,7 @@ describe("RestClient", () => { const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence); - const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signature = await pen.sign(signBytes); const signedTx = makeSignedTx(theMsg, fee, memo, signature); const result = await client.postTx(marshalTx(signedTx)); // console.log("Raw log:", result.raw_log); diff --git a/packages/sdk/src/signature.spec.ts b/packages/sdk/src/signature.spec.ts new file mode 100644 index 00000000..23dc8cda --- /dev/null +++ b/packages/sdk/src/signature.spec.ts @@ -0,0 +1,79 @@ +import { Encoding } from "@iov/encoding"; + +import { decodeSignature, encodeSecp256k1Signature } from "./signature"; +import { StdSignature } from "./types"; + +const { fromBase64 } = Encoding; + +describe("signature", () => { + describe("encodeSecp256k1Signature", () => { + it("encodes a full signature", () => { + const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); + const signature = fromBase64( + "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + ); + expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ + // eslint-disable-next-line @typescript-eslint/camelcase + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }); + }); + + it("compresses uncompressed public keys", () => { + const pubkey = fromBase64( + "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", + ); + const signature = fromBase64( + "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + ); + expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ + // eslint-disable-next-line @typescript-eslint/camelcase + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }); + }); + + it("removes recovery values from signature data", () => { + const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); + const signature = Uint8Array.from([ + ...fromBase64( + "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + ), + 99, + ]); + expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ + // eslint-disable-next-line @typescript-eslint/camelcase + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }); + }); + }); + + describe("decodeSignature", () => { + it("works for secp256k1", () => { + const signature: StdSignature = { + // eslint-disable-next-line @typescript-eslint/camelcase + pub_key: { + type: "tendermint/PubKeySecp256k1", + value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", + }, + signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + }; + expect(decodeSignature(signature)).toEqual({ + pubkey: fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"), + signature: fromBase64( + "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", + ), + }); + }); + }); +}); diff --git a/packages/sdk/src/signature.ts b/packages/sdk/src/signature.ts new file mode 100644 index 00000000..56eb6af6 --- /dev/null +++ b/packages/sdk/src/signature.ts @@ -0,0 +1,29 @@ +import { Secp256k1 } from "@iov/crypto"; +import { Encoding } from "@iov/encoding"; + +import { encodeSecp256k1Pubkey } from "./pubkey"; +import { pubkeyType, StdSignature } from "./types"; + +export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature { + return { + // eslint-disable-next-line @typescript-eslint/camelcase + pub_key: encodeSecp256k1Pubkey(pubkey), + // Recovery seems to be unused + signature: Encoding.toBase64(Secp256k1.trimRecoveryByte(signature)), + }; +} + +export function decodeSignature( + signature: StdSignature, +): { readonly pubkey: Uint8Array; readonly signature: Uint8Array } { + switch (signature.pub_key.type) { + // Note: please don't add cases here without writing additional unit tests + case pubkeyType.secp256k1: + return { + pubkey: Encoding.fromBase64(signature.pub_key.value), + signature: Encoding.fromBase64(signature.signature), + }; + default: + throw new Error("Unsupported pubkey type"); + } +} diff --git a/packages/sdk/types/encoding.d.ts b/packages/sdk/types/encoding.d.ts index e4a6c77f..4d32b80b 100644 --- a/packages/sdk/types/encoding.d.ts +++ b/packages/sdk/types/encoding.d.ts @@ -1,4 +1,4 @@ -import { Msg, StdFee, StdSignature, StdTx } from "./types"; +import { Msg, StdFee, StdTx } from "./types"; export declare function marshalTx(tx: StdTx): Uint8Array; export declare function makeSignBytes( msgs: readonly Msg[], @@ -8,4 +8,3 @@ export declare function makeSignBytes( accountNumber: number, sequence: number, ): Uint8Array; -export declare function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature; diff --git a/packages/sdk/types/index.d.ts b/packages/sdk/types/index.d.ts index 9250b24c..ec6bdaca 100644 --- a/packages/sdk/types/index.d.ts +++ b/packages/sdk/types/index.d.ts @@ -3,8 +3,9 @@ import * as types from "./types"; export { logs, types }; export { CosmosAddressBech32Prefix, encodeAddress, isValidAddress } from "./address"; export { unmarshalTx } from "./decoding"; -export { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding"; +export { makeSignBytes, marshalTx } from "./encoding"; export { RestClient, TxsResponse } from "./restclient"; +export { encodeSecp256k1Signature } from "./signature"; export { CosmWasmClient, ExecuteResult, GetNonceResult, PostTxResult } from "./cosmwasmclient"; export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen"; export { diff --git a/packages/sdk/types/pen.d.ts b/packages/sdk/types/pen.d.ts index 08a3f8d8..ee129395 100644 --- a/packages/sdk/types/pen.d.ts +++ b/packages/sdk/types/pen.d.ts @@ -1,4 +1,5 @@ import { Slip10RawIndex } from "@iov/crypto"; +import { StdSignature } from "./types"; export declare type PrehashType = "sha256" | "sha512" | null; /** * A pen is the most basic tool you can think of for signing. It works @@ -12,7 +13,7 @@ export declare type PrehashType = "sha256" | "sha512" | null; */ export interface Pen { readonly pubkey: Uint8Array; - readonly createSignature: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; + readonly sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; } /** * The Cosmoshub derivation path in the form `m/44'/118'/0'/0/a` @@ -25,7 +26,7 @@ export declare class Secp256k1Pen implements Pen { private readonly privkey; private constructor(); /** - * Creates a fixed length encoding of the signature parameters r (32 bytes) and s (32 bytes). + * Creates and returns a signature */ - createSignature(signBytes: Uint8Array, prehashType?: PrehashType): Promise; + sign(signBytes: Uint8Array, prehashType?: PrehashType): Promise; } diff --git a/packages/sdk/types/signature.d.ts b/packages/sdk/types/signature.d.ts new file mode 100644 index 00000000..c6908ddc --- /dev/null +++ b/packages/sdk/types/signature.d.ts @@ -0,0 +1,8 @@ +import { StdSignature } from "./types"; +export declare function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature; +export declare function decodeSignature( + signature: StdSignature, +): { + readonly pubkey: Uint8Array; + readonly signature: Uint8Array; +}; diff --git a/scripts/cosm/deploy_erc20.js b/scripts/cosm/deploy_erc20.js index 94ed3522..1420a113 100755 --- a/scripts/cosm/deploy_erc20.js +++ b/scripts/cosm/deploy_erc20.js @@ -1,7 +1,7 @@ #!/usr/bin/env node /* eslint-disable @typescript-eslint/camelcase */ -const { CosmWasmClient, encodeSecp256k1Signature, Secp256k1Pen } = require("@cosmwasm/sdk"); +const { CosmWasmClient, Secp256k1Pen } = require("@cosmwasm/sdk"); const fs = require("fs"); const httpUrl = "http://localhost:1317"; @@ -56,9 +56,7 @@ const initMsgCash = { async function main() { const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { - return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); - }); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); const wasm = fs.readFileSync(__dirname + "/contracts/cw-erc20.wasm"); const codeId = await client.upload(wasm, "Upload ERC20 contract");