From 30098f181be57698be1b8c16899d9eb161c9b427 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Tue, 24 Oct 2023 12:50:53 +0200 Subject: [PATCH 1/4] feat: ica/icq api and models definition --- package-lock.json | 12 +- package.json | 4 +- src/client/lcd/LCDClient.ts | 6 + src/client/lcd/api/ICAv1API.ts | 61 +++++++++ src/client/lcd/api/ICQv1API.ts | 25 ++++ src/core/Msg.ts | 21 ++++ .../v1/msgs/MsgRegisterInterchainAccount.ts | 119 ++++++++++++++++++ src/core/ica/controller/v1/msgs/MsgSendTx.ts | 112 +++++++++++++++++ src/core/ica/controller/v1/msgs/index.ts | 12 ++ 9 files changed, 364 insertions(+), 8 deletions(-) create mode 100644 src/client/lcd/api/ICAv1API.ts create mode 100644 src/client/lcd/api/ICQv1API.ts create mode 100644 src/core/ica/controller/v1/msgs/MsgRegisterInterchainAccount.ts create mode 100644 src/core/ica/controller/v1/msgs/MsgSendTx.ts create mode 100644 src/core/ica/controller/v1/msgs/index.ts diff --git a/package-lock.json b/package-lock.json index 8f4d4e82..fdd46186 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", - "@terra-money/terra.proto": "^4.0.3", + "@terra-money/terra.proto": "^4.0.4", "assert": "^2.0.0", "axios": "^0.27.2", "bech32": "^2.0.0", @@ -1999,9 +1999,9 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, "node_modules/@terra-money/terra.proto": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-4.0.3.tgz", - "integrity": "sha512-VSSX8ZA+RB7N1CMSMCIBXh8hoo4ZVAE7DEZ6qr+YPBhWm5Tkdwo4SVestCJouMyPNfp/Kf6ii8U8zAwedOUcNw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-4.0.4.tgz", + "integrity": "sha512-Xju3ObFvMWXCDpeOXwa+WpmcbvUFOgJ4shSSfbgocnX5q3250aTaIAaycxkArUtg1QoqV4B5qoboRAplMHYDZw==", "dependencies": { "@improbable-eng/grpc-web": "^0.14.1", "browser-headers": "^0.4.1", diff --git a/package.json b/package.json index 881eda0e..d4971a03 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "description": "The JavaScript SDK for Terra and Feather chains", "license": "MIT", "author": "Terraform Labs, PTE.", @@ -87,7 +87,7 @@ "dependencies": { "@ethersproject/bytes": "^5.7.0", "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", - "@terra-money/terra.proto": "^4.0.3", + "@terra-money/terra.proto": "^4.0.4", "assert": "^2.0.0", "axios": "^0.27.2", "bech32": "^2.0.0", diff --git a/src/client/lcd/LCDClient.ts b/src/client/lcd/LCDClient.ts index 655d744d..c39b589a 100644 --- a/src/client/lcd/LCDClient.ts +++ b/src/client/lcd/LCDClient.ts @@ -24,6 +24,8 @@ import { AllianceAPI } from './api/AllianceAPI'; import { PobAPI } from './api/PobAPI'; import { FeeshareAPI } from './api/FeeshareAPI'; import { GovV1API } from './api/GovV1API'; +import { ICAv1API } from './api/ICAv1API'; +import { ICQv1API } from './api/ICQv1API'; export interface LCDClientConfig { /** @@ -114,6 +116,8 @@ export class LCDClient { public wasm: WasmAPI; public tx: TxAPI; public ibc: IbcAPI; + public icaV1: ICAv1API; + public icqV1: ICQv1API; public ibcTransfer: IbcTransferAPI; public pob: PobAPI; public feeshare: FeeshareAPI; @@ -157,6 +161,8 @@ export class LCDClient { this.tendermint = new TendermintAPI(this); this.wasm = new WasmAPI(this); this.ibc = new IbcAPI(this); + this.icaV1 = new ICAv1API(this); + this.icqV1 = new ICQv1API(this); this.ibcTransfer = new IbcTransferAPI(this); this.tx = new TxAPI(this); this.pob = new PobAPI(this); diff --git a/src/client/lcd/api/ICAv1API.ts b/src/client/lcd/api/ICAv1API.ts new file mode 100644 index 00000000..4fbbcc89 --- /dev/null +++ b/src/client/lcd/api/ICAv1API.ts @@ -0,0 +1,61 @@ +import { Params as HostParams } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/host/v1/host'; +import { Params as ControllerParams } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/controller'; +import { APIParams } from '../APIRequester'; +import { LCDClient } from '../LCDClient'; +import { BaseAPI } from './BaseAPI'; +import { AccAddress } from 'core'; + +export class ICAv1API extends BaseAPI { + constructor(public lcd: LCDClient) { + super(lcd.apiRequesters, lcd.config); + } + + /** + * Query interchain account host module params + * + * @tags Query + * @name params + * @request GET:/ibc/apps/interchain_accounts/host/v1/params + */ + public async hostParams(chainId: string, params: Partial = {}) { + return this.getReqFromChainID(chainId).get<{ params: HostParams }>( + `/ibc/apps/interchain_accounts/host/v1/params`, + params + ); + } + + /** + * Query interchain account controller module params + * + * @tags Query + * @name params + * @request GET:/ibc/apps/interchain_accounts/controller/v1/params + */ + public async controllerParams( + chainId: string, + params: Partial = {} + ) { + return this.getReqFromChainID(chainId).get<{ params: ControllerParams }>( + `/ibc/apps/interchain_accounts/controller/v1/params`, + params + ); + } + + /** + * Returns the interchain account address for a given owner address on a given connection + * + * @tags Query + * @name params + * @request GET:/ibc/apps/interchain_accounts/controller/v1/owners/${ownerAddr}/connections/${connectionId} + */ + public async controllerAccountAddress( + ownerAddr: AccAddress, + connectionId: string, + params: Partial = {} + ) { + return this.getReqFromAddress(ownerAddr).get<{ params: ControllerParams }>( + `/ibc/apps/interchain_accounts/controller/v1/owners/${ownerAddr}/connections/${connectionId}`, + params + ); + } +} diff --git a/src/client/lcd/api/ICQv1API.ts b/src/client/lcd/api/ICQv1API.ts new file mode 100644 index 00000000..09e78e1d --- /dev/null +++ b/src/client/lcd/api/ICQv1API.ts @@ -0,0 +1,25 @@ +import { Params } from '@terra-money/terra.proto/icq/v1/icq'; +import { APIParams } from '../APIRequester'; +import { LCDClient } from '../LCDClient'; +import { BaseAPI } from './BaseAPI'; + +export class ICQv1API extends BaseAPI { + constructor(public lcd: LCDClient) { + super(lcd.apiRequesters, lcd.config); + } + + /** + * Query all parameters associated with the icq module. + * + * @tags Query + * @name params + * @summary Query icq module params + * @request GET:/async-icq/v1/params + */ + public async params(chainId: string, params: Partial = {}) { + return this.getReqFromChainID(chainId).get<{ params: Params }>( + `/async-icq/v1/params`, + params + ); + } +} diff --git a/src/core/Msg.ts b/src/core/Msg.ts index f76dbb8d..541db48e 100644 --- a/src/core/Msg.ts +++ b/src/core/Msg.ts @@ -111,6 +111,11 @@ import { MsgRegisterFeeShare, MsgUpdateFeeShare, } from './feeshare'; +import { + ICAMsg, + MsgRegisterInterchainAccount, + MsgSendTx, +} from './ica/controller/v1/msgs'; export type Msg = | BankMsg @@ -127,6 +132,7 @@ export type Msg = | IbcClientMsg | IbcConnectionMsg | IbcChannelMsg + | ICAMsg | AllianceMsg | CustomMsg | CrisisMsg @@ -169,6 +175,7 @@ export namespace Msg { | IbcClientMsg.Data | IbcConnectionMsg.Data | IbcChannelMsg.Data + | ICAMsg.Data | AllianceMsg.Data | CustomMsg.Data | CrisisMsg.Data @@ -188,6 +195,7 @@ export namespace Msg { | VestingMsg.Proto | WasmMsg.Proto | IbcTransferMsg.Proto + | ICAMsg.Proto | IbcClientMsg.Proto | IbcConnectionMsg.Proto | IbcChannelMsg.Proto @@ -492,6 +500,7 @@ export namespace Msg { return MsgAminoCustom.fromAmino(data as any, isClassic); } } + export function fromData(data: Msg.Data, isClassic?: boolean): Msg { switch (data['@type']) { // alliance @@ -616,6 +625,12 @@ export namespace Msg { case '/ibc.applications.transfer.v1.MsgTransfer': return MsgTransfer.fromData(data, isClassic); + // ibc ica + case '/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount': + return MsgRegisterInterchainAccount.fromData(data, isClassic); + case '/ibc.applications.interchain_accounts.controller.v1.MsgSendTx': + return MsgSendTx.fromData(data, isClassic); + // ibc-client case '/ibc.core.client.v1.MsgCreateClient': return MsgCreateClient.fromData(data, isClassic); @@ -814,6 +829,12 @@ export namespace Msg { case '/ibc.applications.transfer.v1.MsgTransfer': return MsgTransfer.unpackAny(proto, isClassic); + // ibc ica + case '/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount': + return MsgRegisterInterchainAccount.unpackAny(proto, isClassic); + case '/ibc.applications.interchain_accounts.controller.v1.MsgSendTx': + return MsgSendTx.unpackAny(proto, isClassic); + // ibc-client case '/ibc.core.client.v1.MsgCreateClient': return MsgCreateClient.unpackAny(proto, isClassic); diff --git a/src/core/ica/controller/v1/msgs/MsgRegisterInterchainAccount.ts b/src/core/ica/controller/v1/msgs/MsgRegisterInterchainAccount.ts new file mode 100644 index 00000000..9e873696 --- /dev/null +++ b/src/core/ica/controller/v1/msgs/MsgRegisterInterchainAccount.ts @@ -0,0 +1,119 @@ +import { AccAddress } from '../../../../bech32'; +import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; +import { JSONSerializable } from '../../../../../util/json'; +import { MsgRegisterInterchainAccount as MsgRegisterInterchainAccount_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/tx'; + +/** + * A basic message for sending [[Coins]] between Terra accounts. + */ +export class MsgRegisterInterchainAccount extends JSONSerializable< + MsgRegisterInterchainAccount.Amino, + MsgRegisterInterchainAccount.Data, + MsgRegisterInterchainAccount.Proto +> { + /** + * @param owner sender's address + * @param connectionId ibc connection id + * @param version of the interchain account + */ + constructor( + public owner: AccAddress, + public connectionId: string, + public version: string + ) { + super(); + } + + public static fromAmino( + data: MsgRegisterInterchainAccount.Amino, + _?: boolean + ): MsgRegisterInterchainAccount { + _; + data; + throw new Error('Amino not supported on MsgRegisterInterchainAccount'); + } + + public toAmino(_?: boolean): MsgRegisterInterchainAccount.Amino { + _; + throw new Error('Amino not supported on MsgRegisterInterchainAccount'); + } + + public static fromData( + data: MsgRegisterInterchainAccount.Data, + _?: boolean + ): MsgRegisterInterchainAccount { + _; + const { owner, connection_id, version } = data; + + return new MsgRegisterInterchainAccount(owner, connection_id, version); + } + + public toData(_?: boolean): MsgRegisterInterchainAccount.Data { + _; + const { owner, connectionId, version } = this; + return { + '@type': + '/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount', + owner: owner, + connection_id: connectionId, + version: version, + }; + } + + public static fromProto( + proto: MsgRegisterInterchainAccount.Proto, + _?: boolean + ): MsgRegisterInterchainAccount { + _; + return new MsgRegisterInterchainAccount( + proto.owner, + proto.connectionId, + proto.version + ); + } + + public toProto(_?: boolean): MsgRegisterInterchainAccount.Proto { + _; + const { owner, connectionId, version } = this; + return MsgRegisterInterchainAccount_pb.fromPartial({ + owner, + connectionId, + version, + }); + } + + public packAny(isClassic?: boolean): Any { + return Any.fromPartial({ + typeUrl: + '/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount', + value: MsgRegisterInterchainAccount_pb.encode( + this.toProto(isClassic) + ).finish(), + }); + } + + public static unpackAny( + msgAny: Any, + isClassic?: boolean + ): MsgRegisterInterchainAccount { + return MsgRegisterInterchainAccount.fromProto( + MsgRegisterInterchainAccount_pb.decode(msgAny.value), + isClassic + ); + } +} + +export namespace MsgRegisterInterchainAccount { + export interface Amino { + value: {}; + } + + export interface Data { + '@type': '/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount'; + owner: AccAddress; + connection_id: string; + version: string; + } + + export type Proto = MsgRegisterInterchainAccount_pb; +} diff --git a/src/core/ica/controller/v1/msgs/MsgSendTx.ts b/src/core/ica/controller/v1/msgs/MsgSendTx.ts new file mode 100644 index 00000000..01da5039 --- /dev/null +++ b/src/core/ica/controller/v1/msgs/MsgSendTx.ts @@ -0,0 +1,112 @@ +import { AccAddress } from '../../../../bech32'; +import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; +import { JSONSerializable } from '../../../../../util/json'; +import { MsgSendTx as MsgSendTx_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/tx'; +import { InterchainAccountPacketData } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; +import Long from 'long'; + +/** + * A basic message for sending [[Coins]] between Terra accounts. + */ +export class MsgSendTx extends JSONSerializable< + {}, + MsgSendTx.Data, + MsgSendTx.Proto +> { + /** + * @param owner sender's address + * @param connectionId ibc connection id + * @param version of the interchain account + */ + constructor( + public owner: AccAddress, + public connectionId: string, + public relativeTimeout: Long, + public packetData?: InterchainAccountPacketData + ) { + super(); + } + + public static fromAmino(data: MsgSendTx.Amino, _?: boolean): MsgSendTx { + _; + data; + throw new Error('Amino not supported on MsgSendTx'); + } + + public toAmino(_?: boolean): MsgSendTx.Amino { + _; + throw new Error('Amino not supported on MsgSendTx'); + } + + public static fromData(data: MsgSendTx.Data, _?: boolean): MsgSendTx { + _; + const { owner, connection_id, relative_timeout, packet_data } = data; + + return new MsgSendTx( + owner, + connection_id, + Long.fromString(relative_timeout.toString()), + packet_data + ); + } + + public toData(_?: boolean): MsgSendTx.Data { + _; + const { owner, connectionId, relativeTimeout, packetData } = this; + return { + '@type': '/ibc.applications.interchain_accounts.controller.v1.MsgSendTx', + owner: owner, + connection_id: connectionId, + relative_timeout: relativeTimeout.toString(), + packet_data: packetData, + }; + } + + public static fromProto(proto: MsgSendTx.Proto, _?: boolean): MsgSendTx { + _; + return new MsgSendTx( + proto.owner, + proto.connectionId, + proto.relativeTimeout, + proto.packetData + ); + } + + public toProto(_?: boolean): MsgSendTx.Proto { + _; + const { owner, connectionId, relativeTimeout, packetData } = this; + return MsgSendTx_pb.fromPartial({ + owner, + connectionId, + relativeTimeout, + packetData, + }); + } + + public packAny(isClassic?: boolean): Any { + return Any.fromPartial({ + typeUrl: '/ibc.applications.interchain_accounts.controller.v1.MsgSendTx', + value: MsgSendTx_pb.encode(this.toProto(isClassic)).finish(), + }); + } + + public static unpackAny(msgAny: Any, isClassic?: boolean): MsgSendTx { + return MsgSendTx.fromProto(MsgSendTx_pb.decode(msgAny.value), isClassic); + } +} + +export namespace MsgSendTx { + export interface Amino { + value: {}; + } + + export interface Data { + '@type': '/ibc.applications.interchain_accounts.controller.v1.MsgSendTx'; + owner: AccAddress; + connection_id: string; + relative_timeout: string; + packet_data?: InterchainAccountPacketData; + } + + export type Proto = MsgSendTx_pb; +} diff --git a/src/core/ica/controller/v1/msgs/index.ts b/src/core/ica/controller/v1/msgs/index.ts new file mode 100644 index 00000000..fc637551 --- /dev/null +++ b/src/core/ica/controller/v1/msgs/index.ts @@ -0,0 +1,12 @@ +import { MsgRegisterInterchainAccount } from './MsgRegisterInterchainAccount'; +import { MsgSendTx } from './MsgSendTx'; + +export * from './MsgRegisterInterchainAccount'; +export * from './MsgSendTx'; + +export type ICAMsg = MsgRegisterInterchainAccount | MsgSendTx; +export namespace ICAMsg { + export type Amino = MsgRegisterInterchainAccount.Amino | MsgSendTx.Amino; + export type Data = MsgRegisterInterchainAccount.Data | MsgSendTx.Data; + export type Proto = MsgRegisterInterchainAccount.Proto | MsgSendTx.Proto; +} From 3be667c60730b2672eb16aec4f6a618fd8b87ba6 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Wed, 25 Oct 2023 19:34:32 +0200 Subject: [PATCH 2/4] feat: ICA packet data --- package-lock.json | 4 +- package.json | 2 +- src/client/lcd/api/ICAv1API.ts | 5 +- .../v1/InterchainAccountPacketData.ts | 116 ++++++++++++++++++ src/core/ica/controller/v1/msgs/MsgSendTx.ts | 8 +- 5 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 src/core/ica/controller/v1/InterchainAccountPacketData.ts diff --git a/package-lock.json b/package-lock.json index fdd46186..233eaea2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.4", "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", diff --git a/package.json b/package.json index d4971a03..f6087f45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.4", "description": "The JavaScript SDK for Terra and Feather chains", "license": "MIT", "author": "Terraform Labs, PTE.", diff --git a/src/client/lcd/api/ICAv1API.ts b/src/client/lcd/api/ICAv1API.ts index 4fbbcc89..8c2a4186 100644 --- a/src/client/lcd/api/ICAv1API.ts +++ b/src/client/lcd/api/ICAv1API.ts @@ -1,5 +1,6 @@ import { Params as HostParams } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/host/v1/host'; import { Params as ControllerParams } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/controller'; +import { QueryInterchainAccountResponse } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/query'; import { APIParams } from '../APIRequester'; import { LCDClient } from '../LCDClient'; import { BaseAPI } from './BaseAPI'; @@ -53,7 +54,9 @@ export class ICAv1API extends BaseAPI { connectionId: string, params: Partial = {} ) { - return this.getReqFromAddress(ownerAddr).get<{ params: ControllerParams }>( + return this.getReqFromAddress( + ownerAddr + ).get( `/ibc/apps/interchain_accounts/controller/v1/owners/${ownerAddr}/connections/${connectionId}`, params ); diff --git a/src/core/ica/controller/v1/InterchainAccountPacketData.ts b/src/core/ica/controller/v1/InterchainAccountPacketData.ts new file mode 100644 index 00000000..7e87232f --- /dev/null +++ b/src/core/ica/controller/v1/InterchainAccountPacketData.ts @@ -0,0 +1,116 @@ +import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; +import { JSONSerializable } from '../../../../util/json'; +import { + InterchainAccountPacketData as InterchainAccountPacketData_pb, + Type, +} from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; + +/** + * Message to execute actions on host chain of the interchain account. + */ +export class InterchainAccountPacketData extends JSONSerializable< + {}, + InterchainAccountPacketData.Data, + InterchainAccountPacketData.Proto +> { + /** + * @param data base64 encoded proto message of the data e.g.: MsgSend_pb.encode(msgSend.toProto()).string("base64").finish() + * @param connectionId memo field data that will be passed to the message + * @param version of the message TYPE_UNSPECIFIED, TYPE_EXECUTE_TX or UNRECOGNIZED + */ + constructor( + public data: Uint8Array, + public memo: string = '', + public type: Type = Type.TYPE_EXECUTE_TX + ) { + super(); + } + + public static fromAmino( + data: InterchainAccountPacketData.Amino, + _?: boolean + ): InterchainAccountPacketData { + _; + data; + throw new Error('Amino not supported on InterchainAccountPacketData'); + } + + public toAmino(_?: boolean): InterchainAccountPacketData.Amino { + _; + throw new Error('Amino not supported on InterchainAccountPacketData'); + } + + public static fromData( + inputData: InterchainAccountPacketData.Data, + _?: boolean + ): InterchainAccountPacketData { + _; + const { data, type, memo } = inputData; + + return new InterchainAccountPacketData(data, memo, type); + } + + public toData(_?: boolean): InterchainAccountPacketData.Data { + _; + const { data, type, memo } = this; + return { + data, + type, + memo, + }; + } + + public static fromProto( + proto: InterchainAccountPacketData.Proto, + _?: boolean + ): InterchainAccountPacketData { + _; + return new InterchainAccountPacketData( + proto.data as any, + proto.memo, + proto.type + ); + } + + public toProto(_?: boolean): InterchainAccountPacketData.Proto { + _; + const { data, type, memo } = this; + return InterchainAccountPacketData_pb.fromPartial({ + data: data as any, + type, + memo, + }); + } + + public packAny(isClassic?: boolean): Any { + return Any.fromPartial({ + value: InterchainAccountPacketData_pb.encode( + this.toProto(isClassic) + ).finish(), + }); + } + + public static unpackAny( + msgAny: Any, + isClassic?: boolean + ): InterchainAccountPacketData { + return InterchainAccountPacketData.fromProto( + InterchainAccountPacketData_pb.decode(msgAny.value), + isClassic + ); + } +} + +export namespace InterchainAccountPacketData { + export interface Amino { + value: {}; + } + + export interface Data { + data: Uint8Array; + type: Type; + memo: string; + } + + export type Proto = InterchainAccountPacketData_pb; +} diff --git a/src/core/ica/controller/v1/msgs/MsgSendTx.ts b/src/core/ica/controller/v1/msgs/MsgSendTx.ts index 01da5039..cc846e02 100644 --- a/src/core/ica/controller/v1/msgs/MsgSendTx.ts +++ b/src/core/ica/controller/v1/msgs/MsgSendTx.ts @@ -2,11 +2,11 @@ import { AccAddress } from '../../../../bech32'; import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; import { JSONSerializable } from '../../../../../util/json'; import { MsgSendTx as MsgSendTx_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/tx'; -import { InterchainAccountPacketData } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; import Long from 'long'; +import { InterchainAccountPacketData } from '../InterchainAccountPacketData'; /** - * A basic message for sending [[Coins]] between Terra accounts. + * Transaction message to wrap the packet data and execute actions on host chain. */ export class MsgSendTx extends JSONSerializable< {}, @@ -69,6 +69,8 @@ export class MsgSendTx extends JSONSerializable< proto.connectionId, proto.relativeTimeout, proto.packetData + ? InterchainAccountPacketData.fromProto(proto.packetData) + : undefined ); } @@ -79,7 +81,7 @@ export class MsgSendTx extends JSONSerializable< owner, connectionId, relativeTimeout, - packetData, + packetData: packetData as any, }); } From 8f7fc360880768d5a9b5e8e48635949654db4180 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Thu, 26 Oct 2023 15:50:58 +0200 Subject: [PATCH 3/4] wip: ica models --- .../v1/InterchainAccountPacketData.ts | 116 ------------------ src/core/ica/controller/v1/msgs/MsgSendTx.ts | 50 ++++++-- 2 files changed, 43 insertions(+), 123 deletions(-) delete mode 100644 src/core/ica/controller/v1/InterchainAccountPacketData.ts diff --git a/src/core/ica/controller/v1/InterchainAccountPacketData.ts b/src/core/ica/controller/v1/InterchainAccountPacketData.ts deleted file mode 100644 index 7e87232f..00000000 --- a/src/core/ica/controller/v1/InterchainAccountPacketData.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; -import { JSONSerializable } from '../../../../util/json'; -import { - InterchainAccountPacketData as InterchainAccountPacketData_pb, - Type, -} from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; - -/** - * Message to execute actions on host chain of the interchain account. - */ -export class InterchainAccountPacketData extends JSONSerializable< - {}, - InterchainAccountPacketData.Data, - InterchainAccountPacketData.Proto -> { - /** - * @param data base64 encoded proto message of the data e.g.: MsgSend_pb.encode(msgSend.toProto()).string("base64").finish() - * @param connectionId memo field data that will be passed to the message - * @param version of the message TYPE_UNSPECIFIED, TYPE_EXECUTE_TX or UNRECOGNIZED - */ - constructor( - public data: Uint8Array, - public memo: string = '', - public type: Type = Type.TYPE_EXECUTE_TX - ) { - super(); - } - - public static fromAmino( - data: InterchainAccountPacketData.Amino, - _?: boolean - ): InterchainAccountPacketData { - _; - data; - throw new Error('Amino not supported on InterchainAccountPacketData'); - } - - public toAmino(_?: boolean): InterchainAccountPacketData.Amino { - _; - throw new Error('Amino not supported on InterchainAccountPacketData'); - } - - public static fromData( - inputData: InterchainAccountPacketData.Data, - _?: boolean - ): InterchainAccountPacketData { - _; - const { data, type, memo } = inputData; - - return new InterchainAccountPacketData(data, memo, type); - } - - public toData(_?: boolean): InterchainAccountPacketData.Data { - _; - const { data, type, memo } = this; - return { - data, - type, - memo, - }; - } - - public static fromProto( - proto: InterchainAccountPacketData.Proto, - _?: boolean - ): InterchainAccountPacketData { - _; - return new InterchainAccountPacketData( - proto.data as any, - proto.memo, - proto.type - ); - } - - public toProto(_?: boolean): InterchainAccountPacketData.Proto { - _; - const { data, type, memo } = this; - return InterchainAccountPacketData_pb.fromPartial({ - data: data as any, - type, - memo, - }); - } - - public packAny(isClassic?: boolean): Any { - return Any.fromPartial({ - value: InterchainAccountPacketData_pb.encode( - this.toProto(isClassic) - ).finish(), - }); - } - - public static unpackAny( - msgAny: Any, - isClassic?: boolean - ): InterchainAccountPacketData { - return InterchainAccountPacketData.fromProto( - InterchainAccountPacketData_pb.decode(msgAny.value), - isClassic - ); - } -} - -export namespace InterchainAccountPacketData { - export interface Amino { - value: {}; - } - - export interface Data { - data: Uint8Array; - type: Type; - memo: string; - } - - export type Proto = InterchainAccountPacketData_pb; -} diff --git a/src/core/ica/controller/v1/msgs/MsgSendTx.ts b/src/core/ica/controller/v1/msgs/MsgSendTx.ts index cc846e02..638c381d 100644 --- a/src/core/ica/controller/v1/msgs/MsgSendTx.ts +++ b/src/core/ica/controller/v1/msgs/MsgSendTx.ts @@ -3,7 +3,32 @@ import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; import { JSONSerializable } from '../../../../../util/json'; import { MsgSendTx as MsgSendTx_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/tx'; import Long from 'long'; -import { InterchainAccountPacketData } from '../InterchainAccountPacketData'; +import { + InterchainAccountPacketData as InterchainAccountPacketData_pb, + Type, +} from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; +import { Msg } from '../../../../Msg'; +import { serialize } from 'v8'; +import { MsgSend } from '@terra-money/terra.proto/cosmos/bank/v1beta1/tx'; + +export interface InterchainAccountPacketData { + type: Type; + data: Msg; + memo: string; +} +export namespace InterchainAccountPacketData { + export interface Amino { + value: {}; + } + + export interface Data { + type: Type; + data: Msg; + memo: string; + } + + export type Proto = InterchainAccountPacketData_pb; +} /** * Transaction message to wrap the packet data and execute actions on host chain. @@ -22,7 +47,7 @@ export class MsgSendTx extends JSONSerializable< public owner: AccAddress, public connectionId: string, public relativeTimeout: Long, - public packetData?: InterchainAccountPacketData + public packetData: InterchainAccountPacketData ) { super(); } @@ -64,24 +89,35 @@ export class MsgSendTx extends JSONSerializable< public static fromProto(proto: MsgSendTx.Proto, _?: boolean): MsgSendTx { _; + return new MsgSendTx( proto.owner, proto.connectionId, proto.relativeTimeout, - proto.packetData - ? InterchainAccountPacketData.fromProto(proto.packetData) - : undefined + { + data: proto.packetData?.data + ? Msg.fromProto(proto.packetData.data as any) + : Msg.fromData({} as any), + memo: proto.packetData?.memo ? proto.packetData.memo : '', + type: Type.TYPE_EXECUTE_TX, + } ); } public toProto(_?: boolean): MsgSendTx.Proto { _; const { owner, connectionId, relativeTimeout, packetData } = this; + const parsedData = serialize((packetData.data.packAny() as any).value); + return MsgSendTx_pb.fromPartial({ owner, connectionId, relativeTimeout, - packetData: packetData as any, + packetData: { + memo: packetData.memo, + type: packetData.type, + data: parsedData.toString('base64') as any, + }, }); } @@ -107,7 +143,7 @@ export namespace MsgSendTx { owner: AccAddress; connection_id: string; relative_timeout: string; - packet_data?: InterchainAccountPacketData; + packet_data: InterchainAccountPacketData; } export type Proto = MsgSendTx_pb; From 4cd45f6058faf66224806e1a730c518f837b61b6 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Fri, 27 Oct 2023 11:26:46 +0200 Subject: [PATCH 4/4] feat: ica message adjusted offchain --- package-lock.json | 4 +- package.json | 2 +- src/core/ica/controller/v1/CosmosTx.ts | 91 +++++++++++++ .../v1/InterchainAccountPacketData.ts | 121 ++++++++++++++++++ src/core/ica/controller/v1/msgs/MsgSendTx.ts | 52 ++------ 5 files changed, 225 insertions(+), 45 deletions(-) create mode 100644 src/core/ica/controller/v1/CosmosTx.ts create mode 100644 src/core/ica/controller/v1/InterchainAccountPacketData.ts diff --git a/package-lock.json b/package-lock.json index 233eaea2..85863ae3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.4", + "version": "2.0.0-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.4", + "version": "2.0.0-beta.5", "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", diff --git a/package.json b/package.json index f6087f45..7825e7e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.4", + "version": "2.0.0-beta.5", "description": "The JavaScript SDK for Terra and Feather chains", "license": "MIT", "author": "Terraform Labs, PTE.", diff --git a/src/core/ica/controller/v1/CosmosTx.ts b/src/core/ica/controller/v1/CosmosTx.ts new file mode 100644 index 00000000..66de526d --- /dev/null +++ b/src/core/ica/controller/v1/CosmosTx.ts @@ -0,0 +1,91 @@ +import { Msg } from '../../../Msg'; +import { JSONSerializable } from '../../../../util/json'; +import { CosmosTx as CosmosTx_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; +import { Any } from '@terra-money/terra.proto/google/protobuf/any'; + +/** + * CosmosTx represents the encoded transaction + */ +export class CosmosTx extends JSONSerializable< + {}, + CosmosTx.Data, + CosmosTx.Proto +> { + /** + * @param messages all proto messages that are part of the transaction + */ + constructor(public messages: Msg[]) { + super(); + } + + public static fromAmino(data: CosmosTx.Amino, _?: boolean): CosmosTx { + _; + data; + throw new Error('Amino not supported on CosmosTx'); + } + + public toAmino(_?: boolean): CosmosTx.Amino { + _; + throw new Error('Amino not supported on CosmosTx'); + } + + public static fromData(data: CosmosTx.Data, _?: boolean): CosmosTx { + _; + console.log('CosmosTx#fromData', data); + const parsedData = Buffer.from(data, 'base64'); + const { messages } = CosmosTx_pb.decode(parsedData); + return new CosmosTx(messages.map(msg => Msg.fromProto(msg))); + } + + public toData(_?: boolean): CosmosTx.Data { + _; + console.log('CosmosTx#toData', this.messages); + const { messages } = this; + + const ct = CosmosTx_pb.encode({ + messages: messages.map(msg => msg.packAny()) as Any[], + }); + + return Buffer.from(ct.finish()).toString('base64'); + } + + public static fromProto(proto: CosmosTx.Proto, _?: boolean): CosmosTx { + _; + console.log('CosmosTx#fromProto', proto); + return new CosmosTx(proto.messages.map(msg => Msg.fromProto(msg))); + } + + public toProto(_?: boolean): CosmosTx.Proto { + _; + console.log('CosmosTx#toProto', this.messages); + const { messages } = this; + + const ct = CosmosTx_pb.encode({ + messages: messages.map(msg => msg.packAny()) as Any[], + }); + + return Buffer.from(ct.finish()).toString('base64') as any; + } + + public packAny(isClassic?: boolean): Any { + console.log('CosmosTx#packAny', this.messages); + return Any.fromPartial({ + value: this.toProto(isClassic) as any, + }); + } + + public static unpackAny(msgAny: Any, isClassic?: boolean): CosmosTx { + console.log('CosmosTx#unpackAny', msgAny); + return CosmosTx.fromProto(CosmosTx_pb.decode(msgAny.value), isClassic); + } +} + +export namespace CosmosTx { + export interface Amino { + value: {}; + } + type Base64String = string; + export type Data = Base64String; + + export type Proto = CosmosTx_pb; +} diff --git a/src/core/ica/controller/v1/InterchainAccountPacketData.ts b/src/core/ica/controller/v1/InterchainAccountPacketData.ts new file mode 100644 index 00000000..22a39685 --- /dev/null +++ b/src/core/ica/controller/v1/InterchainAccountPacketData.ts @@ -0,0 +1,121 @@ +import { JSONSerializable } from '../../../../util/json'; +import { + InterchainAccountPacketData as InterchainAccountPacketData_pb, + Type, +} from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; +import { CosmosTx } from './CosmosTx'; +import { Any } from '@terra-money/terra.proto/google/protobuf/any'; + +/** + * PacketData represents the encoded data to be executed on + * host chain by the intechain account. + */ +export class InterchainAccountPacketData extends JSONSerializable< + {}, + InterchainAccountPacketData.Data, + InterchainAccountPacketData.Proto +> { + /** + * @param data to be executed on host chain + * @param memo for the transaction to be executed on host chain + * @param type by default is **TYPE_EXECUTE_TX** which means that the Msg is converted from proto TYPE_UNSPECIFIED, TYPE_EXECUTE_TX or UNRECOGNIZED + */ + constructor( + public data: CosmosTx, + public memo: string = '', + public type: Type = Type.TYPE_EXECUTE_TX + ) { + super(); + } + + public static fromAmino( + data: InterchainAccountPacketData.Amino, + _?: boolean + ): InterchainAccountPacketData { + _; + data; + throw new Error('Amino not supported on InterchainAccountPacketData'); + } + + public toAmino(_?: boolean): InterchainAccountPacketData.Amino { + _; + throw new Error('Amino not supported on InterchainAccountPacketData'); + } + + public static fromData( + packetData: InterchainAccountPacketData.Data, + _?: boolean + ): InterchainAccountPacketData { + _; + const { data, memo, type } = packetData; + + return new InterchainAccountPacketData(CosmosTx.fromData(data), memo, type); + } + + public toData(_?: boolean): InterchainAccountPacketData.Data { + _; + const { data, memo, type } = this; + return { + data: data.toData(), + memo, + type, + }; + } + + public static fromProto( + proto: InterchainAccountPacketData.Proto, + _?: boolean + ): InterchainAccountPacketData { + _; + + return new InterchainAccountPacketData( + CosmosTx.unpackAny(proto.data as any), + proto.memo, + proto.type + ); + } + + public toProto(_?: boolean): InterchainAccountPacketData.Proto { + _; + const { data, memo, type } = this; + + return InterchainAccountPacketData_pb.fromPartial({ + data: data.toProto() as any, + memo, + type, + }); + } + + public packAny(isClassic?: boolean): Any { + return Any.fromPartial({ + value: InterchainAccountPacketData_pb.encode( + this.toProto(isClassic) + ).finish(), + }); + } + + public static unpackAny( + msgAny: Any, + isClassic?: boolean + ): InterchainAccountPacketData { + return InterchainAccountPacketData.fromProto( + InterchainAccountPacketData_pb.decode(msgAny.value), + isClassic + ); + } +} + +export namespace InterchainAccountPacketData { + export interface Amino { + value: {}; + } + + type Base64String = string; + export interface Data { + type: Type; + data: Base64String; + memo: string; + } + + export type Proto = InterchainAccountPacketData_pb; +} diff --git a/src/core/ica/controller/v1/msgs/MsgSendTx.ts b/src/core/ica/controller/v1/msgs/MsgSendTx.ts index 638c381d..1d439237 100644 --- a/src/core/ica/controller/v1/msgs/MsgSendTx.ts +++ b/src/core/ica/controller/v1/msgs/MsgSendTx.ts @@ -3,32 +3,7 @@ import { Any } from '@terra-money/legacy.proto/google/protobuf/any'; import { JSONSerializable } from '../../../../../util/json'; import { MsgSendTx as MsgSendTx_pb } from '@terra-money/terra.proto/ibc/applications/interchain_accounts/controller/v1/tx'; import Long from 'long'; -import { - InterchainAccountPacketData as InterchainAccountPacketData_pb, - Type, -} from '@terra-money/terra.proto/ibc/applications/interchain_accounts/v1/packet'; -import { Msg } from '../../../../Msg'; -import { serialize } from 'v8'; -import { MsgSend } from '@terra-money/terra.proto/cosmos/bank/v1beta1/tx'; - -export interface InterchainAccountPacketData { - type: Type; - data: Msg; - memo: string; -} -export namespace InterchainAccountPacketData { - export interface Amino { - value: {}; - } - - export interface Data { - type: Type; - data: Msg; - memo: string; - } - - export type Proto = InterchainAccountPacketData_pb; -} +import { InterchainAccountPacketData } from '../InterchainAccountPacketData'; /** * Transaction message to wrap the packet data and execute actions on host chain. @@ -47,7 +22,7 @@ export class MsgSendTx extends JSONSerializable< public owner: AccAddress, public connectionId: string, public relativeTimeout: Long, - public packetData: InterchainAccountPacketData + public packetData?: InterchainAccountPacketData ) { super(); } @@ -72,6 +47,8 @@ export class MsgSendTx extends JSONSerializable< connection_id, Long.fromString(relative_timeout.toString()), packet_data + ? InterchainAccountPacketData.fromData(packet_data) + : undefined ); } @@ -83,7 +60,7 @@ export class MsgSendTx extends JSONSerializable< owner: owner, connection_id: connectionId, relative_timeout: relativeTimeout.toString(), - packet_data: packetData, + packet_data: packetData ? packetData.toData() : undefined, }; } @@ -94,30 +71,21 @@ export class MsgSendTx extends JSONSerializable< proto.owner, proto.connectionId, proto.relativeTimeout, - { - data: proto.packetData?.data - ? Msg.fromProto(proto.packetData.data as any) - : Msg.fromData({} as any), - memo: proto.packetData?.memo ? proto.packetData.memo : '', - type: Type.TYPE_EXECUTE_TX, - } + proto.packetData + ? InterchainAccountPacketData.fromProto(proto.packetData) + : undefined ); } public toProto(_?: boolean): MsgSendTx.Proto { _; const { owner, connectionId, relativeTimeout, packetData } = this; - const parsedData = serialize((packetData.data.packAny() as any).value); return MsgSendTx_pb.fromPartial({ owner, connectionId, relativeTimeout, - packetData: { - memo: packetData.memo, - type: packetData.type, - data: parsedData.toString('base64') as any, - }, + packetData: packetData?.toProto(), }); } @@ -143,7 +111,7 @@ export namespace MsgSendTx { owner: AccAddress; connection_id: string; relative_timeout: string; - packet_data: InterchainAccountPacketData; + packet_data?: InterchainAccountPacketData.Data; } export type Proto = MsgSendTx_pb;