@frak-labs/react-sdk 0.1.1 → 0.2.0-beta.7898df5b
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 +25 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +29 -68
- package/dist/index.d.ts +28 -67
- package/dist/index.js +1 -1
- package/package.json +17 -16
- package/src/hook/helper/useReferralInteraction.test.ts +309 -0
- package/src/hook/helper/useReferralInteraction.ts +73 -0
- package/src/hook/index.ts +10 -0
- package/src/hook/useDisplayModal.test.ts +275 -0
- package/src/hook/useDisplayModal.ts +68 -0
- package/src/hook/useFrakClient.test.ts +119 -0
- package/src/hook/useFrakClient.ts +11 -0
- package/src/hook/useFrakConfig.test.ts +184 -0
- package/src/hook/useFrakConfig.ts +22 -0
- package/src/hook/useGetMerchantInformation.ts +56 -0
- package/src/hook/useOpenSso.test.ts +202 -0
- package/src/hook/useOpenSso.ts +51 -0
- package/src/hook/usePrepareSso.test.ts +197 -0
- package/src/hook/usePrepareSso.ts +55 -0
- package/src/hook/useSendTransaction.test.ts +218 -0
- package/src/hook/useSendTransaction.ts +62 -0
- package/src/hook/useSiweAuthenticate.test.ts +258 -0
- package/src/hook/useSiweAuthenticate.ts +66 -0
- package/src/hook/useWalletStatus.test.ts +112 -0
- package/src/hook/useWalletStatus.ts +55 -0
- package/src/hook/utils/useFrakContext.test.ts +157 -0
- package/src/hook/utils/useFrakContext.ts +42 -0
- package/src/hook/utils/useMounted.test.ts +70 -0
- package/src/hook/utils/useMounted.ts +12 -0
- package/src/hook/utils/useWindowLocation.test.ts +54 -0
- package/src/hook/utils/useWindowLocation.ts +40 -0
- package/src/index.ts +25 -0
- package/src/provider/FrakConfigProvider.test.ts +246 -0
- package/src/provider/FrakConfigProvider.ts +54 -0
- package/src/provider/FrakIFrameClientProvider.test.tsx +209 -0
- package/src/provider/FrakIFrameClientProvider.ts +86 -0
- package/src/provider/index.ts +7 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for useMounted hook
|
|
3
|
+
* Tests that the hook correctly tracks component mount state
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
7
|
+
import { describe, expect, it } from "../../../tests/vitest-fixtures";
|
|
8
|
+
import { useMounted } from "./useMounted";
|
|
9
|
+
|
|
10
|
+
describe("useMounted", () => {
|
|
11
|
+
it("should return true after mount", async () => {
|
|
12
|
+
const { result } = renderHook(() => useMounted());
|
|
13
|
+
|
|
14
|
+
// In React Testing Library, effects run synchronously after render
|
|
15
|
+
// So by the time we check result.current, the effect has already run
|
|
16
|
+
await waitFor(() => {
|
|
17
|
+
expect(result.current).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should remain true after multiple re-renders", async () => {
|
|
22
|
+
const { result, rerender } = renderHook(() => useMounted());
|
|
23
|
+
|
|
24
|
+
// Wait for initial mount
|
|
25
|
+
await waitFor(() => {
|
|
26
|
+
expect(result.current).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Re-render multiple times
|
|
30
|
+
rerender();
|
|
31
|
+
expect(result.current).toBe(true);
|
|
32
|
+
|
|
33
|
+
rerender();
|
|
34
|
+
expect(result.current).toBe(true);
|
|
35
|
+
|
|
36
|
+
rerender();
|
|
37
|
+
expect(result.current).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should be stable across re-renders", async () => {
|
|
41
|
+
const { result, rerender } = renderHook(() => useMounted());
|
|
42
|
+
|
|
43
|
+
// Wait for mount
|
|
44
|
+
await waitFor(() => {
|
|
45
|
+
expect(result.current).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const firstValue = result.current;
|
|
49
|
+
|
|
50
|
+
// Re-render
|
|
51
|
+
rerender();
|
|
52
|
+
const secondValue = result.current;
|
|
53
|
+
|
|
54
|
+
// Values should be the same
|
|
55
|
+
expect(firstValue).toBe(secondValue);
|
|
56
|
+
expect(firstValue).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should handle unmounting gracefully", async () => {
|
|
60
|
+
const { result, unmount } = renderHook(() => useMounted());
|
|
61
|
+
|
|
62
|
+
// Wait for mount
|
|
63
|
+
await waitFor(() => {
|
|
64
|
+
expect(result.current).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Unmount should not throw
|
|
68
|
+
expect(() => unmount()).not.toThrow();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for useWindowLocation hook
|
|
3
|
+
* Tests hook that tracks window.location changes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { renderHook } from "@testing-library/react";
|
|
7
|
+
import { describe, expect, test, vi } from "vitest";
|
|
8
|
+
import { useWindowLocation } from "./useWindowLocation";
|
|
9
|
+
|
|
10
|
+
describe("useWindowLocation", () => {
|
|
11
|
+
test("should return current window location", () => {
|
|
12
|
+
const { result } = renderHook(() => useWindowLocation());
|
|
13
|
+
|
|
14
|
+
expect(result.current.location).toBeDefined();
|
|
15
|
+
expect(result.current.href).toBeDefined();
|
|
16
|
+
expect(typeof result.current.href).toBe("string");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("should derive href from location", () => {
|
|
20
|
+
const { result } = renderHook(() => useWindowLocation());
|
|
21
|
+
|
|
22
|
+
if (result.current.location) {
|
|
23
|
+
expect(result.current.href).toBe(result.current.location.href);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("should register popstate listener", () => {
|
|
28
|
+
const addEventListenerSpy = vi.spyOn(window, "addEventListener");
|
|
29
|
+
|
|
30
|
+
renderHook(() => useWindowLocation());
|
|
31
|
+
|
|
32
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith(
|
|
33
|
+
"popstate",
|
|
34
|
+
expect.any(Function)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
addEventListenerSpy.mockRestore();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("should cleanup popstate listener on unmount", () => {
|
|
41
|
+
const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
|
|
42
|
+
|
|
43
|
+
const { unmount } = renderHook(() => useWindowLocation());
|
|
44
|
+
|
|
45
|
+
unmount();
|
|
46
|
+
|
|
47
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith(
|
|
48
|
+
"popstate",
|
|
49
|
+
expect.any(Function)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
removeEventListenerSpy.mockRestore();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useMounted } from "./useMounted";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns the current window location and href
|
|
6
|
+
* @ignore
|
|
7
|
+
*/
|
|
8
|
+
export function useWindowLocation(): {
|
|
9
|
+
location: Location | undefined;
|
|
10
|
+
href: string | undefined;
|
|
11
|
+
} {
|
|
12
|
+
const isMounted = useMounted();
|
|
13
|
+
const [location, setLocation] = useState<Location | undefined>(
|
|
14
|
+
isMounted ? window.location : undefined
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!isMounted) return;
|
|
19
|
+
|
|
20
|
+
// Method to the current window location
|
|
21
|
+
function setWindowLocation() {
|
|
22
|
+
setLocation(window.location);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!location) {
|
|
26
|
+
setWindowLocation();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
window.addEventListener("popstate", setWindowLocation);
|
|
30
|
+
|
|
31
|
+
return () => {
|
|
32
|
+
window.removeEventListener("popstate", setWindowLocation);
|
|
33
|
+
};
|
|
34
|
+
}, [isMounted, location]);
|
|
35
|
+
|
|
36
|
+
// Derive the href from the location
|
|
37
|
+
const href = useMemo(() => location?.href, [location?.href]);
|
|
38
|
+
|
|
39
|
+
return { location, href };
|
|
40
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Providers export
|
|
2
|
+
|
|
3
|
+
// Hooks export
|
|
4
|
+
export {
|
|
5
|
+
useDisplayModal,
|
|
6
|
+
useFrakClient,
|
|
7
|
+
useFrakConfig,
|
|
8
|
+
useGetMerchantInformation,
|
|
9
|
+
useOpenSso,
|
|
10
|
+
usePrepareSso,
|
|
11
|
+
useReferralInteraction,
|
|
12
|
+
useSendTransactionAction,
|
|
13
|
+
useSiweAuthenticate,
|
|
14
|
+
useWalletStatus,
|
|
15
|
+
} from "./hook";
|
|
16
|
+
export type {
|
|
17
|
+
FrakConfigProviderProps,
|
|
18
|
+
FrakIFrameClientProps,
|
|
19
|
+
} from "./provider";
|
|
20
|
+
export {
|
|
21
|
+
FrakConfigContext,
|
|
22
|
+
FrakConfigProvider,
|
|
23
|
+
FrakIFrameClientContext,
|
|
24
|
+
FrakIFrameClientProvider,
|
|
25
|
+
} from "./provider";
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for FrakConfigProvider
|
|
3
|
+
* Tests that the provider correctly provides config to child components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { render } from "@testing-library/react";
|
|
7
|
+
import React, { createElement } from "react";
|
|
8
|
+
import { describe, expect, test } from "../../tests/vitest-fixtures";
|
|
9
|
+
import { FrakConfigContext, FrakConfigProvider } from "./FrakConfigProvider";
|
|
10
|
+
|
|
11
|
+
describe("FrakConfigProvider", () => {
|
|
12
|
+
test("should render children", ({ mockFrakConfig }) => {
|
|
13
|
+
const { container } = render(
|
|
14
|
+
createElement(
|
|
15
|
+
FrakConfigProvider,
|
|
16
|
+
{ config: mockFrakConfig },
|
|
17
|
+
createElement("div", { "data-testid": "child" }, "Test Child")
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(
|
|
22
|
+
container.querySelector('[data-testid="child"]')
|
|
23
|
+
).toBeInTheDocument();
|
|
24
|
+
expect(container.textContent).toContain("Test Child");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("should provide config to context consumers", ({ mockFrakConfig }) => {
|
|
28
|
+
let receivedConfig: any;
|
|
29
|
+
|
|
30
|
+
const Consumer = () => {
|
|
31
|
+
const config = React.useContext(FrakConfigContext);
|
|
32
|
+
receivedConfig = config;
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
render(
|
|
37
|
+
createElement(
|
|
38
|
+
FrakConfigProvider,
|
|
39
|
+
{ config: mockFrakConfig },
|
|
40
|
+
createElement(Consumer)
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(receivedConfig).toBeDefined();
|
|
45
|
+
expect(receivedConfig.domain).toBe(mockFrakConfig.domain);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("should apply default walletUrl", () => {
|
|
49
|
+
const configWithoutWalletUrl = {
|
|
50
|
+
domain: "example.com",
|
|
51
|
+
metadata: {
|
|
52
|
+
name: "Test App",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
let receivedConfig: any;
|
|
57
|
+
|
|
58
|
+
const Consumer = () => {
|
|
59
|
+
const config = React.useContext(FrakConfigContext);
|
|
60
|
+
receivedConfig = config;
|
|
61
|
+
return null;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
render(
|
|
65
|
+
createElement(
|
|
66
|
+
FrakConfigProvider,
|
|
67
|
+
{ config: configWithoutWalletUrl },
|
|
68
|
+
createElement(Consumer)
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
expect(receivedConfig.walletUrl).toBe("https://wallet.frak.id");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("should preserve custom walletUrl", ({ mockFrakConfig }) => {
|
|
76
|
+
let receivedConfig: any;
|
|
77
|
+
|
|
78
|
+
const Consumer = () => {
|
|
79
|
+
const config = React.useContext(FrakConfigContext);
|
|
80
|
+
receivedConfig = config;
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
render(
|
|
85
|
+
createElement(
|
|
86
|
+
FrakConfigProvider,
|
|
87
|
+
{ config: mockFrakConfig },
|
|
88
|
+
createElement(Consumer)
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect(receivedConfig.walletUrl).toBe(mockFrakConfig.walletUrl);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("should fallback domain to window.location.host", () => {
|
|
96
|
+
const configWithoutDomain = {
|
|
97
|
+
metadata: {
|
|
98
|
+
name: "Test App",
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
let receivedConfig: any;
|
|
103
|
+
|
|
104
|
+
const Consumer = () => {
|
|
105
|
+
const config = React.useContext(FrakConfigContext);
|
|
106
|
+
receivedConfig = config;
|
|
107
|
+
return null;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
render(
|
|
111
|
+
createElement(
|
|
112
|
+
FrakConfigProvider,
|
|
113
|
+
{ config: configWithoutDomain as any },
|
|
114
|
+
createElement(Consumer)
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// In test environment, window.location.host is "localhost:3000" (JSDOM default)
|
|
119
|
+
expect(receivedConfig.domain).toBe(window.location.host);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("should pass through all config properties", ({ mockFrakConfig }) => {
|
|
123
|
+
let receivedConfig: any;
|
|
124
|
+
|
|
125
|
+
const Consumer = () => {
|
|
126
|
+
const config = React.useContext(FrakConfigContext);
|
|
127
|
+
receivedConfig = config;
|
|
128
|
+
return null;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
render(
|
|
132
|
+
createElement(
|
|
133
|
+
FrakConfigProvider,
|
|
134
|
+
{ config: mockFrakConfig },
|
|
135
|
+
createElement(Consumer)
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
expect(receivedConfig.domain).toBe(mockFrakConfig.domain);
|
|
140
|
+
expect(receivedConfig.walletUrl).toBe(mockFrakConfig.walletUrl);
|
|
141
|
+
expect(receivedConfig.metadata).toEqual(mockFrakConfig.metadata);
|
|
142
|
+
expect(receivedConfig.customizations).toEqual(
|
|
143
|
+
mockFrakConfig.customizations
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("should handle minimal config", () => {
|
|
148
|
+
const minimalConfig = {
|
|
149
|
+
domain: "minimal.com",
|
|
150
|
+
metadata: {
|
|
151
|
+
name: "Minimal Test App",
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let receivedConfig: any;
|
|
156
|
+
|
|
157
|
+
const Consumer = () => {
|
|
158
|
+
const config = React.useContext(FrakConfigContext);
|
|
159
|
+
receivedConfig = config;
|
|
160
|
+
return null;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
render(
|
|
164
|
+
createElement(
|
|
165
|
+
FrakConfigProvider,
|
|
166
|
+
{ config: minimalConfig },
|
|
167
|
+
createElement(Consumer)
|
|
168
|
+
)
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
expect(receivedConfig.domain).toBe("minimal.com");
|
|
172
|
+
expect(receivedConfig.walletUrl).toBe("https://wallet.frak.id");
|
|
173
|
+
expect(receivedConfig.metadata.name).toBe("Minimal Test App");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("should support nested providers with different configs", () => {
|
|
177
|
+
const outerConfig = {
|
|
178
|
+
domain: "outer.com",
|
|
179
|
+
walletUrl: "https://wallet-outer.frak.id",
|
|
180
|
+
metadata: {
|
|
181
|
+
name: "Outer App",
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const innerConfig = {
|
|
186
|
+
domain: "inner.com",
|
|
187
|
+
walletUrl: "https://wallet-inner.frak.id",
|
|
188
|
+
metadata: {
|
|
189
|
+
name: "Inner App",
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
let outerReceivedConfig: any;
|
|
194
|
+
let innerReceivedConfig: any;
|
|
195
|
+
|
|
196
|
+
const OuterConsumer = () => {
|
|
197
|
+
const config = React.useContext(FrakConfigContext);
|
|
198
|
+
outerReceivedConfig = config;
|
|
199
|
+
return null;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const InnerConsumer = () => {
|
|
203
|
+
const config = React.useContext(FrakConfigContext);
|
|
204
|
+
innerReceivedConfig = config;
|
|
205
|
+
return null;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
render(
|
|
209
|
+
createElement(
|
|
210
|
+
FrakConfigProvider,
|
|
211
|
+
{ config: outerConfig },
|
|
212
|
+
createElement(OuterConsumer),
|
|
213
|
+
createElement(
|
|
214
|
+
FrakConfigProvider,
|
|
215
|
+
{ config: innerConfig },
|
|
216
|
+
createElement(InnerConsumer)
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
expect(outerReceivedConfig.domain).toBe("outer.com");
|
|
222
|
+
expect(innerReceivedConfig.domain).toBe("inner.com");
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test("should render multiple children", ({ mockFrakConfig }) => {
|
|
226
|
+
const { container } = render(
|
|
227
|
+
createElement(
|
|
228
|
+
FrakConfigProvider,
|
|
229
|
+
{ config: mockFrakConfig },
|
|
230
|
+
createElement("div", { "data-testid": "child1" }, "Child 1"),
|
|
231
|
+
createElement("div", { "data-testid": "child2" }, "Child 2"),
|
|
232
|
+
createElement("div", { "data-testid": "child3" }, "Child 3")
|
|
233
|
+
)
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expect(
|
|
237
|
+
container.querySelector('[data-testid="child1"]')
|
|
238
|
+
).toBeInTheDocument();
|
|
239
|
+
expect(
|
|
240
|
+
container.querySelector('[data-testid="child2"]')
|
|
241
|
+
).toBeInTheDocument();
|
|
242
|
+
expect(
|
|
243
|
+
container.querySelector('[data-testid="child3"]')
|
|
244
|
+
).toBeInTheDocument();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FrakWalletSdkConfig } from "@frak-labs/core-sdk";
|
|
2
|
+
import { createContext, createElement, type PropsWithChildren } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The context that will keep the Frak Wallet SDK configuration
|
|
6
|
+
* @ignore
|
|
7
|
+
*/
|
|
8
|
+
export const FrakConfigContext = createContext<FrakWalletSdkConfig | undefined>(
|
|
9
|
+
undefined
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Props to instantiate the Frak Wallet SDK configuration provider
|
|
14
|
+
*
|
|
15
|
+
* @group provider
|
|
16
|
+
*/
|
|
17
|
+
export type FrakConfigProviderProps = {
|
|
18
|
+
/**
|
|
19
|
+
* The wanted Frak configuration
|
|
20
|
+
* @see {@link @frak-labs/core-sdk!index.FrakWalletSdkConfig | FrakWalletSdkConfig}
|
|
21
|
+
*/
|
|
22
|
+
config: FrakWalletSdkConfig;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Simple config provider for the Frak Wallet SDK
|
|
27
|
+
*
|
|
28
|
+
* Should be wrapped within a {@link @tanstack/react-query!QueryClientProvider | `QueryClientProvider`}
|
|
29
|
+
*
|
|
30
|
+
* @group provider
|
|
31
|
+
*
|
|
32
|
+
* @param parameters
|
|
33
|
+
*/
|
|
34
|
+
export function FrakConfigProvider(
|
|
35
|
+
parameters: PropsWithChildren<FrakConfigProviderProps>
|
|
36
|
+
) {
|
|
37
|
+
const { children, config } = parameters;
|
|
38
|
+
return createElement(
|
|
39
|
+
FrakConfigContext.Provider,
|
|
40
|
+
{
|
|
41
|
+
value: {
|
|
42
|
+
...config,
|
|
43
|
+
walletUrl: config.walletUrl ?? "https://wallet.frak.id",
|
|
44
|
+
domain:
|
|
45
|
+
config.domain ??
|
|
46
|
+
(typeof window !== "undefined"
|
|
47
|
+
? window?.location?.host
|
|
48
|
+
: undefined) ??
|
|
49
|
+
"not-found",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
children
|
|
53
|
+
);
|
|
54
|
+
}
|