telescope icon indicating copy to clipboard operation
telescope copied to clipboard

`fromPartial` not generating/using interface decoders

Open NoahSaso opened this issue 1 year ago • 1 comments

The fromJSON and toJSON methods do not create a Cosmos_govv1beta1Content_FromJSON nor Cosmos_govv1beta1Content_ToJSON like the Amino encoders/decoders do.

I'm trying to take a generic proposal object (with type URL and a JSON value with a bunch of custom fields) and encode it. To do so, I was hoping to use something like Cosmos_govv1beta1Content_FromJSON to encode any of the detected proposal types automatically, but it's never created.

Instead, both functions use Any every time (example from /cosmos.gov.v1beta1.MsgSubmitProposal):

  fromJSON(object: any): MsgSubmitProposal {
    return {
      content: isSet(object.content) ? Any.fromJSON(object.content) : undefined,
      initialDeposit: Array.isArray(object?.initialDeposit) ? object.initialDeposit.map((e: any) => Coin.fromJSON(e)) : [],
      proposer: isSet(object.proposer) ? String(object.proposer) : ""
    };
  },
  toJSON(message: MsgSubmitProposal): unknown {
    const obj: any = {};
    message.content !== undefined && (obj.content = message.content ? Any.toJSON(message.content) : undefined);
    if (message.initialDeposit) {
      obj.initialDeposit = message.initialDeposit.map(e => e ? Coin.toJSON(e) : undefined);
    } else {
      obj.initialDeposit = [];
    }
    message.proposer !== undefined && (obj.proposer = message.proposer);
    return obj;
  },

NoahSaso avatar Aug 16 '23 09:08 NoahSaso

Ok so I guess fromJSON and toJSON are unnecessary, but fromPartial should do the same thing I think.

  fromPartial(object: Partial<MsgSubmitProposal>): MsgSubmitProposal {
    const message = createBaseMsgSubmitProposal();
    message.content = object.content !== undefined && object.content !== null ? Any.fromPartial(object.content) : undefined;
    message.initialDeposit = object.initialDeposit?.map(e => Coin.fromPartial(e)) || [];
    message.proposer = object.proposer ?? "";
    return message;
  },

message.content should be able to decode using a switch statement interface decoder just like the decode function. The benefit being that I can then pass an arbitrary typeUrl and value object for content to fromPartial and the decoder will figure out which protobuf it is and encode value into a Uint8Array automatically, just like decode:

  decode(input: BinaryReader | Uint8Array, length?: number): MsgSubmitProposal {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseMsgSubmitProposal();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.content = (Cosmos_govv1beta1Content_InterfaceDecoder(reader) as Any);
          break;
        case 2:
          message.initialDeposit.push(Coin.decode(reader, reader.uint32()));
          break;
        case 3:
          message.proposer = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

NoahSaso avatar Aug 16 '23 23:08 NoahSaso