@rubanrubi/hardhat-dashboard 0.1.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/types/rpc.d.ts +2 -0
- package/dist/types/rpc.js.map +1 -1
- package/dist/ui/app.js +445 -121
- package/dist/ui/app.js.map +4 -4
- package/dist/ui/styles.css +203 -0
- package/package.json +2 -1
package/dist/ui/app.js
CHANGED
|
@@ -1083,7 +1083,7 @@ var require_react_development = __commonJS({
|
|
|
1083
1083
|
}
|
|
1084
1084
|
return dispatcher.useContext(Context);
|
|
1085
1085
|
}
|
|
1086
|
-
function
|
|
1086
|
+
function useState3(initialState) {
|
|
1087
1087
|
var dispatcher = resolveDispatcher();
|
|
1088
1088
|
return dispatcher.useState(initialState);
|
|
1089
1089
|
}
|
|
@@ -1886,7 +1886,7 @@ var require_react_development = __commonJS({
|
|
|
1886
1886
|
exports.useMemo = useMemo;
|
|
1887
1887
|
exports.useReducer = useReducer;
|
|
1888
1888
|
exports.useRef = useRef2;
|
|
1889
|
-
exports.useState =
|
|
1889
|
+
exports.useState = useState3;
|
|
1890
1890
|
exports.useSyncExternalStore = useSyncExternalStore;
|
|
1891
1891
|
exports.useTransition = useTransition;
|
|
1892
1892
|
exports.version = ReactVersion;
|
|
@@ -2433,7 +2433,7 @@ var require_react_dom_development = __commonJS({
|
|
|
2433
2433
|
var HostPortal = 4;
|
|
2434
2434
|
var HostComponent = 5;
|
|
2435
2435
|
var HostText = 6;
|
|
2436
|
-
var
|
|
2436
|
+
var Fragment2 = 7;
|
|
2437
2437
|
var Mode = 8;
|
|
2438
2438
|
var ContextConsumer = 9;
|
|
2439
2439
|
var ContextProvider = 10;
|
|
@@ -3590,7 +3590,7 @@ var require_react_dom_development = __commonJS({
|
|
|
3590
3590
|
return "DehydratedFragment";
|
|
3591
3591
|
case ForwardRef:
|
|
3592
3592
|
return getWrappedName$1(type, type.render, "ForwardRef");
|
|
3593
|
-
case
|
|
3593
|
+
case Fragment2:
|
|
3594
3594
|
return "Fragment";
|
|
3595
3595
|
case HostComponent:
|
|
3596
3596
|
return type;
|
|
@@ -12019,7 +12019,7 @@ var require_react_dom_development = __commonJS({
|
|
|
12019
12019
|
}
|
|
12020
12020
|
}
|
|
12021
12021
|
function updateFragment2(returnFiber, current2, fragment, lanes, key) {
|
|
12022
|
-
if (current2 === null || current2.tag !==
|
|
12022
|
+
if (current2 === null || current2.tag !== Fragment2) {
|
|
12023
12023
|
var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
|
|
12024
12024
|
created.return = returnFiber;
|
|
12025
12025
|
return created;
|
|
@@ -12422,7 +12422,7 @@ var require_react_dom_development = __commonJS({
|
|
|
12422
12422
|
if (child.key === key) {
|
|
12423
12423
|
var elementType = element.type;
|
|
12424
12424
|
if (elementType === REACT_FRAGMENT_TYPE) {
|
|
12425
|
-
if (child.tag ===
|
|
12425
|
+
if (child.tag === Fragment2) {
|
|
12426
12426
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
12427
12427
|
var existing = useFiber(child, element.props.children);
|
|
12428
12428
|
existing.return = returnFiber;
|
|
@@ -17898,7 +17898,7 @@ var require_react_dom_development = __commonJS({
|
|
|
17898
17898
|
var _resolvedProps2 = workInProgress2.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
|
|
17899
17899
|
return updateForwardRef(current2, workInProgress2, type, _resolvedProps2, renderLanes2);
|
|
17900
17900
|
}
|
|
17901
|
-
case
|
|
17901
|
+
case Fragment2:
|
|
17902
17902
|
return updateFragment(current2, workInProgress2, renderLanes2);
|
|
17903
17903
|
case Mode:
|
|
17904
17904
|
return updateMode(current2, workInProgress2, renderLanes2);
|
|
@@ -18170,7 +18170,7 @@ var require_react_dom_development = __commonJS({
|
|
|
18170
18170
|
case SimpleMemoComponent:
|
|
18171
18171
|
case FunctionComponent:
|
|
18172
18172
|
case ForwardRef:
|
|
18173
|
-
case
|
|
18173
|
+
case Fragment2:
|
|
18174
18174
|
case Mode:
|
|
18175
18175
|
case Profiler:
|
|
18176
18176
|
case ContextConsumer:
|
|
@@ -22431,7 +22431,7 @@ var require_react_dom_development = __commonJS({
|
|
|
22431
22431
|
return fiber;
|
|
22432
22432
|
}
|
|
22433
22433
|
function createFiberFromFragment(elements, mode, lanes, key) {
|
|
22434
|
-
var fiber = createFiber(
|
|
22434
|
+
var fiber = createFiber(Fragment2, elements, key, mode);
|
|
22435
22435
|
fiber.lanes = lanes;
|
|
22436
22436
|
return fiber;
|
|
22437
22437
|
}
|
|
@@ -24463,10 +24463,10 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
24463
24463
|
return jsxWithValidation(type, props, key, false);
|
|
24464
24464
|
}
|
|
24465
24465
|
}
|
|
24466
|
-
var
|
|
24466
|
+
var jsx6 = jsxWithValidationDynamic;
|
|
24467
24467
|
var jsxs5 = jsxWithValidationStatic;
|
|
24468
24468
|
exports.Fragment = REACT_FRAGMENT_TYPE;
|
|
24469
|
-
exports.jsx =
|
|
24469
|
+
exports.jsx = jsx6;
|
|
24470
24470
|
exports.jsxs = jsxs5;
|
|
24471
24471
|
})();
|
|
24472
24472
|
}
|
|
@@ -24486,7 +24486,7 @@ var require_jsx_runtime = __commonJS({
|
|
|
24486
24486
|
});
|
|
24487
24487
|
|
|
24488
24488
|
// src/ui/app.tsx
|
|
24489
|
-
var
|
|
24489
|
+
var import_react2 = __toESM(require_react());
|
|
24490
24490
|
var import_client = __toESM(require_client());
|
|
24491
24491
|
|
|
24492
24492
|
// src/types/rpc.ts
|
|
@@ -24506,8 +24506,98 @@ function formatTimestamp(value) {
|
|
|
24506
24506
|
second: "2-digit"
|
|
24507
24507
|
});
|
|
24508
24508
|
}
|
|
24509
|
-
function
|
|
24510
|
-
return
|
|
24509
|
+
function shortenAddress(addr) {
|
|
24510
|
+
return `${addr.slice(0, 8)}...${addr.slice(-6)}`;
|
|
24511
|
+
}
|
|
24512
|
+
function formatWeiValue(hex) {
|
|
24513
|
+
try {
|
|
24514
|
+
const wei = BigInt(hex);
|
|
24515
|
+
if (wei === 0n) return "";
|
|
24516
|
+
const eth = Number(wei) / 1e18;
|
|
24517
|
+
return `${eth.toFixed(6)} ETH`;
|
|
24518
|
+
} catch {
|
|
24519
|
+
return hex;
|
|
24520
|
+
}
|
|
24521
|
+
}
|
|
24522
|
+
function hexToUtf8(hex) {
|
|
24523
|
+
try {
|
|
24524
|
+
const bytes = (hex.startsWith("0x") ? hex.slice(2) : hex).match(/.{2}/g) ?? [];
|
|
24525
|
+
const decoded = bytes.map((b) => String.fromCharCode(parseInt(b, 16))).join("");
|
|
24526
|
+
return decoded.trim() || hex;
|
|
24527
|
+
} catch {
|
|
24528
|
+
return hex;
|
|
24529
|
+
}
|
|
24530
|
+
}
|
|
24531
|
+
function extractTxFields(request) {
|
|
24532
|
+
if (request.method !== "eth_sendTransaction") return null;
|
|
24533
|
+
const params = request.params;
|
|
24534
|
+
const first = Array.isArray(params) ? params[0] : params;
|
|
24535
|
+
if (!first || typeof first !== "object") return null;
|
|
24536
|
+
const tx = first;
|
|
24537
|
+
const to = typeof tx.to === "string" && tx.to.length > 2 ? tx.to : void 0;
|
|
24538
|
+
const from = typeof tx.from === "string" ? tx.from : void 0;
|
|
24539
|
+
const rawValue = typeof tx.value === "string" ? tx.value : void 0;
|
|
24540
|
+
const value = rawValue && rawValue !== "0x0" && rawValue !== "0x00" && rawValue !== "0x" ? formatWeiValue(rawValue) : void 0;
|
|
24541
|
+
return { from, to, value: value || void 0, isDeployment: !to };
|
|
24542
|
+
}
|
|
24543
|
+
function getMethodLabel(method) {
|
|
24544
|
+
switch (method) {
|
|
24545
|
+
case "eth_sendTransaction":
|
|
24546
|
+
return "Send Transaction";
|
|
24547
|
+
case "eth_sign":
|
|
24548
|
+
return "Sign Message";
|
|
24549
|
+
case "personal_sign":
|
|
24550
|
+
return "Sign Message";
|
|
24551
|
+
case "eth_signTypedData":
|
|
24552
|
+
case "eth_signTypedData_v1":
|
|
24553
|
+
case "eth_signTypedData_v3":
|
|
24554
|
+
case "eth_signTypedData_v4":
|
|
24555
|
+
return "Sign Typed Data";
|
|
24556
|
+
default:
|
|
24557
|
+
return method;
|
|
24558
|
+
}
|
|
24559
|
+
}
|
|
24560
|
+
function SigningMessageView({ request }) {
|
|
24561
|
+
const params = Array.isArray(request.params) ? request.params : [];
|
|
24562
|
+
if (request.method === "personal_sign") {
|
|
24563
|
+
const raw = typeof params[0] === "string" ? params[0] : "";
|
|
24564
|
+
const message = raw.startsWith("0x") ? hexToUtf8(raw) : raw;
|
|
24565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-message-box", children: [
|
|
24566
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-field-label", children: "Message" }),
|
|
24567
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-message-content", children: message || raw })
|
|
24568
|
+
] });
|
|
24569
|
+
}
|
|
24570
|
+
if (request.method === "eth_sign") {
|
|
24571
|
+
const raw = typeof params[1] === "string" ? params[1] : "";
|
|
24572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-message-box", children: [
|
|
24573
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-field-label", children: "Message hash" }),
|
|
24574
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-message-content mono", children: raw })
|
|
24575
|
+
] });
|
|
24576
|
+
}
|
|
24577
|
+
if (request.method.startsWith("eth_signTypedData")) {
|
|
24578
|
+
const rawData = typeof params[1] === "string" ? params[1] : JSON.stringify(params[1]);
|
|
24579
|
+
try {
|
|
24580
|
+
const parsed = typeof rawData === "string" ? JSON.parse(rawData) : rawData;
|
|
24581
|
+
const domain = parsed?.domain;
|
|
24582
|
+
const message = parsed?.message;
|
|
24583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-message-box", children: [
|
|
24584
|
+
domain ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-typed-section", children: [
|
|
24585
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-field-label", children: "Domain" }),
|
|
24586
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { className: "tx-typed-pre", children: JSON.stringify(domain, null, 2) })
|
|
24587
|
+
] }) : null,
|
|
24588
|
+
message ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-typed-section", children: [
|
|
24589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-field-label", children: "Message" }),
|
|
24590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { className: "tx-typed-pre", children: JSON.stringify(message, null, 2) })
|
|
24591
|
+
] }) : null
|
|
24592
|
+
] });
|
|
24593
|
+
} catch {
|
|
24594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-message-box", children: [
|
|
24595
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-field-label", children: "Typed data" }),
|
|
24596
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tx-message-content mono", children: rawData })
|
|
24597
|
+
] });
|
|
24598
|
+
}
|
|
24599
|
+
}
|
|
24600
|
+
return null;
|
|
24511
24601
|
}
|
|
24512
24602
|
function PendingTxCard({
|
|
24513
24603
|
request,
|
|
@@ -24516,26 +24606,63 @@ function PendingTxCard({
|
|
|
24516
24606
|
onReject
|
|
24517
24607
|
}) {
|
|
24518
24608
|
const actionLabel = request.requiresApproval ? "Confirm" : "Run";
|
|
24609
|
+
const txFields = extractTxFields(request);
|
|
24610
|
+
const isSigningMethod = [
|
|
24611
|
+
"eth_sign",
|
|
24612
|
+
"personal_sign",
|
|
24613
|
+
"eth_signTypedData",
|
|
24614
|
+
"eth_signTypedData_v1",
|
|
24615
|
+
"eth_signTypedData_v3",
|
|
24616
|
+
"eth_signTypedData_v4"
|
|
24617
|
+
].includes(request.method);
|
|
24519
24618
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: `request-card ${request.status === "processing" ? "processing" : ""}`, children: [
|
|
24520
24619
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "request-top", children: [
|
|
24521
24620
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
24522
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "method", children: request.method }),
|
|
24621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "method", children: getMethodLabel(request.method) }),
|
|
24523
24622
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "timestamp", children: [
|
|
24524
24623
|
"Queued at ",
|
|
24525
24624
|
formatTimestamp(request.createdAt)
|
|
24526
24625
|
] })
|
|
24527
24626
|
] }),
|
|
24528
24627
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tag-row", children: [
|
|
24628
|
+
txFields?.isDeployment ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tag deploy", children: "Contract Deployment" }) : null,
|
|
24529
24629
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tag", children: request.requiresApproval ? "Approval required" : "Read-only passthrough" }),
|
|
24530
24630
|
request.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tag success", children: "Processing" }) : null
|
|
24531
24631
|
] })
|
|
24532
24632
|
] }),
|
|
24533
|
-
|
|
24534
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
24535
|
-
|
|
24536
|
-
|
|
24633
|
+
txFields ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-summary", children: [
|
|
24634
|
+
txFields.isDeployment ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-summary-row", children: [
|
|
24635
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-label", children: "Action" }),
|
|
24636
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-value", children: request.decodedCall?.contractName ? `Deploy ${request.decodedCall.contractName}` : "Deploy new contract" })
|
|
24637
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-summary-row", children: [
|
|
24638
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-label", children: "To" }),
|
|
24639
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-value mono", children: txFields.to ? shortenAddress(txFields.to) : "\u2014" })
|
|
24640
|
+
] }),
|
|
24641
|
+
txFields.from ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-summary-row", children: [
|
|
24642
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-label", children: "From" }),
|
|
24643
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-value mono", children: shortenAddress(txFields.from) })
|
|
24644
|
+
] }) : null,
|
|
24645
|
+
txFields.value ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tx-summary-row", children: [
|
|
24646
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-label", children: "Value" }),
|
|
24647
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tx-field-value value-accent", children: txFields.value })
|
|
24648
|
+
] }) : null
|
|
24649
|
+
] }) : null,
|
|
24650
|
+
request.decodedCall?.matched ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "decoded-call", children: [
|
|
24651
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("strong", { children: [
|
|
24652
|
+
request.decodedCall.contractName ?? "Contract",
|
|
24653
|
+
".",
|
|
24654
|
+
request.decodedCall.functionName ?? "call"
|
|
24655
|
+
] }),
|
|
24656
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "decoded-sig", children: request.decodedCall.signature }),
|
|
24657
|
+
request.decodedCall.args.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "decoded-args", children: request.decodedCall.args.map((argument, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: argument }, `${request.queueId}-arg-${index}`)) }) : null
|
|
24658
|
+
] }) : request.decodedCall && !request.decodedCall.matched && request.decodedCall.selector ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "decoded-call unmatched", children: [
|
|
24659
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Unknown function" }),
|
|
24660
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "decoded-sig", children: [
|
|
24661
|
+
"Selector: ",
|
|
24662
|
+
request.decodedCall.selector
|
|
24663
|
+
] })
|
|
24537
24664
|
] }) : null,
|
|
24538
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
24665
|
+
isSigningMethod ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SigningMessageView, { request }) : null,
|
|
24539
24666
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "button-row", style: { marginTop: 14 }, children: [
|
|
24540
24667
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "button-primary", disabled: busy, onClick: () => onConfirm(request), children: busy ? "Waiting for wallet..." : actionLabel }),
|
|
24541
24668
|
request.requiresApproval ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "button-danger", disabled: busy, onClick: () => onReject(request), children: "Reject" }) : null
|
|
@@ -24543,8 +24670,31 @@ function PendingTxCard({
|
|
|
24543
24670
|
] });
|
|
24544
24671
|
}
|
|
24545
24672
|
|
|
24546
|
-
// src/ui/components/
|
|
24673
|
+
// src/ui/components/CopyButton.tsx
|
|
24674
|
+
var import_react = __toESM(require_react());
|
|
24547
24675
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
|
|
24676
|
+
function CopyButton({ text, label = "Copy" }) {
|
|
24677
|
+
const [copied, setCopied] = (0, import_react.useState)(false);
|
|
24678
|
+
function handleCopy() {
|
|
24679
|
+
void navigator.clipboard.writeText(text).then(() => {
|
|
24680
|
+
setCopied(true);
|
|
24681
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
24682
|
+
});
|
|
24683
|
+
}
|
|
24684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "copy-btn", onClick: handleCopy, title: text, children: copied ? "\u2713" : label });
|
|
24685
|
+
}
|
|
24686
|
+
|
|
24687
|
+
// src/ui/components/TxHistory.tsx
|
|
24688
|
+
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
|
|
24689
|
+
var DEPLOYMENT_METHODS = /* @__PURE__ */ new Set([
|
|
24690
|
+
"eth_sendTransaction",
|
|
24691
|
+
"eth_sign",
|
|
24692
|
+
"personal_sign",
|
|
24693
|
+
"eth_signTypedData",
|
|
24694
|
+
"eth_signTypedData_v1",
|
|
24695
|
+
"eth_signTypedData_v3",
|
|
24696
|
+
"eth_signTypedData_v4"
|
|
24697
|
+
]);
|
|
24548
24698
|
function formatTimestamp2(value) {
|
|
24549
24699
|
return new Date(value).toLocaleTimeString([], {
|
|
24550
24700
|
hour: "2-digit",
|
|
@@ -24555,65 +24705,198 @@ function formatTimestamp2(value) {
|
|
|
24555
24705
|
function getStatusClass(status) {
|
|
24556
24706
|
return status === "confirmed" ? "success" : "error";
|
|
24557
24707
|
}
|
|
24558
|
-
function
|
|
24559
|
-
|
|
24708
|
+
function getMethodLabel2(method) {
|
|
24709
|
+
switch (method) {
|
|
24710
|
+
case "eth_sendTransaction":
|
|
24711
|
+
return "Send Transaction";
|
|
24712
|
+
case "eth_sign":
|
|
24713
|
+
return "Sign Message";
|
|
24714
|
+
case "personal_sign":
|
|
24715
|
+
return "Sign Message";
|
|
24716
|
+
case "eth_signTypedData":
|
|
24717
|
+
case "eth_signTypedData_v1":
|
|
24718
|
+
case "eth_signTypedData_v3":
|
|
24719
|
+
case "eth_signTypedData_v4":
|
|
24720
|
+
return "Sign Typed Data";
|
|
24721
|
+
default:
|
|
24722
|
+
return method;
|
|
24723
|
+
}
|
|
24724
|
+
}
|
|
24725
|
+
function getActionSummary(entry) {
|
|
24726
|
+
if (entry.decodedCall?.matched) {
|
|
24727
|
+
const name = entry.decodedCall.contractName ?? "Contract";
|
|
24728
|
+
const fn = entry.decodedCall.functionName ?? "call";
|
|
24729
|
+
return `${name}.${fn}`;
|
|
24730
|
+
}
|
|
24731
|
+
if (entry.method === "eth_sendTransaction") {
|
|
24732
|
+
const params = entry;
|
|
24733
|
+
const first = Array.isArray(params) ? params[0] : void 0;
|
|
24734
|
+
const tx = first && typeof first === "object" ? first : void 0;
|
|
24735
|
+
const hasTo = tx && typeof tx.to === "string" && tx.to.length > 2;
|
|
24736
|
+
return hasTo ? "Contract interaction" : "Contract deployment";
|
|
24737
|
+
}
|
|
24738
|
+
return "";
|
|
24739
|
+
}
|
|
24740
|
+
function getTxHash(entry) {
|
|
24741
|
+
if (typeof entry.result === "string" && entry.result.startsWith("0x") && entry.result.length === 66) {
|
|
24742
|
+
return entry.result;
|
|
24743
|
+
}
|
|
24744
|
+
return void 0;
|
|
24560
24745
|
}
|
|
24561
24746
|
function TxHistory({ entries }) {
|
|
24562
|
-
|
|
24563
|
-
|
|
24747
|
+
const relevant = entries.filter((e) => DEPLOYMENT_METHODS.has(e.method));
|
|
24748
|
+
if (!relevant.length) {
|
|
24749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "empty-state", children: "Confirmed transactions and signing events will appear here during this session." });
|
|
24564
24750
|
}
|
|
24565
|
-
return /* @__PURE__ */ (0,
|
|
24566
|
-
|
|
24567
|
-
|
|
24568
|
-
|
|
24569
|
-
|
|
24570
|
-
|
|
24571
|
-
"
|
|
24572
|
-
|
|
24573
|
-
|
|
24574
|
-
|
|
24575
|
-
|
|
24576
|
-
|
|
24577
|
-
|
|
24578
|
-
|
|
24579
|
-
entry.decodedCall.contractName,
|
|
24580
|
-
".",
|
|
24581
|
-
entry.decodedCall.functionName
|
|
24751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "card-list", children: relevant.map((entry) => {
|
|
24752
|
+
const actionSummary = getActionSummary(entry);
|
|
24753
|
+
const txHash = getTxHash(entry);
|
|
24754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "history-card", children: [
|
|
24755
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "history-top", children: [
|
|
24756
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
24757
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "method", children: getMethodLabel2(entry.method) }),
|
|
24758
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "timestamp", children: [
|
|
24759
|
+
formatTimestamp2(entry.createdAt),
|
|
24760
|
+
" \u2192 ",
|
|
24761
|
+
formatTimestamp2(entry.completedAt)
|
|
24762
|
+
] })
|
|
24763
|
+
] }),
|
|
24764
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `tag ${getStatusClass(entry.status)}`, children: entry.status })
|
|
24582
24765
|
] }),
|
|
24583
|
-
/* @__PURE__ */ (0,
|
|
24584
|
-
|
|
24585
|
-
|
|
24586
|
-
|
|
24587
|
-
|
|
24766
|
+
actionSummary ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "history-action", children: actionSummary }) : null,
|
|
24767
|
+
entry.decodedCall?.matched ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "decoded-call", children: [
|
|
24768
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
|
|
24769
|
+
entry.decodedCall.contractName,
|
|
24770
|
+
".",
|
|
24771
|
+
entry.decodedCall.functionName
|
|
24772
|
+
] }),
|
|
24773
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "decoded-sig", children: entry.decodedCall.signature })
|
|
24774
|
+
] }) : null,
|
|
24775
|
+
txHash ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "history-hash", children: [
|
|
24776
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "tx-field-label", children: "Tx hash" }),
|
|
24777
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "history-hash-value mono", children: [
|
|
24778
|
+
txHash.slice(0, 18),
|
|
24779
|
+
"...",
|
|
24780
|
+
txHash.slice(-8)
|
|
24781
|
+
] }),
|
|
24782
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CopyButton, { text: txHash })
|
|
24783
|
+
] }) : null,
|
|
24784
|
+
entry.error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "history-error", children: entry.error.message }) : null
|
|
24785
|
+
] }, entry.queueId);
|
|
24786
|
+
}) });
|
|
24588
24787
|
}
|
|
24589
24788
|
|
|
24590
24789
|
// src/ui/components/WalletBadge.tsx
|
|
24591
|
-
var
|
|
24790
|
+
var import_jsx_runtime4 = __toESM(require_jsx_runtime());
|
|
24592
24791
|
function WalletBadge({ wallet }) {
|
|
24593
24792
|
if (!wallet.available) {
|
|
24594
|
-
return /* @__PURE__ */ (0,
|
|
24793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pill", children: "MetaMask not detected" });
|
|
24595
24794
|
}
|
|
24596
24795
|
if (!wallet.connected) {
|
|
24597
|
-
return /* @__PURE__ */ (0,
|
|
24598
|
-
/* @__PURE__ */ (0,
|
|
24599
|
-
/* @__PURE__ */ (0,
|
|
24796
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "pill", children: [
|
|
24797
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: wallet.walletName }),
|
|
24798
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: wallet.locked ? "Locked or not connected" : "Waiting for account access" })
|
|
24600
24799
|
] });
|
|
24601
24800
|
}
|
|
24602
|
-
|
|
24603
|
-
|
|
24604
|
-
/* @__PURE__ */ (0,
|
|
24801
|
+
const shortAddress = wallet.account ? `${wallet.account.slice(0, 6)}...${wallet.account.slice(-4)}` : "No account";
|
|
24802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "wallet-info-pill", children: [
|
|
24803
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "wallet-dot" }),
|
|
24804
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { className: "wallet-network-name", children: wallet.networkName ?? wallet.chainId ?? "Connected" }),
|
|
24805
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "wallet-sep", children: "\xB7" }),
|
|
24806
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "wallet-address", title: wallet.account, children: shortAddress }),
|
|
24807
|
+
wallet.account ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CopyButton, { text: wallet.account }) : null,
|
|
24808
|
+
wallet.balance ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
24809
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "wallet-sep", children: "\xB7" }),
|
|
24810
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "wallet-balance", children: wallet.balance })
|
|
24811
|
+
] }) : null
|
|
24605
24812
|
] });
|
|
24606
24813
|
}
|
|
24607
24814
|
|
|
24608
24815
|
// src/ui/wallet.ts
|
|
24609
24816
|
var CHAIN_NAMES = {
|
|
24817
|
+
// Ethereum
|
|
24610
24818
|
"0x1": "Ethereum Mainnet",
|
|
24611
|
-
"0xaa36a7": "Sepolia",
|
|
24612
|
-
"
|
|
24613
|
-
|
|
24819
|
+
"0xaa36a7": "Sepolia Testnet",
|
|
24820
|
+
"0x5": "Goerli Testnet",
|
|
24821
|
+
// Polygon
|
|
24822
|
+
"0x89": "Polygon Mainnet",
|
|
24823
|
+
"0x13882": "Polygon Amoy Testnet",
|
|
24824
|
+
"0x13881": "Polygon Mumbai Testnet",
|
|
24825
|
+
"0x44d": "Polygon zkEVM",
|
|
24826
|
+
"0x5a2": "Polygon zkEVM Testnet",
|
|
24827
|
+
// BNB Smart Chain
|
|
24828
|
+
"0x38": "BNB Smart Chain",
|
|
24829
|
+
"0x61": "BNB Testnet",
|
|
24830
|
+
// Avalanche
|
|
24831
|
+
"0xa86a": "Avalanche C-Chain",
|
|
24832
|
+
"0xa869": "Avalanche Fuji Testnet",
|
|
24833
|
+
// Arbitrum
|
|
24614
24834
|
"0xa4b1": "Arbitrum One",
|
|
24615
|
-
"
|
|
24616
|
-
"
|
|
24835
|
+
"0x66eee": "Arbitrum Sepolia",
|
|
24836
|
+
"0x66eed": "Arbitrum Goerli",
|
|
24837
|
+
// Optimism
|
|
24838
|
+
"0xa": "Optimism Mainnet",
|
|
24839
|
+
"0xaa37dc": "Optimism Sepolia",
|
|
24840
|
+
"0x1a4": "Optimism Goerli",
|
|
24841
|
+
// Base
|
|
24842
|
+
"0x2105": "Base Mainnet",
|
|
24843
|
+
"0x14a34": "Base Sepolia",
|
|
24844
|
+
// zkSync Era
|
|
24845
|
+
"0x144": "zkSync Era Mainnet",
|
|
24846
|
+
"0x12c": "zkSync Era Sepolia",
|
|
24847
|
+
// Linea
|
|
24848
|
+
"0xe708": "Linea Mainnet",
|
|
24849
|
+
"0xe704": "Linea Goerli",
|
|
24850
|
+
// Scroll
|
|
24851
|
+
"0x82750": "Scroll Mainnet",
|
|
24852
|
+
"0x8274f": "Scroll Sepolia",
|
|
24853
|
+
// Fantom
|
|
24854
|
+
"0xfa": "Fantom Opera",
|
|
24855
|
+
"0xfa2": "Fantom Testnet",
|
|
24856
|
+
// Gnosis
|
|
24857
|
+
"0x64": "Gnosis Chain",
|
|
24858
|
+
"0x27d8": "Chiado Testnet",
|
|
24859
|
+
// Celo
|
|
24860
|
+
"0xa4ec": "Celo Mainnet",
|
|
24861
|
+
"0xaef3": "Celo Alfajores",
|
|
24862
|
+
// Blast
|
|
24863
|
+
"0x13e31": "Blast Mainnet",
|
|
24864
|
+
"0xa0c71fd": "Blast Sepolia",
|
|
24865
|
+
// Mantle
|
|
24866
|
+
"0x1388": "Mantle Mainnet",
|
|
24867
|
+
"0x1389": "Mantle Testnet",
|
|
24868
|
+
// Moonbeam
|
|
24869
|
+
"0x504": "Moonbeam",
|
|
24870
|
+
"0x505": "Moonriver",
|
|
24871
|
+
"0x507": "Moonbase Alpha",
|
|
24872
|
+
// Metis
|
|
24873
|
+
"0x440": "Metis Andromeda",
|
|
24874
|
+
// Cronos
|
|
24875
|
+
"0x19": "Cronos Mainnet",
|
|
24876
|
+
"0x152": "Cronos Testnet",
|
|
24877
|
+
// Local development
|
|
24878
|
+
"0x539": "Hardhat Local (1337)",
|
|
24879
|
+
"0x7a69": "Hardhat / Anvil Local"
|
|
24880
|
+
};
|
|
24881
|
+
var NATIVE_SYMBOLS = {
|
|
24882
|
+
"0x89": "POL",
|
|
24883
|
+
"0x13882": "POL",
|
|
24884
|
+
"0x13881": "POL",
|
|
24885
|
+
"0x44d": "ETH",
|
|
24886
|
+
"0x38": "BNB",
|
|
24887
|
+
"0x61": "BNB",
|
|
24888
|
+
"0xa86a": "AVAX",
|
|
24889
|
+
"0xa869": "AVAX",
|
|
24890
|
+
"0xfa": "FTM",
|
|
24891
|
+
"0xfa2": "FTM",
|
|
24892
|
+
"0x64": "xDAI",
|
|
24893
|
+
"0x27d8": "xDAI",
|
|
24894
|
+
"0xa4ec": "CELO",
|
|
24895
|
+
"0xaef3": "CELO",
|
|
24896
|
+
"0x504": "GLMR",
|
|
24897
|
+
"0x505": "MOVR",
|
|
24898
|
+
"0x19": "CRO",
|
|
24899
|
+
"0x152": "CRO"
|
|
24617
24900
|
};
|
|
24618
24901
|
function getNetworkName(chainId) {
|
|
24619
24902
|
if (!chainId) {
|
|
@@ -24621,6 +24904,21 @@ function getNetworkName(chainId) {
|
|
|
24621
24904
|
}
|
|
24622
24905
|
return CHAIN_NAMES[chainId.toLowerCase()] ?? `Chain ${chainId}`;
|
|
24623
24906
|
}
|
|
24907
|
+
function getNativeSymbol(chainId) {
|
|
24908
|
+
if (!chainId) return "ETH";
|
|
24909
|
+
return NATIVE_SYMBOLS[chainId.toLowerCase()] ?? "ETH";
|
|
24910
|
+
}
|
|
24911
|
+
function formatBalance(balanceHex, symbol) {
|
|
24912
|
+
try {
|
|
24913
|
+
const wei = BigInt(balanceHex);
|
|
24914
|
+
const ethValue = Number(wei) / 1e18;
|
|
24915
|
+
if (ethValue === 0) return `0 ${symbol}`;
|
|
24916
|
+
if (ethValue < 1e-4) return `< 0.0001 ${symbol}`;
|
|
24917
|
+
return `${ethValue.toFixed(4)} ${symbol}`;
|
|
24918
|
+
} catch {
|
|
24919
|
+
return `\u2014 ${symbol}`;
|
|
24920
|
+
}
|
|
24921
|
+
}
|
|
24624
24922
|
function getEthereumProvider() {
|
|
24625
24923
|
return window.ethereum;
|
|
24626
24924
|
}
|
|
@@ -24639,6 +24937,20 @@ async function getWalletStatus(provider = getEthereumProvider()) {
|
|
|
24639
24937
|
]);
|
|
24640
24938
|
const accounts = Array.isArray(accountsResult) ? accountsResult : [];
|
|
24641
24939
|
const chainId = typeof chainIdResult === "string" ? chainIdResult : void 0;
|
|
24940
|
+
const nativeSymbol = getNativeSymbol(chainId);
|
|
24941
|
+
let balance;
|
|
24942
|
+
if (accounts.length > 0) {
|
|
24943
|
+
try {
|
|
24944
|
+
const balanceHex = await provider.request({
|
|
24945
|
+
method: "eth_getBalance",
|
|
24946
|
+
params: [accounts[0], "latest"]
|
|
24947
|
+
});
|
|
24948
|
+
if (typeof balanceHex === "string") {
|
|
24949
|
+
balance = formatBalance(balanceHex, nativeSymbol);
|
|
24950
|
+
}
|
|
24951
|
+
} catch {
|
|
24952
|
+
}
|
|
24953
|
+
}
|
|
24642
24954
|
return {
|
|
24643
24955
|
available: true,
|
|
24644
24956
|
connected: accounts.length > 0,
|
|
@@ -24646,7 +24958,9 @@ async function getWalletStatus(provider = getEthereumProvider()) {
|
|
|
24646
24958
|
walletName: provider.isMetaMask ? "MetaMask" : "Browser Wallet",
|
|
24647
24959
|
account: accounts[0],
|
|
24648
24960
|
chainId,
|
|
24649
|
-
networkName: getNetworkName(chainId)
|
|
24961
|
+
networkName: getNetworkName(chainId),
|
|
24962
|
+
balance,
|
|
24963
|
+
nativeSymbol
|
|
24650
24964
|
};
|
|
24651
24965
|
}
|
|
24652
24966
|
async function connectWallet(provider = getEthereumProvider()) {
|
|
@@ -24684,7 +24998,7 @@ function subscribeToWallet(onChange, provider = getEthereumProvider()) {
|
|
|
24684
24998
|
}
|
|
24685
24999
|
|
|
24686
25000
|
// src/ui/app.tsx
|
|
24687
|
-
var
|
|
25001
|
+
var import_jsx_runtime5 = __toESM(require_jsx_runtime());
|
|
24688
25002
|
var INITIAL_SNAPSHOT = {
|
|
24689
25003
|
pending: [],
|
|
24690
25004
|
history: [],
|
|
@@ -24731,15 +25045,15 @@ function formatLastUpdated(timestamp) {
|
|
|
24731
25045
|
});
|
|
24732
25046
|
}
|
|
24733
25047
|
function App() {
|
|
24734
|
-
const [snapshot, setSnapshot] = (0,
|
|
24735
|
-
const [wallet, setWallet] = (0,
|
|
24736
|
-
const [socketConnected, setSocketConnected] = (0,
|
|
24737
|
-
const [busyIds, setBusyIds] = (0,
|
|
24738
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
24739
|
-
const socketRef = (0,
|
|
24740
|
-
const autoRunningIdsRef = (0,
|
|
25048
|
+
const [snapshot, setSnapshot] = (0, import_react2.useState)(INITIAL_SNAPSHOT);
|
|
25049
|
+
const [wallet, setWallet] = (0, import_react2.useState)(EMPTY_WALLET_STATE);
|
|
25050
|
+
const [socketConnected, setSocketConnected] = (0, import_react2.useState)(false);
|
|
25051
|
+
const [busyIds, setBusyIds] = (0, import_react2.useState)([]);
|
|
25052
|
+
const [errorMessage, setErrorMessage] = (0, import_react2.useState)(null);
|
|
25053
|
+
const socketRef = (0, import_react2.useRef)(null);
|
|
25054
|
+
const autoRunningIdsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
24741
25055
|
const provider = getEthereumProvider();
|
|
24742
|
-
(0,
|
|
25056
|
+
(0, import_react2.useEffect)(() => {
|
|
24743
25057
|
const socket = new WebSocket(`${window.location.origin.replace(/^http/, "ws")}/ws`);
|
|
24744
25058
|
socketRef.current = socket;
|
|
24745
25059
|
socket.onopen = async () => {
|
|
@@ -24769,7 +25083,7 @@ function App() {
|
|
|
24769
25083
|
socket.close();
|
|
24770
25084
|
};
|
|
24771
25085
|
}, [provider]);
|
|
24772
|
-
(0,
|
|
25086
|
+
(0, import_react2.useEffect)(() => {
|
|
24773
25087
|
const unsubscribe = subscribeToWallet(async () => {
|
|
24774
25088
|
try {
|
|
24775
25089
|
const nextWallet = await getWalletStatus(provider);
|
|
@@ -24812,7 +25126,7 @@ function App() {
|
|
|
24812
25126
|
setBusyIds((current) => current.filter((id) => id !== request.queueId));
|
|
24813
25127
|
}
|
|
24814
25128
|
}
|
|
24815
|
-
(0,
|
|
25129
|
+
(0, import_react2.useEffect)(() => {
|
|
24816
25130
|
if (!wallet.connected) {
|
|
24817
25131
|
return;
|
|
24818
25132
|
}
|
|
@@ -24852,75 +25166,85 @@ function App() {
|
|
|
24852
25166
|
} else if (!wallet.connected) {
|
|
24853
25167
|
warnings.push("Connect MetaMask to this page so the dashboard can forward queued requests.");
|
|
24854
25168
|
}
|
|
24855
|
-
return /* @__PURE__ */ (0,
|
|
24856
|
-
/* @__PURE__ */ (0,
|
|
24857
|
-
/* @__PURE__ */ (0,
|
|
24858
|
-
/* @__PURE__ */ (0,
|
|
24859
|
-
/* @__PURE__ */ (0,
|
|
25169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("main", { className: "app-shell", children: [
|
|
25170
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "hero", children: [
|
|
25171
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hero-card", children: [
|
|
25172
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { children: "Review every Hardhat request before it hits the wallet." }),
|
|
25173
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
24860
25174
|
"This dashboard keeps private keys out of ",
|
|
24861
|
-
/* @__PURE__ */ (0,
|
|
25175
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "hardhat.config.ts" }),
|
|
24862
25176
|
" by routing JSON-RPC calls through a local approval queue. Signatures stay inside MetaMask and connected hardware wallets."
|
|
24863
25177
|
] }),
|
|
24864
|
-
/* @__PURE__ */ (0,
|
|
24865
|
-
/* @__PURE__ */ (0,
|
|
24866
|
-
/* @__PURE__ */ (0,
|
|
25178
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hero-meta", children: [
|
|
25179
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WalletBadge, { wallet }),
|
|
25180
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pill", children: [
|
|
24867
25181
|
"WebSocket ",
|
|
24868
25182
|
socketConnected ? "connected" : "offline"
|
|
24869
25183
|
] }),
|
|
24870
|
-
/* @__PURE__ */ (0,
|
|
25184
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pill", children: [
|
|
24871
25185
|
"Last update ",
|
|
24872
25186
|
formatLastUpdated(snapshot.updatedAt)
|
|
24873
25187
|
] })
|
|
24874
25188
|
] })
|
|
24875
25189
|
] }),
|
|
24876
|
-
/* @__PURE__ */ (0,
|
|
24877
|
-
/* @__PURE__ */ (0,
|
|
24878
|
-
/* @__PURE__ */ (0,
|
|
25190
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { className: "hero-card status-card", children: [
|
|
25191
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: "Wallet Control" }),
|
|
25192
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
24879
25193
|
"Open MetaMask in this browser profile, connect the page, then leave this tab visible while running ",
|
|
24880
|
-
/* @__PURE__ */ (0,
|
|
25194
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "--network dashboard" }),
|
|
24881
25195
|
" commands from Hardhat."
|
|
24882
25196
|
] }),
|
|
24883
|
-
/* @__PURE__ */ (0,
|
|
24884
|
-
/* @__PURE__ */ (0,
|
|
24885
|
-
/* @__PURE__ */ (0,
|
|
25197
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "button-row", children: [
|
|
25198
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "button-primary", onClick: () => void handleConnectWallet(), children: wallet.connected ? "Reconnect Wallet" : "Connect Wallet" }),
|
|
25199
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "button-secondary", onClick: () => window.location.reload(), children: "Reload UI" })
|
|
24886
25200
|
] })
|
|
24887
25201
|
] })
|
|
24888
25202
|
] }),
|
|
24889
|
-
/* @__PURE__ */ (0,
|
|
24890
|
-
/* @__PURE__ */ (0,
|
|
24891
|
-
/* @__PURE__ */ (0,
|
|
24892
|
-
/* @__PURE__ */ (0,
|
|
25203
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "status-strip", children: [
|
|
25204
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "metric", children: [
|
|
25205
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "label", children: "Pending" }),
|
|
25206
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: snapshot.pending.length })
|
|
24893
25207
|
] }),
|
|
24894
|
-
/* @__PURE__ */ (0,
|
|
24895
|
-
/* @__PURE__ */ (0,
|
|
24896
|
-
/* @__PURE__ */ (0,
|
|
25208
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "metric", children: [
|
|
25209
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "label", children: "Session History" }),
|
|
25210
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: snapshot.history.filter(
|
|
25211
|
+
(e) => [
|
|
25212
|
+
"eth_sendTransaction",
|
|
25213
|
+
"eth_sign",
|
|
25214
|
+
"personal_sign",
|
|
25215
|
+
"eth_signTypedData",
|
|
25216
|
+
"eth_signTypedData_v1",
|
|
25217
|
+
"eth_signTypedData_v3",
|
|
25218
|
+
"eth_signTypedData_v4"
|
|
25219
|
+
].includes(e.method)
|
|
25220
|
+
).length })
|
|
24897
25221
|
] }),
|
|
24898
|
-
/* @__PURE__ */ (0,
|
|
24899
|
-
/* @__PURE__ */ (0,
|
|
24900
|
-
/* @__PURE__ */ (0,
|
|
25222
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "metric", children: [
|
|
25223
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "label", children: "Network" }),
|
|
25224
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: wallet.networkName ?? wallet.chainId ?? "Not connected" })
|
|
24901
25225
|
] }),
|
|
24902
|
-
/* @__PURE__ */ (0,
|
|
24903
|
-
/* @__PURE__ */ (0,
|
|
24904
|
-
/* @__PURE__ */ (0,
|
|
25226
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "metric", children: [
|
|
25227
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "label", children: "Balance" }),
|
|
25228
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: wallet.balance ?? (wallet.connected ? "Fetching\u2026" : "\u2014") })
|
|
24905
25229
|
] })
|
|
24906
25230
|
] }),
|
|
24907
|
-
warnings.length > 0 || errorMessage ? /* @__PURE__ */ (0,
|
|
24908
|
-
warnings.map((warning) => /* @__PURE__ */ (0,
|
|
24909
|
-
/* @__PURE__ */ (0,
|
|
24910
|
-
/* @__PURE__ */ (0,
|
|
25231
|
+
warnings.length > 0 || errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { children: [
|
|
25232
|
+
warnings.map((warning) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "warning-banner", children: [
|
|
25233
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Attention" }),
|
|
25234
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: warning })
|
|
24911
25235
|
] }, warning)),
|
|
24912
|
-
errorMessage ? /* @__PURE__ */ (0,
|
|
24913
|
-
/* @__PURE__ */ (0,
|
|
24914
|
-
/* @__PURE__ */ (0,
|
|
25236
|
+
errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "warning-banner", children: [
|
|
25237
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Wallet error" }),
|
|
25238
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: errorMessage })
|
|
24915
25239
|
] }) : null
|
|
24916
25240
|
] }) : null,
|
|
24917
|
-
/* @__PURE__ */ (0,
|
|
24918
|
-
/* @__PURE__ */ (0,
|
|
24919
|
-
/* @__PURE__ */ (0,
|
|
24920
|
-
/* @__PURE__ */ (0,
|
|
24921
|
-
/* @__PURE__ */ (0,
|
|
25241
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "dashboard-grid", children: [
|
|
25242
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "panel", children: [
|
|
25243
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "panel-header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
25244
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: "Pending Requests" }),
|
|
25245
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "panel-subtitle", children: "Signing methods require your confirmation. Read-only calls run automatically once the wallet is connected." })
|
|
24922
25246
|
] }) }),
|
|
24923
|
-
/* @__PURE__ */ (0,
|
|
25247
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "card-list", children: snapshot.pending.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "empty-state", children: "No requests are waiting for approval." }) : snapshot.pending.map((request) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
24924
25248
|
PendingTxCard,
|
|
24925
25249
|
{
|
|
24926
25250
|
request,
|
|
@@ -24931,12 +25255,12 @@ function App() {
|
|
|
24931
25255
|
request.queueId
|
|
24932
25256
|
)) })
|
|
24933
25257
|
] }),
|
|
24934
|
-
/* @__PURE__ */ (0,
|
|
24935
|
-
/* @__PURE__ */ (0,
|
|
24936
|
-
/* @__PURE__ */ (0,
|
|
24937
|
-
/* @__PURE__ */ (0,
|
|
25258
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "panel", children: [
|
|
25259
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "panel-header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
25260
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: "Tx History" }),
|
|
25261
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "panel-subtitle", children: "Confirmed, rejected, failed, and expired requests from this session." })
|
|
24938
25262
|
] }) }),
|
|
24939
|
-
/* @__PURE__ */ (0,
|
|
25263
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TxHistory, { entries: snapshot.history })
|
|
24940
25264
|
] })
|
|
24941
25265
|
] })
|
|
24942
25266
|
] });
|
|
@@ -24945,7 +25269,7 @@ var container = document.getElementById("root");
|
|
|
24945
25269
|
if (!container) {
|
|
24946
25270
|
throw new Error("Unable to find the dashboard root element.");
|
|
24947
25271
|
}
|
|
24948
|
-
(0, import_client.createRoot)(container).render(/* @__PURE__ */ (0,
|
|
25272
|
+
(0, import_client.createRoot)(container).render(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(App, {}));
|
|
24949
25273
|
/*! Bundled license information:
|
|
24950
25274
|
|
|
24951
25275
|
react/cjs/react.development.js:
|