From 87e0047012c102e4a8b6ff2c461ffffe28ab79ea Mon Sep 17 00:00:00 2001 From: "jinseong.cho" Date: Sun, 19 Feb 2023 03:36:42 +0900 Subject: [PATCH 1/4] feat:implement instantiate permission in amino --- .../src/modules/wasm/aminomessages.spec.ts | 56 ++++++++++++++++ .../src/modules/wasm/aminomessages.ts | 67 +++++++++++++++++-- .../src/signingcosmwasmclient.spec.ts | 21 ++++++ .../src/signingcosmwasmclient.ts | 3 + 4 files changed, 142 insertions(+), 5 deletions(-) diff --git a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts index 4f75c472..1ddb441f 100644 --- a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts +++ b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts @@ -9,6 +9,7 @@ import { MsgStoreCode, MsgUpdateAdmin, } from "cosmjs-types/cosmwasm/wasm/v1/tx"; +import { AccessType } from "cosmjs-types/cosmwasm/wasm/v1/types"; import Long from "long"; import { @@ -38,6 +39,34 @@ describe("AminoTypes", () => { value: { sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", wasm_byte_code: "WUVMTE9XIFNVQk1BUklORQ==", + instantiate_permission: undefined, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgStoreCode with access type", () => { + const msg: MsgStoreCode = { + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + wasmByteCode: fromBase64("WUVMTE9XIFNVQk1BUklORQ=="), + instantiatePermission: { + permission: AccessType.ACCESS_TYPE_ONLY_ADDRESS, + address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }; + const aminoMsg = new AminoTypes(createWasmAminoConverters()).toAmino({ + typeUrl: "/cosmwasm.wasm.v1.MsgStoreCode", + value: msg, + }); + const expected: AminoMsgStoreCode = { + type: "wasm/MsgStoreCode", + value: { + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + wasm_byte_code: "WUVMTE9XIFNVQk1BUklORQ==", + instantiate_permission: { + permission: "OnlyAddress", + address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, }, }; expect(aminoMsg).toEqual(expected); @@ -209,6 +238,33 @@ describe("AminoTypes", () => { }); }); + it("works for MsgStoreCode with access type", () => { + const aminoMsg: AminoMsgStoreCode = { + type: "wasm/MsgStoreCode", + value: { + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + wasm_byte_code: "WUVMTE9XIFNVQk1BUklORQ==", + instantiate_permission: { + permission: "OnlyAddress", + address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }, + }; + const msg = new AminoTypes(createWasmAminoConverters()).fromAmino(aminoMsg); + const expectedValue: MsgStoreCode = { + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + wasmByteCode: fromBase64("WUVMTE9XIFNVQk1BUklORQ=="), + instantiatePermission: { + permission: AccessType.ACCESS_TYPE_ONLY_ADDRESS, + address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }; + expect(msg).toEqual({ + typeUrl: "/cosmwasm.wasm.v1.MsgStoreCode", + value: expectedValue, + }); + }); + it("works for MsgInstantiateContract", () => { // With admin { diff --git a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts index 5ba5cac9..5fc534e3 100644 --- a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts +++ b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts @@ -9,13 +9,51 @@ import { MsgStoreCode, MsgUpdateAdmin, } from "cosmjs-types/cosmwasm/wasm/v1/tx"; +import { AccessType } from "cosmjs-types/cosmwasm/wasm/v1/types"; import Long from "long"; -// TODO: implement +export function accessTypeFromString(str: string): AccessType { + switch (str) { + case "Unspecified": + return AccessType.ACCESS_TYPE_UNSPECIFIED; + case "Nobody": + return AccessType.ACCESS_TYPE_NOBODY; + case "OnlyAddress": + return AccessType.ACCESS_TYPE_ONLY_ADDRESS; + case "Everybody": + return AccessType.ACCESS_TYPE_EVERYBODY; + default: + return AccessType.UNRECOGNIZED; + } +} + +export function accessTypeToString(object: any): string { + switch (object) { + case AccessType.ACCESS_TYPE_UNSPECIFIED: + return "Unspecified"; + case AccessType.ACCESS_TYPE_NOBODY: + return "Nobody"; + case AccessType.ACCESS_TYPE_ONLY_ADDRESS: + return "OnlyAddress"; + case AccessType.ACCESS_TYPE_EVERYBODY: + return "Everybody"; + case AccessType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + /** * @see https://github.com/CosmWasm/wasmd/blob/v0.18.0-rc1/proto/cosmwasm/wasm/v1/types.proto#L36-L41 */ -type AccessConfig = never; +export interface AccessConfig { + /** + * Permission should be one kind of string 'Nobody', 'OnlyAddress', 'Everybody', 'Unspecified' + * @see https://github.com/CosmWasm/wasmd/blob/v0.28.0/x/wasm/types/params.go#L54 + */ + readonly permission: string; + readonly address?: string; +} /** * The Amino JSON representation of [MsgStoreCode]. @@ -128,14 +166,33 @@ export function createWasmAminoConverters(): AminoConverters { return { "/cosmwasm.wasm.v1.MsgStoreCode": { aminoType: "wasm/MsgStoreCode", - toAmino: ({ sender, wasmByteCode }: MsgStoreCode): AminoMsgStoreCode["value"] => ({ + toAmino: ({ + sender, + wasmByteCode, + instantiatePermission, + }: MsgStoreCode): AminoMsgStoreCode["value"] => ({ sender: sender, wasm_byte_code: toBase64(wasmByteCode), + instantiate_permission: instantiatePermission + ? { + permission: accessTypeToString(instantiatePermission.permission), + address: instantiatePermission.address || undefined, + } + : undefined, }), - fromAmino: ({ sender, wasm_byte_code }: AminoMsgStoreCode["value"]): MsgStoreCode => ({ + fromAmino: ({ + sender, + wasm_byte_code, + instantiate_permission, + }: AminoMsgStoreCode["value"]): MsgStoreCode => ({ sender: sender, wasmByteCode: fromBase64(wasm_byte_code), - instantiatePermission: undefined, + instantiatePermission: instantiate_permission + ? { + permission: accessTypeFromString(instantiate_permission.permission), + address: instantiate_permission.address ?? "", + } + : undefined, }), }, "/cosmwasm.wasm.v1.MsgInstantiateContract": { diff --git a/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts b/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts index fac91980..b0c47274 100644 --- a/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts +++ b/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts @@ -20,6 +20,7 @@ import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; import { AuthInfo, TxBody, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { MsgExecuteContract, MsgStoreCode } from "cosmjs-types/cosmwasm/wasm/v1/tx"; +import { AccessConfig, AccessType } from "cosmjs-types/cosmwasm/wasm/v1/types"; import Long from "long"; import pako from "pako"; import protobuf from "protobufjs/minimal"; @@ -113,6 +114,26 @@ describe("SigningCosmWasmClient", () => { expect(codeId).toBeGreaterThanOrEqual(1); client.disconnect(); }); + + it("works with legacy Amino signer access type", async () => { + pendingWithoutWasmd(); + const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic, { prefix: wasmd.prefix }); + const options = { ...defaultSigningClientOptions, prefix: wasmd.prefix }; + const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options); + const wasm = getHackatom().data; + const accessConfig: AccessConfig = { + permission: AccessType.ACCESS_TYPE_EVERYBODY, + address: "", + }; + const { codeId, originalChecksum, originalSize, compressedChecksum, compressedSize } = + await client.upload(alice.address0, wasm, defaultUploadFee, "test memo", accessConfig); + expect(originalChecksum).toEqual(toHex(sha256(wasm))); + expect(originalSize).toEqual(wasm.length); + expect(compressedChecksum).toMatch(/^[0-9a-f]{64}$/); + expect(compressedSize).toBeLessThan(wasm.length * 0.5); + expect(codeId).toBeGreaterThanOrEqual(1); + client.disconnect(); + }); }); describe("instantiate", () => { diff --git a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts index 5d03812a..e5340da7 100644 --- a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts @@ -45,6 +45,7 @@ import { MsgStoreCode, MsgUpdateAdmin, } from "cosmjs-types/cosmwasm/wasm/v1/tx"; +import { AccessConfig } from "cosmjs-types/cosmwasm/wasm/v1/types"; import Long from "long"; import pako from "pako"; @@ -251,6 +252,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { wasmCode: Uint8Array, fee: StdFee | "auto" | number, memo = "", + instantiatePermission?: AccessConfig, ): Promise { const compressed = pako.gzip(wasmCode, { level: 9 }); const storeCodeMsg: MsgStoreCodeEncodeObject = { @@ -258,6 +260,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { value: MsgStoreCode.fromPartial({ sender: senderAddress, wasmByteCode: compressed, + instantiatePermission, }), }; From 7a453131d6556e1a0b96cdc854e6f3553c473278 Mon Sep 17 00:00:00 2001 From: "jinseong.cho" Date: Mon, 19 Jun 2023 13:24:25 +0900 Subject: [PATCH 2/4] support cosmjs-types 0.8.0 --- .../src/modules/wasm/aminomessages.spec.ts | 4 ++++ .../src/modules/wasm/aminomessages.ts | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts index 5be3ddfa..ffa7bbbd 100644 --- a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts +++ b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.spec.ts @@ -54,6 +54,7 @@ describe("AminoTypes", () => { instantiatePermission: { permission: AccessType.ACCESS_TYPE_ONLY_ADDRESS, address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + addresses: [], }, }; const aminoMsg = new AminoTypes(createWasmAminoConverters()).toAmino({ @@ -68,6 +69,7 @@ describe("AminoTypes", () => { instantiate_permission: { permission: "OnlyAddress", address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + addresses: undefined, }, }, }; @@ -315,6 +317,7 @@ describe("AminoTypes", () => { instantiate_permission: { permission: "OnlyAddress", address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + addresses: undefined, }, }, }; @@ -325,6 +328,7 @@ describe("AminoTypes", () => { instantiatePermission: { permission: AccessType.ACCESS_TYPE_ONLY_ADDRESS, address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + addresses: [], }, }; expect(msg).toEqual({ diff --git a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts index fca808d1..0bb180b6 100644 --- a/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts +++ b/packages/cosmwasm-stargate/src/modules/wasm/aminomessages.ts @@ -23,6 +23,8 @@ export function accessTypeFromString(str: string): AccessType { return AccessType.ACCESS_TYPE_ONLY_ADDRESS; case "Everybody": return AccessType.ACCESS_TYPE_EVERYBODY; + case "AnyOfAddresses": + return AccessType.ACCESS_TYPE_ANY_OF_ADDRESSES; default: return AccessType.UNRECOGNIZED; } @@ -38,6 +40,8 @@ export function accessTypeToString(object: any): string { return "OnlyAddress"; case AccessType.ACCESS_TYPE_EVERYBODY: return "Everybody"; + case AccessType.ACCESS_TYPE_ANY_OF_ADDRESSES: + return "AnyOfAddresses"; case AccessType.UNRECOGNIZED: default: return "UNRECOGNIZED"; @@ -49,11 +53,16 @@ export function accessTypeToString(object: any): string { */ export interface AccessConfig { /** - * Permission should be one kind of string 'Nobody', 'OnlyAddress', 'Everybody', 'Unspecified' - * @see https://github.com/CosmWasm/wasmd/blob/v0.28.0/x/wasm/types/params.go#L54 + * Permission should be one kind of string 'Nobody', 'OnlyAddress', 'Everybody', 'AnyOfAddresses', 'Unspecified' + * @see https://github.com/CosmWasm/wasmd/blob/v0.31.0/x/wasm/types/params.go#L54 */ readonly permission: string; + /** + * Address + * Deprecated: replaced by addresses + */ readonly address?: string; + readonly addresses?: string[]; } /** @@ -204,6 +213,8 @@ export function createWasmAminoConverters(): AminoConverters { ? { permission: accessTypeToString(instantiatePermission.permission), address: instantiatePermission.address || undefined, + addresses: + instantiatePermission.addresses.length !== 0 ? instantiatePermission.addresses : undefined, } : undefined, }), @@ -218,6 +229,7 @@ export function createWasmAminoConverters(): AminoConverters { ? { permission: accessTypeFromString(instantiate_permission.permission), address: instantiate_permission.address ?? "", + addresses: instantiate_permission.addresses ?? [], } : undefined, }), From c201dfb5ac68ddfd3c600266c232f90d3d957128 Mon Sep 17 00:00:00 2001 From: "jinseong.cho" Date: Mon, 19 Jun 2023 14:57:03 +0900 Subject: [PATCH 3/4] support addresses field in access config --- .../src/signingcosmwasmclient.spec.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts b/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts index a7ae19d8..55ab0bb8 100644 --- a/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts +++ b/packages/cosmwasm-stargate/src/signingcosmwasmclient.spec.ts @@ -136,12 +136,17 @@ describe("SigningCosmWasmClient", () => { const accessConfig: AccessConfig = { permission: AccessType.ACCESS_TYPE_EVERYBODY, address: "", + addresses: [], }; - const { codeId, originalChecksum, originalSize, compressedChecksum, compressedSize } = - await client.upload(alice.address0, wasm, defaultUploadFee, "test memo", accessConfig); - expect(originalChecksum).toEqual(toHex(sha256(wasm))); + const { codeId, checksum, originalSize, compressedSize } = await client.upload( + alice.address0, + wasm, + defaultUploadFee, + "test memo", + accessConfig, + ); + expect(checksum).toEqual(toHex(sha256(wasm))); expect(originalSize).toEqual(wasm.length); - expect(compressedChecksum).toMatch(/^[0-9a-f]{64}$/); expect(compressedSize).toBeLessThan(wasm.length * 0.5); expect(codeId).toBeGreaterThanOrEqual(1); client.disconnect(); From 15fc60d640c5fd4dca2462e70a2fd2141b3bec32 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 19 Jun 2023 15:14:27 +0200 Subject: [PATCH 4/4] CHANGELOG: Add Amino JSON support for instantiate_permission --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45c8face..264926d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,10 @@ and this project adheres to - @cosmjs/stargateAdd `StargateClient.broadcastTxSync` and `SigningStargateClient.signAndBroadcastSync` to allow broadcasting without waiting for block inclusion. ([#1396]) +- @cosmjs/cosmwasm-stargate: Add Amino JSON support for + `MsgStoreCode.instantiate_permission`. ([#334]) +[#334]: https://github.com/cosmos/cosmjs/issues/334 [#1266]: https://github.com/cosmos/cosmjs/issues/1266 [#1305]: https://github.com/cosmos/cosmjs/issues/1305 [#1396]: https://github.com/cosmos/cosmjs/pull/1396