Skip to content

Allow XDR types to generate from / output to JSON #25

@morleyzhi

Description

@morleyzhi

Broadly, this allows a developer to compose XDR representations in JSON and convert them into real XDR objects (and vice versa).

The developer story here is: a developer reads the XDR definition, writes the transaction / asset / whatever in JSON, then is able to convert it to an XDR.

For example, given the following XDR definition of Transaction:

struct Transaction
{
    // account used to run the transaction
    AccountID sourceAccount;

    // the fee the sourceAccount will pay
    uint32 fee;

    // sequence number to consume in the account
    SequenceNumber seqNum;

    // validity range (inclusive) for the last ledger close time
    TimeBounds* timeBounds;

    Memo memo;

    Operation operations<100>;

    // reserved for future use
    union switch (int v)
    {
    case 0:
        void;
    }
    ext;
};

The JSON would look like:

{
    "sourceAccount": "G...",
    "fee": 100,
    "seqNum": 1234,
    "timeBounds": null,
    "memo": {
      "type": MEMO_NONE
    },
    "operations": [
      {
        "sourceAccount": null,
        "type": CREATE_ACCOUNT,
        "destination": "G...",
        "startingBalance": 200000000
      }
    ]
    "ext": 0 // maybe default to zero-value when omitted?
};

This example is for Transaction object but in general you should be able to do the same thing with any XDR object, you check it's definition, write JSON and you can quickly convert it to actual XDR representation.

There are some things to figure out:

  • How do you represent XDR union, ex:
    union Memo switch (MemoType type)
    {
    case MEMO_NONE:
        void;
    case MEMO_TEXT:
        string text<28>;
    case MEMO_ID:
        uint64 id;
    case MEMO_HASH:
        Hash hash; // the hash of what to pull from the content server
    case MEMO_RETURN:
        Hash retHash; // the hash of the tx you are rejecting
    };
    An obvious way is to use union switch name type. So this would become:
    memo = {
     type: MEMO_TEXT,
     text: "Hello world!"
    }
    But maybe there's a better way? SEP-0011 is responsible for very similar thing but is using a different format than JSON so you can check it out.
  • Some types are just bytes and we need to be able to pass a human-readable representation if there is any. For example, AccountID type (sourceAccount in Transaction) is PublicKey which is really:
    union PublicKey switch (PublicKeyType type)
    {
    case PUBLIC_KEY_TYPE_ED25519:
        uint256 ed25519;
    };
    Would be great to have a helper methods to quickly create byte arrays, ex:
    sourceAccount: AccountId("G..."),
  • Other types require some modifications from human-readable form (ex. all amounts). We should probably have helper functions for this as well.

Originally posted by @bartekn in stellar/js-stellar-base#157 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions