Skip to content

Commit

Permalink
Improve Soroban XDR rendering (#746)
Browse files Browse the repository at this point in the history
  • Loading branch information
quietbits authored Feb 29, 2024
1 parent dffff83 commit b373e8a
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 9 deletions.
32 changes: 23 additions & 9 deletions src/helpers/extrapolateFromXdr.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@
// - string: string values that appear as just plain text
// - object: typed values always with a type and value `{type: 'code', value: 'Foo();'}`

import * as StellarSdk from "stellar-sdk";
import {
xdr,
StrKey,
Keypair,
Operation,
scValToNative,
nativeToScVal,
} from "stellar-sdk";
import isArray from "lodash/isArray";
import isString from "lodash/isString";
import functionsIn from "lodash/functionsIn";
import includes from "lodash/includes";
import without from "lodash/without";
import { scValByType } from "helpers/sorobanXdrUtils";

export default function extrapolateFromXdr(input, type) {
// TODO: Check to see if type exists
// TODO: input validation

let xdr, StrKey, Keypair, Operation;

xdr = StellarSdk.xdr;
StrKey = StellarSdk.StrKey;
Keypair = StellarSdk.Keypair;
Operation = StellarSdk.Operation;

function buildTreeFromObject(object, anchor, name) {
anchor.type = name;

Expand Down Expand Up @@ -59,7 +60,8 @@ export default function extrapolateFromXdr(input, type) {
if (isString(object.arm())) {
anchor.nodes = [{}];
buildTreeFromObject(
object[object.arm()](),
// Soroban or Classic
scValByType(object) ?? object[object.arm()](),
anchor.nodes[anchor.nodes.length - 1],
object.arm(),
);
Expand Down Expand Up @@ -181,6 +183,18 @@ export default function extrapolateFromXdr(input, type) {
return object.toString();
}

if (name === "contractId") {
return StrKey.encodeContract(object);
}

if (name === "functionName" || name === "sym") {
return object.toString();
}

if (name === "durability") {
return JSON.stringify(object);
}

if (object && object._isBuffer) {
return {
type: "code",
Expand Down
79 changes: 79 additions & 0 deletions src/helpers/sorobanXdrUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { StrKey, scValToNative, xdr } from "stellar-sdk";

export const scValByType = (scVal: xdr.ScVal) => {
switch (scVal.switch()) {
case xdr.ScValType.scvAddress(): {
const address = scVal.address();
const addressType = address.switch();
if (addressType.name === "scAddressTypeAccount") {
return StrKey.encodeEd25519PublicKey(address.accountId().ed25519());
}
return StrKey.encodeContract(address.contractId());
}

case xdr.ScValType.scvBool(): {
return scVal.b();
}

case xdr.ScValType.scvBytes(): {
return JSON.stringify(scVal.bytes().toJSON().data);
}

case xdr.ScValType.scvContractInstance(): {
const instance = scVal.instance();
return instance.executable().wasmHash()?.toString("base64");
}

case xdr.ScValType.scvError(): {
const error = scVal.error();
return error.value();
}

case xdr.ScValType.scvTimepoint():
case xdr.ScValType.scvDuration():
case xdr.ScValType.scvI128():
case xdr.ScValType.scvI256():
case xdr.ScValType.scvI32():
case xdr.ScValType.scvI64():
case xdr.ScValType.scvU128():
case xdr.ScValType.scvU256():
case xdr.ScValType.scvU32():
case xdr.ScValType.scvU64(): {
return scValToNative(scVal).toString();
}

case xdr.ScValType.scvLedgerKeyNonce():
case xdr.ScValType.scvLedgerKeyContractInstance(): {
if (scVal.switch().name === "scvLedgerKeyNonce") {
const val = scVal.nonceKey().nonce();
return val.toString();
}
return scVal.value();
}

case xdr.ScValType.scvVec():
case xdr.ScValType.scvMap(): {
return JSON.stringify(
scValToNative(scVal),
(_, val) => (typeof val === "bigint" ? val.toString() : val),
2,
);
}

case xdr.ScValType.scvString():
case xdr.ScValType.scvSymbol(): {
const native = scValToNative(scVal);
if (native.constructor === "Uint8Array") {
return native.toString();
}
return native;
}

case xdr.ScValType.scvVoid(): {
return null;
}

default:
return null;
}
};

0 comments on commit b373e8a

Please sign in to comment.