@hardkas/react 0.4.0-alpha → 0.5.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/README.md +1 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +200 -8
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ React hooks and provider context for integrating with the HardKAS deterministic
|
|
|
4
4
|
|
|
5
5
|
## ⚠️ Alpha-Only Local-Runtime Coupling Warning
|
|
6
6
|
|
|
7
|
-
Please note that in the `v0.
|
|
7
|
+
Please note that in the `v0.5.1-alpha` release, this package has direct dependencies on the **`@hardkas/bridge-local`** package to facilitate local bridge payload planning and prefix-mining simulations directly within hooks like `useBridgeLocalPlan` and `useBridgeLocalSimulation`.
|
|
8
8
|
|
|
9
9
|
### 🛡️ Production & Browser Safety
|
|
10
10
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,16 @@ import * as viem from 'viem';
|
|
|
6
6
|
import { PublicClient, Address } from 'viem';
|
|
7
7
|
import { Hex } from '../types/misc.js';
|
|
8
8
|
|
|
9
|
+
interface EIP6963ProviderInfo {
|
|
10
|
+
uuid: string;
|
|
11
|
+
name: string;
|
|
12
|
+
icon: string;
|
|
13
|
+
rdns: string;
|
|
14
|
+
}
|
|
15
|
+
interface EIP6963ProviderDetail {
|
|
16
|
+
info: EIP6963ProviderInfo;
|
|
17
|
+
provider: any;
|
|
18
|
+
}
|
|
9
19
|
interface HardKasReactConfig {
|
|
10
20
|
readonly kaspaRpcUrl?: string;
|
|
11
21
|
readonly igraRpcUrl?: string;
|
|
@@ -28,6 +38,13 @@ interface HardKasContextValue {
|
|
|
28
38
|
readonly sseStatus: SSEStatus;
|
|
29
39
|
readonly lastEvent: RuntimeEvent | null;
|
|
30
40
|
readonly subscribe: (callback: EventCallback) => () => void;
|
|
41
|
+
readonly providers: EIP6963ProviderDetail[];
|
|
42
|
+
readonly activeProvider: EIP6963ProviderDetail | null;
|
|
43
|
+
readonly walletAddress: string | null;
|
|
44
|
+
readonly walletChainId: number | null;
|
|
45
|
+
readonly connectWallet: (detail: EIP6963ProviderDetail) => Promise<void>;
|
|
46
|
+
readonly disconnectWallet: () => void;
|
|
47
|
+
readonly switchChain: (chainId: number) => Promise<void>;
|
|
31
48
|
}
|
|
32
49
|
interface HardKasProviderProps {
|
|
33
50
|
readonly config: HardKasReactConfig;
|
|
@@ -89,8 +106,19 @@ declare function useKaspaBalance(options?: {
|
|
|
89
106
|
declare function useIgraAccount(): {
|
|
90
107
|
name: string | undefined;
|
|
91
108
|
address: `0x${string}` | undefined;
|
|
109
|
+
isWallet: boolean;
|
|
92
110
|
isLoading: boolean;
|
|
93
111
|
};
|
|
112
|
+
declare function useIgraWallet(): {
|
|
113
|
+
providers: EIP6963ProviderDetail[];
|
|
114
|
+
activeProvider: EIP6963ProviderDetail | null;
|
|
115
|
+
walletAddress: string | null;
|
|
116
|
+
walletChainId: number | null;
|
|
117
|
+
connectWallet: (detail: EIP6963ProviderDetail) => Promise<void>;
|
|
118
|
+
disconnectWallet: () => void;
|
|
119
|
+
switchChain: (chainId: number) => Promise<void>;
|
|
120
|
+
isConnected: boolean;
|
|
121
|
+
};
|
|
94
122
|
declare function useIgraBalance(options?: {
|
|
95
123
|
refetchInterval?: number;
|
|
96
124
|
}): _tanstack_react_query.UseQueryResult<bigint, Error>;
|
|
@@ -4719,4 +4747,4 @@ declare function useIgraWriteContract(): _tanstack_react_query.UseMutationResult
|
|
|
4719
4747
|
}, unknown>;
|
|
4720
4748
|
declare function useIgraWaitForReceipt(): _tanstack_react_query.UseMutationResult<viem.TransactionReceipt, Error, `0x${string}`, unknown>;
|
|
4721
4749
|
|
|
4722
|
-
export { type EventCallback, type HardKasContextValue, HardKasProvider, type HardKasReactConfig, type HealthInfo, type KasWareLocalState, type KasWareSessionMatch, type MetaMaskLocalState, type RuntimeEvent, type SSEStatus, type SandboxConnection, type SessionInfo, useBridgeLocalPlan, useBridgeLocalSimulation, useConnectKasWareLocal, useCreateSandboxSession, useDisconnectSandboxSession, useHardKas, useHardKasHealth, useHardKasSession, useIgraAccount, useIgraBalance, useIgraInjectedAccount, useIgraReadContract, useIgraWaitForReceipt, useIgraWriteContract, useKasWareLocal, useKasWareSessionMatch, useKaspaBalance, useKaspaWallet, useLocalIgraWalletClient, useMetaMaskLocal, usePairSandboxSession, useSandboxSessions, useSwitchToLocalIgra };
|
|
4750
|
+
export { type EventCallback, type HardKasContextValue, HardKasProvider, type HardKasReactConfig, type HealthInfo, type KasWareLocalState, type KasWareSessionMatch, type MetaMaskLocalState, type RuntimeEvent, type SSEStatus, type SandboxConnection, type SessionInfo, useBridgeLocalPlan, useBridgeLocalSimulation, useConnectKasWareLocal, useCreateSandboxSession, useDisconnectSandboxSession, useHardKas, useHardKasHealth, useHardKasSession, useIgraAccount, useIgraBalance, useIgraInjectedAccount, useIgraReadContract, useIgraWaitForReceipt, useIgraWallet, useIgraWriteContract, useKasWareLocal, useKasWareSessionMatch, useKaspaBalance, useKaspaWallet, useLocalIgraWalletClient, useMetaMaskLocal, usePairSandboxSession, useSandboxSessions, useSwitchToLocalIgra };
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,10 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
12
12
|
const eventSource = React.useRef(null);
|
|
13
13
|
const reconnectTimer = React.useRef(null);
|
|
14
14
|
const backoffMs = React.useRef(500);
|
|
15
|
+
const [providers, setProviders] = React.useState([]);
|
|
16
|
+
const [activeProvider, setActiveProvider] = React.useState(null);
|
|
17
|
+
const [walletAddress, setWalletAddress] = React.useState(null);
|
|
18
|
+
const [walletChainId, setWalletChainId] = React.useState(null);
|
|
15
19
|
const subscribe = React.useCallback((callback) => {
|
|
16
20
|
listeners.current.add(callback);
|
|
17
21
|
return () => listeners.current.delete(callback);
|
|
@@ -91,6 +95,135 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
91
95
|
}
|
|
92
96
|
};
|
|
93
97
|
}, [connect]);
|
|
98
|
+
React.useEffect(() => {
|
|
99
|
+
if (typeof window === "undefined") return;
|
|
100
|
+
const handleAnnounce = (event) => {
|
|
101
|
+
const detail = event.detail;
|
|
102
|
+
if (!detail || !detail.info || !detail.provider) return;
|
|
103
|
+
setProviders((prev) => {
|
|
104
|
+
if (prev.some((p) => p.info.rdns === detail.info.rdns)) return prev;
|
|
105
|
+
return [...prev, detail];
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
window.addEventListener("eip6963:announceProvider", handleAnnounce);
|
|
109
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
110
|
+
return () => {
|
|
111
|
+
window.removeEventListener("eip6963:announceProvider", handleAnnounce);
|
|
112
|
+
};
|
|
113
|
+
}, []);
|
|
114
|
+
const connectWallet = React.useCallback(async (detail) => {
|
|
115
|
+
try {
|
|
116
|
+
const accounts = await detail.provider.request({ method: "eth_requestAccounts" });
|
|
117
|
+
const chainIdHex = await detail.provider.request({ method: "eth_chainId" });
|
|
118
|
+
const chainId = typeof chainIdHex === "string" ? parseInt(chainIdHex, 16) : Number(chainIdHex);
|
|
119
|
+
setActiveProvider(detail);
|
|
120
|
+
if (accounts && accounts[0]) {
|
|
121
|
+
setWalletAddress(accounts[0]);
|
|
122
|
+
}
|
|
123
|
+
setWalletChainId(chainId);
|
|
124
|
+
if (typeof window !== "undefined") {
|
|
125
|
+
window.localStorage.setItem("hardkas:active-wallet", detail.info.rdns);
|
|
126
|
+
}
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error("Failed to connect wallet:", err);
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
}, []);
|
|
132
|
+
const disconnectWallet = React.useCallback(() => {
|
|
133
|
+
setActiveProvider(null);
|
|
134
|
+
setWalletAddress(null);
|
|
135
|
+
setWalletChainId(null);
|
|
136
|
+
if (typeof window !== "undefined") {
|
|
137
|
+
window.localStorage.removeItem("hardkas:active-wallet");
|
|
138
|
+
}
|
|
139
|
+
}, []);
|
|
140
|
+
const switchChain = React.useCallback(async (targetChainId) => {
|
|
141
|
+
if (!activeProvider) {
|
|
142
|
+
throw new Error("No active wallet connected");
|
|
143
|
+
}
|
|
144
|
+
const hexChainId = `0x${targetChainId.toString(16)}`;
|
|
145
|
+
try {
|
|
146
|
+
await activeProvider.provider.request({
|
|
147
|
+
method: "wallet_switchEthereumChain",
|
|
148
|
+
params: [{ chainId: hexChainId }]
|
|
149
|
+
});
|
|
150
|
+
setWalletChainId(targetChainId);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
if (err.code === 4902) {
|
|
153
|
+
if (targetChainId === 19416) {
|
|
154
|
+
await activeProvider.provider.request({
|
|
155
|
+
method: "wallet_addEthereumChain",
|
|
156
|
+
params: [{
|
|
157
|
+
chainId: hexChainId,
|
|
158
|
+
chainName: "Igra Local",
|
|
159
|
+
nativeCurrency: { name: "Igra Kaspa", symbol: "iKAS", decimals: 18 },
|
|
160
|
+
rpcUrls: [config.igraRpcUrl || "http://127.0.0.1:8545"]
|
|
161
|
+
}]
|
|
162
|
+
});
|
|
163
|
+
setWalletChainId(targetChainId);
|
|
164
|
+
} else {
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, [activeProvider, config.igraRpcUrl]);
|
|
172
|
+
React.useEffect(() => {
|
|
173
|
+
if (typeof window === "undefined" || providers.length === 0 || activeProvider) return;
|
|
174
|
+
const savedRdns = window.localStorage.getItem("hardkas:active-wallet");
|
|
175
|
+
if (savedRdns) {
|
|
176
|
+
const match = providers.find((p) => p.info.rdns === savedRdns);
|
|
177
|
+
if (match) {
|
|
178
|
+
connectWallet(match).catch(() => {
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}, [providers, activeProvider, connectWallet]);
|
|
183
|
+
React.useEffect(() => {
|
|
184
|
+
if (!activeProvider) {
|
|
185
|
+
setWalletAddress(null);
|
|
186
|
+
setWalletChainId(null);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const provider = activeProvider.provider;
|
|
190
|
+
const handleAccountsChanged = (accounts) => {
|
|
191
|
+
if (accounts && accounts[0]) {
|
|
192
|
+
setWalletAddress(accounts[0]);
|
|
193
|
+
} else {
|
|
194
|
+
setActiveProvider(null);
|
|
195
|
+
setWalletAddress(null);
|
|
196
|
+
setWalletChainId(null);
|
|
197
|
+
if (typeof window !== "undefined") {
|
|
198
|
+
window.localStorage.removeItem("hardkas:active-wallet");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const handleChainChanged = (chainIdHex) => {
|
|
203
|
+
const chainId = typeof chainIdHex === "string" ? parseInt(chainIdHex, 16) : Number(chainIdHex);
|
|
204
|
+
setWalletChainId(chainId);
|
|
205
|
+
};
|
|
206
|
+
const handleDisconnect = () => {
|
|
207
|
+
setActiveProvider(null);
|
|
208
|
+
setWalletAddress(null);
|
|
209
|
+
setWalletChainId(null);
|
|
210
|
+
if (typeof window !== "undefined") {
|
|
211
|
+
window.localStorage.removeItem("hardkas:active-wallet");
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
if (provider.on) {
|
|
215
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
216
|
+
provider.on("chainChanged", handleChainChanged);
|
|
217
|
+
provider.on("disconnect", handleDisconnect);
|
|
218
|
+
}
|
|
219
|
+
return () => {
|
|
220
|
+
if (provider.removeListener) {
|
|
221
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
222
|
+
provider.removeListener("chainChanged", handleChainChanged);
|
|
223
|
+
provider.removeListener("disconnect", handleDisconnect);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}, [activeProvider]);
|
|
94
227
|
const igraClient = useMemo(() => {
|
|
95
228
|
return createPublicClient({
|
|
96
229
|
chain: {
|
|
@@ -114,8 +247,29 @@ function HardKasProvider({ config, children, queryClient: externalQueryClient })
|
|
|
114
247
|
queryClient,
|
|
115
248
|
sseStatus,
|
|
116
249
|
lastEvent,
|
|
117
|
-
subscribe
|
|
118
|
-
|
|
250
|
+
subscribe,
|
|
251
|
+
providers,
|
|
252
|
+
activeProvider,
|
|
253
|
+
walletAddress,
|
|
254
|
+
walletChainId,
|
|
255
|
+
connectWallet,
|
|
256
|
+
disconnectWallet,
|
|
257
|
+
switchChain
|
|
258
|
+
}), [
|
|
259
|
+
config,
|
|
260
|
+
igraClient,
|
|
261
|
+
queryClient,
|
|
262
|
+
sseStatus,
|
|
263
|
+
lastEvent,
|
|
264
|
+
subscribe,
|
|
265
|
+
providers,
|
|
266
|
+
activeProvider,
|
|
267
|
+
walletAddress,
|
|
268
|
+
walletChainId,
|
|
269
|
+
connectWallet,
|
|
270
|
+
disconnectWallet,
|
|
271
|
+
switchChain
|
|
272
|
+
]);
|
|
119
273
|
return /* @__PURE__ */ jsx(HardKasContext.Provider, { value, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children }) });
|
|
120
274
|
}
|
|
121
275
|
function useHardKas() {
|
|
@@ -250,10 +404,34 @@ function useKaspaBalance(options = {}) {
|
|
|
250
404
|
import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
251
405
|
function useIgraAccount() {
|
|
252
406
|
const { data: session } = useHardKasSession();
|
|
407
|
+
const { walletAddress } = useHardKas();
|
|
408
|
+
const address = walletAddress || session?.l2.address;
|
|
253
409
|
return {
|
|
254
|
-
name: session?.l2.account,
|
|
255
|
-
address
|
|
256
|
-
|
|
410
|
+
name: walletAddress ? "Browser Wallet" : session?.l2.account,
|
|
411
|
+
address,
|
|
412
|
+
isWallet: !!walletAddress,
|
|
413
|
+
isLoading: !session && !walletAddress
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function useIgraWallet() {
|
|
417
|
+
const {
|
|
418
|
+
providers,
|
|
419
|
+
activeProvider,
|
|
420
|
+
walletAddress,
|
|
421
|
+
walletChainId,
|
|
422
|
+
connectWallet,
|
|
423
|
+
disconnectWallet,
|
|
424
|
+
switchChain
|
|
425
|
+
} = useHardKas();
|
|
426
|
+
return {
|
|
427
|
+
providers,
|
|
428
|
+
activeProvider,
|
|
429
|
+
walletAddress,
|
|
430
|
+
walletChainId,
|
|
431
|
+
connectWallet,
|
|
432
|
+
disconnectWallet,
|
|
433
|
+
switchChain,
|
|
434
|
+
isConnected: !!walletAddress
|
|
257
435
|
};
|
|
258
436
|
}
|
|
259
437
|
function useIgraBalance(options = {}) {
|
|
@@ -587,6 +765,7 @@ function useDisconnectSandboxSession() {
|
|
|
587
765
|
|
|
588
766
|
// src/hooks/contracts.ts
|
|
589
767
|
import { useQuery as useQuery7, useMutation as useMutation3 } from "@tanstack/react-query";
|
|
768
|
+
import { createWalletClient as createWalletClient2, custom as custom2 } from "viem";
|
|
590
769
|
function useIgraReadContract(options) {
|
|
591
770
|
const { igraClient, config } = useHardKas();
|
|
592
771
|
const { data: session } = useHardKasSession();
|
|
@@ -605,12 +784,24 @@ function useIgraReadContract(options) {
|
|
|
605
784
|
});
|
|
606
785
|
}
|
|
607
786
|
function useIgraWriteContract() {
|
|
787
|
+
const { activeProvider, walletAddress, igraClient } = useHardKas();
|
|
608
788
|
return useMutation3({
|
|
609
789
|
mutationFn: async (params) => {
|
|
610
|
-
|
|
611
|
-
|
|
790
|
+
let client = params.walletClient;
|
|
791
|
+
if (!client) {
|
|
792
|
+
if (!activeProvider) {
|
|
793
|
+
throw new Error("No active browser wallet connected and no walletClient was provided.");
|
|
794
|
+
}
|
|
795
|
+
if (!walletAddress) {
|
|
796
|
+
throw new Error("No active account address available on connected wallet.");
|
|
797
|
+
}
|
|
798
|
+
client = createWalletClient2({
|
|
799
|
+
account: walletAddress,
|
|
800
|
+
chain: igraClient.chain,
|
|
801
|
+
transport: custom2(activeProvider.provider)
|
|
802
|
+
});
|
|
612
803
|
}
|
|
613
|
-
return await
|
|
804
|
+
return await client.writeContract({
|
|
614
805
|
address: params.address,
|
|
615
806
|
abi: params.abi,
|
|
616
807
|
functionName: params.functionName,
|
|
@@ -642,6 +833,7 @@ export {
|
|
|
642
833
|
useIgraInjectedAccount,
|
|
643
834
|
useIgraReadContract,
|
|
644
835
|
useIgraWaitForReceipt,
|
|
836
|
+
useIgraWallet,
|
|
645
837
|
useIgraWriteContract,
|
|
646
838
|
useKasWareLocal,
|
|
647
839
|
useKasWareSessionMatch,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@tanstack/react-query": "^5.61.5",
|
|
16
16
|
"viem": "^2.21.51",
|
|
17
|
-
"@hardkas/bridge-local": "0.
|
|
18
|
-
"@hardkas/
|
|
19
|
-
"@hardkas/kaspa-rpc": "0.
|
|
20
|
-
"@hardkas/
|
|
21
|
-
"@hardkas/l2": "0.
|
|
17
|
+
"@hardkas/bridge-local": "0.5.1-alpha",
|
|
18
|
+
"@hardkas/sessions": "0.5.1-alpha",
|
|
19
|
+
"@hardkas/kaspa-rpc": "0.5.1-alpha",
|
|
20
|
+
"@hardkas/core": "0.5.1-alpha",
|
|
21
|
+
"@hardkas/l2": "0.5.1-alpha"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@testing-library/dom": "^10.4.1",
|