@hardkas/react 0.5.5-alpha → 0.6.1-alpha
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/dist/index.d.ts +180 -21
- package/dist/index.js +614 -90
- package/package.json +5 -6
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ interface HardKasReactConfig {
|
|
|
25
25
|
readonly devServerUrl?: string;
|
|
26
26
|
}
|
|
27
27
|
type SSEStatus = "connecting" | "connected" | "disconnected" | "reconnecting" | "failed";
|
|
28
|
+
type ProjectionStatus = "synced" | "stale" | "syncing";
|
|
28
29
|
interface RuntimeEvent {
|
|
29
30
|
type: string;
|
|
30
31
|
payload?: any;
|
|
@@ -36,6 +37,10 @@ interface HardKasContextValue {
|
|
|
36
37
|
readonly igraClient: PublicClient;
|
|
37
38
|
readonly queryClient: QueryClient;
|
|
38
39
|
readonly sseStatus: SSEStatus;
|
|
40
|
+
readonly projectionStatus: ProjectionStatus;
|
|
41
|
+
readonly generationId: string | null;
|
|
42
|
+
readonly lastSyncedAt: string | null;
|
|
43
|
+
readonly apiFetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
39
44
|
readonly lastEvent: RuntimeEvent | null;
|
|
40
45
|
readonly subscribe: (callback: EventCallback) => () => void;
|
|
41
46
|
readonly providers: EIP6963ProviderDetail[];
|
|
@@ -123,26 +128,25 @@ declare function useIgraBalance(options?: {
|
|
|
123
128
|
refetchInterval?: number;
|
|
124
129
|
}): _tanstack_react_query.UseQueryResult<bigint, Error>;
|
|
125
130
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}, unknown>;
|
|
131
|
+
interface HardKasEventInfo {
|
|
132
|
+
eventId: string;
|
|
133
|
+
kind: string;
|
|
134
|
+
domain: string;
|
|
135
|
+
workflowId: string;
|
|
136
|
+
correlationId: string;
|
|
137
|
+
causationId: string | null;
|
|
138
|
+
txId: string | null;
|
|
139
|
+
artifactId: string | null;
|
|
140
|
+
networkId: string;
|
|
141
|
+
timestamp: string | null;
|
|
142
|
+
payload: any;
|
|
143
|
+
}
|
|
144
|
+
interface UseEventsResponse {
|
|
145
|
+
events: HardKasEventInfo[];
|
|
146
|
+
observabilityDrift?: boolean;
|
|
147
|
+
reason?: string;
|
|
148
|
+
}
|
|
149
|
+
declare function useEvents(kind?: string, txId?: string): _tanstack_react_query.UseQueryResult<UseEventsResponse, Error>;
|
|
146
150
|
|
|
147
151
|
type CcipRequestReturnType = Hex;
|
|
148
152
|
|
|
@@ -4748,4 +4752,159 @@ declare function useIgraWriteContract(): _tanstack_react_query.UseMutationResult
|
|
|
4748
4752
|
}, unknown>;
|
|
4749
4753
|
declare function useIgraWaitForReceipt(): _tanstack_react_query.UseMutationResult<viem.TransactionReceipt, Error, `0x${string}`, unknown>;
|
|
4750
4754
|
|
|
4751
|
-
|
|
4755
|
+
interface OverviewStats {
|
|
4756
|
+
projectName: string;
|
|
4757
|
+
network: string;
|
|
4758
|
+
workspaceRoot: string;
|
|
4759
|
+
artifactDir: string;
|
|
4760
|
+
queryStorePath: string;
|
|
4761
|
+
runtimeState: "EMPTY" | "ACTIVE" | "PENDING" | "DEGRADED" | "CORRUPTED" | "VERIFIED";
|
|
4762
|
+
runtimeReason: string;
|
|
4763
|
+
recommendedAction: string;
|
|
4764
|
+
guarantees: {
|
|
4765
|
+
artifactIntegrity: "available" | "failed" | "not_checked";
|
|
4766
|
+
localReplay: "verified" | "failed" | "not_checked";
|
|
4767
|
+
consensusValidated: boolean;
|
|
4768
|
+
networkFinality: boolean;
|
|
4769
|
+
};
|
|
4770
|
+
counts: {
|
|
4771
|
+
artifacts: number;
|
|
4772
|
+
transactions: number;
|
|
4773
|
+
events: number;
|
|
4774
|
+
replays: number;
|
|
4775
|
+
pendingReplays: number;
|
|
4776
|
+
corruptedArtifacts: number;
|
|
4777
|
+
degradedProjections: number;
|
|
4778
|
+
};
|
|
4779
|
+
}
|
|
4780
|
+
declare function useOverview(): _tanstack_react_query.UseQueryResult<OverviewStats | null, Error>;
|
|
4781
|
+
|
|
4782
|
+
interface HardKasAccountInfo {
|
|
4783
|
+
name: string;
|
|
4784
|
+
kind: string;
|
|
4785
|
+
address: string;
|
|
4786
|
+
balance: string;
|
|
4787
|
+
privateKeyEnv?: string;
|
|
4788
|
+
walletId?: string;
|
|
4789
|
+
}
|
|
4790
|
+
interface HardKasAccountsResponse {
|
|
4791
|
+
accounts: HardKasAccountInfo[];
|
|
4792
|
+
provenance?: {
|
|
4793
|
+
authority: string;
|
|
4794
|
+
derivedFrom?: string;
|
|
4795
|
+
originalPath?: string;
|
|
4796
|
+
integrity: "verified" | "corrupted" | "invalid_json" | "unknown";
|
|
4797
|
+
replayScope: "local-only" | "global" | "unknown";
|
|
4798
|
+
consensusValidated: boolean;
|
|
4799
|
+
};
|
|
4800
|
+
}
|
|
4801
|
+
declare function useAccounts(): _tanstack_react_query.UseQueryResult<HardKasAccountsResponse, Error>;
|
|
4802
|
+
|
|
4803
|
+
interface TransactionSummary {
|
|
4804
|
+
id: string;
|
|
4805
|
+
txId?: string;
|
|
4806
|
+
planId?: string;
|
|
4807
|
+
signedId?: string;
|
|
4808
|
+
status: string;
|
|
4809
|
+
from: string;
|
|
4810
|
+
to: string;
|
|
4811
|
+
amountSompi: string;
|
|
4812
|
+
amount: string;
|
|
4813
|
+
feeSompi?: string;
|
|
4814
|
+
timestamp: string;
|
|
4815
|
+
mode: string;
|
|
4816
|
+
networkId: string;
|
|
4817
|
+
layer: "L1" | "L2";
|
|
4818
|
+
}
|
|
4819
|
+
interface LineageNode {
|
|
4820
|
+
id: string;
|
|
4821
|
+
label: string;
|
|
4822
|
+
schema: string;
|
|
4823
|
+
}
|
|
4824
|
+
interface LineageEdge {
|
|
4825
|
+
from: string;
|
|
4826
|
+
to: string;
|
|
4827
|
+
label: string;
|
|
4828
|
+
}
|
|
4829
|
+
interface TransactionDetail {
|
|
4830
|
+
id: string;
|
|
4831
|
+
plan: any;
|
|
4832
|
+
signed: any;
|
|
4833
|
+
receipt: any;
|
|
4834
|
+
trace: any;
|
|
4835
|
+
replay: any;
|
|
4836
|
+
lineage: {
|
|
4837
|
+
nodes: LineageNode[];
|
|
4838
|
+
edges: LineageEdge[];
|
|
4839
|
+
};
|
|
4840
|
+
}
|
|
4841
|
+
declare function useTransactions(): _tanstack_react_query.UseQueryResult<TransactionSummary[], Error>;
|
|
4842
|
+
declare function useTransaction(id: string): _tanstack_react_query.UseQueryResult<TransactionDetail | null, Error>;
|
|
4843
|
+
|
|
4844
|
+
interface ArtifactSummary {
|
|
4845
|
+
artifactId: string;
|
|
4846
|
+
contentHash: string;
|
|
4847
|
+
schema: string;
|
|
4848
|
+
version: string;
|
|
4849
|
+
kind: string;
|
|
4850
|
+
mode: string;
|
|
4851
|
+
networkId: string;
|
|
4852
|
+
txId?: string;
|
|
4853
|
+
createdAt: string;
|
|
4854
|
+
path: string;
|
|
4855
|
+
}
|
|
4856
|
+
declare function useArtifacts(schemaFilter?: string): _tanstack_react_query.UseQueryResult<ArtifactSummary[], Error>;
|
|
4857
|
+
declare function useArtifact(id: string): _tanstack_react_query.UseQueryResult<any, Error>;
|
|
4858
|
+
|
|
4859
|
+
interface ReplaySummary {
|
|
4860
|
+
artifactId: string;
|
|
4861
|
+
txId: string;
|
|
4862
|
+
planOk: boolean;
|
|
4863
|
+
receiptOk: boolean;
|
|
4864
|
+
invariantsOk: boolean;
|
|
4865
|
+
ok: boolean;
|
|
4866
|
+
checks: {
|
|
4867
|
+
workflowDeterministic: string;
|
|
4868
|
+
consensusValidation: string;
|
|
4869
|
+
l2BridgeCorrectness: string;
|
|
4870
|
+
};
|
|
4871
|
+
errors: string[];
|
|
4872
|
+
divergencesCount: number;
|
|
4873
|
+
createdAt: string;
|
|
4874
|
+
}
|
|
4875
|
+
interface UseReplayStatusResponse {
|
|
4876
|
+
replays: ReplaySummary[];
|
|
4877
|
+
pendingReplays: any[];
|
|
4878
|
+
pendingReplay: boolean;
|
|
4879
|
+
reason?: string;
|
|
4880
|
+
}
|
|
4881
|
+
declare function useReplayStatus(): _tanstack_react_query.UseQueryResult<UseReplayStatusResponse, Error>;
|
|
4882
|
+
declare function useReplayDetail(txId: string): _tanstack_react_query.UseQueryResult<any, Error>;
|
|
4883
|
+
|
|
4884
|
+
interface DeploymentSummary {
|
|
4885
|
+
artifactId: string;
|
|
4886
|
+
label: string;
|
|
4887
|
+
networkId: string;
|
|
4888
|
+
status: string;
|
|
4889
|
+
txId?: string;
|
|
4890
|
+
deployedAt: string;
|
|
4891
|
+
deployedAddresses: string[];
|
|
4892
|
+
deployer?: string;
|
|
4893
|
+
notes?: string;
|
|
4894
|
+
}
|
|
4895
|
+
declare function useDeployments(): _tanstack_react_query.UseQueryResult<DeploymentSummary[], Error>;
|
|
4896
|
+
|
|
4897
|
+
interface ActivityEvent {
|
|
4898
|
+
eventId: string;
|
|
4899
|
+
kind: string;
|
|
4900
|
+
domain: string;
|
|
4901
|
+
workflowId: string;
|
|
4902
|
+
txId?: string;
|
|
4903
|
+
artifactId?: string;
|
|
4904
|
+
networkId: string;
|
|
4905
|
+
timestamp: string;
|
|
4906
|
+
payload: any;
|
|
4907
|
+
}
|
|
4908
|
+
declare function useActivity(): _tanstack_react_query.UseQueryResult<ActivityEvent[], Error>;
|
|
4909
|
+
|
|
4910
|
+
export { type ActivityEvent, type ArtifactSummary, type DeploymentSummary, type EventCallback, type HardKasAccountInfo, type HardKasAccountsResponse, type HardKasContextValue, type HardKasEventInfo, HardKasProvider, type HardKasReactConfig, type HealthInfo, type KasWareLocalState, type KasWareSessionMatch, type LineageEdge, type LineageNode, type MetaMaskLocalState, type OverviewStats, type ReplaySummary, type RuntimeEvent, type SSEStatus, type SandboxConnection, type SessionInfo, type TransactionDetail, type TransactionSummary, type UseEventsResponse, type UseReplayStatusResponse, useAccounts, useActivity, useArtifact, useArtifacts, useConnectKasWareLocal, useCreateSandboxSession, useDeployments, useDisconnectSandboxSession, useEvents, useHardKas, useHardKasHealth, useHardKasSession, useIgraAccount, useIgraBalance, useIgraInjectedAccount, useIgraReadContract, useIgraWaitForReceipt, useIgraWallet, useIgraWriteContract, useKasWareLocal, useKasWareSessionMatch, useKaspaBalance, useKaspaWallet, useLocalIgraWalletClient, useMetaMaskLocal, useOverview, usePairSandboxSession, useReplayDetail, useReplayStatus, useSandboxSessions, useSwitchToLocalIgra, useTransaction, useTransactions };
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
import React, { createContext, useContext, useMemo } from "react";
|
|
3
3
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
4
|
import { createPublicClient, http } from "viem";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
var HardKasContext = createContext(void 0);
|
|
7
7
|
function HardKasProvider({ config, children, queryClient: externalQueryClient }) {
|
|
8
8
|
const queryClient = useMemo(() => externalQueryClient ?? new QueryClient(), [externalQueryClient]);
|
|
9
9
|
const [sseStatus, setSseStatus] = React.useState("disconnected");
|
|
10
|
+
const [projectionStatus, setProjectionStatus] = React.useState("synced");
|
|
11
|
+
const [generationId, setGenerationId] = React.useState(null);
|
|
12
|
+
const [lastSyncedAt, setLastSyncedAt] = React.useState(null);
|
|
10
13
|
const [lastEvent, setLastEvent] = React.useState(null);
|
|
11
14
|
const listeners = React.useRef(/* @__PURE__ */ new Set());
|
|
12
15
|
const eventSource = React.useRef(null);
|
|
@@ -16,10 +19,58 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
16
19
|
const [activeProvider, setActiveProvider] = React.useState(null);
|
|
17
20
|
const [walletAddress, setWalletAddress] = React.useState(null);
|
|
18
21
|
const [walletChainId, setWalletChainId] = React.useState(null);
|
|
22
|
+
const devToken = React.useMemo(() => {
|
|
23
|
+
if (typeof window !== "undefined") {
|
|
24
|
+
if (window.__HARDKAS_DEV_TOKEN__) {
|
|
25
|
+
return window.__HARDKAS_DEV_TOKEN__;
|
|
26
|
+
}
|
|
27
|
+
const params = new URLSearchParams(window.location.search);
|
|
28
|
+
return params.get("token") || "";
|
|
29
|
+
}
|
|
30
|
+
return "";
|
|
31
|
+
}, []);
|
|
32
|
+
const [tokenMissing, setTokenMissing] = React.useState(false);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (typeof window !== "undefined") {
|
|
35
|
+
const isTest = typeof globalThis.vi !== "undefined" || window.__MOCK_SSE__ || process.env.NODE_ENV === "test";
|
|
36
|
+
const isDashboard = window.location.pathname.startsWith("/") || window.location.port === "7420" || window.location.port === "5173";
|
|
37
|
+
if (isDashboard && !isTest && !devToken) {
|
|
38
|
+
setTokenMissing(true);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, [devToken]);
|
|
19
42
|
const subscribe = React.useCallback((callback) => {
|
|
20
43
|
listeners.current.add(callback);
|
|
21
44
|
return () => listeners.current.delete(callback);
|
|
22
45
|
}, []);
|
|
46
|
+
const apiFetch = React.useCallback(async (input, init) => {
|
|
47
|
+
const headers = new Headers(init?.headers || {});
|
|
48
|
+
if (devToken) {
|
|
49
|
+
headers.set("Authorization", `Bearer ${devToken}`);
|
|
50
|
+
}
|
|
51
|
+
const method = init?.method?.toUpperCase() || "GET";
|
|
52
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
53
|
+
headers.set("X-Hardkas-Request", "true");
|
|
54
|
+
}
|
|
55
|
+
const mergedInit = {
|
|
56
|
+
...init,
|
|
57
|
+
headers
|
|
58
|
+
};
|
|
59
|
+
const response = await fetch(input, mergedInit);
|
|
60
|
+
const genHeader = response.headers?.get?.("X-Hardkas-Generation");
|
|
61
|
+
if (genHeader) {
|
|
62
|
+
setGenerationId((prev) => {
|
|
63
|
+
if (prev !== genHeader) {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
if (queryClient) queryClient.invalidateQueries();
|
|
66
|
+
}, 0);
|
|
67
|
+
return genHeader;
|
|
68
|
+
}
|
|
69
|
+
return prev;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return response;
|
|
73
|
+
}, [queryClient, devToken]);
|
|
23
74
|
const connect = React.useCallback(() => {
|
|
24
75
|
if (typeof window === "undefined") return;
|
|
25
76
|
if (!config.devServerUrl) {
|
|
@@ -35,9 +86,20 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
35
86
|
}
|
|
36
87
|
setSseStatus("connecting");
|
|
37
88
|
const baseUrl = config.devServerUrl;
|
|
38
|
-
|
|
89
|
+
let url = baseUrl.endsWith("/") ? `${baseUrl}api/stream` : `${baseUrl}/api/stream`;
|
|
90
|
+
if (devToken) {
|
|
91
|
+
url += (url.includes("?") ? "&" : "?") + `token=${encodeURIComponent(devToken)}`;
|
|
92
|
+
}
|
|
39
93
|
const es = new EventSource(url);
|
|
40
94
|
eventSource.current = es;
|
|
95
|
+
if (typeof window !== "undefined") {
|
|
96
|
+
window.__MOCK_SSE_CLOSE__ = () => {
|
|
97
|
+
es.close();
|
|
98
|
+
if (es.onerror) {
|
|
99
|
+
es.onerror.call(es, new Event("error"));
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
41
103
|
es.onopen = () => {
|
|
42
104
|
setSseStatus("connected");
|
|
43
105
|
backoffMs.current = 500;
|
|
@@ -70,6 +132,9 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
70
132
|
"sandbox-session-paired",
|
|
71
133
|
"sandbox-session-expired",
|
|
72
134
|
"sandbox-session-disconnected",
|
|
135
|
+
"projection-stale",
|
|
136
|
+
"projection-synced",
|
|
137
|
+
"query-synced",
|
|
73
138
|
"ping",
|
|
74
139
|
"heartbeat"
|
|
75
140
|
];
|
|
@@ -82,9 +147,20 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
82
147
|
};
|
|
83
148
|
setLastEvent(event);
|
|
84
149
|
listeners.current.forEach((l) => l(event));
|
|
150
|
+
if (type === "projection-stale") {
|
|
151
|
+
setProjectionStatus("stale");
|
|
152
|
+
}
|
|
153
|
+
if (type === "projection-synced" || type === "query-synced") {
|
|
154
|
+
setProjectionStatus("synced");
|
|
155
|
+
setLastSyncedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
156
|
+
if (event.payload?.generationId) {
|
|
157
|
+
setGenerationId(event.payload.generationId);
|
|
158
|
+
}
|
|
159
|
+
queryClient.invalidateQueries();
|
|
160
|
+
}
|
|
85
161
|
});
|
|
86
162
|
});
|
|
87
|
-
}, [config.devServerUrl]);
|
|
163
|
+
}, [config.devServerUrl, queryClient, devToken]);
|
|
88
164
|
React.useEffect(() => {
|
|
89
165
|
connect();
|
|
90
166
|
return () => {
|
|
@@ -248,6 +324,10 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
248
324
|
igraClient,
|
|
249
325
|
queryClient,
|
|
250
326
|
sseStatus,
|
|
327
|
+
projectionStatus,
|
|
328
|
+
generationId,
|
|
329
|
+
lastSyncedAt,
|
|
330
|
+
apiFetch,
|
|
251
331
|
lastEvent,
|
|
252
332
|
subscribe,
|
|
253
333
|
providers,
|
|
@@ -262,6 +342,10 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
262
342
|
igraClient,
|
|
263
343
|
queryClient,
|
|
264
344
|
sseStatus,
|
|
345
|
+
projectionStatus,
|
|
346
|
+
generationId,
|
|
347
|
+
lastSyncedAt,
|
|
348
|
+
apiFetch,
|
|
265
349
|
lastEvent,
|
|
266
350
|
subscribe,
|
|
267
351
|
providers,
|
|
@@ -272,7 +356,30 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
272
356
|
disconnectWallet,
|
|
273
357
|
switchChain
|
|
274
358
|
]);
|
|
275
|
-
return /* @__PURE__ */ jsx(HardKasContext.Provider, { value, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children
|
|
359
|
+
return /* @__PURE__ */ jsx(HardKasContext.Provider, { value, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: tokenMissing ? /* @__PURE__ */ jsx("div", { style: {
|
|
360
|
+
display: "flex",
|
|
361
|
+
flexDirection: "column",
|
|
362
|
+
alignItems: "center",
|
|
363
|
+
justifyContent: "center",
|
|
364
|
+
height: "100vh",
|
|
365
|
+
width: "100vw",
|
|
366
|
+
backgroundColor: "#1a1a1a",
|
|
367
|
+
color: "#f87171",
|
|
368
|
+
fontFamily: "sans-serif",
|
|
369
|
+
textAlign: "center",
|
|
370
|
+
padding: "20px"
|
|
371
|
+
}, children: /* @__PURE__ */ jsxs("div", { style: {
|
|
372
|
+
backgroundColor: "#2d2d2d",
|
|
373
|
+
border: "2px solid #ef4444",
|
|
374
|
+
borderRadius: "8px",
|
|
375
|
+
padding: "30px",
|
|
376
|
+
maxWidth: "450px",
|
|
377
|
+
boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.5)"
|
|
378
|
+
}, children: [
|
|
379
|
+
/* @__PURE__ */ jsx("h2", { style: { color: "#ef4444", marginTop: 0 }, children: "Dashboard authentication token missing." }),
|
|
380
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#d1d5db", lineHeight: "1.5" }, children: "The dev-server is secured against local workstation CSRF and DNS rebinding attacks." }),
|
|
381
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#9ca3af", fontWeight: "bold" }, children: "Restart hardkas dashboard." })
|
|
382
|
+
] }) }) : children }) });
|
|
276
383
|
}
|
|
277
384
|
function useHardKas() {
|
|
278
385
|
const context = useContext(HardKasContext);
|
|
@@ -286,7 +393,7 @@ function useHardKas() {
|
|
|
286
393
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
287
394
|
import { useEffect } from "react";
|
|
288
395
|
function useHardKasSession(name) {
|
|
289
|
-
const { config, subscribe } = useHardKas();
|
|
396
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
290
397
|
const queryClient = useQueryClient();
|
|
291
398
|
const sessionToResolve = name || config.sessionName;
|
|
292
399
|
useEffect(() => {
|
|
@@ -303,7 +410,7 @@ function useHardKasSession(name) {
|
|
|
303
410
|
try {
|
|
304
411
|
const baseUrl = config.devServerUrl || "";
|
|
305
412
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/session` : `${baseUrl}/api/session` : "/api/session";
|
|
306
|
-
const response = await
|
|
413
|
+
const response = await apiFetch(url);
|
|
307
414
|
const json = await response.json();
|
|
308
415
|
const active = json.active;
|
|
309
416
|
if (!active) return null;
|
|
@@ -329,7 +436,7 @@ function useHardKasSession(name) {
|
|
|
329
436
|
import { useQuery as useQuery2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
330
437
|
import { useEffect as useEffect2 } from "react";
|
|
331
438
|
function useHardKasHealth() {
|
|
332
|
-
const { config, subscribe } = useHardKas();
|
|
439
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
333
440
|
const queryClient = useQueryClient2();
|
|
334
441
|
useEffect2(() => {
|
|
335
442
|
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "health"] });
|
|
@@ -345,7 +452,7 @@ function useHardKasHealth() {
|
|
|
345
452
|
try {
|
|
346
453
|
const baseUrl = config.devServerUrl || "";
|
|
347
454
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/health` : `${baseUrl}/api/health` : "/api/health";
|
|
348
|
-
const res = await
|
|
455
|
+
const res = await apiFetch(url);
|
|
349
456
|
if (!res || !res.ok) {
|
|
350
457
|
throw new Error("Failed to fetch health from dev server");
|
|
351
458
|
}
|
|
@@ -362,7 +469,8 @@ function useHardKasHealth() {
|
|
|
362
469
|
}
|
|
363
470
|
|
|
364
471
|
// src/hooks/kaspa.ts
|
|
365
|
-
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
472
|
+
import { useQuery as useQuery3, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
473
|
+
import { useEffect as useEffect3 } from "react";
|
|
366
474
|
function useKaspaWallet() {
|
|
367
475
|
const { data: session } = useHardKasSession();
|
|
368
476
|
return {
|
|
@@ -372,9 +480,18 @@ function useKaspaWallet() {
|
|
|
372
480
|
};
|
|
373
481
|
}
|
|
374
482
|
function useKaspaBalance(options = {}) {
|
|
375
|
-
const { config } = useHardKas();
|
|
483
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
484
|
+
const queryClient = useQueryClient3();
|
|
376
485
|
const { address, name } = useKaspaWallet();
|
|
377
486
|
const { data: health } = useHardKasHealth();
|
|
487
|
+
useEffect3(() => {
|
|
488
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["kaspa", "balance"] });
|
|
489
|
+
return subscribe((event) => {
|
|
490
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
491
|
+
sync();
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}, [queryClient, subscribe]);
|
|
378
495
|
const l1Status = health?.kaspa?.status || health?.l1?.status;
|
|
379
496
|
const isL1Online = l1Status === "healthy" || l1Status === "simulated-mode" || l1Status === "ok" || l1Status === "running" || l1Status === "online" || !!address && address.startsWith("kaspa:sim_");
|
|
380
497
|
return useQuery3({
|
|
@@ -382,7 +499,21 @@ function useKaspaBalance(options = {}) {
|
|
|
382
499
|
queryFn: async () => {
|
|
383
500
|
if (!address) return 0n;
|
|
384
501
|
if (address.startsWith("kaspa:sim_") || l1Status === "simulated-mode") {
|
|
385
|
-
|
|
502
|
+
try {
|
|
503
|
+
const baseUrl = config.devServerUrl || "";
|
|
504
|
+
const fetchUrl = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/accounts` : `${baseUrl}/api/accounts` : "/api/accounts";
|
|
505
|
+
const res = await apiFetch(fetchUrl);
|
|
506
|
+
if (res.ok) {
|
|
507
|
+
const data = await res.json();
|
|
508
|
+
const match = (data.accounts || []).find((a) => a.address === address);
|
|
509
|
+
if (match) {
|
|
510
|
+
return BigInt(match.balanceSompi || match.balance || "0");
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
} catch (e) {
|
|
514
|
+
console.warn("Failed to fetch derived simulated balance, falling back to 0:", e);
|
|
515
|
+
}
|
|
516
|
+
return 0n;
|
|
386
517
|
}
|
|
387
518
|
let url = config.kaspaRpcUrl || "http://127.0.0.1:16110";
|
|
388
519
|
if (url.includes("127.0.0.1:16110") || url.includes("localhost:16110")) {
|
|
@@ -433,7 +564,7 @@ function useKaspaBalance(options = {}) {
|
|
|
433
564
|
}
|
|
434
565
|
}
|
|
435
566
|
try {
|
|
436
|
-
const response = await
|
|
567
|
+
const response = await apiFetch(url, {
|
|
437
568
|
method: "POST",
|
|
438
569
|
headers: { "Content-Type": "application/json" },
|
|
439
570
|
body: JSON.stringify({
|
|
@@ -455,10 +586,11 @@ function useKaspaBalance(options = {}) {
|
|
|
455
586
|
}
|
|
456
587
|
|
|
457
588
|
// src/hooks/igra.ts
|
|
458
|
-
import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
589
|
+
import { useQuery as useQuery4, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
590
|
+
import { useEffect as useEffect4 } from "react";
|
|
459
591
|
function useIgraAccount() {
|
|
460
592
|
const { data: session } = useHardKasSession();
|
|
461
|
-
const { walletAddress } = useHardKas();
|
|
593
|
+
const { walletAddress, apiFetch } = useHardKas();
|
|
462
594
|
const address = walletAddress || session?.l2.address;
|
|
463
595
|
return {
|
|
464
596
|
name: walletAddress ? "Browser Wallet" : session?.l2.account,
|
|
@@ -475,7 +607,8 @@ function useIgraWallet() {
|
|
|
475
607
|
walletChainId,
|
|
476
608
|
connectWallet,
|
|
477
609
|
disconnectWallet,
|
|
478
|
-
switchChain
|
|
610
|
+
switchChain,
|
|
611
|
+
apiFetch
|
|
479
612
|
} = useHardKas();
|
|
480
613
|
return {
|
|
481
614
|
providers,
|
|
@@ -489,10 +622,18 @@ function useIgraWallet() {
|
|
|
489
622
|
};
|
|
490
623
|
}
|
|
491
624
|
function useIgraBalance(options = {}) {
|
|
492
|
-
const { igraClient } = useHardKas();
|
|
625
|
+
const { igraClient, config, subscribe, apiFetch } = useHardKas();
|
|
626
|
+
const queryClient = useQueryClient4();
|
|
493
627
|
const { address } = useIgraAccount();
|
|
628
|
+
useEffect4(() => {
|
|
629
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["igra", "balance"] });
|
|
630
|
+
return subscribe((event) => {
|
|
631
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
632
|
+
sync();
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
}, [queryClient, subscribe]);
|
|
494
636
|
const { data: session } = useHardKasSession();
|
|
495
|
-
const { config } = useHardKas();
|
|
496
637
|
const { data: health } = useHardKasHealth();
|
|
497
638
|
const l2Status = health?.igra?.status || health?.l2?.status;
|
|
498
639
|
const isL2Online = l2Status === "healthy" || l2Status === "ok" || l2Status === "running" || l2Status === "online" || !!address && (address.startsWith("0xsim_") || address.startsWith("kaspa:sim_") || !address.startsWith("0x"));
|
|
@@ -501,7 +642,23 @@ function useIgraBalance(options = {}) {
|
|
|
501
642
|
queryFn: async () => {
|
|
502
643
|
if (!address) return 0n;
|
|
503
644
|
if (address.startsWith("0xsim_") || !address.startsWith("0x") || l2Status === "simulated-mode") {
|
|
504
|
-
|
|
645
|
+
try {
|
|
646
|
+
const baseUrl = config.devServerUrl || "";
|
|
647
|
+
const fetchUrl = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/accounts` : `${baseUrl}/api/accounts` : "/api/accounts";
|
|
648
|
+
const res = await apiFetch(fetchUrl);
|
|
649
|
+
if (res.ok) {
|
|
650
|
+
const data = await res.json();
|
|
651
|
+
const match = (data.accounts || []).find(
|
|
652
|
+
(a) => a.address.toLowerCase() === address.toLowerCase() || a.name.toLowerCase() === address.toLowerCase()
|
|
653
|
+
);
|
|
654
|
+
if (match) {
|
|
655
|
+
return BigInt(match.balanceSompi || match.balance || "0");
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
} catch (e) {
|
|
659
|
+
console.warn("Failed to fetch derived simulated L2 balance, falling back to 0:", e);
|
|
660
|
+
}
|
|
661
|
+
return 0n;
|
|
505
662
|
}
|
|
506
663
|
try {
|
|
507
664
|
return await igraClient.getBalance({ address });
|
|
@@ -514,48 +671,56 @@ function useIgraBalance(options = {}) {
|
|
|
514
671
|
});
|
|
515
672
|
}
|
|
516
673
|
|
|
517
|
-
// src/hooks/
|
|
518
|
-
import { useQuery as useQuery5
|
|
519
|
-
import {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const { config } = useHardKas();
|
|
674
|
+
// src/hooks/events.ts
|
|
675
|
+
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
676
|
+
import { useEffect as useEffect5 } from "react";
|
|
677
|
+
import { useQueryClient as useQueryClient5 } from "@tanstack/react-query";
|
|
678
|
+
function useEvents(kind, txId) {
|
|
679
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
680
|
+
const queryClient = useQueryClient5();
|
|
681
|
+
const queryKey = ["hardkas", "events", kind, txId];
|
|
682
|
+
useEffect5(() => {
|
|
683
|
+
return subscribe((event) => {
|
|
684
|
+
queryClient.invalidateQueries({ queryKey: ["hardkas", "events"] });
|
|
685
|
+
});
|
|
686
|
+
}, [queryClient, subscribe]);
|
|
523
687
|
return useQuery5({
|
|
524
|
-
queryKey
|
|
688
|
+
queryKey,
|
|
525
689
|
queryFn: async () => {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
690
|
+
try {
|
|
691
|
+
const baseUrl = config.devServerUrl || "";
|
|
692
|
+
const queryParams = new URLSearchParams();
|
|
693
|
+
if (kind) queryParams.append("kind", kind);
|
|
694
|
+
if (txId) queryParams.append("txId", txId);
|
|
695
|
+
const queryStr = queryParams.toString() ? `?${queryParams.toString()}` : "";
|
|
696
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/events${queryStr}` : `${baseUrl}/api/events${queryStr}` : `/api/events${queryStr}`;
|
|
697
|
+
const response = await apiFetch(url);
|
|
698
|
+
if (!response.ok) return { events: [] };
|
|
699
|
+
const data = await response.json();
|
|
700
|
+
return {
|
|
701
|
+
events: data.events || [],
|
|
702
|
+
observabilityDrift: data.observabilityDrift,
|
|
703
|
+
reason: data.reason
|
|
704
|
+
};
|
|
705
|
+
} catch (e) {
|
|
706
|
+
console.error("Failed to fetch events from dev server:", e);
|
|
707
|
+
return { events: [] };
|
|
708
|
+
}
|
|
544
709
|
},
|
|
545
|
-
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
function useBridgeLocalSimulation() {
|
|
549
|
-
return useMutation({
|
|
550
|
-
mutationFn: async (params) => {
|
|
551
|
-
return simulatePrefixMining(params.payloadBase, params.prefix, { timeoutMs: 1e4 });
|
|
552
|
-
}
|
|
710
|
+
staleTime: 5e3
|
|
553
711
|
});
|
|
554
712
|
}
|
|
555
713
|
|
|
556
714
|
// src/hooks/metamask.ts
|
|
557
|
-
import { useState, useEffect as
|
|
715
|
+
import { useState, useEffect as useEffect6, useCallback } from "react";
|
|
558
716
|
import { createWalletClient, custom } from "viem";
|
|
717
|
+
var getMetaMaskProvider = () => {
|
|
718
|
+
if (typeof window === "undefined" || !window.ethereum) return null;
|
|
719
|
+
if (window.ethereum.providers) {
|
|
720
|
+
return window.ethereum.providers.find((p) => p.isMetaMask) || window.ethereum;
|
|
721
|
+
}
|
|
722
|
+
return window.ethereum;
|
|
723
|
+
};
|
|
559
724
|
function useMetaMaskLocal() {
|
|
560
725
|
const [state, setState] = useState({
|
|
561
726
|
installed: false,
|
|
@@ -565,12 +730,12 @@ function useMetaMaskLocal() {
|
|
|
565
730
|
errors: []
|
|
566
731
|
});
|
|
567
732
|
const checkStatus = useCallback(async () => {
|
|
568
|
-
|
|
733
|
+
const provider = getMetaMaskProvider();
|
|
734
|
+
if (!provider) {
|
|
569
735
|
setState((s) => ({ ...s, installed: false }));
|
|
570
736
|
return;
|
|
571
737
|
}
|
|
572
738
|
try {
|
|
573
|
-
const provider = window.ethereum;
|
|
574
739
|
const chainIdHex = await provider.request({ method: "eth_chainId" });
|
|
575
740
|
const chainId = parseInt(chainIdHex, 16);
|
|
576
741
|
const accounts = await provider.request({ method: "eth_accounts" });
|
|
@@ -588,17 +753,18 @@ function useMetaMaskLocal() {
|
|
|
588
753
|
}
|
|
589
754
|
}, []);
|
|
590
755
|
const connect = useCallback(async () => {
|
|
591
|
-
|
|
756
|
+
const provider = getMetaMaskProvider();
|
|
757
|
+
if (!provider) return;
|
|
592
758
|
try {
|
|
593
|
-
await
|
|
759
|
+
await provider.request({ method: "eth_requestAccounts" });
|
|
594
760
|
await checkStatus();
|
|
595
761
|
} catch (e) {
|
|
596
762
|
setState((s) => ({ ...s, errors: [...s.errors, e.message] }));
|
|
597
763
|
}
|
|
598
764
|
}, [checkStatus]);
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
765
|
+
useEffect6(() => {
|
|
766
|
+
const provider = getMetaMaskProvider();
|
|
767
|
+
if (!provider) return;
|
|
602
768
|
checkStatus();
|
|
603
769
|
const handleChange = () => checkStatus();
|
|
604
770
|
provider.on("accountsChanged", handleChange);
|
|
@@ -616,16 +782,17 @@ function useMetaMaskLocal() {
|
|
|
616
782
|
}
|
|
617
783
|
function useSwitchToLocalIgra() {
|
|
618
784
|
const switchChain = async () => {
|
|
619
|
-
|
|
785
|
+
const provider = getMetaMaskProvider();
|
|
786
|
+
if (!provider) return;
|
|
620
787
|
try {
|
|
621
|
-
await
|
|
788
|
+
await provider.request({
|
|
622
789
|
method: "wallet_switchEthereumChain",
|
|
623
790
|
params: [{ chainId: "0x4bd8" }]
|
|
624
791
|
// 19416
|
|
625
792
|
});
|
|
626
793
|
} catch (e) {
|
|
627
794
|
if (e.code === 4902) {
|
|
628
|
-
await
|
|
795
|
+
await provider.request({
|
|
629
796
|
method: "wallet_addEthereumChain",
|
|
630
797
|
params: [{
|
|
631
798
|
chainId: "0x4bd8",
|
|
@@ -651,17 +818,18 @@ function useIgraInjectedAccount(sessionL2Address) {
|
|
|
651
818
|
function useLocalIgraWalletClient() {
|
|
652
819
|
const { state } = useMetaMaskLocal();
|
|
653
820
|
const getClient = useCallback(() => {
|
|
654
|
-
|
|
821
|
+
const provider = getMetaMaskProvider();
|
|
822
|
+
if (!state.connected || !provider) return null;
|
|
655
823
|
return createWalletClient({
|
|
656
824
|
account: state.account,
|
|
657
|
-
transport: custom(
|
|
825
|
+
transport: custom(provider)
|
|
658
826
|
});
|
|
659
827
|
}, [state.connected, state.account]);
|
|
660
828
|
return { getClient };
|
|
661
829
|
}
|
|
662
830
|
|
|
663
831
|
// src/hooks/kasware.ts
|
|
664
|
-
import { useState as useState2, useEffect as
|
|
832
|
+
import { useState as useState2, useEffect as useEffect7, useCallback as useCallback2 } from "react";
|
|
665
833
|
function useKasWareLocal() {
|
|
666
834
|
const [state, setState] = useState2({
|
|
667
835
|
installed: false,
|
|
@@ -693,7 +861,7 @@ function useKasWareLocal() {
|
|
|
693
861
|
setState((s) => ({ ...s, errors: [e.message] }));
|
|
694
862
|
}
|
|
695
863
|
}, []);
|
|
696
|
-
|
|
864
|
+
useEffect7(() => {
|
|
697
865
|
if (typeof window === "undefined" || !window.kasware) return;
|
|
698
866
|
const provider = window.kasware;
|
|
699
867
|
checkStatus();
|
|
@@ -753,12 +921,12 @@ function useKasWareSessionMatch(sessionL1Address) {
|
|
|
753
921
|
}
|
|
754
922
|
|
|
755
923
|
// src/hooks/sandbox.ts
|
|
756
|
-
import { useQuery as useQuery6, useMutation
|
|
757
|
-
import { useEffect as
|
|
924
|
+
import { useQuery as useQuery6, useMutation, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
|
|
925
|
+
import { useEffect as useEffect8 } from "react";
|
|
758
926
|
function useSandboxSessions() {
|
|
759
|
-
const { config, subscribe } = useHardKas();
|
|
760
|
-
const queryClient =
|
|
761
|
-
|
|
927
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
928
|
+
const queryClient = useQueryClient6();
|
|
929
|
+
useEffect8(() => {
|
|
762
930
|
const sync = () => queryClient.invalidateQueries({ queryKey: ["sandbox", "sessions"] });
|
|
763
931
|
return subscribe((event) => {
|
|
764
932
|
if ([
|
|
@@ -776,20 +944,20 @@ function useSandboxSessions() {
|
|
|
776
944
|
queryFn: async () => {
|
|
777
945
|
const baseUrl = config.devServerUrl || "";
|
|
778
946
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/walletconnect/sandbox/sessions` : `${baseUrl}/api/walletconnect/sandbox/sessions` : "/api/walletconnect/sandbox/sessions";
|
|
779
|
-
const res = await
|
|
947
|
+
const res = await apiFetch(url);
|
|
780
948
|
const json = await res.json();
|
|
781
949
|
return json.sessions;
|
|
782
950
|
}
|
|
783
951
|
});
|
|
784
952
|
}
|
|
785
953
|
function useCreateSandboxSession() {
|
|
786
|
-
const { config } = useHardKas();
|
|
787
|
-
const queryClient =
|
|
788
|
-
return
|
|
954
|
+
const { config, apiFetch } = useHardKas();
|
|
955
|
+
const queryClient = useQueryClient6();
|
|
956
|
+
return useMutation({
|
|
789
957
|
mutationFn: async () => {
|
|
790
958
|
const baseUrl = config.devServerUrl || "";
|
|
791
959
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/walletconnect/sandbox/create` : `${baseUrl}/api/walletconnect/sandbox/create` : "/api/walletconnect/sandbox/create";
|
|
792
|
-
const res = await
|
|
960
|
+
const res = await apiFetch(url, { method: "POST" });
|
|
793
961
|
return await res.json();
|
|
794
962
|
},
|
|
795
963
|
onSuccess: () => {
|
|
@@ -798,13 +966,13 @@ function useCreateSandboxSession() {
|
|
|
798
966
|
});
|
|
799
967
|
}
|
|
800
968
|
function usePairSandboxSession() {
|
|
801
|
-
const { config } = useHardKas();
|
|
802
|
-
const queryClient =
|
|
803
|
-
return
|
|
969
|
+
const { config, apiFetch } = useHardKas();
|
|
970
|
+
const queryClient = useQueryClient6();
|
|
971
|
+
return useMutation({
|
|
804
972
|
mutationFn: async (id) => {
|
|
805
973
|
const baseUrl = config.devServerUrl || "";
|
|
806
974
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/walletconnect/sandbox/pair` : `${baseUrl}/api/walletconnect/sandbox/pair` : "/api/walletconnect/sandbox/pair";
|
|
807
|
-
const res = await
|
|
975
|
+
const res = await apiFetch(url, {
|
|
808
976
|
method: "POST",
|
|
809
977
|
headers: { "Content-Type": "application/json" },
|
|
810
978
|
body: JSON.stringify({ id })
|
|
@@ -817,13 +985,13 @@ function usePairSandboxSession() {
|
|
|
817
985
|
});
|
|
818
986
|
}
|
|
819
987
|
function useDisconnectSandboxSession() {
|
|
820
|
-
const { config } = useHardKas();
|
|
821
|
-
const queryClient =
|
|
822
|
-
return
|
|
988
|
+
const { config, apiFetch } = useHardKas();
|
|
989
|
+
const queryClient = useQueryClient6();
|
|
990
|
+
return useMutation({
|
|
823
991
|
mutationFn: async (id) => {
|
|
824
992
|
const baseUrl = config.devServerUrl || "";
|
|
825
993
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/walletconnect/sandbox/disconnect` : `${baseUrl}/api/walletconnect/sandbox/disconnect` : "/api/walletconnect/sandbox/disconnect";
|
|
826
|
-
const res = await
|
|
994
|
+
const res = await apiFetch(url, {
|
|
827
995
|
method: "POST",
|
|
828
996
|
headers: { "Content-Type": "application/json" },
|
|
829
997
|
body: JSON.stringify({ id })
|
|
@@ -837,7 +1005,7 @@ function useDisconnectSandboxSession() {
|
|
|
837
1005
|
}
|
|
838
1006
|
|
|
839
1007
|
// src/hooks/contracts.ts
|
|
840
|
-
import { useQuery as useQuery7, useMutation as
|
|
1008
|
+
import { useQuery as useQuery7, useMutation as useMutation2 } from "@tanstack/react-query";
|
|
841
1009
|
import { createWalletClient as createWalletClient2, custom as custom2 } from "viem";
|
|
842
1010
|
function useIgraReadContract(options) {
|
|
843
1011
|
const { igraClient, config } = useHardKas();
|
|
@@ -858,7 +1026,7 @@ function useIgraReadContract(options) {
|
|
|
858
1026
|
}
|
|
859
1027
|
function useIgraWriteContract() {
|
|
860
1028
|
const { activeProvider, walletAddress, igraClient } = useHardKas();
|
|
861
|
-
return
|
|
1029
|
+
return useMutation2({
|
|
862
1030
|
mutationFn: async (params) => {
|
|
863
1031
|
let client = params.walletClient;
|
|
864
1032
|
if (!client) {
|
|
@@ -885,19 +1053,370 @@ function useIgraWriteContract() {
|
|
|
885
1053
|
}
|
|
886
1054
|
function useIgraWaitForReceipt() {
|
|
887
1055
|
const { igraClient } = useHardKas();
|
|
888
|
-
return
|
|
1056
|
+
return useMutation2({
|
|
889
1057
|
mutationFn: async (hash) => {
|
|
890
1058
|
return await igraClient.waitForTransactionReceipt({ hash });
|
|
891
1059
|
}
|
|
892
1060
|
});
|
|
893
1061
|
}
|
|
1062
|
+
|
|
1063
|
+
// src/hooks/overview.ts
|
|
1064
|
+
import { useQuery as useQuery8, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
|
|
1065
|
+
import { useEffect as useEffect9 } from "react";
|
|
1066
|
+
function useOverview() {
|
|
1067
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1068
|
+
const queryClient = useQueryClient7();
|
|
1069
|
+
useEffect9(() => {
|
|
1070
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "overview"] });
|
|
1071
|
+
return subscribe((event) => {
|
|
1072
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1073
|
+
sync();
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
}, [queryClient, subscribe]);
|
|
1077
|
+
return useQuery8({
|
|
1078
|
+
queryKey: ["hardkas", "overview"],
|
|
1079
|
+
queryFn: async () => {
|
|
1080
|
+
try {
|
|
1081
|
+
const baseUrl = config.devServerUrl || "";
|
|
1082
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/overview` : `${baseUrl}/api/overview` : "/api/overview";
|
|
1083
|
+
const response = await apiFetch(url);
|
|
1084
|
+
if (!response.ok) return null;
|
|
1085
|
+
return await response.json();
|
|
1086
|
+
} catch (e) {
|
|
1087
|
+
console.error("Failed to fetch overview stats from dev server:", e);
|
|
1088
|
+
return null;
|
|
1089
|
+
}
|
|
1090
|
+
},
|
|
1091
|
+
staleTime: 6e4
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// src/hooks/accounts.ts
|
|
1096
|
+
import { useQuery as useQuery9, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
|
|
1097
|
+
import { useEffect as useEffect10 } from "react";
|
|
1098
|
+
function useAccounts() {
|
|
1099
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1100
|
+
const queryClient = useQueryClient8();
|
|
1101
|
+
useEffect10(() => {
|
|
1102
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "accounts"] });
|
|
1103
|
+
return subscribe((event) => {
|
|
1104
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1105
|
+
sync();
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
}, [queryClient, subscribe]);
|
|
1109
|
+
return useQuery9({
|
|
1110
|
+
queryKey: ["hardkas", "accounts"],
|
|
1111
|
+
queryFn: async () => {
|
|
1112
|
+
try {
|
|
1113
|
+
const baseUrl = config.devServerUrl || "";
|
|
1114
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/accounts` : `${baseUrl}/api/accounts` : "/api/accounts";
|
|
1115
|
+
const response = await apiFetch(url);
|
|
1116
|
+
if (!response.ok) return { accounts: [] };
|
|
1117
|
+
const data = await response.json();
|
|
1118
|
+
return data || { accounts: [] };
|
|
1119
|
+
} catch (e) {
|
|
1120
|
+
console.error("Failed to fetch accounts from dev server:", e);
|
|
1121
|
+
return { accounts: [] };
|
|
1122
|
+
}
|
|
1123
|
+
},
|
|
1124
|
+
staleTime: 3e4
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// src/hooks/transactions.ts
|
|
1129
|
+
import { useQuery as useQuery10, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
|
|
1130
|
+
import { useEffect as useEffect11 } from "react";
|
|
1131
|
+
function useTransactions() {
|
|
1132
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1133
|
+
const queryClient = useQueryClient9();
|
|
1134
|
+
useEffect11(() => {
|
|
1135
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "transactions"] });
|
|
1136
|
+
return subscribe((event) => {
|
|
1137
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1138
|
+
sync();
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
}, [queryClient, subscribe]);
|
|
1142
|
+
return useQuery10({
|
|
1143
|
+
queryKey: ["hardkas", "transactions"],
|
|
1144
|
+
queryFn: async () => {
|
|
1145
|
+
try {
|
|
1146
|
+
const baseUrl = config.devServerUrl || "";
|
|
1147
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/transactions` : `${baseUrl}/api/transactions` : "/api/transactions";
|
|
1148
|
+
const response = await apiFetch(url);
|
|
1149
|
+
if (!response.ok) return [];
|
|
1150
|
+
const data = await response.json();
|
|
1151
|
+
return data.transactions || [];
|
|
1152
|
+
} catch (e) {
|
|
1153
|
+
console.error("Failed to fetch transactions from dev server:", e);
|
|
1154
|
+
return [];
|
|
1155
|
+
}
|
|
1156
|
+
},
|
|
1157
|
+
staleTime: 1e4
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
function useTransaction(id) {
|
|
1161
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1162
|
+
const queryClient = useQueryClient9();
|
|
1163
|
+
useEffect11(() => {
|
|
1164
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "transaction", id] });
|
|
1165
|
+
return subscribe((event) => {
|
|
1166
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1167
|
+
sync();
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
}, [id, queryClient, subscribe]);
|
|
1171
|
+
return useQuery10({
|
|
1172
|
+
queryKey: ["hardkas", "transaction", id],
|
|
1173
|
+
queryFn: async () => {
|
|
1174
|
+
if (!id) return null;
|
|
1175
|
+
try {
|
|
1176
|
+
const baseUrl = config.devServerUrl || "";
|
|
1177
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/transactions/${id}` : `${baseUrl}/api/transactions/${id}` : `/api/transactions/${id}`;
|
|
1178
|
+
const response = await apiFetch(url);
|
|
1179
|
+
if (!response.ok) return null;
|
|
1180
|
+
return await response.json();
|
|
1181
|
+
} catch (e) {
|
|
1182
|
+
console.error(`Failed to fetch transaction detail for '${id}':`, e);
|
|
1183
|
+
return null;
|
|
1184
|
+
}
|
|
1185
|
+
},
|
|
1186
|
+
enabled: !!id,
|
|
1187
|
+
staleTime: 1e4
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// src/hooks/artifacts.ts
|
|
1192
|
+
import { useQuery as useQuery11, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
|
|
1193
|
+
import { useEffect as useEffect12 } from "react";
|
|
1194
|
+
function useArtifacts(schemaFilter) {
|
|
1195
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1196
|
+
const queryClient = useQueryClient10();
|
|
1197
|
+
useEffect12(() => {
|
|
1198
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "artifacts", schemaFilter || "all"] });
|
|
1199
|
+
return subscribe((event) => {
|
|
1200
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1201
|
+
sync();
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
}, [schemaFilter, queryClient, subscribe]);
|
|
1205
|
+
return useQuery11({
|
|
1206
|
+
queryKey: ["hardkas", "artifacts", schemaFilter || "all"],
|
|
1207
|
+
queryFn: async () => {
|
|
1208
|
+
try {
|
|
1209
|
+
const baseUrl = config.devServerUrl || "";
|
|
1210
|
+
const queryParams = schemaFilter ? `?schema=${schemaFilter}` : "";
|
|
1211
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/artifacts${queryParams}` : `${baseUrl}/api/artifacts${queryParams}` : `/api/artifacts${queryParams}`;
|
|
1212
|
+
const response = await apiFetch(url);
|
|
1213
|
+
if (!response.ok) return [];
|
|
1214
|
+
const data = await response.json();
|
|
1215
|
+
return data.artifacts || [];
|
|
1216
|
+
} catch (e) {
|
|
1217
|
+
console.error("Failed to fetch artifacts from dev server:", e);
|
|
1218
|
+
return [];
|
|
1219
|
+
}
|
|
1220
|
+
},
|
|
1221
|
+
staleTime: 3e4
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
function useArtifact(id) {
|
|
1225
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1226
|
+
const queryClient = useQueryClient10();
|
|
1227
|
+
useEffect12(() => {
|
|
1228
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "artifact", id] });
|
|
1229
|
+
return subscribe((event) => {
|
|
1230
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1231
|
+
sync();
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
}, [id, queryClient, subscribe]);
|
|
1235
|
+
return useQuery11({
|
|
1236
|
+
queryKey: ["hardkas", "artifact", id],
|
|
1237
|
+
queryFn: async () => {
|
|
1238
|
+
if (!id) return null;
|
|
1239
|
+
try {
|
|
1240
|
+
const baseUrl = config.devServerUrl || "";
|
|
1241
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/artifacts/${id}` : `${baseUrl}/api/artifacts/${id}` : `/api/artifacts/${id}`;
|
|
1242
|
+
const response = await apiFetch(url);
|
|
1243
|
+
if (!response.ok) return null;
|
|
1244
|
+
const data = await response.json();
|
|
1245
|
+
return data.artifact || null;
|
|
1246
|
+
} catch (e) {
|
|
1247
|
+
console.error(`Failed to fetch artifact detail for '${id}':`, e);
|
|
1248
|
+
return null;
|
|
1249
|
+
}
|
|
1250
|
+
},
|
|
1251
|
+
enabled: !!id,
|
|
1252
|
+
staleTime: 3e4
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
// src/hooks/replay.ts
|
|
1257
|
+
import { useQuery as useQuery12, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
|
|
1258
|
+
import { useEffect as useEffect13 } from "react";
|
|
1259
|
+
function useReplayStatus() {
|
|
1260
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1261
|
+
const queryClient = useQueryClient11();
|
|
1262
|
+
useEffect13(() => {
|
|
1263
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "replay"] });
|
|
1264
|
+
return subscribe((event) => {
|
|
1265
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1266
|
+
sync();
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
1269
|
+
}, [queryClient, subscribe]);
|
|
1270
|
+
return useQuery12({
|
|
1271
|
+
queryKey: ["hardkas", "replay"],
|
|
1272
|
+
queryFn: async () => {
|
|
1273
|
+
try {
|
|
1274
|
+
const baseUrl = config.devServerUrl || "";
|
|
1275
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/replay` : `${baseUrl}/api/replay` : "/api/replay";
|
|
1276
|
+
const response = await apiFetch(url);
|
|
1277
|
+
if (!response.ok) return { replays: [], pendingReplays: [], pendingReplay: false };
|
|
1278
|
+
const data = await response.json();
|
|
1279
|
+
const formatReplay = (r) => {
|
|
1280
|
+
return {
|
|
1281
|
+
artifactId: r.artifactId,
|
|
1282
|
+
txId: r.payload?.txId || r.txId,
|
|
1283
|
+
planOk: r.payload?.planOk ?? false,
|
|
1284
|
+
receiptOk: r.payload?.receiptOk ?? false,
|
|
1285
|
+
invariantsOk: r.payload?.invariantsOk ?? false,
|
|
1286
|
+
ok: r.payload?.planOk && r.payload?.receiptOk && r.payload?.invariantsOk ? true : false,
|
|
1287
|
+
checks: r.payload?.checks || {
|
|
1288
|
+
workflowDeterministic: "unknown",
|
|
1289
|
+
consensusValidation: "unknown",
|
|
1290
|
+
l2BridgeCorrectness: "unknown"
|
|
1291
|
+
},
|
|
1292
|
+
errors: r.payload?.errors || [],
|
|
1293
|
+
divergencesCount: r.payload?.divergencesCount || 0,
|
|
1294
|
+
createdAt: r.createdAt || r.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1297
|
+
return {
|
|
1298
|
+
replays: (data.replays || []).map(formatReplay),
|
|
1299
|
+
pendingReplays: data.pendingReplays || [],
|
|
1300
|
+
pendingReplay: data.pendingReplay || false,
|
|
1301
|
+
reason: data.reason
|
|
1302
|
+
};
|
|
1303
|
+
} catch (e) {
|
|
1304
|
+
console.error("Failed to fetch replay status from dev server:", e);
|
|
1305
|
+
return { replays: [], pendingReplays: [], pendingReplay: false };
|
|
1306
|
+
}
|
|
1307
|
+
},
|
|
1308
|
+
staleTime: 3e4
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
function useReplayDetail(txId) {
|
|
1312
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1313
|
+
const queryClient = useQueryClient11();
|
|
1314
|
+
useEffect13(() => {
|
|
1315
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "replay", txId] });
|
|
1316
|
+
return subscribe((event) => {
|
|
1317
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1318
|
+
sync();
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
}, [txId, queryClient, subscribe]);
|
|
1322
|
+
return useQuery12({
|
|
1323
|
+
queryKey: ["hardkas", "replay", txId],
|
|
1324
|
+
queryFn: async () => {
|
|
1325
|
+
if (!txId) return null;
|
|
1326
|
+
try {
|
|
1327
|
+
const baseUrl = config.devServerUrl || "";
|
|
1328
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/replay/${txId}` : `${baseUrl}/api/replay/${txId}` : `/api/replay/${txId}`;
|
|
1329
|
+
const response = await apiFetch(url);
|
|
1330
|
+
if (!response.ok) return null;
|
|
1331
|
+
const data = await response.json();
|
|
1332
|
+
return data.replay || null;
|
|
1333
|
+
} catch (e) {
|
|
1334
|
+
console.error(`Failed to fetch replay details for transaction '${txId}':`, e);
|
|
1335
|
+
return null;
|
|
1336
|
+
}
|
|
1337
|
+
},
|
|
1338
|
+
enabled: !!txId,
|
|
1339
|
+
staleTime: 3e4
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// src/hooks/deployments.ts
|
|
1344
|
+
import { useQuery as useQuery13, useQueryClient as useQueryClient12 } from "@tanstack/react-query";
|
|
1345
|
+
import { useEffect as useEffect14 } from "react";
|
|
1346
|
+
function useDeployments() {
|
|
1347
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1348
|
+
const queryClient = useQueryClient12();
|
|
1349
|
+
useEffect14(() => {
|
|
1350
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "deployments"] });
|
|
1351
|
+
return subscribe((event) => {
|
|
1352
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1353
|
+
sync();
|
|
1354
|
+
}
|
|
1355
|
+
});
|
|
1356
|
+
}, [queryClient, subscribe]);
|
|
1357
|
+
return useQuery13({
|
|
1358
|
+
queryKey: ["hardkas", "deployments"],
|
|
1359
|
+
queryFn: async () => {
|
|
1360
|
+
try {
|
|
1361
|
+
const baseUrl = config.devServerUrl || "";
|
|
1362
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/deployments` : `${baseUrl}/api/deployments` : "/api/deployments";
|
|
1363
|
+
const response = await apiFetch(url);
|
|
1364
|
+
if (!response.ok) return [];
|
|
1365
|
+
const data = await response.json();
|
|
1366
|
+
return data.deployments || [];
|
|
1367
|
+
} catch (e) {
|
|
1368
|
+
console.error("Failed to fetch deployments from dev server:", e);
|
|
1369
|
+
return [];
|
|
1370
|
+
}
|
|
1371
|
+
},
|
|
1372
|
+
staleTime: 3e4
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
// src/hooks/activity.ts
|
|
1377
|
+
import { useQuery as useQuery14, useQueryClient as useQueryClient13 } from "@tanstack/react-query";
|
|
1378
|
+
import { useEffect as useEffect15 } from "react";
|
|
1379
|
+
function useActivity() {
|
|
1380
|
+
const { config, subscribe, apiFetch } = useHardKas();
|
|
1381
|
+
const queryClient = useQueryClient13();
|
|
1382
|
+
useEffect15(() => {
|
|
1383
|
+
const sync = () => queryClient.invalidateQueries({ queryKey: ["hardkas", "activity"] });
|
|
1384
|
+
return subscribe((event) => {
|
|
1385
|
+
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1386
|
+
sync();
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
}, [queryClient, subscribe]);
|
|
1390
|
+
return useQuery14({
|
|
1391
|
+
queryKey: ["hardkas", "activity"],
|
|
1392
|
+
queryFn: async () => {
|
|
1393
|
+
try {
|
|
1394
|
+
const baseUrl = config.devServerUrl || "";
|
|
1395
|
+
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/activity` : `${baseUrl}/api/activity` : "/api/activity";
|
|
1396
|
+
const response = await apiFetch(url);
|
|
1397
|
+
if (!response.ok) return [];
|
|
1398
|
+
const data = await response.json();
|
|
1399
|
+
return data.activity || [];
|
|
1400
|
+
} catch (e) {
|
|
1401
|
+
console.error("Failed to fetch activity from dev server:", e);
|
|
1402
|
+
return [];
|
|
1403
|
+
}
|
|
1404
|
+
},
|
|
1405
|
+
staleTime: 5e3
|
|
1406
|
+
// Frequent updates safe because it's local dev
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
894
1409
|
export {
|
|
895
1410
|
HardKasProvider,
|
|
896
|
-
|
|
897
|
-
|
|
1411
|
+
useAccounts,
|
|
1412
|
+
useActivity,
|
|
1413
|
+
useArtifact,
|
|
1414
|
+
useArtifacts,
|
|
898
1415
|
useConnectKasWareLocal,
|
|
899
1416
|
useCreateSandboxSession,
|
|
1417
|
+
useDeployments,
|
|
900
1418
|
useDisconnectSandboxSession,
|
|
1419
|
+
useEvents,
|
|
901
1420
|
useHardKas,
|
|
902
1421
|
useHardKasHealth,
|
|
903
1422
|
useHardKasSession,
|
|
@@ -914,7 +1433,12 @@ export {
|
|
|
914
1433
|
useKaspaWallet,
|
|
915
1434
|
useLocalIgraWalletClient,
|
|
916
1435
|
useMetaMaskLocal,
|
|
1436
|
+
useOverview,
|
|
917
1437
|
usePairSandboxSession,
|
|
1438
|
+
useReplayDetail,
|
|
1439
|
+
useReplayStatus,
|
|
918
1440
|
useSandboxSessions,
|
|
919
|
-
useSwitchToLocalIgra
|
|
1441
|
+
useSwitchToLocalIgra,
|
|
1442
|
+
useTransaction,
|
|
1443
|
+
useTransactions
|
|
920
1444
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,11 +14,10 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@tanstack/react-query": "^5.61.5",
|
|
16
16
|
"viem": "^2.21.51",
|
|
17
|
-
"@hardkas/
|
|
18
|
-
"@hardkas/
|
|
19
|
-
"@hardkas/
|
|
20
|
-
"@hardkas/
|
|
21
|
-
"@hardkas/l2": "0.5.5-alpha"
|
|
17
|
+
"@hardkas/core": "0.6.1-alpha",
|
|
18
|
+
"@hardkas/sessions": "0.6.1-alpha",
|
|
19
|
+
"@hardkas/kaspa-rpc": "0.6.1-alpha",
|
|
20
|
+
"@hardkas/l2": "0.6.1-alpha"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {
|
|
24
23
|
"@testing-library/dom": "^10.4.1",
|