Skip to content

Union.toXDR fails when using a defaultArm different to Void. #30

@abuiles

Description

@abuiles

When creating a union, If defaultArm declaration uses a type different to XDR.Void - you can't call toXDR on it.

What version are you on?
1.1.1

To Reproduce

const XDR = require('js-xdr');

const types = XDR.config((xdr) => {
  xdr.enum("TransactionMetaType", {
    none: 0,
    paid: 1,
    pending: 2,
    rejected: 3,
  });

  xdr.union("TransactionMeta", {
    switchOn: xdr.lookup("TransactionMetaType"),
    switches: [
      ["none", xdr.void()],
      ["paid", "price"],
      ["rejected", "rejected"],
    ],
    arms: {
      price: xdr.int(),
      rejected: xdr.string(5)
    },
    defaultArm: xdr.string(28),
  });
});

const transactionMeta = types.TransactionMeta.pending("waiting for KYC");

try {
  console.log(transactionMeta.toXDR())
} catch(e) {
  console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  console.log("Calling transactionMeta.toXDR() fails with the following error because _armType is not defined");
  console.log(e);
  console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

  // Doing the following works
  transactionMeta._armType = transactionMeta._arm
  console.log(transactionMeta.toXDR())
}

Expected behavior
You should be able to convert toXDR unions with a defaultArm different to Void.

declaration:
           type-specifier identifier
         | type-specifier identifier "[" value "]"
         | type-specifier identifier "<" [ value ] ">"
         | "opaque" identifier "[" value "]"
         | "opaque" identifier "<" [ value ] ">"
         | "string" identifier "<" [ value ] ">"
         | type-specifier "*" identifier
         | "void"

union-body:
   "switch" "(" declaration ")" "{"
      case-spec
      case-spec *
      [ "default" ":" declaration ";" ]
   "}"

Culprit

The root of the issue is likely here

this._armType = this.constructor.armTypeForArm(this._arm);

Which calls

return this._arms[arm];

It needs to keep into account the default arm (which doesn't have a matching value in _arms)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions