@edgeandnode/graph-auth-kit 0.2.0

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.
Files changed (57) hide show
  1. package/README.md +238 -0
  2. package/dist/Components/ConnectModal.d.ts +2 -0
  3. package/dist/Components/ConnectModal.d.ts.map +1 -0
  4. package/dist/Components/ConnectorOption.d.ts +13 -0
  5. package/dist/Components/ConnectorOption.d.ts.map +1 -0
  6. package/dist/Components/MultisigSignerOptions.d.ts +2 -0
  7. package/dist/Components/MultisigSignerOptions.d.ts.map +1 -0
  8. package/dist/Components/PrimaryConnectOptions.d.ts +2 -0
  9. package/dist/Components/PrimaryConnectOptions.d.ts.map +1 -0
  10. package/dist/Components/SafeInputForm.d.ts +2 -0
  11. package/dist/Components/SafeInputForm.d.ts.map +1 -0
  12. package/dist/Components/SafeSelection.d.ts +2 -0
  13. package/dist/Components/SafeSelection.d.ts.map +1 -0
  14. package/dist/GraphAuthKit.context-DBwb2jco.js +936 -0
  15. package/dist/GraphAuthKit.context.d.ts +80 -0
  16. package/dist/GraphAuthKit.context.d.ts.map +1 -0
  17. package/dist/GraphAuthKitInner.context.d.ts +109 -0
  18. package/dist/GraphAuthKitInner.context.d.ts.map +1 -0
  19. package/dist/client.d.ts +8612 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/constants.d.ts +329 -0
  22. package/dist/constants.d.ts.map +1 -0
  23. package/dist/errors.d.ts +21 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/hooks.d.ts +74 -0
  26. package/dist/hooks.d.ts.map +1 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +442 -0
  30. package/dist/safe/SafeEthersSigner.d.ts +37 -0
  31. package/dist/safe/SafeEthersSigner.d.ts.map +1 -0
  32. package/dist/safe/SafeMinimal.abi.d.ts +80 -0
  33. package/dist/safe/SafeMinimal.abi.d.ts.map +1 -0
  34. package/dist/safe/constants.d.ts +26 -0
  35. package/dist/safe/constants.d.ts.map +1 -0
  36. package/dist/safe/index.d.ts +3 -0
  37. package/dist/safe/index.d.ts.map +1 -0
  38. package/dist/safe/index.js +11 -0
  39. package/dist/safe/safeViemActions.d.ts +4 -0
  40. package/dist/safe/safeViemActions.d.ts.map +1 -0
  41. package/dist/safe/utils.d.ts +38 -0
  42. package/dist/safe/utils.d.ts.map +1 -0
  43. package/dist/safe/utils.test.d.ts +2 -0
  44. package/dist/safe/utils.test.d.ts.map +1 -0
  45. package/dist/test-harness/MockGraphAuthKit.context.d.ts +102 -0
  46. package/dist/test-harness/MockGraphAuthKit.context.d.ts.map +1 -0
  47. package/dist/test-harness/index.d.ts +2 -0
  48. package/dist/test-harness/index.d.ts.map +1 -0
  49. package/dist/test-harness/index.js +63 -0
  50. package/dist/types.d.ts +54 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/utils-KuRu9vB-.js +218 -0
  53. package/dist/utils.d.ts +18 -0
  54. package/dist/utils.d.ts.map +1 -0
  55. package/dist/utils.test.d.ts +2 -0
  56. package/dist/utils.test.d.ts.map +1 -0
  57. package/package.json +93 -0
@@ -0,0 +1,936 @@
1
+ import { jsx, jsxs, Fragment } from "@theme-ui/core/jsx-runtime";
2
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
+ import { createContext, useContext, useRef, useState, useReducer, useEffect } from "react";
4
+ import { useConfig, useConnect, useDisconnect, useAccountEffect, createConfig, createStorage, cookieStorage, cookieToInitialState, WagmiProvider } from "wagmi";
5
+ import { coinbaseWallet, injected, walletConnect } from "wagmi/connectors";
6
+ import { Icon, ExperimentalButton, Alert, Divider, Link, ExperimentalSelect, ExperimentalInput, List, ExperimentalModal, ExperimentalLoadingIndicator } from "@edgeandnode/gds";
7
+ import { http, createPublicClient, createClient, isAddress } from "viem";
8
+ import { z } from "zod";
9
+ import { k as SupportedClientChainId, D as DefChain, e as L2ChainTestnet, h as L1ChainTestnet, g as L1Chain, S as SafeSupportedNetworks, M as MULTISIG_AUTH_STORAGE_KEY, L as L2Chain, d as isSafeOwner, a as SafeSupportedNetworkNames, i as isValidSafe, j as AUTH_STORAGE_KEY } from "./utils-KuRu9vB-.js";
10
+ import { addrShortener } from "@edgeandnode/common";
11
+ import { providers } from "ethers";
12
+ import { NetworkIcon } from "@edgeandnode/go";
13
+ const RequiredInfuraKey = z.object({
14
+ infuraKey: z.string({ required_error: "The Infura Key is required" }).min(1).readonly()
15
+ });
16
+ const RequiredWalletConnectProjectId = z.object({
17
+ walletConnectProjectID: z.string({ required_error: "The WalletConnect Project ID is required" }).min(1).readonly()
18
+ });
19
+ const GraphAuthKitProps = RequiredInfuraKey.merge(RequiredWalletConnectProjectId).extend({
20
+ meta: z.object({
21
+ name: z.union([z.literal("Graph Explorer"), z.literal("Subgraph Studio")]).readonly(),
22
+ url: z.string().url().optional().nullable().readonly()
23
+ }).readonly(),
24
+ chains: z.union([z.literal("ALL"), z.literal("MAINNET"), z.literal("TESTNET")]).default("ALL").readonly()
25
+ });
26
+ const GraphAuthKitConnector = z.union([
27
+ z.literal(coinbaseWallet.type),
28
+ z.literal(injected.type),
29
+ z.literal("multisig"),
30
+ z.literal(walletConnect.type)
31
+ ]).readonly();
32
+ RequiredInfuraKey.extend({
33
+ chain: SupportedClientChainId.optional().nullable().default(DefChain.id)
34
+ });
35
+ function buildInfuraHttpTransport({
36
+ chain = DefChain.id,
37
+ infuraKey
38
+ }) {
39
+ switch (chain) {
40
+ case L1Chain.id: {
41
+ return http(`https://mainnet.infura.io/v3/${infuraKey}`);
42
+ }
43
+ case L1ChainTestnet.id: {
44
+ return http(`https://sepolia.infura.io/v3/${infuraKey}`);
45
+ }
46
+ case L2ChainTestnet.id: {
47
+ return http(`https://arbitrum-sepolia.infura.io/v3/${infuraKey}`);
48
+ }
49
+ default: {
50
+ return http(`https://arbitrum-mainnet.infura.io/v3/${infuraKey}`);
51
+ }
52
+ }
53
+ }
54
+ const BuildPublicClientArgs = RequiredInfuraKey.extend({
55
+ chain: z.custom().optional().default(DefChain)
56
+ });
57
+ function buildPublicClient({ chain = DefChain, infuraKey }) {
58
+ const transport = buildInfuraHttpTransport({
59
+ chain: chain.id,
60
+ infuraKey
61
+ });
62
+ return createPublicClient({
63
+ chain,
64
+ transport
65
+ });
66
+ }
67
+ const BuildClientArgs = RequiredInfuraKey.extend({
68
+ chain: z.custom().optional().default(DefChain)
69
+ });
70
+ function buildClient({ chain = DefChain, infuraKey }) {
71
+ const transport = buildInfuraHttpTransport({
72
+ chain: chain.id,
73
+ infuraKey
74
+ });
75
+ return createClient({
76
+ chain,
77
+ transport
78
+ });
79
+ }
80
+ const MultisigErrorMap = {
81
+ INVALID_SIGNER: {
82
+ title: "Signer Wallet is Invalid",
83
+ description: "This wallet is not a valid signing wallet for the Multisig. You can try again with a different wallet using the options below."
84
+ },
85
+ INVALID_NETWORK: {
86
+ title: "Invalid network",
87
+ description: "The signing wallet must be connected to the same network as the Multisig."
88
+ }
89
+ };
90
+ const MultisigSchema = z.object({
91
+ network: z.custom(
92
+ (val) => val != null && typeof val === "number" && SafeSupportedNetworks.safeParse(val).success
93
+ ),
94
+ address: z.string().min(42),
95
+ enteredSafeIsValid: z.boolean().optional()
96
+ });
97
+ const defInnerState = {
98
+ _infuraKey: "",
99
+ _connectModalOpen: false,
100
+ _setConnectModalOpen() {
101
+ },
102
+ _modalTitle: "Connect your wallet",
103
+ _setModalTitle() {
104
+ },
105
+ _setModalSubtitle() {
106
+ },
107
+ _modalState: "primary",
108
+ _setModalState() {
109
+ },
110
+ _setSafeInfo() {
111
+ },
112
+ _authenticating: false,
113
+ _setAuthenticating() {
114
+ },
115
+ _connect() {
116
+ },
117
+ _connectMultisig() {
118
+ },
119
+ _reset() {
120
+ }
121
+ };
122
+ const GraphAuthKitInnerContext = createContext(defInnerState);
123
+ function useGraphAuthKitInnerContext() {
124
+ return useContext(GraphAuthKitInnerContext);
125
+ }
126
+ function GraphAuthKitInnerContextProvider({ infuraKey, children }) {
127
+ const config = useConfig();
128
+ const { connect, connectors } = useConnect();
129
+ const { disconnectAsync } = useDisconnect();
130
+ const firstConnectCheckRef = useRef();
131
+ const [_connectModalOpen, setConnectModalOpen] = useState(false);
132
+ const [_modalTitle, setModalTitle] = useState();
133
+ const [_modalSubtitle, setModalSubtitle] = useState();
134
+ const [_authenticating, setAuthenticating] = useState(false);
135
+ const [_connector, setConnector] = useState();
136
+ const [_connectFailureMessage, setConnectFailureMessage] = useState();
137
+ const [_modalState, setModalState] = useState("primary");
138
+ const [_enteredMultisigInfo, setEnteredMultisigInfo] = useState();
139
+ useAccountEffect({
140
+ async onConnect(data) {
141
+ var _a;
142
+ if (!firstConnectCheckRef.current) {
143
+ const multisigCookie = await ((_a = config.storage) == null ? void 0 : _a.getItem(MULTISIG_AUTH_STORAGE_KEY));
144
+ if (multisigCookie) {
145
+ const parsedMultisigSchema = MultisigSchema.safeParse(
146
+ typeof multisigCookie === "string" ? JSON.parse(multisigCookie) : multisigCookie
147
+ );
148
+ if (parsedMultisigSchema.success && isAddress(parsedMultisigSchema.data.address)) {
149
+ setEnteredMultisigInfo(parsedMultisigSchema.data);
150
+ setConnector("multisig");
151
+ }
152
+ } else {
153
+ const parsedConnector = GraphAuthKitConnector.safeParse(data.connector.type);
154
+ const connector = parsedConnector.success ? parsedConnector.data : "injected";
155
+ setConnector(connector);
156
+ }
157
+ firstConnectCheckRef.current = true;
158
+ }
159
+ }
160
+ });
161
+ const _connect = async (connector) => {
162
+ setAuthenticating(true);
163
+ setConnector(void 0);
164
+ setConnectFailureMessage(void 0);
165
+ const conn = connectors.find((c) => c.type === connector) ?? injected();
166
+ connect(
167
+ { connector: conn },
168
+ {
169
+ onSuccess() {
170
+ setConnector(connector);
171
+ setConnectModalOpen(false);
172
+ setModalTitle("Connect your wallet");
173
+ setModalSubtitle(void 0);
174
+ setEnteredMultisigInfo(void 0);
175
+ setModalState("primary");
176
+ },
177
+ onError(err) {
178
+ if (err.code === 4001) {
179
+ return;
180
+ }
181
+ console.error("GraphAuthKit.connect - failure connecting wallet", { err });
182
+ setConnectFailureMessage({ title: err.name, description: err.message });
183
+ },
184
+ onSettled() {
185
+ setAuthenticating(false);
186
+ }
187
+ }
188
+ );
189
+ };
190
+ const _connectMultisig = async (params) => {
191
+ setAuthenticating(true);
192
+ setConnector(void 0);
193
+ setConnectFailureMessage(void 0);
194
+ const conn = connectors.find((c) => c.type === params.connector) ?? injected();
195
+ connect(
196
+ { connector: conn },
197
+ {
198
+ async onSuccess(data) {
199
+ var _a;
200
+ if (data.chainId !== params.network) {
201
+ await disconnectAsync({ connector: typeof conn === "function" ? void 0 : conn }).then(() => {
202
+ var _a2;
203
+ void ((_a2 = config.storage) == null ? void 0 : _a2.removeItem(MULTISIG_AUTH_STORAGE_KEY));
204
+ setConnectFailureMessage(MultisigErrorMap["INVALID_NETWORK"]);
205
+ });
206
+ return;
207
+ }
208
+ const [eoa] = data.accounts;
209
+ const client = buildPublicClient({
210
+ infuraKey,
211
+ chain: params.network === L2Chain.id ? L2Chain : params.network === L1Chain.id ? L1Chain : L1ChainTestnet
212
+ });
213
+ const eoaIsSafeOwner = await isSafeOwner({
214
+ client,
215
+ chain: params.network,
216
+ safeAddress: params.address,
217
+ eoa
218
+ });
219
+ if (!eoaIsSafeOwner) {
220
+ await disconnectAsync({ connector: typeof conn === "function" ? void 0 : conn }).then(() => {
221
+ var _a2;
222
+ void ((_a2 = config.storage) == null ? void 0 : _a2.removeItem(MULTISIG_AUTH_STORAGE_KEY));
223
+ setConnectFailureMessage(MultisigErrorMap["INVALID_SIGNER"]);
224
+ });
225
+ return;
226
+ }
227
+ setConnector("multisig");
228
+ void ((_a = config.storage) == null ? void 0 : _a.setItem(MULTISIG_AUTH_STORAGE_KEY, _enteredMultisigInfo));
229
+ setConnectModalOpen(false);
230
+ setModalTitle("Connect your wallet");
231
+ setModalSubtitle(void 0);
232
+ setModalState("primary");
233
+ },
234
+ onError(err) {
235
+ var _a;
236
+ if (err.code === 4001) {
237
+ return;
238
+ }
239
+ void ((_a = config.storage) == null ? void 0 : _a.removeItem(MULTISIG_AUTH_STORAGE_KEY));
240
+ setConnectFailureMessage({ title: err.name, description: err.message });
241
+ },
242
+ onSettled() {
243
+ setAuthenticating(false);
244
+ }
245
+ }
246
+ );
247
+ };
248
+ return /* @__PURE__ */ jsx(
249
+ GraphAuthKitInnerContext.Provider,
250
+ {
251
+ value: {
252
+ _infuraKey: infuraKey,
253
+ _connectModalOpen,
254
+ _setConnectModalOpen: setConnectModalOpen,
255
+ _modalTitle,
256
+ _setModalTitle: setModalTitle,
257
+ _modalSubtitle,
258
+ _setModalSubtitle: setModalSubtitle,
259
+ _modalState,
260
+ _setModalState: setModalState,
261
+ _enteredMultisigInfo,
262
+ _setSafeInfo: setEnteredMultisigInfo,
263
+ _authenticating,
264
+ _setAuthenticating: setAuthenticating,
265
+ _connector,
266
+ _connectFailureMessage,
267
+ _connect,
268
+ _connectMultisig,
269
+ _reset() {
270
+ var _a;
271
+ setAuthenticating(false);
272
+ setConnector(void 0);
273
+ setConnectFailureMessage(void 0);
274
+ setModalTitle("Connect your wallet");
275
+ setModalSubtitle(void 0);
276
+ setEnteredMultisigInfo(void 0);
277
+ setModalState("primary");
278
+ void ((_a = config.storage) == null ? void 0 : _a.removeItem(MULTISIG_AUTH_STORAGE_KEY));
279
+ }
280
+ },
281
+ children
282
+ }
283
+ );
284
+ }
285
+ function ConnectorOption(props) {
286
+ return /* @__PURE__ */ jsxs(
287
+ "button",
288
+ {
289
+ className: "flex w-full cursor-pointer items-center gap-x-2 rounded-4 border border-white/4 bg-white/4 p-4 text-white/48 hover:border-white/16 hover:bg-white/8 hover:text-white aria-selected:border-white/16 aria-selected:bg-white/8 aria-selected:text-white",
290
+ style: {
291
+ WebkitBackfaceVisibility: "hidden"
292
+ },
293
+ onClick: props.onClick,
294
+ disabled: props.disabled,
295
+ children: [
296
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center justify-center", children: /* @__PURE__ */ jsx(props.Image, { size: "24px" }) }),
297
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
298
+ /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx("h6", { className: "text-h16 whitespace-nowrap text-inherit", children: props.title }) }),
299
+ props.description ? /* @__PURE__ */ jsx("div", { className: "text-p14 flex text-white/48", children: props.description }) : null
300
+ ] })
301
+ ]
302
+ }
303
+ );
304
+ }
305
+ const multisigConnectOptions = [
306
+ {
307
+ connector: "injected",
308
+ title: "MetaMask",
309
+ Image: Icon.LogoMetaMaskColor
310
+ },
311
+ {
312
+ connector: "walletConnect",
313
+ title: "WalletConnect",
314
+ Image: Icon.LogoWalletConnectColor
315
+ },
316
+ {
317
+ connector: "coinbaseWallet",
318
+ title: "Coinbase Wallet",
319
+ Image: Icon.LogoCoinbaseWallet
320
+ }
321
+ ];
322
+ function MultisigSignerOptions() {
323
+ const authKit = useGraphAuthKit();
324
+ const ctx = useGraphAuthKitInnerContext();
325
+ const [selectedConnector, setSelectedConnector] = useState(null);
326
+ if (ctx._enteredMultisigInfo == null || !ctx._enteredMultisigInfo.address) {
327
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between gap-y-24", children: [
328
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
329
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-x-3", children: /* @__PURE__ */ jsx("span", { className: "text-c12 hidden text-white/64 md:inline", children: "Multisig Connection" }) }),
330
+ /* @__PURE__ */ jsx("h3", { className: "text-h24", children: "No Safe address entered." })
331
+ ] }),
332
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between", children: [
333
+ /* @__PURE__ */ jsx(ExperimentalButton, { variant: "primary", iconBefore: /* @__PURE__ */ jsx(Icon.ArrowLeft, {}), onClick: () => ctx._setModalState("safe_entry"), children: "Enter Safe" }),
334
+ /* @__PURE__ */ jsx(ExperimentalButton, { variant: "tertiary", className: "hidden md:inline", onClick: () => authKit.closeConnectModal(), children: "Cancel" })
335
+ ] })
336
+ ] });
337
+ }
338
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
339
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
340
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
341
+ /* @__PURE__ */ jsx("span", { className: "text-c12 hidden text-white/64 md:inline", children: "Multisig Connection" }),
342
+ /* @__PURE__ */ jsx("div", { className: "hidden h-[10px] w-px bg-white/64 md:inline" }),
343
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
344
+ /* @__PURE__ */ jsx(Icon.LogoSafeColor, { size: "16px" }),
345
+ /* @__PURE__ */ jsx("p", { className: "text-p12 text-white/64", children: addrShortener(ctx._enteredMultisigInfo.address) }),
346
+ /* @__PURE__ */ jsx(
347
+ ExperimentalButton,
348
+ {
349
+ variant: "tertiary",
350
+ size: "xsmall",
351
+ onClick: () => {
352
+ ctx._setSafeInfo(void 0);
353
+ ctx._setModalState("safe_entry");
354
+ },
355
+ children: "Change"
356
+ }
357
+ )
358
+ ] })
359
+ ] }),
360
+ /* @__PURE__ */ jsx("h3", { className: "text-h24", children: "Select a signing wallet" })
361
+ ] }),
362
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-center gap-8", children: [
363
+ ctx._connectFailureMessage ? /* @__PURE__ */ jsx(
364
+ Alert,
365
+ {
366
+ severity: "error",
367
+ title: ctx._connectFailureMessage.title,
368
+ description: ctx._connectFailureMessage.description
369
+ }
370
+ ) : null,
371
+ /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-y-2", children: multisigConnectOptions.map((opt) => /* @__PURE__ */ jsx(
372
+ ConnectorOption,
373
+ {
374
+ ...opt,
375
+ selected: selectedConnector != null && selectedConnector === opt.connector,
376
+ onClick: () => {
377
+ if (ctx._enteredMultisigInfo == null || !isAddress(ctx._enteredMultisigInfo.address)) {
378
+ return;
379
+ }
380
+ setSelectedConnector(opt.connector);
381
+ void ctx._connectMultisig({
382
+ connector: opt.connector,
383
+ network: ctx._enteredMultisigInfo.network,
384
+ address: ctx._enteredMultisigInfo.address
385
+ });
386
+ }
387
+ },
388
+ opt.connector
389
+ )) })
390
+ ] }),
391
+ /* @__PURE__ */ jsx(Divider, {}),
392
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between", children: [
393
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
394
+ /* @__PURE__ */ jsx("p", { className: "text-p14", children: "Wallet didn't open?" }),
395
+ /* @__PURE__ */ jsxs(
396
+ Link.Secondary,
397
+ {
398
+ size: "14px",
399
+ onClick: () => {
400
+ if (selectedConnector == null || ctx._enteredMultisigInfo == null || !isAddress(ctx._enteredMultisigInfo.address)) {
401
+ return;
402
+ }
403
+ void ctx._connectMultisig({
404
+ connector: selectedConnector,
405
+ network: ctx._enteredMultisigInfo.network,
406
+ address: ctx._enteredMultisigInfo.address
407
+ });
408
+ },
409
+ children: [
410
+ "Try again ",
411
+ /* @__PURE__ */ jsx(Icon.RotateLeft, { size: "14px" })
412
+ ]
413
+ }
414
+ )
415
+ ] }),
416
+ /* @__PURE__ */ jsx(ExperimentalButton, { variant: "tertiary", className: "hidden md:inline", onClick: () => authKit.closeConnectModal(), children: "Cancel" })
417
+ ] })
418
+ ] });
419
+ }
420
+ const primaryConnectOptions = [
421
+ {
422
+ connector: "injected",
423
+ title: "MetaMask",
424
+ Image: Icon.LogoMetaMaskColor
425
+ },
426
+ {
427
+ connector: "walletConnect",
428
+ title: "WalletConnect",
429
+ Image: Icon.LogoWalletConnectColor
430
+ },
431
+ {
432
+ connector: "coinbaseWallet",
433
+ title: "Coinbase Wallet",
434
+ Image: Icon.LogoCoinbaseWallet
435
+ },
436
+ {
437
+ connector: "multisig",
438
+ title: "Safe",
439
+ Image: Icon.LogoSafeColor
440
+ }
441
+ ];
442
+ function PrimaryConnectOptions() {
443
+ const ctx = useGraphAuthKitInnerContext();
444
+ const [selectedConnector, setSelectedConnector] = useState(null);
445
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
446
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
447
+ ctx._modalSubtitle ? /* @__PURE__ */ jsx("p", { className: "text-c12 text-white/64", children: ctx._modalSubtitle }) : null,
448
+ /* @__PURE__ */ jsx("h3", { className: "text-h24", children: ctx._modalTitle })
449
+ ] }),
450
+ ctx._connectFailureMessage ? /* @__PURE__ */ jsx(
451
+ Alert,
452
+ {
453
+ severity: "error",
454
+ title: ctx._connectFailureMessage.title,
455
+ description: ctx._connectFailureMessage.description
456
+ }
457
+ ) : null,
458
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 md:grid-cols-2", children: primaryConnectOptions.map((opt) => /* @__PURE__ */ jsx(
459
+ ConnectorOption,
460
+ {
461
+ ...opt,
462
+ disabled: ctx._authenticating,
463
+ selected: selectedConnector != null && selectedConnector === opt.connector,
464
+ onClick: () => {
465
+ setSelectedConnector(opt.connector);
466
+ if (opt.connector === "multisig") {
467
+ ctx._setModalState("safe_entry");
468
+ } else {
469
+ void ctx._connect(opt.connector);
470
+ }
471
+ }
472
+ },
473
+ opt.connector
474
+ )) }),
475
+ /* @__PURE__ */ jsxs("p", { className: "text-p12 text-white/64", children: [
476
+ "By connecting a wallet, you agree to The Graph's",
477
+ " ",
478
+ /* @__PURE__ */ jsx(Link.Inline, { href: "https://thegraph.com/terms-of-service/", target: "_blank", children: "Terms of Service" }),
479
+ " ",
480
+ "and acknowledge that you have read and understood the disclaimers therein."
481
+ ] })
482
+ ] });
483
+ }
484
+ z.union([
485
+ z.object({
486
+ action: z.literal("SET_NETWORK"),
487
+ payload: z.custom(
488
+ (val) => val != null && typeof val === "number" && SafeSupportedNetworks.safeParse(val).success
489
+ )
490
+ }),
491
+ z.object({
492
+ action: z.literal("SET_SAFE_ADDRESS"),
493
+ payload: z.string().min(42)
494
+ }),
495
+ z.object({
496
+ action: z.literal("SET_SAFE_VALID"),
497
+ payload: z.boolean().optional()
498
+ }),
499
+ z.object({
500
+ action: z.literal("RESET")
501
+ })
502
+ ]);
503
+ function SafeInputFormReducer(state, action) {
504
+ switch (action.action) {
505
+ case "SET_NETWORK": {
506
+ return {
507
+ ...state,
508
+ network: action.payload
509
+ };
510
+ }
511
+ case "SET_SAFE_VALID": {
512
+ return {
513
+ ...state,
514
+ enteredSafeIsValid: action.payload
515
+ };
516
+ }
517
+ case "SET_SAFE_ADDRESS": {
518
+ return {
519
+ ...state,
520
+ address: action.payload
521
+ };
522
+ }
523
+ default: {
524
+ return {
525
+ ...state,
526
+ enteredSafeIsValid: void 0,
527
+ network: L2Chain.id,
528
+ address: "0x"
529
+ };
530
+ }
531
+ }
532
+ }
533
+ function SafeInputForm() {
534
+ const ctx = useGraphAuthKitInnerContext();
535
+ const previouslyUsedSafes = usePreviouslyUsedSafes();
536
+ const [state, dispatch] = useReducer(SafeInputFormReducer, {
537
+ network: L2Chain.id,
538
+ address: ""
539
+ });
540
+ async function validateMultisigSchema(_state) {
541
+ if (!isAddress(_state.address)) {
542
+ return dispatch({ action: "SET_SAFE_VALID", payload: false });
543
+ }
544
+ const client = buildPublicClient({
545
+ chain: _state.network === L2Chain.id ? L2Chain : _state.network === L1Chain.id ? L1Chain : L1ChainTestnet,
546
+ infuraKey: ctx._infuraKey
547
+ });
548
+ const valid = await isValidSafe({
549
+ client,
550
+ chain: _state.network,
551
+ safeAddress: _state.address
552
+ });
553
+ dispatch({ action: "SET_SAFE_VALID", payload: valid });
554
+ }
555
+ const handleMultisigAddressChange = (entered) => {
556
+ var _a;
557
+ let networkId = void 0;
558
+ if (entered.includes(":")) {
559
+ const [shortName, address] = entered.split(":");
560
+ networkId = (_a = Object.values(SafeSupportedNetworkNames).find((supported) => supported.shortName === shortName)) == null ? void 0 : _a.id;
561
+ entered = address;
562
+ if (networkId) {
563
+ dispatch({ action: "SET_NETWORK", payload: networkId });
564
+ }
565
+ }
566
+ dispatch({ action: "SET_SAFE_ADDRESS", payload: entered });
567
+ void validateMultisigSchema({ ...state, network: networkId || state.network, address: entered });
568
+ };
569
+ const isSubmitDisabled = !state.address || !state.enteredSafeIsValid;
570
+ return /* @__PURE__ */ jsxs(
571
+ "form",
572
+ {
573
+ noValidate: true,
574
+ className: "flex flex-col gap-y-6",
575
+ onSubmit: (e) => {
576
+ e.preventDefault();
577
+ if (state.enteredSafeIsValid && state.address) {
578
+ previouslyUsedSafes.save(state.network, state.address);
579
+ }
580
+ ctx._setSafeInfo(state);
581
+ ctx._setModalState("safe_eoa_signer");
582
+ },
583
+ children: [
584
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-2", children: [
585
+ ctx._modalSubtitle ? /* @__PURE__ */ jsx("p", { className: "text-c12 text-white/64", children: ctx._modalSubtitle }) : null,
586
+ /* @__PURE__ */ jsx("h3", { className: "text-h24", children: "Safe Multisig" })
587
+ ] }),
588
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-center gap-y-6", children: [
589
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-y-4", children: [
590
+ /* @__PURE__ */ jsx(
591
+ ExperimentalSelect,
592
+ {
593
+ placeholder: "Select Safe Network",
594
+ value: state.network,
595
+ onChange: (selected) => {
596
+ dispatch({ action: "SET_NETWORK", payload: selected });
597
+ void validateMultisigSchema({ ...state, network: selected });
598
+ },
599
+ valueLabel: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
600
+ /* @__PURE__ */ jsx(NetworkIcon, { chain: `evm-${state.network}` }),
601
+ SafeSupportedNetworkNames[state.network].name
602
+ ] }),
603
+ children: Object.values(SafeSupportedNetworkNames).sort((a, b) => {
604
+ if (a.id === L2Chain.id) {
605
+ return -1;
606
+ } else if (b.id === L2Chain.id) {
607
+ return 1;
608
+ }
609
+ return a.id - b.id;
610
+ }).map((n) => /* @__PURE__ */ jsx(ExperimentalSelect.Option, { value: n.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
611
+ /* @__PURE__ */ jsx(NetworkIcon, { chain: `evm-${n.id}` }),
612
+ n.name
613
+ ] }) }, n.id))
614
+ }
615
+ ),
616
+ /* @__PURE__ */ jsx(
617
+ ExperimentalInput,
618
+ {
619
+ id: "multisigAddress",
620
+ name: "multisigAddress",
621
+ label: "Multisig Address",
622
+ value: state.address || "",
623
+ onChange: handleMultisigAddressChange,
624
+ placeholder: "0x...",
625
+ status: state.enteredSafeIsValid !== void 0 && !state.enteredSafeIsValid && state.address ? "error" : state.enteredSafeIsValid ? "success" : void 0,
626
+ message: state.enteredSafeIsValid !== void 0 && !state.enteredSafeIsValid && state.address ? "Invalid Safe Adrress" : state.enteredSafeIsValid ? "Valid Safe Address" : void 0
627
+ }
628
+ )
629
+ ] }),
630
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between gap-x-4", children: [
631
+ /* @__PURE__ */ jsx(
632
+ ExperimentalButton,
633
+ {
634
+ type: "submit",
635
+ variant: "primary",
636
+ disabled: isSubmitDisabled,
637
+ iconAfter: /* @__PURE__ */ jsx(Icon.ArrowRight, { size: "16px" }),
638
+ children: "Continue"
639
+ }
640
+ ),
641
+ /* @__PURE__ */ jsx(
642
+ ExperimentalButton,
643
+ {
644
+ variant: "tertiary",
645
+ onClick: () => {
646
+ dispatch({ action: "RESET" });
647
+ ctx._setModalState("primary");
648
+ },
649
+ children: "Back"
650
+ }
651
+ )
652
+ ] })
653
+ ] }),
654
+ previouslyUsedSafes.values.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
655
+ /* @__PURE__ */ jsx(Divider, {}),
656
+ /* @__PURE__ */ jsxs("div", { children: [
657
+ /* @__PURE__ */ jsx("p", { className: "text-c12 text-white/64", children: " Previously used:" }),
658
+ /* @__PURE__ */ jsx(List.Bullets, { sx: { mt: "8px" }, children: previouslyUsedSafes.values.map((safeAddress) => /* @__PURE__ */ jsx(List.Item, { children: /* @__PURE__ */ jsxs(
659
+ Link,
660
+ {
661
+ size: "12px",
662
+ autoIcon: false,
663
+ sx: { transform: "translateY(-2.5px)" },
664
+ onClick: () => {
665
+ var _a;
666
+ const [shortName, address] = safeAddress.address.split(":");
667
+ const networkId = (_a = Object.values(SafeSupportedNetworkNames).find(
668
+ (supported) => supported.shortName === shortName
669
+ )) == null ? void 0 : _a.id;
670
+ if (networkId) {
671
+ ctx._setSafeInfo({ network: networkId, address, enteredSafeIsValid: true });
672
+ ctx._setModalState("safe_eoa_signer");
673
+ } else {
674
+ handleMultisigAddressChange(safeAddress.address);
675
+ }
676
+ },
677
+ children: [
678
+ /* @__PURE__ */ jsx("span", { className: "inline md:hidden", children: shortenMultisigAddress(safeAddress.address) }),
679
+ /* @__PURE__ */ jsx("span", { className: "hidden md:inline", children: safeAddress.address })
680
+ ]
681
+ }
682
+ ) }, `${safeAddress.address}__${safeAddress.timestamp}`)) })
683
+ ] })
684
+ ] }) : null
685
+ ]
686
+ }
687
+ );
688
+ }
689
+ function shortenMultisigAddress(multisig) {
690
+ const [shortName, address] = multisig.split(":");
691
+ return `${shortName}:${addrShortener(address)}`;
692
+ }
693
+ function usePreviouslyUsedSafes() {
694
+ const SIZE = 3;
695
+ function safesDb(onSuccess) {
696
+ const openRequest = window.indexedDB.open("previouslyUsedSafes", 1);
697
+ openRequest.onerror = () => {
698
+ };
699
+ openRequest.onupgradeneeded = function() {
700
+ const db = this.result;
701
+ const store = db.createObjectStore("previouslyUsedSafes", { keyPath: "address" });
702
+ store.createIndex("timestamp", "timestamp", { unique: false });
703
+ };
704
+ openRequest.onsuccess = onSuccess;
705
+ }
706
+ const [previouslyUsedSafes, setPreviouslyUsedSafes] = useState([]);
707
+ useEffect(() => {
708
+ if (typeof window === "undefined" || !window.indexedDB) return;
709
+ safesDb(function() {
710
+ const db = this.result;
711
+ if (!db) return;
712
+ const transaction = db.transaction("previouslyUsedSafes", "readonly");
713
+ const objectStore = transaction.objectStore("previouslyUsedSafes");
714
+ const index = objectStore.index("timestamp");
715
+ const cursorRequest = index.openCursor(null, "prev");
716
+ const entries = [];
717
+ cursorRequest.onsuccess = function() {
718
+ const cursor = this.result;
719
+ if (cursor && entries.length < SIZE) {
720
+ entries.push(cursor.value);
721
+ cursor.continue();
722
+ }
723
+ };
724
+ transaction.oncomplete = function() {
725
+ setPreviouslyUsedSafes(entries);
726
+ };
727
+ });
728
+ }, []);
729
+ return {
730
+ values: [...new Set(previouslyUsedSafes)],
731
+ save(network, safeAddress) {
732
+ if (typeof window === "undefined" || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
733
+ !window.indexedDB || previouslyUsedSafes.some((entry2) => entry2.address === safeAddress)) {
734
+ return;
735
+ }
736
+ const shortName = SafeSupportedNetworkNames[network].shortName;
737
+ const entry = {
738
+ address: `${shortName}:${safeAddress}`,
739
+ timestamp: (/* @__PURE__ */ new Date()).getTime()
740
+ };
741
+ setPreviouslyUsedSafes((prev) => [...prev, entry].slice(0, SIZE));
742
+ safesDb(function() {
743
+ const db = this.result;
744
+ if (!db) {
745
+ return;
746
+ }
747
+ const transaction = db.transaction("previouslyUsedSafes", "readwrite");
748
+ const objectStore = transaction.objectStore("previouslyUsedSafes");
749
+ objectStore.put(entry);
750
+ });
751
+ }
752
+ };
753
+ }
754
+ function ConnectModal() {
755
+ const ctx = useGraphAuthKitInnerContext();
756
+ return /* @__PURE__ */ jsx(
757
+ ExperimentalModal,
758
+ {
759
+ open: ctx._connectModalOpen,
760
+ onClose: () => {
761
+ ctx._setConnectModalOpen(false);
762
+ ctx._reset();
763
+ },
764
+ suppressHydrationWarning: true,
765
+ className: "[--gds-modal-max-width:550px]",
766
+ children: /* @__PURE__ */ jsxs("div", { className: "flex h-fit w-full grow items-center justify-center", children: [
767
+ ctx._authenticating ? /* @__PURE__ */ jsx(ExperimentalLoadingIndicator, { className: "absolute -top-10 left-0 size-4" }) : null,
768
+ /* @__PURE__ */ jsx(
769
+ "div",
770
+ {
771
+ className: "flex w-full grow flex-col aria-busy:pointer-events-none aria-busy:opacity-64",
772
+ "aria-busy": ctx._authenticating ? "true" : void 0,
773
+ children: /* @__PURE__ */ jsx(ExperimentalModal.Steps, { currentStep: ctx._modalState, children: (step) => {
774
+ switch (step) {
775
+ case "safe_entry": {
776
+ return /* @__PURE__ */ jsx(SafeInputForm, {});
777
+ }
778
+ case "safe_eoa_signer": {
779
+ return /* @__PURE__ */ jsx(MultisigSignerOptions, {});
780
+ }
781
+ default: {
782
+ return /* @__PURE__ */ jsx(PrimaryConnectOptions, {});
783
+ }
784
+ }
785
+ } })
786
+ }
787
+ )
788
+ ] })
789
+ }
790
+ );
791
+ }
792
+ function chainIsSupportedChain(chain) {
793
+ return SupportedClientChainId.safeParse(chain.id).success;
794
+ }
795
+ function isChainL2(chain) {
796
+ return chain === L2Chain.id || chain === L2ChainTestnet.id;
797
+ }
798
+ function isChainL1(chain) {
799
+ return chain === L1Chain.id || chain === L1ChainTestnet.id;
800
+ }
801
+ function isChainMainnet(chain) {
802
+ return chain === L1Chain.id || chain === L2Chain.id;
803
+ }
804
+ function isChainTestnet(chain) {
805
+ return chain === L1ChainTestnet.id || chain === L2ChainTestnet.id;
806
+ }
807
+ function clientToProvider(client) {
808
+ var _a, _b;
809
+ const { chain, transport } = client;
810
+ const network = {
811
+ chainId: chain.id,
812
+ name: chain.name,
813
+ ensAddress: (_b = (_a = chain.contracts) == null ? void 0 : _a.ensRegistry) == null ? void 0 : _b.address
814
+ };
815
+ const provider = new providers.Web3Provider(transport, network);
816
+ return provider;
817
+ }
818
+ async function connectedWalletIsEoA(client, address) {
819
+ const code = await client.getCode({ address });
820
+ return code == null || code === "0x";
821
+ }
822
+ const GraphAuthKitContext = createContext({
823
+ openConnectModal() {
824
+ },
825
+ closeConnectModal() {
826
+ },
827
+ disconnect() {
828
+ }
829
+ });
830
+ function useGraphAuthKit() {
831
+ return useContext(GraphAuthKitContext);
832
+ }
833
+ function GraphAuthKitProvider(props) {
834
+ const image = props.meta.name === "Graph Explorer" ? "https://storage.googleapis.com/graph-website/seo/graph-explorer.jpg" : "https://storage.googleapis.com/graph-website/seo/subgraph-studio.jpg";
835
+ const description = props.meta.name === "Graph Explorer" ? `See what’s happening on The Graph Network and participate as a Delegator, Curator, Indexer, or Developer.` : "Use the Subgraph Studio to test, deploy, and publish your subgraphs to the decentralized network.";
836
+ const url = props.meta.url || (props.meta.name === "Graph Explorer" ? "https://thegraph.com/explorer" : "https://thegraph.com/studio");
837
+ const chains = props.chains === "ALL" ? [L2Chain, L2ChainTestnet, L1Chain, L1ChainTestnet] : props.chains === "MAINNET" ? [L2Chain, L1Chain] : [L2ChainTestnet, L1ChainTestnet];
838
+ const queryClient = props.queryClient ?? new QueryClient({
839
+ defaultOptions: {
840
+ queries: {
841
+ staleTime: 60 * 1e3
842
+ }
843
+ }
844
+ });
845
+ const config = createConfig({
846
+ chains,
847
+ ssr: typeof window !== "undefined",
848
+ client(params) {
849
+ const chain = chainIsSupportedChain(params.chain) ? params.chain : DefChain;
850
+ return buildClient({ chain, infuraKey: props.infuraKey });
851
+ },
852
+ connectors: [
853
+ injected(),
854
+ coinbaseWallet({
855
+ appName: props.meta.name,
856
+ appLogoUrl: image
857
+ }),
858
+ walletConnect({
859
+ projectId: props.walletConnectProjectID,
860
+ metadata: {
861
+ name: props.meta.name,
862
+ description,
863
+ url,
864
+ icons: [image]
865
+ },
866
+ qrModalOptions: {
867
+ themeMode: "dark"
868
+ }
869
+ })
870
+ ],
871
+ storage: createStorage({
872
+ storage: cookieStorage,
873
+ key: AUTH_STORAGE_KEY
874
+ })
875
+ });
876
+ const initialState = cookieToInitialState(config, props.initialStateCookie);
877
+ return /* @__PURE__ */ jsx(WagmiProvider, { config, initialState, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(GraphAuthKitInnerContextProvider, { infuraKey: props.infuraKey, children: /* @__PURE__ */ jsx(GraphAuthKitContent, { children: props.children }) }) }) });
878
+ }
879
+ function GraphAuthKitContent({ children }) {
880
+ const { disconnect } = useDisconnect();
881
+ const innerContext = useGraphAuthKitInnerContext();
882
+ return /* @__PURE__ */ jsxs(
883
+ GraphAuthKitContext.Provider,
884
+ {
885
+ value: {
886
+ openConnectModal(props) {
887
+ innerContext._setConnectModalOpen(true);
888
+ innerContext._setModalTitle((props == null ? void 0 : props.title) ?? "Connect your wallet");
889
+ innerContext._setModalSubtitle(props == null ? void 0 : props.subtitle);
890
+ },
891
+ closeConnectModal() {
892
+ innerContext._setConnectModalOpen(false);
893
+ innerContext._reset();
894
+ },
895
+ disconnect() {
896
+ disconnect(
897
+ {},
898
+ {
899
+ onSettled() {
900
+ innerContext._reset();
901
+ }
902
+ }
903
+ );
904
+ }
905
+ },
906
+ children: [
907
+ /* @__PURE__ */ jsx(ConnectModal, {}),
908
+ children
909
+ ]
910
+ }
911
+ );
912
+ }
913
+ export {
914
+ BuildPublicClientArgs as B,
915
+ GraphAuthKitInnerContext as G,
916
+ RequiredInfuraKey as R,
917
+ GraphAuthKitContext as a,
918
+ buildClient as b,
919
+ chainIsSupportedChain as c,
920
+ defInnerState as d,
921
+ clientToProvider as e,
922
+ buildInfuraHttpTransport as f,
923
+ buildPublicClient as g,
924
+ BuildClientArgs as h,
925
+ useGraphAuthKit as i,
926
+ GraphAuthKitProvider as j,
927
+ RequiredWalletConnectProjectId as k,
928
+ GraphAuthKitProps as l,
929
+ GraphAuthKitConnector as m,
930
+ isChainL2 as n,
931
+ isChainL1 as o,
932
+ isChainMainnet as p,
933
+ isChainTestnet as q,
934
+ connectedWalletIsEoA as r,
935
+ useGraphAuthKitInnerContext as u
936
+ };