Skip to content

Commit

Permalink
View XDR stream + update Trezor deps (#1178)
Browse files Browse the repository at this point in the history
* View XDR stream + update Trezor deps

* Show proper array of JSON objects
  • Loading branch information
quietbits authored Dec 4, 2024
1 parent 29c2377 commit 7294bec
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 180 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
"@ledgerhq/hw-transport-webusb": "^6.29.4",
"@stellar/design-system": "^2.0.0-beta.17",
"@stellar/stellar-sdk": "^13.0.0",
"@stellar/stellar-xdr-json": "^22.0.0-rc.1",
"@stellar/stellar-xdr-json": "^22.0.0-rc.1.1",
"@tanstack/react-query": "^5.59.0",
"@tanstack/react-query-devtools": "^5.59.0",
"@trezor/connect-plugin-stellar": "^9.0.3",
"@trezor/connect-web": "^9.4.2",
"@trezor/connect-plugin-stellar": "^9.0.6",
"@trezor/connect-web": "^9.4.4",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"bignumber.js": "^9.1.2",
"dompurify": "^3.1.7",
Expand Down
76 changes: 67 additions & 9 deletions src/app/(sidebar)/xdr/view/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { delayedAction } from "@/helpers/delayedAction";
import { getNetworkHeaders } from "@/helpers/getNetworkHeaders";
import { useIsXdrInit } from "@/hooks/useIsXdrInit";
import { useStore } from "@/store/useStore";
import { AnyObject } from "@/types/types";

export default function ViewXdr() {
const { xdr, network } = useStore();
Expand Down Expand Up @@ -60,6 +61,28 @@ export default function ViewXdr() {

const isFetchingLatestTxn = isLatestTxnFetching || isLatestTxnLoading;

const maybeStreamXdr = (
xdrType: string,
xdrString: string,
originalError: any,
) => {
try {
const streamXdrJson = StellarXdr.decode_stream(xdrType, xdrString);

return {
jsonString: JSON.stringify(streamXdrJson),
jsonArray: streamXdrJson.map((s) => parseToLosslessJson(s)),
error: "",
};
} catch (e) {
// If the stream fails, assume that the XDR is invalid and return the original error.
return {
jsonString: "",
error: `Unable to decode input as ${xdrType}: ${originalError}. Select another XDR type.`,
};
}
};

const xdrDecodeJson = () => {
if (!(isXdrInit && xdr.blob && xdr.type)) {
return null;
Expand All @@ -70,13 +93,12 @@ export default function ViewXdr() {

return {
jsonString: xdrJson,
jsonArray: [parseToLosslessJson(xdrJson)],
error: "",
};
} catch (e) {
return {
jsonString: "",
error: `Unable to decode input as ${xdr.type}: ${e}. Select another XDR type.`,
};
// It's possible that the XDR is a stream
return maybeStreamXdr(xdr.type, xdr.blob, e);
}
};

Expand Down Expand Up @@ -157,6 +179,42 @@ export default function ViewXdr() {
return null;
};

const renderJsonContent = ({
jsonArray,
xdr,
}: {
jsonArray: AnyObject[];
xdr: string;
}) => {
if (jsonArray.length > 1) {
return (
<div className="PrettyJson PrettyJson__array">
<div className="PrettyJson__inline">
<span className="PrettyJson__bracket">[</span>
<span className="PrettyJson__expandSize">{`${jsonArray.length} items`}</span>
</div>
{jsonArray.map((j, index) => (
<>
<PrettyJsonTransaction
// Using index here because we can't get something unique from the JSON
key={`pretty-json-${index}`}
json={j}
xdr={xdr}
/>
</>
))}
<span className="PrettyJson__bracket">]</span>
</div>
);
}

if (jsonArray.length === 1) {
return <PrettyJsonTransaction json={jsonArray[0]} xdr={xdr} />;
}

return null;
};

return (
<Box gap="md">
<PageCard heading="View XDR">
Expand Down Expand Up @@ -233,18 +291,18 @@ export default function ViewXdr() {
</Box>

<>
{xdrJsonDecoded?.jsonString ? (
{xdrJsonDecoded?.jsonString && xdrJsonDecoded?.jsonArray ? (
<Box gap="lg">
<>{renderClaimableBalanceIds()}</>

<div
className="PageBody__content PageBody__scrollable"
data-testid="view-xdr-render-json"
>
<PrettyJsonTransaction
json={parseToLosslessJson(xdrJsonDecoded.jsonString)}
xdr={xdr.blob}
/>
{renderJsonContent({
jsonArray: xdrJsonDecoded.jsonArray,
xdr: xdr.blob,
})}
</div>

<Box gap="md" direction="row" justify="end">
Expand Down
8 changes: 6 additions & 2 deletions src/components/PrettyJson/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export const PrettyJson = ({
<div className="PrettyJson">
<Bracket char="{" />
{render(json)}
<Bracket char="}" />
<Bracket char="}" isEnd />
</div>
);
};
Expand Down Expand Up @@ -334,12 +334,16 @@ const Bracket = ({
char,
children,
isCollapsed,
isEnd,
}: {
char: Char;
children?: React.ReactNode;
isCollapsed?: boolean;
isEnd?: boolean;
}) => (
<span className="PrettyJson__bracket">
<span
className={`PrettyJson__bracket${isEnd ? " PrettyJson__bracket--end" : ""}`}
>
{char}
{children}
{isCollapsed ? `...${getClosingChar(char)}` : null}
Expand Down
12 changes: 12 additions & 0 deletions src/components/PrettyJson/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
position: relative;
}

&__array {
& > .PrettyJson {
padding-left: pxToRem(16px);

& > .PrettyJson__bracket--end {
&::after {
content: ",";
}
}
}
}

&--click {
cursor: pointer;
}
Expand Down
9 changes: 7 additions & 2 deletions src/helpers/StellarXdr.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import init, { decode, encode, guess } from "@stellar/stellar-xdr-json";
import init, {
decode,
decode_stream,
encode,
guess,
} from "@stellar/stellar-xdr-json";

// A wrapper for the Stellar XDR JSON
declare global {
Expand All @@ -14,4 +19,4 @@ const initialize = async () => {
}
};

export { initialize, decode, encode, guess };
export { initialize, decode, decode_stream, encode, guess };
25 changes: 23 additions & 2 deletions tests/viewXdrToJsonPage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ test.describe("View XDR to JSON Page", () => {
const xdrTypeOptions = page.getByTestId("xdr-type-select-options");
const jsonView = page.getByTestId("view-xdr-render-json");
const decodeErrorMsg = page.getByText(
"Unable to decode input as TransactionEnvelope: xdr value invalid. Select another XDR type.",
"Unable to decode input as TransactionEnvelope: length limit exceeded. Select another XDR type.",
);

// Initial state
Expand Down Expand Up @@ -128,6 +128,25 @@ test.describe("View XDR to JSON Page", () => {
await expect(claimableBalanceOp).toBeVisible();
});

test("Import XDR stream", async ({ page }) => {
const xdrInput = page.getByLabel("Base-64 encoded XDR");
const xdrTypeInput = page.getByLabel("XDR type");
const jsonView = page.getByTestId("view-xdr-render-json");

await xdrInput.fill(MOCK_XDR_STREAM);

await expect(
page.getByText(
"Unable to decode input as TransactionEnvelope: xdr value invalid. Select another XDR type.",
),
).toBeVisible();
await expect(jsonView).toBeHidden();

await xdrTypeInput.focus();
await page.getByText("ScSpecEntry").first().click();
await expect(jsonView).toBeVisible();
});

test("Fetch latest transaction", async ({ page }) => {
// Click to fetch
await page
Expand Down Expand Up @@ -183,9 +202,11 @@ const MOCK_TX_TRANSACTION_ENVELOPE_HASH =
const MOCK_TX_TRANSACTION_ENVELOPE_CLAIMABLE_BALANCE =
"AAAAAgAAAAAZCaG2HvD37MucM8Z4qhClE0XQWhEakEgovVIZfS+4JgAAAMgAADgIAAAALAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAADgAAAAAAAAAAAJiWgAAAAAEAAAAAAAAAABv1ZY2hLWb8m+1MaU/6hIGsWBvl7J70/xL8wq4+s9NSAAAAAAAAAAAAAAABAAAAABv1ZY2hLWb8m+1MaU/6hIGsWBvl7J70/xL8wq4+s9NSAAAAAAAAAAAAmJaAAAAAAAAAAAA=";
const MOCK_TX_TRANSACTION_RESULT =
"AAAAAAAABEwAAAAAAAAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
"AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA=";
const MOCK_TX_TRANSACTION_META =
"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";
const MOCK_XDR_STREAM =
"AAAAAAAAAAAAAAAKaW5pdGlhbGl6ZQAAAAAAAwAAAAAAAAAPdG9rZW5fd2FzbV9oYXNoAAAAA+4AAAAgAAAAAAAAAAd0b2tlbl9hAAAAABMAAAAAAAAAB3Rva2VuX2IAAAAAEwAAAAAAAAAAAAAAAAAAAAhzaGFyZV9pZAAAAAAAAAABAAAAEwAAAAAAAAAAAAAAB2RlcG9zaXQAAAAABQAAAAAAAAACdG8AAAAAABMAAAAAAAAACWRlc2lyZWRfYQAAAAAAAAsAAAAAAAAABW1pbl9hAAAAAAAACwAAAAAAAAAJZGVzaXJlZF9iAAAAAAAACwAAAAAAAAAFbWluX2IAAAAAAAALAAAAAAAAAAAAAAAAAAAABHN3YXAAAAAEAAAAAAAAAAJ0bwAAAAAAEwAAAAAAAAAFYnV5X2EAAAAAAAABAAAAAAAAAANvdXQAAAAACwAAAAAAAAAGaW5fbWF4AAAAAAALAAAAAAAAAAAAAAAAAAAACHdpdGhkcmF3AAAABAAAAAAAAAACdG8AAAAAABMAAAAAAAAADHNoYXJlX2Ftb3VudAAAAAsAAAAAAAAABW1pbl9hAAAAAAAACwAAAAAAAAAFbWluX2IAAAAAAAALAAAAAQAAA+0AAAACAAAACwAAAAsAAAAAAAAAAAAAAAlnZXRfcnNydnMAAAAAAAAAAAAAAQAAA+0AAAACAAAACwAAAAs=";

const MOCK_LATEST_TX_RESPONSE = {
_links: {
Expand Down
Loading

0 comments on commit 7294bec

Please sign in to comment.