Merge pull request #693 from cosmos/support-different-generated-types
Bring back support for pbjs generated types
This commit is contained in:
commit
f4d313b56a
@ -1,4 +1,12 @@
|
||||
export { EncodeObject, GeneratedType, Registry } from "./registry";
|
||||
export {
|
||||
isPbjsGeneratedType,
|
||||
isTsProtoGeneratedType,
|
||||
EncodeObject,
|
||||
GeneratedType,
|
||||
Registry,
|
||||
TsProtoGeneratedType,
|
||||
PbjsGeneratedType,
|
||||
} from "./registry";
|
||||
export { DirectSecp256k1HdWallet } from "./directsecp256k1hdwallet";
|
||||
export { DirectSecp256k1Wallet } from "./directsecp256k1wallet";
|
||||
export { makeCosmoshubPath } from "./paths";
|
||||
|
||||
@ -1,17 +1,23 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { fromHex } from "@cosmjs/encoding";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import Long from "long";
|
||||
import { Field, Type } from "protobufjs";
|
||||
|
||||
import { MsgSend as IMsgSend } from "./codec/cosmos/bank/v1beta1/tx";
|
||||
import { TxBody } from "./codec/cosmos/tx/v1beta1/tx";
|
||||
import { Any } from "./codec/google/protobuf/any";
|
||||
import { Registry } from "./registry";
|
||||
import { isPbjsGeneratedType, isTsProtoGeneratedType, Registry } from "./registry";
|
||||
|
||||
describe("registry demo", () => {
|
||||
it("works with a default msg", () => {
|
||||
const registry = new Registry();
|
||||
const Coin = registry.lookupType("/cosmos.base.v1beta1.Coin")!;
|
||||
const MsgSend = registry.lookupType("/cosmos.bank.v1beta1.MsgSend")!;
|
||||
const Coin = registry.lookupType("/cosmos.base.v1beta1.Coin");
|
||||
const MsgSend = registry.lookupType("/cosmos.bank.v1beta1.MsgSend");
|
||||
assert(Coin);
|
||||
assert(MsgSend);
|
||||
assert(isTsProtoGeneratedType(Coin));
|
||||
assert(isTsProtoGeneratedType(MsgSend));
|
||||
|
||||
const coin = Coin.fromPartial({
|
||||
denom: "ucosm",
|
||||
@ -49,35 +55,53 @@ describe("registry demo", () => {
|
||||
expect(msgSendDecoded.amount).toEqual(msgSend.amount);
|
||||
});
|
||||
|
||||
// TODO: Can't autogenerate types from TS code using ts-proto
|
||||
// it("works with a custom msg", () => {
|
||||
// const typeUrl = "/demo.MsgDemo";
|
||||
// const registry = new Registry([[typeUrl, MsgDemoType]]);
|
||||
// const MsgDemo = registry.lookupType(typeUrl)!;
|
||||
it("works with a custom msg", () => {
|
||||
// From https://gist.github.com/fadeev/a4981eff1cf3a805ef10e25313d5f2b7
|
||||
const typeUrl = "/blog.MsgCreatePost";
|
||||
const MsgCreatePostOriginal = new Type("MsgCreatePost")
|
||||
.add(new Field("creator", 1, "string"))
|
||||
.add(new Field("title", 2, "string"))
|
||||
.add(new Field("body", 3, "string"))
|
||||
.add(new Field("attachment", 4, "bytes"));
|
||||
|
||||
// const msgDemo = MsgDemo.fromPartial({
|
||||
// example: "Some example text",
|
||||
// });
|
||||
// const msgDemoBytes = MsgDemo.encode(msgDemo).finish();
|
||||
// const msgDemoWrapped = Any.create({
|
||||
// type_url: typeUrl,
|
||||
// value: msgDemoBytes,
|
||||
// });
|
||||
// const txBody = TxBody.create({
|
||||
// messages: [msgDemoWrapped],
|
||||
// memo: "Some memo",
|
||||
// timeoutHeight: Long.fromNumber(9999),
|
||||
// extensionOptions: [],
|
||||
// });
|
||||
// const txBodyBytes = TxBody.encode(txBody).finish();
|
||||
const registry = new Registry([[typeUrl, MsgCreatePostOriginal]]);
|
||||
const MsgCreatePost = registry.lookupType(typeUrl);
|
||||
assert(MsgCreatePost);
|
||||
assert(isPbjsGeneratedType(MsgCreatePost));
|
||||
|
||||
// const txBodyDecoded = TxBody.decode(txBodyBytes);
|
||||
// const msg = txBodyDecoded.messages[0];
|
||||
// assert(msg.type_url);
|
||||
// assert(msg.value);
|
||||
const msgDemo = MsgCreatePost.create({
|
||||
creator: "Me",
|
||||
title: "Something with stars",
|
||||
body: "la la la",
|
||||
attachment: fromHex("AABBAABB66FE"),
|
||||
});
|
||||
const msgDemoBytes = MsgCreatePost.encode(msgDemo).finish();
|
||||
const msgDemoWrapped = Any.fromPartial({
|
||||
typeUrl: typeUrl,
|
||||
value: msgDemoBytes,
|
||||
});
|
||||
const txBody = TxBody.fromPartial({
|
||||
messages: [msgDemoWrapped],
|
||||
memo: "Some memo",
|
||||
timeoutHeight: Long.fromNumber(9999),
|
||||
extensionOptions: [],
|
||||
});
|
||||
const txBodyBytes = TxBody.encode(txBody).finish();
|
||||
|
||||
// const decoder = registry.lookupType(msg.type_url)!;
|
||||
// const msgDemoDecoded = decoder.decode(msg.value);
|
||||
// expect(msgDemoDecoded.example).toEqual(msgDemo.example);
|
||||
// });
|
||||
const txBodyDecoded = TxBody.decode(txBodyBytes);
|
||||
const msg = txBodyDecoded.messages[0];
|
||||
assert(msg.typeUrl);
|
||||
assert(msg.value);
|
||||
|
||||
const decoder = registry.lookupType(msg.typeUrl)!;
|
||||
const msgDemoDecoded = decoder.decode(msg.value);
|
||||
expect(msgDemoDecoded).toEqual(
|
||||
jasmine.objectContaining({
|
||||
creator: "Me",
|
||||
title: "Something with stars",
|
||||
body: "la la la",
|
||||
}),
|
||||
);
|
||||
expect(Uint8Array.from(msgDemoDecoded.attachment)).toEqual(fromHex("AABBAABB66FE"));
|
||||
});
|
||||
});
|
||||
|
||||
@ -7,7 +7,10 @@ import { Coin } from "./codec/cosmos/base/v1beta1/coin";
|
||||
import { TxBody } from "./codec/cosmos/tx/v1beta1/tx";
|
||||
import { Any } from "./codec/google/protobuf/any";
|
||||
|
||||
export interface GeneratedType {
|
||||
/**
|
||||
* A type generated by [ts-proto](https://github.com/stephenh/ts-proto).
|
||||
*/
|
||||
export interface TsProtoGeneratedType {
|
||||
readonly encode: (message: any | { [k: string]: any }, writer?: protobuf.Writer) => protobuf.Writer;
|
||||
readonly decode: (input: Uint8Array | protobuf.Reader, length?: number) => any;
|
||||
readonly fromJSON: (object: { [k: string]: any }) => any;
|
||||
@ -15,6 +18,28 @@ export interface GeneratedType {
|
||||
readonly toJSON: (message: any | { [k: string]: any }) => unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* A type generated by [protobufjs](https://github.com/protobufjs/protobuf.js).
|
||||
*
|
||||
* This can be used if you want to create types at runtime using pure JavaScript.
|
||||
* See https://gist.github.com/fadeev/a4981eff1cf3a805ef10e25313d5f2b7
|
||||
*/
|
||||
export interface PbjsGeneratedType {
|
||||
readonly create: (properties?: { [k: string]: any }) => any;
|
||||
readonly encode: (message: any | { [k: string]: any }, writer?: protobuf.Writer) => protobuf.Writer;
|
||||
readonly decode: (reader: protobuf.Reader | Uint8Array, length?: number) => any;
|
||||
}
|
||||
|
||||
export type GeneratedType = TsProtoGeneratedType | PbjsGeneratedType;
|
||||
|
||||
export function isTsProtoGeneratedType(type: GeneratedType): type is TsProtoGeneratedType {
|
||||
return typeof (type as TsProtoGeneratedType).fromPartial === "function";
|
||||
}
|
||||
|
||||
export function isPbjsGeneratedType(type: GeneratedType): type is PbjsGeneratedType {
|
||||
return !isTsProtoGeneratedType(type);
|
||||
}
|
||||
|
||||
export interface EncodeObject {
|
||||
readonly typeUrl: string;
|
||||
readonly value: any;
|
||||
@ -56,6 +81,22 @@ export class Registry {
|
||||
this.types.set(typeUrl, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a type that was previously added to the registry.
|
||||
*
|
||||
* The generator information (ts-proto or pbjs) gets lost along the way.
|
||||
* If you need to work with the result type in TypeScript, you can use:
|
||||
*
|
||||
* ```
|
||||
* import { assert } from "@cosmjs/utils";
|
||||
*
|
||||
* const Coin = registry.lookupType("/cosmos.base.v1beta1.Coin");
|
||||
* assert(Coin); // Ensures not unset
|
||||
* assert(isTsProtoGeneratedType(Coin)); // Ensures this is the type we expect
|
||||
*
|
||||
* // Coin is typed TsProtoGeneratedType now.
|
||||
* ```
|
||||
*/
|
||||
public lookupType(typeUrl: string): GeneratedType | undefined {
|
||||
return this.types.get(typeUrl);
|
||||
}
|
||||
@ -73,8 +114,8 @@ export class Registry {
|
||||
return this.encodeTxBody(value);
|
||||
}
|
||||
const type = this.lookupTypeWithError(typeUrl);
|
||||
const created = type.fromPartial(value);
|
||||
return Uint8Array.from(type.encode(created).finish());
|
||||
const instance = isTsProtoGeneratedType(type) ? type.fromPartial(value) : type.create(value);
|
||||
return Uint8Array.from(type.encode(instance).finish());
|
||||
}
|
||||
|
||||
public encodeTxBody(txBodyFields: TxBodyValue): Uint8Array {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user