Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/stellar/laboratory into sc-…
Browse files Browse the repository at this point in the history
…contract-storage-filters
  • Loading branch information
quietbits committed Jan 29, 2025
2 parents 8fe9aef + b0c63b7 commit cb74434
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 35 deletions.
22 changes: 13 additions & 9 deletions src/app/(sidebar)/transaction/build/components/Operations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import { getClaimableBalanceIdFromXdr } from "@/helpers/getClaimableBalanceIdFro
import { localStorageSavedTransactions } from "@/helpers/localStorageSavedTransactions";

import { OP_SET_TRUST_LINE_FLAGS } from "@/constants/settings";
import { TRANSACTION_OPERATIONS } from "@/constants/transactionOperations";
import {
INITIAL_OPERATION,
TRANSACTION_OPERATIONS,
} from "@/constants/transactionOperations";
import { useStore } from "@/store/useStore";
import {
AnyObject,
Expand All @@ -37,15 +40,18 @@ import {
OpBuildingError,
OptionSigner,
RevokeSponsorshipValue,
TxnOperation,
} from "@/types/types";

export const Operations = () => {
const { transaction, network } = useStore();
const { operations: txnOperations, xdr: txnXdr } = transaction.build;
const { classic } = transaction.build;
const { operations: txnOperations, xdr: txnXdr } = classic;

const {
// Classic
updateBuildOperations,
updateBuildSingleOperation,
// Either Classic or (@todo) Soroban
updateBuildIsValid,
setBuildOperationsError,
} = transaction;
Expand All @@ -61,11 +67,6 @@ export const Operations = () => {
const [operationsError, setOperationsError] = useState<OperationError[]>([]);
const [isSaveTxnModalVisible, setIsSaveTxnModalVisible] = useState(false);

const INITIAL_OPERATION: TxnOperation = {
operation_type: "",
params: [],
};

const EMPTY_OPERATION_ERROR: OperationError = {
operationType: "",
error: {},
Expand Down Expand Up @@ -856,6 +857,9 @@ export const Operations = () => {
>
<option value="">Select operation type</option>
<option value="create_account">Create Account</option>
<option disabled={true} value="extend_footprint_ttl">
Extend Footprint TTL (Soroban)
</option>
<option value="payment">Payment</option>
<option value="path_payment_strict_send">
Path Payment Strict Send
Expand Down Expand Up @@ -1236,7 +1240,7 @@ export const Operations = () => {
page: "build",
shareableUrl: shareableUrl("transactions-build"),
params: transaction.build.params,
operations: transaction.build.operations,
operations: transaction.build.classic.operations,
}}
allSavedItems={localStorageSavedTransactions.get()}
isVisible={isSaveTxnModalVisible}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,10 @@ const MAX_INT64 = "9223372036854775807";
export const TransactionXdr = () => {
const { transaction, network } = useStore();
const router = useRouter();
const {
params: txnParams,
operations: txnOperations,
isValid,
} = transaction.build;
const { classic, params: txnParams, isValid } = transaction.build;
const { updateSignActiveView, updateSignImportXdr, updateBuildXdr } =
transaction;
const { operations: txnOperations } = classic;

const isXdrInit = useIsXdrInit();

Expand Down
7 changes: 6 additions & 1 deletion src/constants/transactionOperations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
OPERATION_TRUSTLINE_CLEAR_FLAGS,
OPERATION_TRUSTLINE_SET_FLAGS,
} from "@/constants/settings";
import { AnyObject } from "@/types/types";
import { AnyObject, TxnOperation } from "@/types/types";

type TransactionOperation = {
label: string;
Expand All @@ -19,6 +19,11 @@ type TransactionOperation = {
custom?: AnyObject;
};

export const INITIAL_OPERATION: TxnOperation = {
operation_type: "",
params: [],
};

export const TRANSACTION_OPERATIONS: { [key: string]: TransactionOperation } = {
create_account: {
label: "Create Account",
Expand Down
63 changes: 53 additions & 10 deletions src/store/createStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,22 @@ export interface Store {
// Transaction
transaction: {
build: {
// classic
classic: {
operations: TxnOperation[];
xdr: string;
};
// soroban
soroban: {
operation: TxnOperation;
xdr: string;
};
// used for both classic and soroban
params: TransactionBuildParams;
operations: TxnOperation[];
error: {
params: string[];
operations: OpBuildingError[];
};
xdr: string;
isValid: {
params: boolean;
operations: boolean;
Expand All @@ -133,7 +142,7 @@ export interface Store {
triggerOnLaunch?: boolean;
};
feeBump: FeeBumpParams;
// [Transaction] Build Transaction actions
// [Transaction] Build Classic Transaction actions
updateBuildParams: (params: TransactionBuildParamsObj) => void;
updateBuildOperations: (operations: TxnOperation[]) => void;
updateBuildXdr: (xdr: string) => void;
Expand All @@ -152,6 +161,10 @@ export interface Store {
setBuildParamsError: (error: string[]) => void;
setBuildOperationsError: (error: OpBuildingError[]) => void;
resetBuildParams: () => void;
// [Transaction] Build Soroban Transaction actions
updateSorobanBuildOperation: (operation: TxnOperation) => void;
updateSorobanBuildXdr: (xdr: string) => void;
// [Transaction] Both Classic & Soroban Transaction actions
resetBuild: () => void;
// [Transaction] Sign Transaction actions
updateSignActiveView: (viewId: SignTxActiveView) => void;
Expand Down Expand Up @@ -216,15 +229,27 @@ const initTransactionParamsState = {
memo: {},
};

const initTransactionOperationState = {
operation_type: "",
params: {},
source_account: "",
};

const initTransactionState = {
build: {
classic: {
operations: [],
xdr: "",
},
soroban: {
operation: initTransactionOperationState,
xdr: "",
},
params: initTransactionParamsState,
operations: [],
error: {
params: [],
operations: [],
},
xdr: "",
isValid: {
params: false,
operations: false,
Expand Down Expand Up @@ -394,6 +419,7 @@ export const createStore = (options: CreateStoreOptions) =>
// Transaction
transaction: {
...initTransactionState,
// Classic Build
updateBuildParams: (params: TransactionBuildParamsObj) =>
set((state) => {
state.transaction.build.params = {
Expand All @@ -403,15 +429,15 @@ export const createStore = (options: CreateStoreOptions) =>
}),
updateBuildOperations: (operations) =>
set((state) => {
state.transaction.build.operations = operations;
state.transaction.build.classic.operations = operations;
}),
updateBuildXdr: (xdr) =>
set((state) => {
state.transaction.build.xdr = xdr;
state.transaction.build.classic.xdr = xdr;
}),
updateBuildSingleOperation: (index, operation) =>
set((state) => {
state.transaction.build.operations[index] = operation;
state.transaction.build.classic.operations[index] = operation;
}),
updateBuildIsValid: ({
params,
Expand Down Expand Up @@ -447,10 +473,21 @@ export const createStore = (options: CreateStoreOptions) =>
set((state) => {
state.transaction.build.params = initTransactionParamsState;
}),
// Soroban Build
updateSorobanBuildOperation: (operation: TxnOperation) =>
set((state) => {
state.transaction.build.soroban.operation = operation;
}),
updateSorobanBuildXdr: (xdr: string) =>
set((state) => {
state.transaction.build.soroban.xdr = xdr;
}),
// Classic & Soroban
resetBuild: () =>
set((state) => {
state.transaction.build = initTransactionState.build;
}),
// Sign
updateSignActiveView: (viewId: SignTxActiveView) =>
set((state) => {
state.transaction.sign.activeView = viewId;
Expand Down Expand Up @@ -558,11 +595,17 @@ export const createStore = (options: CreateStoreOptions) =>
},
transaction: {
build: {
classic: {
operations: true,
xdr: false,
},
soroban: {
operation: true,
xdr: false,
},
params: true,
operations: true,
error: false,
isValid: true,
xdr: false,
},
sign: {
activeView: true,
Expand Down
7 changes: 6 additions & 1 deletion src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ export type SponsorshipType =
| "claimable_balance"
| "signer";

// =============================================================================
// Soroban Operations
// =============================================================================
export type SorobanOpType = "extend_footprint_ttl";

// =============================================================================
// RPC
// =============================================================================
Expand All @@ -250,7 +255,7 @@ export type FiltersObject = {
topics: string[];
};

export type XdrType = "TransactionEnvelope" | "LedgerKey";
export type XdrType = "TransactionEnvelope" | "LedgerKey" | "ScVal";

export type LedgerKeyType =
| "account"
Expand Down
12 changes: 9 additions & 3 deletions src/validate/methods/getContractIdError.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
const CONTRACT_LENGTH = 56;
// https://developers.stellar.org/docs/learn/encyclopedia/contract-development/types/built-in-types#bytes-strings-bytes-bytesn-string
// contract IDs are fixed 32-byte byte arrays, and are represented as BytesN<32>
// A 32 byte binary array is equal to 256 bits (32 * 8)
// To represent 256 bits in base32, we need at least 52 characters
const CONTRACT_MIN_LENGTH = 52;

export const getContractIdError = (value: string) => {
if (value.charAt(0) !== "C") {
return "The string must start with 'C'.";
} else if (value.length !== CONTRACT_LENGTH) {
return `The string must be exactly ${CONTRACT_LENGTH} characters long.`;
}
if (value.length < CONTRACT_MIN_LENGTH) {
return `The string length should be at least ${CONTRACT_MIN_LENGTH} characters long.`;
}
// skipping max length check in case it includes metadata

return false;
};
4 changes: 4 additions & 0 deletions tests/feeBumpPage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ test.describe("Fee Bump Page", () => {
await expect(signButton).toBeVisible();
await signButton.click();

await page.waitForURL("**/transaction/sign");

await expect(page.locator("h1")).toHaveText("Transaction Overview");
await expect(page.getByLabel("Transaction Envelope XDR")).toHaveText(
MOCK_XDR,
Expand All @@ -76,6 +78,8 @@ test.describe("Fee Bump Page", () => {
await expect(viewButton).toBeVisible();
await viewButton.click();

await page.waitForURL("**/xdr/view");

await expect(page.locator("h1")).toHaveText("View XDR");
await expect(page.getByLabel("Base-64 encoded XDR")).toHaveText(MOCK_XDR);
});
Expand Down
5 changes: 3 additions & 2 deletions tests/savedTransactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ test.describe("Saved Transactions Page", () => {
// local storage data
let pageContext: Page;

test.beforeAll(async ({ browser }) => {
test.beforeEach(async ({ browser }) => {
const browserContext = await browser.newContext({
storageState: MOCK_LOCAL_STORAGE,
});
Expand All @@ -45,7 +45,7 @@ test.describe("Saved Transactions Page", () => {
await expect(txItems).toHaveCount(2);
});

test("Submit item", async () => {
test("[Classic] Submit item", async () => {
const submitItem = pageContext
.getByTestId("saved-transactions-item")
.nth(0);
Expand Down Expand Up @@ -73,6 +73,7 @@ test.describe("Saved Transactions Page", () => {

// View in submitter
await submitItem.getByText("View in submitter").click();
await pageContext.waitForURL("**/transaction/submit");

await expect(pageContext.locator("h1")).toHaveText("Submit Transaction");
await expect(
Expand Down
8 changes: 4 additions & 4 deletions tests/urlParams.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ test.describe("URL Params", () => {
});

test.describe("Transactions", () => {
test("Build Transaction", async ({ page }) => {
test("[Classic] Build Transaction", async ({ page }) => {
await page.goto(
"http://localhost:3000/transaction/build?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;&transaction$build$params$source_account=GA46LGGOLXJY5OSX6N4LHV4MWDFXNGLK76I4NDNKKYAXRRSKI5AJGMXG&fee=2000&seq_num=3668692344766465&cond$time$max_time=1733409768;;&memo$text=123;;&operations@$operation_type=create_account&params$destination=GC5TQ7TXKHGE5JQMZPYV5KBSQ67X6PYQVU5QN7JRGWCHRA227UFPZ6LD&starting_balance=3000;&source_account=;&$operation_type=payment&params$destination=GAJAIHPKNTJ362TAUWTU2S56B7PULRTMY456LUELK53USX43537IFMS3&asset$code=USDC&issuer=GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5&type=credit_alphanum4;&amount=4000;&source_account=GA46LGGOLXJY5OSX6N4LHV4MWDFXNGLK76I4NDNKKYAXRRSKI5AJGMXG;;&isValid$params:true&operations:true;;",
"http://localhost:3000/transaction/build?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;&transaction$build$classic$operations@$operation_type=create_account&params$destination=GC5TQ7TXKHGE5JQMZPYV5KBSQ67X6PYQVU5QN7JRGWCHRA227UFPZ6LD&starting_balance=3000;&source_account=;&$operation_type=payment&params$destination=GAJAIHPKNTJ362TAUWTU2S56B7PULRTMY456LUELK53USX43537IFMS3&asset$code=USDC&issuer=GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5&type=credit_alphanum4;&amount=4000;&source_account=GA46LGGOLXJY5OSX6N4LHV4MWDFXNGLK76I4NDNKKYAXRRSKI5AJGMXG;;;&params$source_account=GA46LGGOLXJY5OSX6N4LHV4MWDFXNGLK76I4NDNKKYAXRRSKI5AJGMXG&fee=2000&seq_num=3668692344766465&cond$time$max_time=1733409768;;&memo$text=123;;&isValid$params:true&operations:true;;",
);

await expect(page.locator("h1")).toHaveText("Build Transaction");
Expand Down Expand Up @@ -111,7 +111,7 @@ test.describe("URL Params", () => {
);
});

test("Sign Transaction", async ({ page }) => {
test("[Classic] Sign Transaction", async ({ page }) => {
await page.goto(
"http://localhost:3000/transaction/sign?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;&transaction$sign$activeView=overview&importXdr=AAAAAgAAAAA55ZjOXdOOulfzeLPXjLDLdplq//5HGjapWAXjGSkdAkwAAD6AADQioAAAAAQAAAAEAAAAAAAAAAAAAAABnUbvoAAAAAQAAAAMxMjMAAAAAAgAAAAAAAAAAAAAAALs4fndRzE6mDMvxXqgyh79//PxCtOwb9MTWEeINa//Qr8AAAABvwjrAAAAAABAAAAADnlmM5d0466V//N4s9eMsMt2mWr//kcaNqlYBeMZKR0CTAAAAAQAAAAASBB3qbNO//amClp01Lvg//fRcZsxzvl0ItXd0lfm+7+ggAAAAFVU0RDAAAAAEI+fQXy7K+//7BkrIVo//G+lq7bjY5wJUq+NBPgIH3layAAAACVAvkAAAAAAAAAAAAA==;;",
);
Expand Down Expand Up @@ -143,7 +143,7 @@ test.describe("URL Params", () => {
);
});

test("Submit Transaction", async ({ page }) => {
test("[Classic] Submit Transaction", async ({ page }) => {
await page.goto(
"http://localhost:3000/transaction/submit?$=network$id=testnet&label=Testnet&horizonUrl=https:////horizon-testnet.stellar.org&rpcUrl=https:////soroban-testnet.stellar.org&passphrase=Test%20SDF%20Network%20/;%20September%202015;&xdr$blob=AAAAAgAAAAA55ZjOXdOOulfzeLPXjLDLdplq//5HGjapWAXjGSkdAkwAAD6AADQioAAAAAQAAAAEAAAAAAAAAAAAAAABnUbvoAAAAAQAAAAMxMjMAAAAAAgAAAAAAAAAAAAAAALs4fndRzE6mDMvxXqgyh79//PxCtOwb9MTWEeINa//Qr8AAAABvwjrAAAAAABAAAAADnlmM5d0466V//N4s9eMsMt2mWr//kcaNqlYBeMZKR0CTAAAAAQAAAAASBB3qbNO//amClp01Lvg//fRcZsxzvl0ItXd0lfm+7+ggAAAAFVU0RDAAAAAEI+fQXy7K+//7BkrIVo//G+lq7bjY5wJUq+NBPgIH3layAAAACVAvkAAAAAAAAAAAAA==;;",
);
Expand Down

0 comments on commit cb74434

Please sign in to comment.