@hardkas/react 0.7.3-alpha → 0.7.5-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.js +199 -141
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -4,8 +4,15 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
|
4
4
|
import { createPublicClient, http } from "viem";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
var HardKasContext = createContext(void 0);
|
|
7
|
-
function HardKasProvider({
|
|
8
|
-
|
|
7
|
+
function HardKasProvider({
|
|
8
|
+
config,
|
|
9
|
+
children,
|
|
10
|
+
queryClient: externalQueryClient
|
|
11
|
+
}) {
|
|
12
|
+
const queryClient = useMemo(
|
|
13
|
+
() => externalQueryClient ?? new QueryClient(),
|
|
14
|
+
[externalQueryClient]
|
|
15
|
+
);
|
|
9
16
|
const [sseStatus, setSseStatus] = React.useState("disconnected");
|
|
10
17
|
const [projectionStatus, setProjectionStatus] = React.useState("synced");
|
|
11
18
|
const [generationId, setGenerationId] = React.useState(null);
|
|
@@ -43,34 +50,37 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
43
50
|
listeners.current.add(callback);
|
|
44
51
|
return () => listeners.current.delete(callback);
|
|
45
52
|
}, []);
|
|
46
|
-
const apiFetch = React.useCallback(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
53
|
+
const apiFetch = React.useCallback(
|
|
54
|
+
async (input, init) => {
|
|
55
|
+
const headers = new Headers(init?.headers || {});
|
|
56
|
+
if (devToken) {
|
|
57
|
+
headers.set("Authorization", `Bearer ${devToken}`);
|
|
58
|
+
}
|
|
59
|
+
const method = init?.method?.toUpperCase() || "GET";
|
|
60
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
61
|
+
headers.set("X-Hardkas-Request", "true");
|
|
62
|
+
}
|
|
63
|
+
const mergedInit = {
|
|
64
|
+
...init,
|
|
65
|
+
headers
|
|
66
|
+
};
|
|
67
|
+
const response = await fetch(input, mergedInit);
|
|
68
|
+
const genHeader = response.headers?.get?.("X-Hardkas-Generation");
|
|
69
|
+
if (genHeader) {
|
|
70
|
+
setGenerationId((prev) => {
|
|
71
|
+
if (prev !== genHeader) {
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
if (queryClient) queryClient.invalidateQueries();
|
|
74
|
+
}, 0);
|
|
75
|
+
return genHeader;
|
|
76
|
+
}
|
|
77
|
+
return prev;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return response;
|
|
81
|
+
},
|
|
82
|
+
[queryClient, devToken]
|
|
83
|
+
);
|
|
74
84
|
const connect = React.useCallback(() => {
|
|
75
85
|
if (typeof window === "undefined") return;
|
|
76
86
|
if (!config.devServerUrl) {
|
|
@@ -215,38 +225,43 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
215
225
|
window.localStorage.removeItem("hardkas:active-wallet");
|
|
216
226
|
}
|
|
217
227
|
}, []);
|
|
218
|
-
const switchChain = React.useCallback(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
228
|
+
const switchChain = React.useCallback(
|
|
229
|
+
async (targetChainId) => {
|
|
230
|
+
if (!activeProvider) {
|
|
231
|
+
throw new Error("No active wallet connected");
|
|
232
|
+
}
|
|
233
|
+
const hexChainId = `0x${targetChainId.toString(16)}`;
|
|
234
|
+
try {
|
|
235
|
+
await activeProvider.provider.request({
|
|
236
|
+
method: "wallet_switchEthereumChain",
|
|
237
|
+
params: [{ chainId: hexChainId }]
|
|
238
|
+
});
|
|
239
|
+
setWalletChainId(targetChainId);
|
|
240
|
+
} catch (err) {
|
|
241
|
+
if (err.code === 4902) {
|
|
242
|
+
if (targetChainId === 19416) {
|
|
243
|
+
await activeProvider.provider.request({
|
|
244
|
+
method: "wallet_addEthereumChain",
|
|
245
|
+
params: [
|
|
246
|
+
{
|
|
247
|
+
chainId: hexChainId,
|
|
248
|
+
chainName: "Igra Local",
|
|
249
|
+
nativeCurrency: { name: "Igra Kaspa", symbol: "iKAS", decimals: 18 },
|
|
250
|
+
rpcUrls: [config.igraRpcUrl || "http://127.0.0.1:8545"]
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
});
|
|
254
|
+
setWalletChainId(targetChainId);
|
|
255
|
+
} else {
|
|
256
|
+
throw err;
|
|
257
|
+
}
|
|
242
258
|
} else {
|
|
243
259
|
throw err;
|
|
244
260
|
}
|
|
245
|
-
} else {
|
|
246
|
-
throw err;
|
|
247
261
|
}
|
|
248
|
-
}
|
|
249
|
-
|
|
262
|
+
},
|
|
263
|
+
[activeProvider, config.igraRpcUrl]
|
|
264
|
+
);
|
|
250
265
|
React.useEffect(() => {
|
|
251
266
|
if (typeof window === "undefined" || providers.length === 0 || activeProvider) return;
|
|
252
267
|
const savedRdns = window.localStorage.getItem("hardkas:active-wallet");
|
|
@@ -316,70 +331,85 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
316
331
|
transport: http(config.igraRpcUrl || "http://127.0.0.1:8545", { retryCount: 0 })
|
|
317
332
|
});
|
|
318
333
|
}, [config.igraRpcUrl]);
|
|
319
|
-
const value = useMemo(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
334
|
+
const value = useMemo(
|
|
335
|
+
() => ({
|
|
336
|
+
config: {
|
|
337
|
+
...config,
|
|
338
|
+
localOnly: config.localOnly ?? true
|
|
339
|
+
},
|
|
340
|
+
igraClient,
|
|
341
|
+
queryClient,
|
|
342
|
+
sseStatus,
|
|
343
|
+
projectionStatus,
|
|
344
|
+
generationId,
|
|
345
|
+
lastSyncedAt,
|
|
346
|
+
apiFetch,
|
|
347
|
+
lastEvent,
|
|
348
|
+
subscribe,
|
|
349
|
+
providers,
|
|
350
|
+
activeProvider,
|
|
351
|
+
walletAddress,
|
|
352
|
+
walletChainId,
|
|
353
|
+
connectWallet,
|
|
354
|
+
disconnectWallet,
|
|
355
|
+
switchChain
|
|
356
|
+
}),
|
|
357
|
+
[
|
|
358
|
+
config,
|
|
359
|
+
igraClient,
|
|
360
|
+
queryClient,
|
|
361
|
+
sseStatus,
|
|
362
|
+
projectionStatus,
|
|
363
|
+
generationId,
|
|
364
|
+
lastSyncedAt,
|
|
365
|
+
apiFetch,
|
|
366
|
+
lastEvent,
|
|
367
|
+
subscribe,
|
|
368
|
+
providers,
|
|
369
|
+
activeProvider,
|
|
370
|
+
walletAddress,
|
|
371
|
+
walletChainId,
|
|
372
|
+
connectWallet,
|
|
373
|
+
disconnectWallet,
|
|
374
|
+
switchChain
|
|
375
|
+
]
|
|
376
|
+
);
|
|
377
|
+
return /* @__PURE__ */ jsx(HardKasContext.Provider, { value, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: tokenMissing ? /* @__PURE__ */ jsx(
|
|
378
|
+
"div",
|
|
379
|
+
{
|
|
380
|
+
style: {
|
|
381
|
+
display: "flex",
|
|
382
|
+
flexDirection: "column",
|
|
383
|
+
alignItems: "center",
|
|
384
|
+
justifyContent: "center",
|
|
385
|
+
height: "100vh",
|
|
386
|
+
width: "100vw",
|
|
387
|
+
backgroundColor: "#1a1a1a",
|
|
388
|
+
color: "#f87171",
|
|
389
|
+
fontFamily: "sans-serif",
|
|
390
|
+
textAlign: "center",
|
|
391
|
+
padding: "20px"
|
|
392
|
+
},
|
|
393
|
+
children: /* @__PURE__ */ jsxs(
|
|
394
|
+
"div",
|
|
395
|
+
{
|
|
396
|
+
style: {
|
|
397
|
+
backgroundColor: "#2d2d2d",
|
|
398
|
+
border: "2px solid #ef4444",
|
|
399
|
+
borderRadius: "8px",
|
|
400
|
+
padding: "30px",
|
|
401
|
+
maxWidth: "450px",
|
|
402
|
+
boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.5)"
|
|
403
|
+
},
|
|
404
|
+
children: [
|
|
405
|
+
/* @__PURE__ */ jsx("h2", { style: { color: "#ef4444", marginTop: 0 }, children: "Dashboard authentication token missing." }),
|
|
406
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#d1d5db", lineHeight: "1.5" }, children: "The dev-server is secured against local workstation CSRF and DNS rebinding attacks." }),
|
|
407
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#9ca3af", fontWeight: "bold" }, children: "Restart hardkas dashboard." })
|
|
408
|
+
]
|
|
409
|
+
}
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
) : children }) });
|
|
383
413
|
}
|
|
384
414
|
function useHardKas() {
|
|
385
415
|
const context = useContext(HardKasContext);
|
|
@@ -511,7 +541,10 @@ function useKaspaBalance(options = {}) {
|
|
|
511
541
|
}
|
|
512
542
|
}
|
|
513
543
|
} catch (e) {
|
|
514
|
-
console.warn(
|
|
544
|
+
console.warn(
|
|
545
|
+
"Failed to fetch derived simulated balance, falling back to 0:",
|
|
546
|
+
e
|
|
547
|
+
);
|
|
515
548
|
}
|
|
516
549
|
return 0n;
|
|
517
550
|
}
|
|
@@ -530,11 +563,13 @@ function useKaspaBalance(options = {}) {
|
|
|
530
563
|
reject(new Error("WebSocket timeout"));
|
|
531
564
|
}, 3e3);
|
|
532
565
|
ws.onopen = () => {
|
|
533
|
-
ws.send(
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
566
|
+
ws.send(
|
|
567
|
+
JSON.stringify({
|
|
568
|
+
id: 1,
|
|
569
|
+
method: "getBalanceByAddressRequest",
|
|
570
|
+
params: { address }
|
|
571
|
+
})
|
|
572
|
+
);
|
|
538
573
|
};
|
|
539
574
|
ws.onmessage = (event) => {
|
|
540
575
|
clearTimeout(timer);
|
|
@@ -559,7 +594,10 @@ function useKaspaBalance(options = {}) {
|
|
|
559
594
|
};
|
|
560
595
|
});
|
|
561
596
|
} catch (e) {
|
|
562
|
-
console.warn(
|
|
597
|
+
console.warn(
|
|
598
|
+
"Failed to fetch Kaspa balance via WebSocket, falling back to 0:",
|
|
599
|
+
e
|
|
600
|
+
);
|
|
563
601
|
return 0n;
|
|
564
602
|
}
|
|
565
603
|
}
|
|
@@ -656,7 +694,10 @@ function useIgraBalance(options = {}) {
|
|
|
656
694
|
}
|
|
657
695
|
}
|
|
658
696
|
} catch (e) {
|
|
659
|
-
console.warn(
|
|
697
|
+
console.warn(
|
|
698
|
+
"Failed to fetch derived simulated L2 balance, falling back to 0:",
|
|
699
|
+
e
|
|
700
|
+
);
|
|
660
701
|
}
|
|
661
702
|
return 0n;
|
|
662
703
|
}
|
|
@@ -738,7 +779,9 @@ function useMetaMaskLocal() {
|
|
|
738
779
|
try {
|
|
739
780
|
const chainIdHex = await provider.request({ method: "eth_chainId" });
|
|
740
781
|
const chainId = parseInt(chainIdHex, 16);
|
|
741
|
-
const accounts = await provider.request({
|
|
782
|
+
const accounts = await provider.request({
|
|
783
|
+
method: "eth_accounts"
|
|
784
|
+
});
|
|
742
785
|
setState({
|
|
743
786
|
installed: true,
|
|
744
787
|
connected: accounts.length > 0,
|
|
@@ -794,12 +837,14 @@ function useSwitchToLocalIgra() {
|
|
|
794
837
|
if (e.code === 4902) {
|
|
795
838
|
await provider.request({
|
|
796
839
|
method: "wallet_addEthereumChain",
|
|
797
|
-
params: [
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
840
|
+
params: [
|
|
841
|
+
{
|
|
842
|
+
chainId: "0x4bd8",
|
|
843
|
+
chainName: "HardKas Igra Local",
|
|
844
|
+
rpcUrls: ["http://127.0.0.1:8545"],
|
|
845
|
+
nativeCurrency: { name: "iKAS", symbol: "iKAS", decimals: 18 }
|
|
846
|
+
}
|
|
847
|
+
]
|
|
803
848
|
});
|
|
804
849
|
}
|
|
805
850
|
}
|
|
@@ -1011,7 +1056,15 @@ function useIgraReadContract(options) {
|
|
|
1011
1056
|
const { igraClient, config } = useHardKas();
|
|
1012
1057
|
const { data: session } = useHardKasSession();
|
|
1013
1058
|
return useQuery7({
|
|
1014
|
-
queryKey: [
|
|
1059
|
+
queryKey: [
|
|
1060
|
+
"igra",
|
|
1061
|
+
"read",
|
|
1062
|
+
options.address,
|
|
1063
|
+
options.functionName,
|
|
1064
|
+
options.args,
|
|
1065
|
+
config.igraRpcUrl,
|
|
1066
|
+
session?.name
|
|
1067
|
+
],
|
|
1015
1068
|
queryFn: async () => {
|
|
1016
1069
|
return await igraClient.readContract({
|
|
1017
1070
|
address: options.address,
|
|
@@ -1031,7 +1084,9 @@ function useIgraWriteContract() {
|
|
|
1031
1084
|
let client = params.walletClient;
|
|
1032
1085
|
if (!client) {
|
|
1033
1086
|
if (!activeProvider) {
|
|
1034
|
-
throw new Error(
|
|
1087
|
+
throw new Error(
|
|
1088
|
+
"No active browser wallet connected and no walletClient was provided."
|
|
1089
|
+
);
|
|
1035
1090
|
}
|
|
1036
1091
|
if (!walletAddress) {
|
|
1037
1092
|
throw new Error("No active account address available on connected wallet.");
|
|
@@ -1195,7 +1250,9 @@ function useArtifacts(schemaFilter) {
|
|
|
1195
1250
|
const { config, subscribe, apiFetch } = useHardKas();
|
|
1196
1251
|
const queryClient = useQueryClient10();
|
|
1197
1252
|
useEffect12(() => {
|
|
1198
|
-
const sync = () => queryClient.invalidateQueries({
|
|
1253
|
+
const sync = () => queryClient.invalidateQueries({
|
|
1254
|
+
queryKey: ["hardkas", "artifacts", schemaFilter || "all"]
|
|
1255
|
+
});
|
|
1199
1256
|
return subscribe((event) => {
|
|
1200
1257
|
if (["query-synced", "session-changed"].includes(event.type)) {
|
|
1201
1258
|
sync();
|
|
@@ -1299,7 +1356,8 @@ function useReplayStatus() {
|
|
|
1299
1356
|
const baseUrl = config.devServerUrl || "";
|
|
1300
1357
|
const url = baseUrl ? baseUrl.endsWith("/") ? `${baseUrl}api/replay` : `${baseUrl}/api/replay` : "/api/replay";
|
|
1301
1358
|
const response = await apiFetch(url);
|
|
1302
|
-
if (!response.ok)
|
|
1359
|
+
if (!response.ok)
|
|
1360
|
+
return { replays: [], pendingReplays: [], pendingReplay: false };
|
|
1303
1361
|
const data = await response.json();
|
|
1304
1362
|
const formatReplay = (r) => {
|
|
1305
1363
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/react",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@tanstack/react-query": "^5.61.5",
|
|
17
17
|
"viem": "^2.21.51",
|
|
18
|
-
"@hardkas/core": "0.7.
|
|
19
|
-
"@hardkas/
|
|
20
|
-
"@hardkas/
|
|
21
|
-
"@hardkas/
|
|
18
|
+
"@hardkas/core": "0.7.5-alpha",
|
|
19
|
+
"@hardkas/sessions": "0.7.5-alpha",
|
|
20
|
+
"@hardkas/kaspa-rpc": "0.7.5-alpha",
|
|
21
|
+
"@hardkas/l2": "0.7.5-alpha"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@testing-library/dom": "^10.4.1",
|