access-layers-wallet 1.0.2
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 +213 -0
- package/dist/index.d.mts +168 -0
- package/dist/index.d.ts +168 -0
- package/dist/index.js +3392 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3346 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +80 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3392 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defProps = Object.defineProperties;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
8
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
13
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {}))
|
|
16
|
+
if (__hasOwnProp.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
if (__getOwnPropSymbols)
|
|
19
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
+
if (__propIsEnum.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
25
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
26
|
+
var __objRest = (source, exclude) => {
|
|
27
|
+
var target = {};
|
|
28
|
+
for (var prop in source)
|
|
29
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
30
|
+
target[prop] = source[prop];
|
|
31
|
+
if (source != null && __getOwnPropSymbols)
|
|
32
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
33
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
34
|
+
target[prop] = source[prop];
|
|
35
|
+
}
|
|
36
|
+
return target;
|
|
37
|
+
};
|
|
38
|
+
var __export = (target, all) => {
|
|
39
|
+
for (var name in all)
|
|
40
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
41
|
+
};
|
|
42
|
+
var __copyProps = (to, from, except, desc) => {
|
|
43
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
44
|
+
for (let key of __getOwnPropNames(from))
|
|
45
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
46
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
47
|
+
}
|
|
48
|
+
return to;
|
|
49
|
+
};
|
|
50
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
51
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
52
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
53
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
54
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
55
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
56
|
+
mod
|
|
57
|
+
));
|
|
58
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
59
|
+
|
|
60
|
+
// src/index.ts
|
|
61
|
+
var index_exports = {};
|
|
62
|
+
__export(index_exports, {
|
|
63
|
+
Button: () => Button2,
|
|
64
|
+
ConnectWalletHandler: () => ConnectWalletHandler,
|
|
65
|
+
Dialog: () => Dialog2,
|
|
66
|
+
DialogClose: () => DialogClose,
|
|
67
|
+
DialogContent: () => DialogContent2,
|
|
68
|
+
DialogDescription: () => DialogDescription2,
|
|
69
|
+
DialogFooter: () => DialogFooter2,
|
|
70
|
+
DialogHeader: () => DialogHeader2,
|
|
71
|
+
DialogOverlay: () => DialogOverlay2,
|
|
72
|
+
DialogPortal: () => DialogPortal2,
|
|
73
|
+
DialogTitle: () => DialogTitle2,
|
|
74
|
+
DialogTrigger: () => DialogTrigger,
|
|
75
|
+
Toaster: () => Toaster,
|
|
76
|
+
WALLET_EVENTS: () => WALLET_EVENTS2,
|
|
77
|
+
WALLET_ICONS: () => WALLET_ICONS,
|
|
78
|
+
buttonVariants: () => buttonVariants2,
|
|
79
|
+
cn: () => cn2,
|
|
80
|
+
getStoredABI: () => getStoredABI,
|
|
81
|
+
ribbitIcon: () => Ribbit_default,
|
|
82
|
+
standardizeAddress: () => standardizeAddress,
|
|
83
|
+
starkeyIcon: () => Starkey_default,
|
|
84
|
+
useConversionUtils: () => useConversionUtils_default,
|
|
85
|
+
useSupraMultiWallet: () => useSupraMultiWallet_default2
|
|
86
|
+
});
|
|
87
|
+
module.exports = __toCommonJS(index_exports);
|
|
88
|
+
|
|
89
|
+
// src/components/ConnectWalletHandler.tsx
|
|
90
|
+
var import_react2 = require("react");
|
|
91
|
+
|
|
92
|
+
// components/ui/dialog.tsx
|
|
93
|
+
var React = __toESM(require("react"));
|
|
94
|
+
var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
|
|
95
|
+
var import_lucide_react = require("lucide-react");
|
|
96
|
+
|
|
97
|
+
// lib/utils.ts
|
|
98
|
+
var import_clsx = require("clsx");
|
|
99
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
100
|
+
function cn(...inputs) {
|
|
101
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// components/ui/dialog.tsx
|
|
105
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
106
|
+
var Dialog = DialogPrimitive.Root;
|
|
107
|
+
var DialogPortal = DialogPrimitive.Portal;
|
|
108
|
+
var DialogOverlay = React.forwardRef((_a, ref) => {
|
|
109
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
111
|
+
DialogPrimitive.Overlay,
|
|
112
|
+
__spreadValues({
|
|
113
|
+
ref,
|
|
114
|
+
className: cn(
|
|
115
|
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
116
|
+
className
|
|
117
|
+
)
|
|
118
|
+
}, props)
|
|
119
|
+
) });
|
|
120
|
+
});
|
|
121
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
122
|
+
var DialogContent = React.forwardRef((_a, ref) => {
|
|
123
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPortal, { children: [
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay, {}),
|
|
126
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
127
|
+
DialogPrimitive.Content,
|
|
128
|
+
__spreadProps(__spreadValues({
|
|
129
|
+
ref,
|
|
130
|
+
className: cn(
|
|
131
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
132
|
+
className
|
|
133
|
+
)
|
|
134
|
+
}, props), {
|
|
135
|
+
children: [
|
|
136
|
+
children,
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
138
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-4 w-4" }),
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "sr-only", children: "Close" })
|
|
140
|
+
] })
|
|
141
|
+
]
|
|
142
|
+
})
|
|
143
|
+
)
|
|
144
|
+
] });
|
|
145
|
+
});
|
|
146
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
147
|
+
var DialogHeader = (_a) => {
|
|
148
|
+
var _b = _a, {
|
|
149
|
+
className
|
|
150
|
+
} = _b, props = __objRest(_b, [
|
|
151
|
+
"className"
|
|
152
|
+
]);
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
154
|
+
"div",
|
|
155
|
+
__spreadValues({
|
|
156
|
+
className: cn(
|
|
157
|
+
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
158
|
+
className
|
|
159
|
+
)
|
|
160
|
+
}, props)
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
DialogHeader.displayName = "DialogHeader";
|
|
164
|
+
var DialogFooter = (_a) => {
|
|
165
|
+
var _b = _a, {
|
|
166
|
+
className
|
|
167
|
+
} = _b, props = __objRest(_b, [
|
|
168
|
+
"className"
|
|
169
|
+
]);
|
|
170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
171
|
+
"div",
|
|
172
|
+
__spreadValues({
|
|
173
|
+
className: cn(
|
|
174
|
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
175
|
+
className
|
|
176
|
+
)
|
|
177
|
+
}, props)
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
DialogFooter.displayName = "DialogFooter";
|
|
181
|
+
var DialogTitle = React.forwardRef((_a, ref) => {
|
|
182
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
184
|
+
DialogPrimitive.Title,
|
|
185
|
+
__spreadValues({
|
|
186
|
+
ref,
|
|
187
|
+
className: cn(
|
|
188
|
+
"text-lg font-semibold leading-none tracking-tight",
|
|
189
|
+
className
|
|
190
|
+
)
|
|
191
|
+
}, props)
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
195
|
+
var DialogDescription = React.forwardRef((_a, ref) => {
|
|
196
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
198
|
+
DialogPrimitive.Description,
|
|
199
|
+
__spreadValues({
|
|
200
|
+
ref,
|
|
201
|
+
className: cn("text-sm text-muted-foreground", className)
|
|
202
|
+
}, props)
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
206
|
+
|
|
207
|
+
// src/components/ConnectWalletHandler.tsx
|
|
208
|
+
var import_react_visually_hidden = require("@radix-ui/react-visually-hidden");
|
|
209
|
+
var import_sonner2 = require("sonner");
|
|
210
|
+
|
|
211
|
+
// components/ui/button.tsx
|
|
212
|
+
var React2 = __toESM(require("react"));
|
|
213
|
+
var import_react_slot = require("@radix-ui/react-slot");
|
|
214
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
215
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
216
|
+
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
217
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
218
|
+
{
|
|
219
|
+
variants: {
|
|
220
|
+
variant: {
|
|
221
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
222
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
223
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
224
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
225
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
226
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
227
|
+
},
|
|
228
|
+
size: {
|
|
229
|
+
default: "h-10 px-4 py-2",
|
|
230
|
+
sm: "h-9 rounded-md px-3",
|
|
231
|
+
lg: "h-11 rounded-md px-8",
|
|
232
|
+
icon: "h-10 w-10"
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
defaultVariants: {
|
|
236
|
+
variant: "default",
|
|
237
|
+
size: "default"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
var Button = React2.forwardRef(
|
|
242
|
+
(_a, ref) => {
|
|
243
|
+
var _b = _a, { className, variant, size, asChild = false } = _b, props = __objRest(_b, ["className", "variant", "size", "asChild"]);
|
|
244
|
+
const Comp = asChild ? import_react_slot.Slot : "button";
|
|
245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
246
|
+
Comp,
|
|
247
|
+
__spreadValues({
|
|
248
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
249
|
+
ref
|
|
250
|
+
}, props)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
Button.displayName = "Button";
|
|
255
|
+
|
|
256
|
+
// src/components/ConnectWalletHandler.tsx
|
|
257
|
+
var import_framer_motion = require("framer-motion");
|
|
258
|
+
var import_lucide_react2 = require("lucide-react");
|
|
259
|
+
|
|
260
|
+
// hooks/useSupraMultiWallet.ts
|
|
261
|
+
var import_react = require("react");
|
|
262
|
+
var import_tweetnacl = __toESM(require("tweetnacl"));
|
|
263
|
+
var import_navigation = require("next/navigation");
|
|
264
|
+
var import_sonner = require("sonner");
|
|
265
|
+
var import_ribbit_wallet_connect = require("ribbit-wallet-connect");
|
|
266
|
+
|
|
267
|
+
// lib/logger.ts
|
|
268
|
+
var Logger = class {
|
|
269
|
+
constructor() {
|
|
270
|
+
this.isDevelopment = process.env.NODE_ENV === "development";
|
|
271
|
+
}
|
|
272
|
+
log(level, message, context, error) {
|
|
273
|
+
if (!this.isDevelopment && level === "debug") {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const entry = {
|
|
277
|
+
level,
|
|
278
|
+
message,
|
|
279
|
+
timestamp: Date.now(),
|
|
280
|
+
context,
|
|
281
|
+
error
|
|
282
|
+
};
|
|
283
|
+
const logMethod = level === "error" ? console.error : level === "warn" ? console.warn : console.log;
|
|
284
|
+
if (error) {
|
|
285
|
+
logMethod(`[${level.toUpperCase()}] ${message}`, __spreadProps(__spreadValues({}, context), {
|
|
286
|
+
error: {
|
|
287
|
+
name: error.name,
|
|
288
|
+
message: error.message,
|
|
289
|
+
stack: error.stack
|
|
290
|
+
}
|
|
291
|
+
}));
|
|
292
|
+
} else {
|
|
293
|
+
logMethod(`[${level.toUpperCase()}] ${message}`, context || {});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
debug(message, context) {
|
|
297
|
+
this.log("debug", message, context);
|
|
298
|
+
}
|
|
299
|
+
info(message, context) {
|
|
300
|
+
this.log("info", message, context);
|
|
301
|
+
}
|
|
302
|
+
warn(message, context) {
|
|
303
|
+
this.log("warn", message, context);
|
|
304
|
+
}
|
|
305
|
+
error(message, error, context) {
|
|
306
|
+
this.log("error", message, context, error);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
var logger = new Logger();
|
|
310
|
+
|
|
311
|
+
// lib/errors.ts
|
|
312
|
+
var WalletError = class _WalletError extends Error {
|
|
313
|
+
constructor(message, code, cause) {
|
|
314
|
+
super(message);
|
|
315
|
+
this.code = code;
|
|
316
|
+
this.cause = cause;
|
|
317
|
+
this.name = "WalletError";
|
|
318
|
+
Object.setPrototypeOf(this, _WalletError.prototype);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
var WalletConnectionError = class _WalletConnectionError extends WalletError {
|
|
322
|
+
constructor(message, cause) {
|
|
323
|
+
super(message, "WALLET_CONNECTION_ERROR", cause);
|
|
324
|
+
this.name = "WalletConnectionError";
|
|
325
|
+
Object.setPrototypeOf(this, _WalletConnectionError.prototype);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
var TransactionError = class _TransactionError extends WalletError {
|
|
329
|
+
constructor(message, txHash, cause) {
|
|
330
|
+
super(message, "TRANSACTION_ERROR", cause);
|
|
331
|
+
this.txHash = txHash;
|
|
332
|
+
this.name = "TransactionError";
|
|
333
|
+
Object.setPrototypeOf(this, _TransactionError.prototype);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
var SignMessageError = class _SignMessageError extends WalletError {
|
|
337
|
+
constructor(message, cause) {
|
|
338
|
+
super(message, "SIGN_MESSAGE_ERROR", cause);
|
|
339
|
+
this.name = "SignMessageError";
|
|
340
|
+
Object.setPrototypeOf(this, _SignMessageError.prototype);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
var WalletNotInstalledError = class _WalletNotInstalledError extends WalletError {
|
|
344
|
+
constructor(walletType) {
|
|
345
|
+
super(`Wallet ${walletType} is not installed`, "WALLET_NOT_INSTALLED");
|
|
346
|
+
this.name = "WalletNotInstalledError";
|
|
347
|
+
Object.setPrototypeOf(this, _WalletNotInstalledError.prototype);
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
var NetworkError = class _NetworkError extends WalletError {
|
|
351
|
+
constructor(message, cause) {
|
|
352
|
+
super(message, "NETWORK_ERROR", cause);
|
|
353
|
+
this.name = "NetworkError";
|
|
354
|
+
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
// lib/storage.ts
|
|
359
|
+
function setStorageItem(key, value, preferredType = "localStorage") {
|
|
360
|
+
const types = preferredType === "localStorage" ? ["localStorage", "sessionStorage", "cookie"] : preferredType === "sessionStorage" ? ["sessionStorage", "localStorage", "cookie"] : ["cookie", "localStorage", "sessionStorage"];
|
|
361
|
+
for (const type of types) {
|
|
362
|
+
try {
|
|
363
|
+
switch (type) {
|
|
364
|
+
case "localStorage":
|
|
365
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
366
|
+
window.localStorage.setItem(key, value);
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
break;
|
|
370
|
+
case "sessionStorage":
|
|
371
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
372
|
+
window.sessionStorage.setItem(key, value);
|
|
373
|
+
return true;
|
|
374
|
+
}
|
|
375
|
+
break;
|
|
376
|
+
case "cookie":
|
|
377
|
+
if (typeof document !== "undefined") {
|
|
378
|
+
document.cookie = `${key}=${encodeURIComponent(value)}; path=/; max-age=${60 * 60 * 24 * 30}; SameSite=Lax`;
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
} catch (error) {
|
|
384
|
+
logger.warn(`Failed to set ${key} in ${type}`, { error });
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
function getStorageItem(key) {
|
|
390
|
+
try {
|
|
391
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
392
|
+
const value = window.localStorage.getItem(key);
|
|
393
|
+
if (value !== null) return value;
|
|
394
|
+
}
|
|
395
|
+
} catch (error) {
|
|
396
|
+
logger.warn(`Failed to read ${key} from localStorage`, { error });
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
400
|
+
const value = window.sessionStorage.getItem(key);
|
|
401
|
+
if (value !== null) return value;
|
|
402
|
+
}
|
|
403
|
+
} catch (error) {
|
|
404
|
+
logger.warn(`Failed to read ${key} from sessionStorage`, { error });
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
if (typeof document !== "undefined") {
|
|
408
|
+
const match = document.cookie.split("; ").find((r) => r.startsWith(key + "="));
|
|
409
|
+
if (match) {
|
|
410
|
+
return decodeURIComponent(match.split("=").slice(1).join("="));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
} catch (error) {
|
|
414
|
+
logger.warn(`Failed to read ${key} from cookie`, { error });
|
|
415
|
+
}
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
function removeStorageItem(key) {
|
|
419
|
+
try {
|
|
420
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
421
|
+
window.localStorage.removeItem(key);
|
|
422
|
+
}
|
|
423
|
+
} catch (error) {
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
427
|
+
window.sessionStorage.removeItem(key);
|
|
428
|
+
}
|
|
429
|
+
} catch (error) {
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
if (typeof document !== "undefined") {
|
|
433
|
+
document.cookie = `${key}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// lib/constants.ts
|
|
440
|
+
var STORAGE_KEYS = {
|
|
441
|
+
SELECTED_WALLET: "multiwallet.selectedWallet",
|
|
442
|
+
RECENT_WALLET: "recent_wallet_type",
|
|
443
|
+
USER_PROFILE_CACHE: "user_profile_cache",
|
|
444
|
+
USER_PROFILE_CACHE_TIMESTAMP: "user_profile_cache_timestamp",
|
|
445
|
+
IS_SIGNING_WALLET: "isSigningWallet",
|
|
446
|
+
STARKEY_ACCOUNTS: "starkey.accounts.0"
|
|
447
|
+
};
|
|
448
|
+
var CACHE_TTL = {
|
|
449
|
+
PROFILE: 600 * 1e3,
|
|
450
|
+
// 10 minutes
|
|
451
|
+
BALANCE: 30 * 1e3
|
|
452
|
+
// 30 seconds
|
|
453
|
+
};
|
|
454
|
+
var TIMEOUTS = {
|
|
455
|
+
WALLET_DETECTION_POLL: 3e3,
|
|
456
|
+
// 3 seconds (reduced from 5s)
|
|
457
|
+
WALLET_CHECK_INTERVAL: 2e3,
|
|
458
|
+
// 2 seconds
|
|
459
|
+
WALLET_CHECK_MAX_DURATION: 3e4,
|
|
460
|
+
// 30 seconds
|
|
461
|
+
CONNECTION_TIMEOUT: 3e4,
|
|
462
|
+
// 30 seconds
|
|
463
|
+
BALANCE_POLL_INTERVAL: 3e4,
|
|
464
|
+
// 30 seconds
|
|
465
|
+
MODAL_CLOSE_DELAY: 2500,
|
|
466
|
+
// 2.5 seconds
|
|
467
|
+
CLICK_OUTSIDE_DELAY: 2e3
|
|
468
|
+
// 2 seconds
|
|
469
|
+
};
|
|
470
|
+
var WALLET_DOWNLOAD_URLS = {
|
|
471
|
+
starkey: "https://chromewebstore.google.com/detail/starkey-wallet-the-offici/hcjhpkgbmechpabifbggldplacolbkoh",
|
|
472
|
+
ribbit: "https://ribbitwallet.com"
|
|
473
|
+
};
|
|
474
|
+
var DEFAULT_CHAIN_IDS = {
|
|
475
|
+
TESTNET: "6",
|
|
476
|
+
MAINNET: "8"
|
|
477
|
+
};
|
|
478
|
+
var ERROR_MESSAGES = {
|
|
479
|
+
WALLET_NOT_INSTALLED: "Wallet extension not installed",
|
|
480
|
+
CONNECTION_FAILED: "Failed to connect wallet",
|
|
481
|
+
CONNECTION_REJECTED: "Connection rejected by user",
|
|
482
|
+
NO_ACCOUNT_FOUND: "No account found",
|
|
483
|
+
SIGNING_FAILED: "Message signing failed",
|
|
484
|
+
SIGNING_REJECTED: "Message signing rejected",
|
|
485
|
+
TRANSACTION_FAILED: "Transaction failed",
|
|
486
|
+
TRANSACTION_REJECTED: "Transaction rejected",
|
|
487
|
+
NETWORK_ERROR: "Network error occurred",
|
|
488
|
+
UNSUPPORTED_WALLET: "Unsupported wallet type",
|
|
489
|
+
INVALID_ADDRESS: "Invalid wallet address"
|
|
490
|
+
};
|
|
491
|
+
var CONNECTION_MESSAGES = {
|
|
492
|
+
CONNECTING: "Connecting to wallet...",
|
|
493
|
+
SIGNING: "Please sign the message to verify your account",
|
|
494
|
+
SUCCESS: "Successfully connected",
|
|
495
|
+
ERROR: "Connection failed",
|
|
496
|
+
CONNECTED_NOT_SIGNED: "Connected but signature rejected"
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// lib/crypto.ts
|
|
500
|
+
function generateNonce() {
|
|
501
|
+
if (typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues) {
|
|
502
|
+
const array = new Uint32Array(1);
|
|
503
|
+
window.crypto.getRandomValues(array);
|
|
504
|
+
return array[0].toString(36) + Date.now().toString(36);
|
|
505
|
+
}
|
|
506
|
+
return Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// lib/config.ts
|
|
510
|
+
var defaultConfig = {
|
|
511
|
+
rpcUrl: {
|
|
512
|
+
testnet: "https://rpc-testnet.supra.com",
|
|
513
|
+
mainnet: "https://rpc-mainnet.supra.com"
|
|
514
|
+
},
|
|
515
|
+
chainId: process.env.NEXT_PUBLIC_SUPRA_CHAIN_ID || DEFAULT_CHAIN_IDS.TESTNET,
|
|
516
|
+
enableLogging: process.env.NODE_ENV === "development",
|
|
517
|
+
balancePollInterval: 3e4,
|
|
518
|
+
walletDetectionTimeout: 3e3
|
|
519
|
+
};
|
|
520
|
+
var config = __spreadValues({}, defaultConfig);
|
|
521
|
+
function initConfig(userConfig) {
|
|
522
|
+
var _a, _b, _c;
|
|
523
|
+
config = {
|
|
524
|
+
rpcUrl: {
|
|
525
|
+
testnet: ((_a = userConfig == null ? void 0 : userConfig.rpcUrl) == null ? void 0 : _a.testnet) || defaultConfig.rpcUrl.testnet,
|
|
526
|
+
mainnet: ((_b = userConfig == null ? void 0 : userConfig.rpcUrl) == null ? void 0 : _b.mainnet) || defaultConfig.rpcUrl.mainnet
|
|
527
|
+
},
|
|
528
|
+
chainId: (userConfig == null ? void 0 : userConfig.chainId) || defaultConfig.chainId,
|
|
529
|
+
enableLogging: (_c = userConfig == null ? void 0 : userConfig.enableLogging) != null ? _c : defaultConfig.enableLogging,
|
|
530
|
+
balancePollInterval: (userConfig == null ? void 0 : userConfig.balancePollInterval) || defaultConfig.balancePollInterval,
|
|
531
|
+
walletDetectionTimeout: (userConfig == null ? void 0 : userConfig.walletDetectionTimeout) || defaultConfig.walletDetectionTimeout
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function getRpcUrl(chainId) {
|
|
535
|
+
const targetChainId = chainId || config.chainId;
|
|
536
|
+
const isMainnet = targetChainId === DEFAULT_CHAIN_IDS.MAINNET;
|
|
537
|
+
return isMainnet ? config.rpcUrl.mainnet : config.rpcUrl.testnet;
|
|
538
|
+
}
|
|
539
|
+
function getChainId() {
|
|
540
|
+
return config.chainId;
|
|
541
|
+
}
|
|
542
|
+
initConfig();
|
|
543
|
+
|
|
544
|
+
// hooks/useSupraMultiWallet.ts
|
|
545
|
+
var WALLET_CONFIGS = {
|
|
546
|
+
starkey: {
|
|
547
|
+
capabilities: {
|
|
548
|
+
signMessage: true,
|
|
549
|
+
accountSwitching: true,
|
|
550
|
+
networkSwitching: true,
|
|
551
|
+
rawTransactions: true,
|
|
552
|
+
eventListeners: true,
|
|
553
|
+
tokenRevalidation: true
|
|
554
|
+
},
|
|
555
|
+
provider: () => {
|
|
556
|
+
var _a;
|
|
557
|
+
return typeof window !== "undefined" && ((_a = window == null ? void 0 : window.starkey) == null ? void 0 : _a.supra);
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
ribbit: {
|
|
561
|
+
capabilities: {
|
|
562
|
+
signMessage: true,
|
|
563
|
+
accountSwitching: false,
|
|
564
|
+
// Ribbit doesn't support account switching
|
|
565
|
+
networkSwitching: false,
|
|
566
|
+
// Ribbit network switching happens in-app
|
|
567
|
+
rawTransactions: true,
|
|
568
|
+
eventListeners: false,
|
|
569
|
+
tokenRevalidation: false
|
|
570
|
+
// Ribbit doesn't support token revalidation
|
|
571
|
+
},
|
|
572
|
+
provider: () => (0, import_ribbit_wallet_connect.initSdk)()
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
var WALLET_EVENTS = {
|
|
576
|
+
CONNECTED: "wallet-connected",
|
|
577
|
+
PRESIGNED_STATE: "presigned-state",
|
|
578
|
+
POSTSIGNED_STATE: "postsigned-state",
|
|
579
|
+
ERROR: "wallet-error"
|
|
580
|
+
};
|
|
581
|
+
var setStoredWalletType = (walletType) => {
|
|
582
|
+
setStorageItem(STORAGE_KEYS.SELECTED_WALLET, walletType);
|
|
583
|
+
};
|
|
584
|
+
var getStoredWalletType = () => {
|
|
585
|
+
const stored = getStorageItem(STORAGE_KEYS.SELECTED_WALLET);
|
|
586
|
+
if (stored && ["starkey", "ribbit"].includes(stored)) {
|
|
587
|
+
return stored;
|
|
588
|
+
}
|
|
589
|
+
return "starkey";
|
|
590
|
+
};
|
|
591
|
+
var clearStoredWalletType = () => {
|
|
592
|
+
removeStorageItem(STORAGE_KEYS.SELECTED_WALLET);
|
|
593
|
+
};
|
|
594
|
+
var useSupraMultiWallet = () => {
|
|
595
|
+
const router = (0, import_navigation.useRouter)();
|
|
596
|
+
const [selectedWallet, setSelectedWallet] = (0, import_react.useState)("starkey");
|
|
597
|
+
const [walletCapabilities, setWalletCapabilities] = (0, import_react.useState)(
|
|
598
|
+
WALLET_CONFIGS["starkey"].capabilities
|
|
599
|
+
);
|
|
600
|
+
(0, import_react.useEffect)(() => {
|
|
601
|
+
const stored = getStoredWalletType();
|
|
602
|
+
if (stored !== "starkey") {
|
|
603
|
+
setSelectedWallet(stored);
|
|
604
|
+
setWalletCapabilities(WALLET_CONFIGS[stored].capabilities);
|
|
605
|
+
}
|
|
606
|
+
}, []);
|
|
607
|
+
const [supraProvider, setSupraProvider] = (0, import_react.useState)(
|
|
608
|
+
WALLET_CONFIGS.starkey.provider()
|
|
609
|
+
);
|
|
610
|
+
const [ribbitProvider, setRibbitProvider] = (0, import_react.useState)(
|
|
611
|
+
WALLET_CONFIGS.ribbit.provider()
|
|
612
|
+
);
|
|
613
|
+
const [isExtensionInstalled, setIsExtensionInstalled] = (0, import_react.useState)(false);
|
|
614
|
+
const [accounts, setAccounts] = (0, import_react.useState)([]);
|
|
615
|
+
const [networkData, setNetworkData] = (0, import_react.useState)();
|
|
616
|
+
const [balance, setBalance] = (0, import_react.useState)("");
|
|
617
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
618
|
+
const [justRequestedRelative, setJustRequestedRelative] = (0, import_react.useState)(false);
|
|
619
|
+
const [transactions, setTransactions] = (0, import_react.useState)([]);
|
|
620
|
+
const [selectedChainId, setSelectedChainId] = (0, import_react.useState)("");
|
|
621
|
+
const addTransactions = (hash) => {
|
|
622
|
+
setTransactions((prev) => [{ hash }, ...prev]);
|
|
623
|
+
};
|
|
624
|
+
const getCurrentProvider = () => {
|
|
625
|
+
switch (selectedWallet) {
|
|
626
|
+
case "starkey": {
|
|
627
|
+
return supraProvider;
|
|
628
|
+
}
|
|
629
|
+
case "ribbit": {
|
|
630
|
+
return ribbitProvider;
|
|
631
|
+
}
|
|
632
|
+
default: {
|
|
633
|
+
return supraProvider;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
const checkExtensionInstalled = (0, import_react.useCallback)(async () => {
|
|
638
|
+
switch (selectedWallet) {
|
|
639
|
+
case "starkey": {
|
|
640
|
+
const provider = WALLET_CONFIGS.starkey.provider();
|
|
641
|
+
setSupraProvider(provider);
|
|
642
|
+
setIsExtensionInstalled(!!provider);
|
|
643
|
+
return !!provider;
|
|
644
|
+
}
|
|
645
|
+
case "ribbit": {
|
|
646
|
+
const provider = WALLET_CONFIGS.ribbit.provider();
|
|
647
|
+
if (!provider) {
|
|
648
|
+
setRibbitProvider(null);
|
|
649
|
+
setIsExtensionInstalled(false);
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
try {
|
|
653
|
+
setRibbitProvider(provider);
|
|
654
|
+
setIsExtensionInstalled(true);
|
|
655
|
+
return true;
|
|
656
|
+
} catch (error) {
|
|
657
|
+
logger.error("Error checking Ribbit wallet readiness", error);
|
|
658
|
+
setRibbitProvider(null);
|
|
659
|
+
setIsExtensionInstalled(false);
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
default: {
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}, [selectedWallet]);
|
|
668
|
+
const updateAccounts = (0, import_react.useCallback)(async () => {
|
|
669
|
+
const provider = getCurrentProvider();
|
|
670
|
+
if (!provider) return;
|
|
671
|
+
try {
|
|
672
|
+
switch (selectedWallet) {
|
|
673
|
+
case "starkey": {
|
|
674
|
+
const responseAcc = await provider.account();
|
|
675
|
+
const newAccounts = responseAcc.length > 0 ? responseAcc : [];
|
|
676
|
+
setAccounts(newAccounts);
|
|
677
|
+
if (responseAcc.length > 0) {
|
|
678
|
+
setStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS, responseAcc[0]);
|
|
679
|
+
}
|
|
680
|
+
if (newAccounts.length > 0) {
|
|
681
|
+
const balance2 = await provider.balance();
|
|
682
|
+
if (balance2) {
|
|
683
|
+
setBalance(`${balance2.formattedBalance} ${balance2.displayUnit}`);
|
|
684
|
+
}
|
|
685
|
+
const networkData2 = await provider.getChainId();
|
|
686
|
+
setNetworkData(networkData2 || {});
|
|
687
|
+
}
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
case "ribbit": {
|
|
691
|
+
const wallet = provider.getWalletInfo();
|
|
692
|
+
if (wallet == null ? void 0 : wallet.connected) {
|
|
693
|
+
setAccounts([wallet.walletAddress]);
|
|
694
|
+
const walletBalanceRequest = {
|
|
695
|
+
chainId: parseInt(getChainId()),
|
|
696
|
+
resourceType: "0x1::supra_coin::SupraCoin",
|
|
697
|
+
decimals: 8
|
|
698
|
+
};
|
|
699
|
+
const balanceStr = await provider.getWalletBalance(walletBalanceRequest);
|
|
700
|
+
logger.debug("Ribbit balance response", { balance: balanceStr });
|
|
701
|
+
setBalance(`${(balanceStr == null ? void 0 : balanceStr.balance) || 0} SUPRA`);
|
|
702
|
+
} else {
|
|
703
|
+
setAccounts([]);
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
default: {
|
|
708
|
+
setAccounts([]);
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
} catch (error) {
|
|
713
|
+
logger.error("Failed to update accounts", error, { walletType: selectedWallet });
|
|
714
|
+
setAccounts([]);
|
|
715
|
+
switch (selectedWallet) {
|
|
716
|
+
case "starkey": {
|
|
717
|
+
removeStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS);
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
case "ribbit": {
|
|
721
|
+
break;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}, [selectedWallet]);
|
|
726
|
+
(0, import_react.useEffect)(() => {
|
|
727
|
+
let mounted = true;
|
|
728
|
+
const initProvider = async () => {
|
|
729
|
+
const isInstalled = await checkExtensionInstalled();
|
|
730
|
+
if (mounted && isInstalled) {
|
|
731
|
+
updateAccounts();
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
initProvider();
|
|
735
|
+
return () => {
|
|
736
|
+
mounted = false;
|
|
737
|
+
};
|
|
738
|
+
}, [selectedWallet, checkExtensionInstalled, updateAccounts]);
|
|
739
|
+
(0, import_react.useEffect)(() => {
|
|
740
|
+
const checkExtension = async () => {
|
|
741
|
+
return await checkExtensionInstalled();
|
|
742
|
+
};
|
|
743
|
+
checkExtension().then((isInstalled) => {
|
|
744
|
+
if (isInstalled && selectedWallet === "ribbit") {
|
|
745
|
+
updateAccounts();
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
const intv = setInterval(async () => {
|
|
749
|
+
const isInstalled = await checkExtension();
|
|
750
|
+
if (isInstalled) {
|
|
751
|
+
clearInterval(intv);
|
|
752
|
+
if (selectedWallet === "ribbit") {
|
|
753
|
+
updateAccounts();
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}, 1e3);
|
|
757
|
+
setTimeout(() => {
|
|
758
|
+
clearInterval(intv);
|
|
759
|
+
}, TIMEOUTS.WALLET_DETECTION_POLL);
|
|
760
|
+
return () => clearInterval(intv);
|
|
761
|
+
}, [selectedWallet, updateAccounts, checkExtensionInstalled]);
|
|
762
|
+
const checkIsExtensionInstalled = (0, import_react.useCallback)(() => {
|
|
763
|
+
const intervalId = setInterval(async () => {
|
|
764
|
+
const isInstalled = await checkExtensionInstalled();
|
|
765
|
+
if (isInstalled) {
|
|
766
|
+
clearInterval(intervalId);
|
|
767
|
+
updateAccounts();
|
|
768
|
+
}
|
|
769
|
+
}, 500);
|
|
770
|
+
setTimeout(() => clearInterval(intervalId), TIMEOUTS.WALLET_DETECTION_POLL);
|
|
771
|
+
}, [updateAccounts, checkExtensionInstalled]);
|
|
772
|
+
const updateBalance = (0, import_react.useCallback)(async () => {
|
|
773
|
+
const provider = getCurrentProvider();
|
|
774
|
+
if (!provider || !accounts.length) {
|
|
775
|
+
setBalance("");
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
try {
|
|
779
|
+
switch (selectedWallet) {
|
|
780
|
+
case "starkey": {
|
|
781
|
+
const balance2 = await provider.balance();
|
|
782
|
+
if (balance2) {
|
|
783
|
+
setBalance(`${balance2.formattedBalance} ${balance2.displayUnit}`);
|
|
784
|
+
}
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
case "ribbit": {
|
|
788
|
+
const walletBalanceRequest = {
|
|
789
|
+
chainId: parseInt(getChainId()),
|
|
790
|
+
resourceType: "0x1::supra_coin::SupraCoin",
|
|
791
|
+
decimals: 8
|
|
792
|
+
};
|
|
793
|
+
const balanceStr = await provider.getWalletBalance(
|
|
794
|
+
walletBalanceRequest
|
|
795
|
+
);
|
|
796
|
+
logger.debug("Ribbit balance response", { balance: balanceStr });
|
|
797
|
+
setBalance(`${(balanceStr == null ? void 0 : balanceStr.balance) || 0} SUPRA`);
|
|
798
|
+
break;
|
|
799
|
+
}
|
|
800
|
+
default: {
|
|
801
|
+
setBalance("");
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
} catch (error) {
|
|
806
|
+
logger.error("Failed to update balance", error, { walletType: selectedWallet });
|
|
807
|
+
setBalance("");
|
|
808
|
+
}
|
|
809
|
+
}, [selectedWallet, accounts]);
|
|
810
|
+
const getNetworkData = (0, import_react.useCallback)(async () => {
|
|
811
|
+
const provider = getCurrentProvider();
|
|
812
|
+
if (!provider) return {};
|
|
813
|
+
try {
|
|
814
|
+
switch (selectedWallet) {
|
|
815
|
+
case "starkey": {
|
|
816
|
+
const data = await provider.getChainId();
|
|
817
|
+
setNetworkData(data || {});
|
|
818
|
+
return data || {};
|
|
819
|
+
}
|
|
820
|
+
case "ribbit": {
|
|
821
|
+
const chainId = parseInt(getChainId());
|
|
822
|
+
const mockNetworkData = { chainId: chainId.toString() };
|
|
823
|
+
setNetworkData(mockNetworkData);
|
|
824
|
+
return mockNetworkData;
|
|
825
|
+
}
|
|
826
|
+
default: {
|
|
827
|
+
setNetworkData({});
|
|
828
|
+
return {};
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
} catch (error) {
|
|
832
|
+
logger.error("Failed to get network data", error, { walletType: selectedWallet });
|
|
833
|
+
setNetworkData({});
|
|
834
|
+
return {};
|
|
835
|
+
}
|
|
836
|
+
}, [selectedWallet]);
|
|
837
|
+
const connectWallet = async (walletType) => {
|
|
838
|
+
if (walletType) {
|
|
839
|
+
updateSelectedWallet(walletType);
|
|
840
|
+
}
|
|
841
|
+
const provider = walletType ? WALLET_CONFIGS[walletType].provider() : getCurrentProvider();
|
|
842
|
+
if (!provider) {
|
|
843
|
+
const error = new WalletNotInstalledError(walletType || selectedWallet);
|
|
844
|
+
logger.warn("Wallet not installed", { walletType: walletType || selectedWallet });
|
|
845
|
+
import_sonner.toast.error(ERROR_MESSAGES.WALLET_NOT_INSTALLED, {
|
|
846
|
+
description: `Please install the ${walletType || selectedWallet} extension`
|
|
847
|
+
});
|
|
848
|
+
return false;
|
|
849
|
+
}
|
|
850
|
+
setLoading(true);
|
|
851
|
+
try {
|
|
852
|
+
switch (walletType || selectedWallet) {
|
|
853
|
+
case "starkey": {
|
|
854
|
+
await provider.connect();
|
|
855
|
+
logger.info("Starkey wallet connection approved");
|
|
856
|
+
await updateAccounts();
|
|
857
|
+
const responseAcc = await provider.account();
|
|
858
|
+
if (responseAcc.length === 0) {
|
|
859
|
+
throw new WalletConnectionError(ERROR_MESSAGES.NO_ACCOUNT_FOUND);
|
|
860
|
+
}
|
|
861
|
+
if (responseAcc.length) {
|
|
862
|
+
setAccounts(responseAcc);
|
|
863
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
864
|
+
setStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS, responseAcc[0]);
|
|
865
|
+
window.dispatchEvent(
|
|
866
|
+
new CustomEvent(WALLET_EVENTS.PRESIGNED_STATE, {
|
|
867
|
+
detail: {
|
|
868
|
+
timestamp: Date.now(),
|
|
869
|
+
account: responseAcc[0]
|
|
870
|
+
}
|
|
871
|
+
})
|
|
872
|
+
);
|
|
873
|
+
window.dispatchEvent(
|
|
874
|
+
new CustomEvent(WALLET_EVENTS.CONNECTED, {
|
|
875
|
+
detail: {
|
|
876
|
+
timestamp: Date.now(),
|
|
877
|
+
account: responseAcc[0],
|
|
878
|
+
wallet: "starkey"
|
|
879
|
+
}
|
|
880
|
+
})
|
|
881
|
+
);
|
|
882
|
+
try {
|
|
883
|
+
const message = "To verify your account, please sign this message.";
|
|
884
|
+
const nonce = generateNonce();
|
|
885
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
886
|
+
logger.debug("Signature request initiated", { account: responseAcc[0] });
|
|
887
|
+
const signatureResponse = await provider.signMessage({
|
|
888
|
+
message: hexMessage,
|
|
889
|
+
nonce
|
|
890
|
+
});
|
|
891
|
+
if (signatureResponse) {
|
|
892
|
+
logger.info("Signature approved", { account: responseAcc[0] });
|
|
893
|
+
window.dispatchEvent(
|
|
894
|
+
new CustomEvent(WALLET_EVENTS.POSTSIGNED_STATE, {
|
|
895
|
+
detail: {
|
|
896
|
+
timestamp: Date.now(),
|
|
897
|
+
account: responseAcc[0]
|
|
898
|
+
}
|
|
899
|
+
})
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
} catch (signError) {
|
|
903
|
+
const error = new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, signError);
|
|
904
|
+
logger.error("Signing failed", error, { account: responseAcc[0] });
|
|
905
|
+
window.dispatchEvent(
|
|
906
|
+
new CustomEvent(WALLET_EVENTS.ERROR, {
|
|
907
|
+
detail: {
|
|
908
|
+
timestamp: Date.now(),
|
|
909
|
+
error
|
|
910
|
+
}
|
|
911
|
+
})
|
|
912
|
+
);
|
|
913
|
+
throw error;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
case "ribbit": {
|
|
919
|
+
const dappMetadata = {
|
|
920
|
+
name: "multiwallet",
|
|
921
|
+
description: "NFT Marketplace and Lootbox Platform",
|
|
922
|
+
logo: window.location.origin + "/favicon.ico",
|
|
923
|
+
url: window.location.origin
|
|
924
|
+
};
|
|
925
|
+
const response = await provider.connectToWallet(
|
|
926
|
+
dappMetadata
|
|
927
|
+
);
|
|
928
|
+
if (response == null ? void 0 : response.connected) {
|
|
929
|
+
logger.info("Ribbit wallet connection approved");
|
|
930
|
+
}
|
|
931
|
+
if (response.walletAddress == null) {
|
|
932
|
+
throw new WalletConnectionError(ERROR_MESSAGES.NO_ACCOUNT_FOUND);
|
|
933
|
+
}
|
|
934
|
+
if (response == null ? void 0 : response.connected) {
|
|
935
|
+
await updateAccounts();
|
|
936
|
+
if (response.walletAddress) {
|
|
937
|
+
setAccounts([response.walletAddress]);
|
|
938
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
939
|
+
window.dispatchEvent(
|
|
940
|
+
new CustomEvent(WALLET_EVENTS.PRESIGNED_STATE, {
|
|
941
|
+
detail: {
|
|
942
|
+
timestamp: Date.now(),
|
|
943
|
+
account: response.walletAddress
|
|
944
|
+
}
|
|
945
|
+
})
|
|
946
|
+
);
|
|
947
|
+
window.dispatchEvent(
|
|
948
|
+
new CustomEvent(WALLET_EVENTS.CONNECTED, {
|
|
949
|
+
detail: {
|
|
950
|
+
timestamp: Date.now(),
|
|
951
|
+
account: response.walletAddress,
|
|
952
|
+
wallet: "ribbit"
|
|
953
|
+
}
|
|
954
|
+
})
|
|
955
|
+
);
|
|
956
|
+
try {
|
|
957
|
+
const message = "To verify your account, please sign this message.";
|
|
958
|
+
const nonce = generateNonce();
|
|
959
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
960
|
+
logger.debug("Signature request initiated", { account: response.walletAddress });
|
|
961
|
+
const signatureResponse = await provider.signMessage({
|
|
962
|
+
message: hexMessage,
|
|
963
|
+
nonce: parseInt(nonce),
|
|
964
|
+
chainId: parseInt(getChainId())
|
|
965
|
+
});
|
|
966
|
+
if (signatureResponse && signatureResponse.approved) {
|
|
967
|
+
logger.info("Signature approved", { account: response.walletAddress });
|
|
968
|
+
window.dispatchEvent(
|
|
969
|
+
new CustomEvent(WALLET_EVENTS.POSTSIGNED_STATE, {
|
|
970
|
+
detail: {
|
|
971
|
+
timestamp: Date.now(),
|
|
972
|
+
account: response.walletAddress
|
|
973
|
+
}
|
|
974
|
+
})
|
|
975
|
+
);
|
|
976
|
+
} else {
|
|
977
|
+
throw new SignMessageError(signatureResponse.error || ERROR_MESSAGES.SIGNING_REJECTED);
|
|
978
|
+
}
|
|
979
|
+
} catch (signError) {
|
|
980
|
+
const error = new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, signError);
|
|
981
|
+
logger.error("Signing failed", error, { account: response.walletAddress });
|
|
982
|
+
window.dispatchEvent(
|
|
983
|
+
new CustomEvent(WALLET_EVENTS.ERROR, {
|
|
984
|
+
detail: {
|
|
985
|
+
timestamp: Date.now(),
|
|
986
|
+
error
|
|
987
|
+
}
|
|
988
|
+
})
|
|
989
|
+
);
|
|
990
|
+
throw error;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
} else {
|
|
994
|
+
throw new WalletConnectionError(ERROR_MESSAGES.CONNECTION_REJECTED);
|
|
995
|
+
}
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
default: {
|
|
999
|
+
throw new WalletConnectionError(
|
|
1000
|
+
`${ERROR_MESSAGES.UNSUPPORTED_WALLET}: ${walletType || selectedWallet}`
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return true;
|
|
1005
|
+
} catch (error) {
|
|
1006
|
+
const walletError = error instanceof WalletConnectionError ? error : new WalletConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
|
|
1007
|
+
logger.error("Wallet connection failed", walletError, {
|
|
1008
|
+
walletType: walletType || selectedWallet
|
|
1009
|
+
});
|
|
1010
|
+
window.dispatchEvent(
|
|
1011
|
+
new CustomEvent(WALLET_EVENTS.ERROR, {
|
|
1012
|
+
detail: {
|
|
1013
|
+
timestamp: Date.now(),
|
|
1014
|
+
error: walletError
|
|
1015
|
+
}
|
|
1016
|
+
})
|
|
1017
|
+
);
|
|
1018
|
+
return false;
|
|
1019
|
+
} finally {
|
|
1020
|
+
setLoading(false);
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
const disconnectWallet = async () => {
|
|
1024
|
+
const provider = getCurrentProvider();
|
|
1025
|
+
if (!provider) return;
|
|
1026
|
+
try {
|
|
1027
|
+
switch (selectedWallet) {
|
|
1028
|
+
case "starkey": {
|
|
1029
|
+
await provider.disconnect();
|
|
1030
|
+
break;
|
|
1031
|
+
}
|
|
1032
|
+
case "ribbit": {
|
|
1033
|
+
await provider.disconnect();
|
|
1034
|
+
break;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
resetWalletData();
|
|
1038
|
+
clearStoredWalletType();
|
|
1039
|
+
router.push("/");
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
logger.error("Wallet disconnect failed", error, { walletType: selectedWallet });
|
|
1042
|
+
resetWalletData();
|
|
1043
|
+
clearStoredWalletType();
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
const resetWalletData = () => {
|
|
1047
|
+
setAccounts([]);
|
|
1048
|
+
setBalance("");
|
|
1049
|
+
setNetworkData({});
|
|
1050
|
+
switch (selectedWallet) {
|
|
1051
|
+
case "starkey": {
|
|
1052
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1053
|
+
removeStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS);
|
|
1054
|
+
break;
|
|
1055
|
+
}
|
|
1056
|
+
case "ribbit": {
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
const getSequenceNumber = async (address) => {
|
|
1062
|
+
const rpcUrl = getRpcUrl();
|
|
1063
|
+
const data = await fetch(`${rpcUrl}/rpc/v1/accounts/${address}`);
|
|
1064
|
+
if (!data.ok) {
|
|
1065
|
+
throw new NetworkError(`Failed to fetch sequence number for ${address}`);
|
|
1066
|
+
}
|
|
1067
|
+
const accountData = await data.json();
|
|
1068
|
+
return accountData.sequence_number;
|
|
1069
|
+
};
|
|
1070
|
+
const sendRawTransaction = async (moduleAddress, moduleName, functionName, params, runTimeParams = [], txExpiryTime = Math.ceil(Date.now() / 1e3) + 3e3) => {
|
|
1071
|
+
const provider = getCurrentProvider();
|
|
1072
|
+
if (!provider || !accounts.length || !moduleAddress || !moduleName || !functionName)
|
|
1073
|
+
return;
|
|
1074
|
+
try {
|
|
1075
|
+
switch (selectedWallet) {
|
|
1076
|
+
case "starkey": {
|
|
1077
|
+
if (!walletCapabilities.rawTransactions) {
|
|
1078
|
+
throw new TransactionError("Raw transactions not supported by current wallet");
|
|
1079
|
+
}
|
|
1080
|
+
let networkData2 = await getNetworkData();
|
|
1081
|
+
const currentChainId = getChainId();
|
|
1082
|
+
if (networkData2.chainId !== currentChainId) {
|
|
1083
|
+
setSelectedChainId(currentChainId);
|
|
1084
|
+
await provider.changeNetwork({
|
|
1085
|
+
chainId: currentChainId
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
const rawTxPayload = [
|
|
1089
|
+
accounts[0],
|
|
1090
|
+
0,
|
|
1091
|
+
// sequence number
|
|
1092
|
+
moduleAddress,
|
|
1093
|
+
moduleName,
|
|
1094
|
+
functionName,
|
|
1095
|
+
runTimeParams,
|
|
1096
|
+
params,
|
|
1097
|
+
{}
|
|
1098
|
+
];
|
|
1099
|
+
const data = await provider.createRawTransactionData(rawTxPayload);
|
|
1100
|
+
const txHash = await provider.sendTransaction({
|
|
1101
|
+
data,
|
|
1102
|
+
from: accounts[0],
|
|
1103
|
+
to: moduleAddress,
|
|
1104
|
+
chainId: currentChainId,
|
|
1105
|
+
value: ""
|
|
1106
|
+
});
|
|
1107
|
+
addTransactions(txHash || "failed");
|
|
1108
|
+
logger.info("Transaction sent successfully", { txHash, walletType: "starkey" });
|
|
1109
|
+
return txHash;
|
|
1110
|
+
}
|
|
1111
|
+
case "ribbit": {
|
|
1112
|
+
if (!walletCapabilities.rawTransactions) {
|
|
1113
|
+
throw new TransactionError("Raw transactions not supported by current wallet");
|
|
1114
|
+
}
|
|
1115
|
+
const currentChainId = getChainId();
|
|
1116
|
+
let chainId = import_ribbit_wallet_connect.SupraChainId.TESTNET;
|
|
1117
|
+
if (currentChainId === DEFAULT_CHAIN_IDS.TESTNET) {
|
|
1118
|
+
chainId = import_ribbit_wallet_connect.SupraChainId.TESTNET;
|
|
1119
|
+
} else if (currentChainId === DEFAULT_CHAIN_IDS.MAINNET) {
|
|
1120
|
+
chainId = import_ribbit_wallet_connect.SupraChainId.MAINNET;
|
|
1121
|
+
}
|
|
1122
|
+
const rawTxnRequest = {
|
|
1123
|
+
sender: accounts[0],
|
|
1124
|
+
// Use actual sender address
|
|
1125
|
+
moduleAddress,
|
|
1126
|
+
// Use provided module address
|
|
1127
|
+
moduleName,
|
|
1128
|
+
// Use provided module name
|
|
1129
|
+
functionName,
|
|
1130
|
+
// Use provided function name
|
|
1131
|
+
typeArgs: runTimeParams,
|
|
1132
|
+
// Use converted runtime parameters
|
|
1133
|
+
args: params || [],
|
|
1134
|
+
// Use provided parameters
|
|
1135
|
+
chainId
|
|
1136
|
+
};
|
|
1137
|
+
const rawTxnBase64 = await provider.createRawTransactionBuffer(rawTxnRequest);
|
|
1138
|
+
const response = await provider.signAndSendRawTransaction({
|
|
1139
|
+
rawTxn: rawTxnBase64,
|
|
1140
|
+
chainId,
|
|
1141
|
+
meta: {
|
|
1142
|
+
description: `Call ${moduleName}::${functionName}`
|
|
1143
|
+
// Dynamic description
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
if (response.approved) {
|
|
1147
|
+
const txHash = response.txHash || response.result || "success";
|
|
1148
|
+
addTransactions(txHash);
|
|
1149
|
+
logger.info("Transaction sent successfully", { txHash, walletType: "ribbit" });
|
|
1150
|
+
return txHash;
|
|
1151
|
+
} else {
|
|
1152
|
+
throw new TransactionError(response.error || ERROR_MESSAGES.TRANSACTION_REJECTED);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
default: {
|
|
1156
|
+
throw new TransactionError(
|
|
1157
|
+
`Raw transactions not supported for wallet: ${selectedWallet}`
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
const txError = error instanceof TransactionError ? error : new TransactionError(ERROR_MESSAGES.TRANSACTION_FAILED, void 0, error);
|
|
1163
|
+
logger.error("Transaction failed", txError, {
|
|
1164
|
+
walletType: selectedWallet,
|
|
1165
|
+
moduleAddress,
|
|
1166
|
+
moduleName,
|
|
1167
|
+
functionName
|
|
1168
|
+
});
|
|
1169
|
+
throw txError;
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
const signMessage = async (message, nonce, account, forceSign = false) => {
|
|
1173
|
+
const provider = getCurrentProvider();
|
|
1174
|
+
if (!provider) return;
|
|
1175
|
+
const secureNonce = nonce || generateNonce();
|
|
1176
|
+
switch (selectedWallet) {
|
|
1177
|
+
case "starkey": {
|
|
1178
|
+
if (!walletCapabilities.signMessage) {
|
|
1179
|
+
throw new SignMessageError("Message signing not supported by current wallet");
|
|
1180
|
+
}
|
|
1181
|
+
if (!accounts.length && !account) return;
|
|
1182
|
+
if (!accounts.length && account) {
|
|
1183
|
+
accounts[0] = account;
|
|
1184
|
+
}
|
|
1185
|
+
if (getStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET) === "true" && !forceSign) {
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "true");
|
|
1189
|
+
try {
|
|
1190
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
1191
|
+
const response = await provider.signMessage({
|
|
1192
|
+
message: hexMessage,
|
|
1193
|
+
nonce: secureNonce
|
|
1194
|
+
});
|
|
1195
|
+
const { publicKey, signature } = response;
|
|
1196
|
+
const verified = import_tweetnacl.default.sign.detached.verify(
|
|
1197
|
+
new TextEncoder().encode(message),
|
|
1198
|
+
Uint8Array.from(Buffer.from(signature.slice(2), "hex")),
|
|
1199
|
+
Uint8Array.from(Buffer.from(publicKey.slice(2), "hex"))
|
|
1200
|
+
);
|
|
1201
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1202
|
+
logger.info("Message signed successfully", { walletType: "starkey" });
|
|
1203
|
+
return __spreadProps(__spreadValues({}, response), { verified });
|
|
1204
|
+
} catch (error) {
|
|
1205
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1206
|
+
throw new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, error);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
case "ribbit": {
|
|
1210
|
+
if (!walletCapabilities.signMessage) {
|
|
1211
|
+
throw new SignMessageError("Message signing not supported by current wallet");
|
|
1212
|
+
}
|
|
1213
|
+
if (!accounts.length && !account) return;
|
|
1214
|
+
if (!accounts.length && account) {
|
|
1215
|
+
accounts[0] = account;
|
|
1216
|
+
}
|
|
1217
|
+
if (getStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET) === "true" && !forceSign) {
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "true");
|
|
1221
|
+
try {
|
|
1222
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
1223
|
+
const response = await provider.signMessage({
|
|
1224
|
+
message: hexMessage,
|
|
1225
|
+
nonce: parseInt(secureNonce),
|
|
1226
|
+
chainId: parseInt(getChainId())
|
|
1227
|
+
});
|
|
1228
|
+
if (response.approved && response.publicKey && response.signature) {
|
|
1229
|
+
const { publicKey, signature } = response;
|
|
1230
|
+
const verified = import_tweetnacl.default.sign.detached.verify(
|
|
1231
|
+
new TextEncoder().encode(message),
|
|
1232
|
+
Uint8Array.from(Buffer.from(signature.slice(2), "hex")),
|
|
1233
|
+
Uint8Array.from(Buffer.from(publicKey.slice(2), "hex"))
|
|
1234
|
+
);
|
|
1235
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1236
|
+
logger.info("Message signed successfully", { walletType: "ribbit" });
|
|
1237
|
+
return __spreadProps(__spreadValues({}, response), { verified });
|
|
1238
|
+
} else {
|
|
1239
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1240
|
+
throw new SignMessageError(response.error || ERROR_MESSAGES.SIGNING_REJECTED);
|
|
1241
|
+
}
|
|
1242
|
+
} catch (error) {
|
|
1243
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
1244
|
+
throw new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, error);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
default: {
|
|
1248
|
+
throw new SignMessageError(
|
|
1249
|
+
`Message signing not supported for wallet: ${selectedWallet}`
|
|
1250
|
+
);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
(0, import_react.useEffect)(() => {
|
|
1255
|
+
if (selectedWallet === "starkey" && walletCapabilities.eventListeners) {
|
|
1256
|
+
const handleExtensionEvents = (event) => {
|
|
1257
|
+
var _a, _b, _c;
|
|
1258
|
+
if ((_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("starkey-")) {
|
|
1259
|
+
switch ((_c = event == null ? void 0 : event.data) == null ? void 0 : _c.name) {
|
|
1260
|
+
case "starkey-extension-installed": {
|
|
1261
|
+
checkIsExtensionInstalled();
|
|
1262
|
+
break;
|
|
1263
|
+
}
|
|
1264
|
+
case "starkey-wallet-updated": {
|
|
1265
|
+
(async () => {
|
|
1266
|
+
const responseAcc = await supraProvider.account();
|
|
1267
|
+
if (responseAcc.length) {
|
|
1268
|
+
setAccounts(responseAcc);
|
|
1269
|
+
window.dispatchEvent(
|
|
1270
|
+
new CustomEvent(WALLET_EVENTS.CONNECTED, {
|
|
1271
|
+
detail: {
|
|
1272
|
+
timestamp: Date.now(),
|
|
1273
|
+
account: responseAcc[0]
|
|
1274
|
+
}
|
|
1275
|
+
})
|
|
1276
|
+
);
|
|
1277
|
+
await updateBalance();
|
|
1278
|
+
await getNetworkData();
|
|
1279
|
+
} else {
|
|
1280
|
+
logger.debug("Starkey wallet updated: No accounts found - Resetting");
|
|
1281
|
+
resetWalletData();
|
|
1282
|
+
}
|
|
1283
|
+
setLoading(false);
|
|
1284
|
+
})();
|
|
1285
|
+
break;
|
|
1286
|
+
}
|
|
1287
|
+
case "starkey-wallet-disconnected": {
|
|
1288
|
+
resetWalletData();
|
|
1289
|
+
router.push("/");
|
|
1290
|
+
setLoading(false);
|
|
1291
|
+
break;
|
|
1292
|
+
}
|
|
1293
|
+
case "starkey-window-removed": {
|
|
1294
|
+
setLoading(false);
|
|
1295
|
+
break;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
checkIsExtensionInstalled();
|
|
1301
|
+
window.addEventListener("message", handleExtensionEvents);
|
|
1302
|
+
return () => window.removeEventListener("message", handleExtensionEvents);
|
|
1303
|
+
}
|
|
1304
|
+
}, [selectedWallet, walletCapabilities, supraProvider]);
|
|
1305
|
+
const getAvailableWallets = (0, import_react.useCallback)(() => {
|
|
1306
|
+
const availableWallets = [];
|
|
1307
|
+
Object.entries(WALLET_CONFIGS).forEach(([walletType, config2]) => {
|
|
1308
|
+
const provider = config2.provider();
|
|
1309
|
+
const isInstalled = !!provider;
|
|
1310
|
+
switch (walletType) {
|
|
1311
|
+
case "starkey": {
|
|
1312
|
+
availableWallets.push({
|
|
1313
|
+
type: "starkey",
|
|
1314
|
+
name: "Starkey Wallet",
|
|
1315
|
+
isInstalled,
|
|
1316
|
+
capabilities: config2.capabilities
|
|
1317
|
+
});
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1320
|
+
case "ribbit": {
|
|
1321
|
+
availableWallets.push({
|
|
1322
|
+
type: "ribbit",
|
|
1323
|
+
name: "Ribbit Wallet",
|
|
1324
|
+
isInstalled,
|
|
1325
|
+
capabilities: config2.capabilities
|
|
1326
|
+
});
|
|
1327
|
+
break;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
return availableWallets;
|
|
1332
|
+
}, []);
|
|
1333
|
+
const updateSelectedWallet = (walletType) => {
|
|
1334
|
+
setSelectedWallet(walletType);
|
|
1335
|
+
setWalletCapabilities(WALLET_CONFIGS[walletType].capabilities);
|
|
1336
|
+
setStoredWalletType(walletType);
|
|
1337
|
+
};
|
|
1338
|
+
return {
|
|
1339
|
+
// New wallet selection functionality
|
|
1340
|
+
selectedWallet,
|
|
1341
|
+
walletCapabilities,
|
|
1342
|
+
getAvailableWallets,
|
|
1343
|
+
// Add this new function
|
|
1344
|
+
// Existing interface (unchanged)
|
|
1345
|
+
getCurrentProvider,
|
|
1346
|
+
isExtensionInstalled,
|
|
1347
|
+
accounts,
|
|
1348
|
+
networkData,
|
|
1349
|
+
balance,
|
|
1350
|
+
transactions,
|
|
1351
|
+
selectedChainId,
|
|
1352
|
+
connectWallet,
|
|
1353
|
+
// Now accepts optional walletType parameter
|
|
1354
|
+
disconnectWallet,
|
|
1355
|
+
sendRawTransaction,
|
|
1356
|
+
signMessage,
|
|
1357
|
+
setSelectedChainId,
|
|
1358
|
+
// switchToChain,
|
|
1359
|
+
loading
|
|
1360
|
+
// authFetch,
|
|
1361
|
+
// checkAndRevalidateToken,
|
|
1362
|
+
// signIn,
|
|
1363
|
+
};
|
|
1364
|
+
};
|
|
1365
|
+
var useSupraMultiWallet_default = useSupraMultiWallet;
|
|
1366
|
+
|
|
1367
|
+
// src/assets/walletIcons/Starkey.png
|
|
1368
|
+
var Starkey_default = "data:image/png;base64,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";
|
|
1369
|
+
|
|
1370
|
+
// src/assets/walletIcons/Ribbit.jpg
|
|
1371
|
+
var Ribbit_default = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gKgSUNDX1BST0ZJTEUAAQEAAAKQbGNtcwQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAADhjcHJ0AAABQAAAAE53dHB0AAABkAAAABRjaGFkAAABpAAAACxyWFlaAAAB0AAAABRiWFlaAAAB5AAAABRnWFlaAAAB+AAAABRyVFJDAAACDAAAACBnVFJDAAACLAAAACBiVFJDAAACTAAAACBjaHJtAAACbAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABwAAAAcAHMAUgBHAEIAIABiAHUAaQBsAHQALQBpAG4AAG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAMgAAABwATgBvACAAYwBvAHAAeQByAGkAZwBoAHQALAAgAHUAcwBlACAAZgByAGUAZQBsAHkAAAAAWFlaIAAAAAAAAPbWAAEAAAAA0y1zZjMyAAAAAAABDEoAAAXj///zKgAAB5sAAP2H///7ov///aMAAAPYAADAlFhZWiAAAAAAAABvlAAAOO4AAAOQWFlaIAAAAAAAACSdAAAPgwAAtr5YWVogAAAAAAAAYqUAALeQAAAY3nBhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAApbcGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltwYXJhAAAAAAADAAAAAmZmAADypwAADVkAABPQAAAKW2Nocm0AAAAAAAMAAAAAo9cAAFR7AABMzQAAmZoAACZmAAAPXP/bAEMABQMEBAQDBQQEBAUFBQYHDAgHBwcHDwsLCQwRDxISEQ8RERMWHBcTFBoVEREYIRgaHR0fHx8TFyIkIh4kHB4fHv/bAEMBBQUFBwYHDggIDh4UERQeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHv/CABEIAZABkAMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAABgcBBAUDCAL/xAAaAQEAAgMBAAAAAAAAAAAAAAAAAwQBAgUG/9oADAMBAAIQAxAAAAGmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdCeRaRKTbfpUr+WhYvbqQfOXM+nq9tT1Fn18ejbAAAyb2MaPdtGZc2pUm3aEerwwGJT7FyxVyfQe3P4CTcAAAAAAAAADO3qSfXX9RYD9znXEGtfgweKP6ccHvcHmw+kvp2M3rNCrW971iolxsKcW7+c5q++dnp8+oIjUgi9b5nPe6cDTyDSb4kMczvnP57fEZwM5AAAAAAAAA2JJpb0EUSE8tj21WdmcHmKntitTwtGqLXYCpAAAAApu5KVvWejbNaWXpqqa2a0Zqkd7pymLz6EQx64mkAAAAAAAAAkcyg1/cyn8zJBH+jb3bWpxFHcdU6U101nkvxnic0I9QAAAFfWD5y7/OFrQKM9vpXHVOk22Etk2ndQfSnzNRreQ6NsAAAAAAADJ74xY1p6m353la9cWeYoX1vVamr6f/AKVIAi0AEa32krn652HC7uAa6geNdWWmkobN8LU1c2F6KkCmrl5e+3zk/X59D1gAAAAAAAMyGPd+PT6BHmuOAAAAA5fUZzr+e4y5/QMAxgAAAAGfnXk9Lm+m7GBvsAAAAAAA9PMfSHRpu5PPcoK8IAAAAAAAAAAADjdmmrM0Eweg6oAAAAAAAAGbZqZFH9QKitbhc33EEQAAAAAAAAAAgUm/pTPp5d7p4E8oAAAAAAAAAGepy2MW/OvmbZoVvpdS0oo1bBRrqQR9F5eGuNxFo3NJZqmPGbe7VPdvTWxkZ7UEW4/HhpjacGPyyT7lVLEbtiaQg6dzA32AAAAAAAAAAAAAAZwMsAAABnA/WMGM4GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/EACgQAAEEAQMEAgIDAQAAAAAAAAQBAgMFBgAQQBESEzAUFiAhFSKQUP/aAAgBAQABBQL/AEuCqDy9RYqQuvqa6mxYtqGAFiL7Aak8zUWKELr6nqbFim6NALDXlBCTGTwJS06yZX+4crb1r7UI7ZzWubcY5HIksb43+gMaYueooBhE2sLkAN0uWJ1ZlMb9EB1tlqWN8T+OLBITOWa0aHdqq1cavFmdtkdQ06FyK1fyFglJnpq6KuG2yK9c5y7oqoqTfyLHIrV4zU+DU7NRXKFjJczDcZLhZ/Zj6Ez51dtaUoZypikfVMVF19WB19WB0uKC6Zio/cAAKC3bKjVErmornBYyXMw3GS4WORWu2NTzD8WFiyTZR0ZY7YWGySbbNQ2xy4LL+/Zmsqus8LDbJLtmgbI5tqZvnE4uPs77nLGq272waZvZtnE7fDgrF8/szJituMHnb4ts5mb49sJZ3WM7eyfiY2vbd5sJ1bsIRKKQHkwj4zMmEZGYTKWRigijVnszQRZBRCJRCA8mEfGZk4jIzCJSiNsPEWCuKXuJ4lE1XW5ETJ4LmtmriPwxyocbKn6T2SMbJHeVUldP+GP1Lz5kaiMkarZOJhgCq/REMRER+L/t9FaMWHH7SRa3GYYnNa1rfdNHHNHYYujlkorRixUNpItdjEbHRsZGzWXV3xiuHBG6WYSBgw3svbVKyOuKaYFbnNrw6SxSyF9lqMhgCp0XhY41HXXtsQBj4xoYx4DBoSxwA4AoPbcNRlpwsff47nnWknlseExytdWktMC5l0T8St4mJ2SCz8zLrBCSuLjV2j05WTW6CR8ekyF8CQSxTx8e+vmDI9znv5ABxIUldkw8iQzRTM4Z9gIE23yAgvmwzzQuFyWwi0NlIrtRXtXJqM8KTSSRrqUoaLU9/WRaIytOr8nsF19ks9R5Samh8qgXUN7VyaiKFl13N08gdmpritj0VlAbENyGwIR7nOd/zOq/6Bf/xAAoEQACAQMDBAIBBQAAAAAAAAABAgADERIEMDEQFCAhMkFwEyIjQlL/2gAIAQMBAT8B/JzPaM1b6E/Xqqfcp6oH03iTaPqv8wVqrH1FasORFbLcJtALRnVeYQlYQixtKOox9NO5Sdyk7lJWr5+hxFXI2gwpCK6txCIDtk/yW6ai+c098/U1HzPlpfnNRfOae+Y6Kf3EbdZ8KgMBBFxHpK/MCpRF4zZG/lTbBrwolUXiUlTiMwUXM07ZMx26r5teJVZOJ3bx3Z+eqqWNhMTe0IKmx6pVZOJ3bx6jPzKNTBtp/ifMG3Ev7vCb+a8bVWng29RTNtupTDixlSkybiIXNhKVMUxbcIvzH0qniNp3EKMPqWMFFz9TtXh07iFGHIljBSc/UTSH+0VAosPyf//EACwRAAICAQEGBAcBAQAAAAAAAAECAAMEERITITAxMgUQIFEUFSIjM0FwQmH/2gAIAQIBAT8B/pz2heA4mO+Ueg0hy70OjSnPDcH4eknTiZb4gBwSLlZDnRYj5Q7l1iWBuYzaRVCx7Er7jGFWSvCOhRtDMXM2PpfpPjafefHUz46n3mVl73gvSV1l2CiLu8ddIliWdphXWA68st90L/zyzSd6dZhE70aTN/MfV4f+WZpO94zCJ3o08kb7jLy8q3dXK0Vgw1Etx0t7oK6sZdZY+2xY+qmzduGj1V5A1lWOlXbHcIu0ZhPvHduXkW719ZVe9XQz5jZ7Sy57D9R80QudlZsNtbP7jqVOh86r3q7TPmNntLLnt7jMa7dPryrew+sMVOom0ddYSSdT607RysmndPzsWreWcu6lbV0Mux3qPHmVVNYdFlFIpXQcwgEaGW4CN28I+FasNTjqJsmLi2t0E+X2xsK0fqNU69RNkxcexuglXhx/2ZXWqDRf6f8A/8QAPxAAAQIDAwcGCwgDAAAAAAAAAQIDAAQREiFBECIjMUBhcRMUMDJRUiAzNEJicoGRocHRJFOCkJKjseEFQ4P/2gAIAQEABj8C/Muq0wQnvKuEaSZbTwFY8u/b/uNE8058I+0MKRvw6WrTCrPeVcI0ky2ngKx5d+3/AHGifac43RSYYUjfh79rDLCbR/iNMvnc0NdkVCY0cldvXGmlCB2pXFGXc/uKuOSyoAjsMF2RzF/d4GChxJSoawehDLCLSjAcfAee36hlsLdtL7qL40Und6S4szEjmnXRVYK/8W4Gn/uV3V4QUOJKVDWDtCWWhVSoMjIKo3/sdxcP08CoNCITKTis/Uhfbuyl5oUmEC70t0UIoR4aWWUlS1RYTe4eurtyqlZJdEaluDHh4FRAZfI5yBRtw+d6Jih1jZ+V1PTeancga/floBUxbeWliuBvMW2VpfHYLjGKVA+6EOnrjNXxy21Atu95OMXzav0xfMu/CPHTHvH0jxz/ALx9IumXR7BGfMuEbhFmXaCe04nLYbNHHc0cMYoLyYtvLSwDgbzFtlaX6YC4xQihytzoF5zHfW7fbsyGxrUaQJdHUYbShOVybWK8ncnjlbnECnKZq+MTLPBQ6VDWCG/5hycWK8nmo45W5tApylyuOWelddWuUTxTs0qk9+sO7wD8Mr8v51bQysS3nWrZiZcwCQOlr3mwYflj1q2xlYl651bWV1VLg184WjsURsst61PhDU4kasxXyypfZVRaYHOUraXjQVEHmyVOrwqKCFPvKqtUWliinTa9mHStzSRe0aK4GEvMqotMDnKVNLxoKiDzZKnV4VFBCn3lVWrKp5YoXjX2Q6rtUdllQPvBC2XRVCxQxZUKtnqL7fBD7wpLpP6ooOlU2sVSoUIjFTCjmK+XghxYIl0nOPbuiwm4AUEKSdYNDsqp9wXDNb+ZyFp5AWg4GCqTe/Av6xTmpPAiPEWN6lQFzbnLHujVASkAAagOnLbqAtJ1gwVyTtn0F/WPJieBEeTWd6lCAucc5T0E6oCG0hKRqAyc6bGieN+5WyIaT1lGghthHVQKdK3o+UWvUK0huZSLIWNUGYUm1fQDfBdsWFJVZI6V1jFQzeMU2OWB71emSiYSTZNQQbxCWWk2UJFAIUw+mqDHIsJomtePTTKRq5Q7HLKPfpt8w4NRcNNjCkmhBuhqYT5wv47a89WiqUTx2XmrytE4btx20SzR0bWverZkyc2vP1IWcd21mVYVp1C8jzBtAYnarbwXiIDjK0rScRtBl5Qhb2KsEwVrNVHWdpty7hT2jAwEziOSV3heIttOJWntSdkq+6AcEjWYLTGhZ+J220y4tB9E0ijth4bxQxp2HGz6OcI8pCfWFIzJtg/9BFziT7Y0kw0jisR4/lPUFY+zyhO9aozUsp/DHWb/AERntMq+EaeWWjeg1jykJ9YUjRzDK+CxHWHvjPfbTxVF822fVvjQNOOnfmiClCgwk9zX74tKJJ7T+Zf/AP/EACsQAQABAQUIAwADAQEAAAAAAAERACExQVFhEEBxgZGhscEw0fAgkOHxUP/aAAgBAQABPyH+yx2Hn6Xpv5UPOnp9KYrBNT50Zl1FwtErmWfLAfm3LfyokdPf61dst1HLoEqw02mXyWb2+Nb3AZrQpLMgaYe6hgWR+sp5NVLslWRz8HPlsZLd4SNH+X6u3lSPXgUI/Cojt9XIq+0ORb6HugAg2KoXeUjjgUFiuBhegVf2soPalH3iGy1MdeAQjvEhlQZGa6UlbArMZbhRt2mXIkRhKkSO197XztIncgu5vVOXIhEu/mqFIAoYZbcdfW2JpWja8llrSm2ZdpJES5KC1gmj7uTSkkSEy3eybKcy/OazhtEuSwAvoMGuF1TCmwpeXRMauXQSipW+MY879q9qv84xrBnofuj33gCjGoDhVhnekocsnAVLWN7bxnba4FTExP2dDDUQGLRa5QXVMKTDrxdExpQ4GES7YKMl9X+rMZSzkdx3a7RZ5tXKArQJ97TRWZuCx/Z7RpyMGS56eKWa2R3g+vllRZoNUr6o2chJmvennaSq2MxFz+y2pH9xX0u7Fbg8BPqlduK2pWQgLMufW2MEUgyAg8vSke6dZ9fKwdxXc9VPICdQiHwddsNBlZkXHva9pnDzH00YX1Duopc3Uin9bW9eds6iSOejVnicQ8Mas8bgPjU0KW5GhR+2NPxx5/LMz/ANfNTxpZro1x8YPhVljcA8alxS3TQ22WR05bvdCBcrvut53JyLWhwsBShj7iwff8XvyluMwNM6AAQFx8p43FYjTVC4D3a/x+nm5qBiRAYUGcKDXdbIjMmL+DrsvYehTpaLz0iufDd7oCJGSA91A2bbuflok7QCA+cRFQORoaM7cE4UeHGu90JLHIAoU6NHmb3tRtfgEBs/DAHrf13QEZHxloirGNdflaLZbgAibeZTK5CWCMPikYuE+JVBW/Dm2JsefyqcMSwF1IiISzc7hw7QvzGjLBGwRzLpoKjmVIlaEsqzfmFqBH13MbieSzfwYSrwTuafBlGDUJGGMMR130/OD7Cll3RzEtVu/wB99lavaLsTpd13UqFkLT62u945LD8NLLLu8IvsvuPmVckWWTeLuWBt+1p9LZRtXebXM1eIU6S7v32USVrpBunHf65VFzWssbPVw4FY75qMtaEEG/7BQsZyR6Grg4xp0JSTzR88KNHzwiVLQkYLQ6AMIHY+6dsHifdBNr8lM2boPtTsaUfOKjQTk9BOuTZo2S9MqXndfrTozn/0dqw0lD/TpSJavSV/8OXOp+HUal/sB//aAAwDAQACAAMAAAAQ888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888880V0ms888jqr9788888888888pzDl+e9A8k/hDxo8888888888d8+o/9999959q848888888888bmL999999950m+m888888888D+PNN994109989f/APPPPPPPPPE//ffffb3fffffffv/ADzzzzzzzzz3333333333333jzzzzzzzzzyXT333333333337PzzzzzzzzzzzQrPjTLvfnfaZDzzzzzzzzzzzzzzyyzzzyw1zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz/8QAJhEBAAIBAgQHAQEAAAAAAAAAAQARITFBIDBRYRBwcZGhscFAgf/aAAgBAwEBPxDzOPELehE5o9o1C9yI0V32g3wALYY0L7ymP4mUuP8ALh9j0deZUo1dIcG26jEG/wAjstSVNr6j1fid99p3fiNsPtGM7wDFr9htu4LneWHLtHYvg07jBgmLt9cQNfSNO4xV4ezHl+k8NJiaTzFss734lA7Q18ppPMZJiXbvXKWsx2hDOYNCKW78QAZYJjzpHGoeKGcwaEQtxDdt+VfF0eNHapgjJmIrdeIl6305TIbbc5RNjXmHEaTHXmURlJa78wBQsmUdTZ79JqC9oM0E0/8AEOzNuuaqEE0mkqIyq9JVmv4a4aPLn//EACkRAQACAAMGBgMBAAAAAAAAAAEAESExQTBRYXGBsRAgkaHR4XDB8ED/2gAIAQIBAT8Q/JztDuD97piRjoveX4x3IRYC2/SCJZ5AClEZpvi/EtRbwD4mOgOYP90mkomY4O0YAZuBBKM9XfDLqjkQ8dSIM4lXO0O76iX0Zxn0mBm9GLou6ZzDAZNd2GXZCxamTKl67OzdE+4eCy0VXKoUtWfKEKOHbzAcW5jWaMuUCWq75V4B0D6n1s6E3Y8rYfexlfTE1M4497ny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";
|
|
1372
|
+
|
|
1373
|
+
// src/components/ConnectWalletHandler.tsx
|
|
1374
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1375
|
+
var PROFILE_CACHE_KEY = STORAGE_KEYS.USER_PROFILE_CACHE;
|
|
1376
|
+
var PROFILE_CACHE_TIMESTAMP_KEY = STORAGE_KEYS.USER_PROFILE_CACHE_TIMESTAMP;
|
|
1377
|
+
var WALLET_INFO = {
|
|
1378
|
+
starkey: {
|
|
1379
|
+
name: "Starkey Wallet",
|
|
1380
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1381
|
+
"img",
|
|
1382
|
+
{
|
|
1383
|
+
src: Starkey_default,
|
|
1384
|
+
alt: "Starkey Wallet",
|
|
1385
|
+
className: "w-10 h-10 rounded-full"
|
|
1386
|
+
}
|
|
1387
|
+
),
|
|
1388
|
+
downloadUrl: WALLET_DOWNLOAD_URLS.starkey
|
|
1389
|
+
},
|
|
1390
|
+
ribbit: {
|
|
1391
|
+
name: "Ribbit Wallet",
|
|
1392
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1393
|
+
"img",
|
|
1394
|
+
{
|
|
1395
|
+
src: Ribbit_default,
|
|
1396
|
+
alt: "Ribbit Wallet",
|
|
1397
|
+
className: "w-10 h-10 rounded-full"
|
|
1398
|
+
}
|
|
1399
|
+
),
|
|
1400
|
+
downloadUrl: WALLET_DOWNLOAD_URLS.ribbit
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
var ConnectWalletHandler = ({
|
|
1404
|
+
onConnect,
|
|
1405
|
+
onDisconnect,
|
|
1406
|
+
children
|
|
1407
|
+
}) => {
|
|
1408
|
+
const starKeyWalletHook = useSupraMultiWallet_default();
|
|
1409
|
+
const getAvailableWallets = starKeyWalletHook.getAvailableWallets;
|
|
1410
|
+
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
1411
|
+
const [showWalletModal, setShowWalletModal] = (0, import_react2.useState)(false);
|
|
1412
|
+
const [userProfile, setUserProfile] = (0, import_react2.useState)(null);
|
|
1413
|
+
const [walletBalance, setWalletBalance] = (0, import_react2.useState)("0.00");
|
|
1414
|
+
const [availableWallets, setAvailableWallets] = (0, import_react2.useState)([]);
|
|
1415
|
+
const [recentWallet, setRecentWallet] = (0, import_react2.useState)(null);
|
|
1416
|
+
const [selectedWallet, setSelectedWallet] = (0, import_react2.useState)(null);
|
|
1417
|
+
const [hoveredWallet, setHoveredWallet] = (0, import_react2.useState)(null);
|
|
1418
|
+
const [connectionStage, setConnectionStage] = (0, import_react2.useState)("idle");
|
|
1419
|
+
const [connectionStageStartTime, setConnectionStageStartTime] = (0, import_react2.useState)(null);
|
|
1420
|
+
const [canClickOutside, setCanClickOutside] = (0, import_react2.useState)(false);
|
|
1421
|
+
const getProfileFromCache = (0, import_react2.useCallback)(() => {
|
|
1422
|
+
try {
|
|
1423
|
+
if (typeof window === "undefined") return null;
|
|
1424
|
+
const cachedData = getStorageItem(PROFILE_CACHE_KEY);
|
|
1425
|
+
const timestamp = getStorageItem(PROFILE_CACHE_TIMESTAMP_KEY);
|
|
1426
|
+
if (!cachedData || !timestamp) return null;
|
|
1427
|
+
const now = Date.now();
|
|
1428
|
+
const cacheTime = parseInt(timestamp);
|
|
1429
|
+
if (now - cacheTime > CACHE_TTL.PROFILE) {
|
|
1430
|
+
return null;
|
|
1431
|
+
}
|
|
1432
|
+
return JSON.parse(cachedData);
|
|
1433
|
+
} catch (error) {
|
|
1434
|
+
logger.error("Failed to read profile from cache", error);
|
|
1435
|
+
return null;
|
|
1436
|
+
}
|
|
1437
|
+
}, []);
|
|
1438
|
+
const updateWalletBalance = (0, import_react2.useCallback)(async () => {
|
|
1439
|
+
const provider = starKeyWalletHook.getCurrentProvider();
|
|
1440
|
+
if (!provider) return;
|
|
1441
|
+
try {
|
|
1442
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
1443
|
+
switch (starKeyWalletHook.selectedWallet) {
|
|
1444
|
+
case "starkey": {
|
|
1445
|
+
const balance = await provider.balance();
|
|
1446
|
+
if (balance && balance.formattedBalance) {
|
|
1447
|
+
setWalletBalance(balance.formattedBalance);
|
|
1448
|
+
}
|
|
1449
|
+
break;
|
|
1450
|
+
}
|
|
1451
|
+
case "ribbit": {
|
|
1452
|
+
const walletBalanceRequest = {
|
|
1453
|
+
chainId: parseInt(process.env.NEXT_PUBLIC_SUPRA_CHAIN_ID || "6"),
|
|
1454
|
+
resourceType: "0x1::supra_coin::SupraCoin",
|
|
1455
|
+
decimals: 8
|
|
1456
|
+
};
|
|
1457
|
+
try {
|
|
1458
|
+
const balance = await provider.getWalletBalance(walletBalanceRequest);
|
|
1459
|
+
const balanceStr = balance.balance;
|
|
1460
|
+
logger.debug("Ribbit balance fetched", { balance: balanceStr });
|
|
1461
|
+
if (balanceStr) {
|
|
1462
|
+
setWalletBalance(balanceStr);
|
|
1463
|
+
}
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
logger.error("Failed to fetch Ribbit balance", error);
|
|
1466
|
+
}
|
|
1467
|
+
break;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
} catch (error) {
|
|
1471
|
+
logger.error("Failed to update wallet balance", error);
|
|
1472
|
+
}
|
|
1473
|
+
}, [starKeyWalletHook.selectedWallet, starKeyWalletHook.getCurrentProvider]);
|
|
1474
|
+
const connectWallet = (0, import_react2.useCallback)(async (walletType) => {
|
|
1475
|
+
if (walletType) {
|
|
1476
|
+
setLoading(true);
|
|
1477
|
+
setSelectedWallet(walletType);
|
|
1478
|
+
setConnectionStage("connecting");
|
|
1479
|
+
try {
|
|
1480
|
+
const success = await starKeyWalletHook.connectWallet(walletType);
|
|
1481
|
+
if (success) {
|
|
1482
|
+
setStorageItem(STORAGE_KEYS.RECENT_WALLET, walletType);
|
|
1483
|
+
setRecentWallet(walletType);
|
|
1484
|
+
if (starKeyWalletHook.accounts.length > 0) {
|
|
1485
|
+
onConnect == null ? void 0 : onConnect(starKeyWalletHook.accounts[0]);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
} catch (error) {
|
|
1489
|
+
logger.error("Failed to connect wallet", error, { walletType });
|
|
1490
|
+
import_sonner2.toast.error(`Connection failed: ${error.message || "Unknown error"}`);
|
|
1491
|
+
setConnectionStage("idle");
|
|
1492
|
+
} finally {
|
|
1493
|
+
setLoading(false);
|
|
1494
|
+
}
|
|
1495
|
+
} else {
|
|
1496
|
+
handleConnectClick();
|
|
1497
|
+
}
|
|
1498
|
+
}, [starKeyWalletHook, onConnect]);
|
|
1499
|
+
const handleConnectClick = () => {
|
|
1500
|
+
const installedWallets = availableWallets.filter((w) => w.isInstalled);
|
|
1501
|
+
if (installedWallets.length === 0) {
|
|
1502
|
+
setShowWalletModal(true);
|
|
1503
|
+
} else if (installedWallets.length === 1) {
|
|
1504
|
+
setShowWalletModal(true);
|
|
1505
|
+
} else {
|
|
1506
|
+
setShowWalletModal(true);
|
|
1507
|
+
}
|
|
1508
|
+
};
|
|
1509
|
+
const handleDisconnectWallet = (0, import_react2.useCallback)(async () => {
|
|
1510
|
+
setLoading(true);
|
|
1511
|
+
try {
|
|
1512
|
+
await starKeyWalletHook.disconnectWallet();
|
|
1513
|
+
setUserProfile(null);
|
|
1514
|
+
setWalletBalance("0.00");
|
|
1515
|
+
onDisconnect == null ? void 0 : onDisconnect();
|
|
1516
|
+
} catch (error) {
|
|
1517
|
+
logger.error("Failed to disconnect wallet", error);
|
|
1518
|
+
} finally {
|
|
1519
|
+
setLoading(false);
|
|
1520
|
+
}
|
|
1521
|
+
}, [starKeyWalletHook, onDisconnect]);
|
|
1522
|
+
const getConnectionStageInfo = (0, import_react2.useCallback)(() => {
|
|
1523
|
+
const wallet = selectedWallet ? WALLET_INFO[selectedWallet] : null;
|
|
1524
|
+
switch (connectionStage) {
|
|
1525
|
+
case "connecting":
|
|
1526
|
+
return {
|
|
1527
|
+
title: `Waiting for ${(wallet == null ? void 0 : wallet.name) || "Wallet"}`,
|
|
1528
|
+
subtitle: CONNECTION_MESSAGES.CONNECTING,
|
|
1529
|
+
buttonText: "Connecting"
|
|
1530
|
+
};
|
|
1531
|
+
case "signing":
|
|
1532
|
+
return {
|
|
1533
|
+
title: "Sign to verify",
|
|
1534
|
+
subtitle: CONNECTION_MESSAGES.SIGNING,
|
|
1535
|
+
buttonText: "Signing"
|
|
1536
|
+
};
|
|
1537
|
+
case "success":
|
|
1538
|
+
return {
|
|
1539
|
+
title: `Connected to ${(wallet == null ? void 0 : wallet.name.replace(" Wallet", "")) || "Wallet"}`,
|
|
1540
|
+
subtitle: CONNECTION_MESSAGES.SUCCESS,
|
|
1541
|
+
buttonText: "Connected"
|
|
1542
|
+
};
|
|
1543
|
+
case "error":
|
|
1544
|
+
return {
|
|
1545
|
+
title: "Error",
|
|
1546
|
+
subtitle: CONNECTION_MESSAGES.ERROR,
|
|
1547
|
+
buttonText: "Close"
|
|
1548
|
+
};
|
|
1549
|
+
case "connected-not-signed":
|
|
1550
|
+
return {
|
|
1551
|
+
title: `Connected to ${(wallet == null ? void 0 : wallet.name.replace(" Wallet", "")) || "Wallet"}`,
|
|
1552
|
+
subtitle: CONNECTION_MESSAGES.CONNECTED_NOT_SIGNED,
|
|
1553
|
+
buttonText: "Connected"
|
|
1554
|
+
};
|
|
1555
|
+
default:
|
|
1556
|
+
return null;
|
|
1557
|
+
}
|
|
1558
|
+
}, [connectionStage, selectedWallet]);
|
|
1559
|
+
(0, import_react2.useEffect)(() => {
|
|
1560
|
+
const recent = getStorageItem(STORAGE_KEYS.RECENT_WALLET);
|
|
1561
|
+
if (recent && ["starkey", "ribbit"].includes(recent)) {
|
|
1562
|
+
setRecentWallet(recent);
|
|
1563
|
+
}
|
|
1564
|
+
}, []);
|
|
1565
|
+
(0, import_react2.useEffect)(() => {
|
|
1566
|
+
const checkWallets = () => {
|
|
1567
|
+
const wallets = getAvailableWallets();
|
|
1568
|
+
setAvailableWallets(wallets);
|
|
1569
|
+
};
|
|
1570
|
+
checkWallets();
|
|
1571
|
+
const interval = setInterval(checkWallets, TIMEOUTS.WALLET_CHECK_INTERVAL);
|
|
1572
|
+
const timeout = setTimeout(() => clearInterval(interval), TIMEOUTS.WALLET_CHECK_MAX_DURATION);
|
|
1573
|
+
return () => {
|
|
1574
|
+
clearInterval(interval);
|
|
1575
|
+
clearTimeout(timeout);
|
|
1576
|
+
};
|
|
1577
|
+
}, [getAvailableWallets]);
|
|
1578
|
+
(0, import_react2.useEffect)(() => {
|
|
1579
|
+
if (starKeyWalletHook.accounts.length > 0) {
|
|
1580
|
+
updateWalletBalance();
|
|
1581
|
+
}
|
|
1582
|
+
}, [starKeyWalletHook.accounts, starKeyWalletHook.selectedWallet]);
|
|
1583
|
+
(0, import_react2.useEffect)(() => {
|
|
1584
|
+
const handlePresignedState = () => {
|
|
1585
|
+
setConnectionStage(() => "signing");
|
|
1586
|
+
};
|
|
1587
|
+
const handlePostsignedState = () => {
|
|
1588
|
+
setConnectionStage("success");
|
|
1589
|
+
setTimeout(() => {
|
|
1590
|
+
setConnectionStage("idle");
|
|
1591
|
+
setShowWalletModal(false);
|
|
1592
|
+
updateWalletBalance();
|
|
1593
|
+
}, TIMEOUTS.MODAL_CLOSE_DELAY);
|
|
1594
|
+
};
|
|
1595
|
+
const handleWalletError = () => {
|
|
1596
|
+
if (connectionStage == "signing") {
|
|
1597
|
+
setConnectionStage(() => "connected-not-signed");
|
|
1598
|
+
} else {
|
|
1599
|
+
setConnectionStage(() => "error");
|
|
1600
|
+
}
|
|
1601
|
+
setTimeout(() => {
|
|
1602
|
+
setShowWalletModal(false);
|
|
1603
|
+
setSelectedWallet(null);
|
|
1604
|
+
setConnectionStage("idle");
|
|
1605
|
+
setLoading(false);
|
|
1606
|
+
}, TIMEOUTS.MODAL_CLOSE_DELAY);
|
|
1607
|
+
};
|
|
1608
|
+
const handleStarkeyEvents = (event) => {
|
|
1609
|
+
var _a, _b, _c;
|
|
1610
|
+
if ((_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("starkey-")) {
|
|
1611
|
+
switch ((_c = event == null ? void 0 : event.data) == null ? void 0 : _c.name) {
|
|
1612
|
+
case "starkey-wallet-updated":
|
|
1613
|
+
case "starkey-wallet-connected":
|
|
1614
|
+
setTimeout(updateWalletBalance, 1);
|
|
1615
|
+
break;
|
|
1616
|
+
case "starkey-wallet-disconnected":
|
|
1617
|
+
setWalletBalance("0.00");
|
|
1618
|
+
break;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
window.addEventListener("presigned-state", handlePresignedState);
|
|
1623
|
+
window.addEventListener("postsigned-state", handlePostsignedState);
|
|
1624
|
+
window.addEventListener("wallet-error", handleWalletError);
|
|
1625
|
+
window.addEventListener("message", handleStarkeyEvents);
|
|
1626
|
+
return () => {
|
|
1627
|
+
window.removeEventListener("presigned-state", handlePresignedState);
|
|
1628
|
+
window.removeEventListener("postsigned-state", handlePostsignedState);
|
|
1629
|
+
window.removeEventListener("wallet-error", handleWalletError);
|
|
1630
|
+
window.removeEventListener("message", handleStarkeyEvents);
|
|
1631
|
+
};
|
|
1632
|
+
}, [connectionStage]);
|
|
1633
|
+
(0, import_react2.useEffect)(() => {
|
|
1634
|
+
const handleProfileUpdated = (event) => {
|
|
1635
|
+
const { address, username, profileImage } = event.detail;
|
|
1636
|
+
if (starKeyWalletHook.accounts[0] === address) {
|
|
1637
|
+
setUserProfile({ address, username, profileImage });
|
|
1638
|
+
}
|
|
1639
|
+
};
|
|
1640
|
+
window.addEventListener("profile-updated", handleProfileUpdated);
|
|
1641
|
+
return () => {
|
|
1642
|
+
window.removeEventListener("profile-updated", handleProfileUpdated);
|
|
1643
|
+
};
|
|
1644
|
+
}, [starKeyWalletHook.accounts]);
|
|
1645
|
+
(0, import_react2.useEffect)(() => {
|
|
1646
|
+
if (starKeyWalletHook.accounts.length > 0) {
|
|
1647
|
+
const handleVisibilityChange = () => {
|
|
1648
|
+
if (!document.hidden) {
|
|
1649
|
+
updateWalletBalance();
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
1653
|
+
const balanceInterval = setInterval(() => {
|
|
1654
|
+
if (!document.hidden) {
|
|
1655
|
+
updateWalletBalance();
|
|
1656
|
+
}
|
|
1657
|
+
}, TIMEOUTS.BALANCE_POLL_INTERVAL);
|
|
1658
|
+
return () => {
|
|
1659
|
+
clearInterval(balanceInterval);
|
|
1660
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
}, [starKeyWalletHook.accounts, updateWalletBalance]);
|
|
1664
|
+
(0, import_react2.useEffect)(() => {
|
|
1665
|
+
if (connectionStage === "connecting" || connectionStage === "signing") {
|
|
1666
|
+
setConnectionStageStartTime(Date.now());
|
|
1667
|
+
setCanClickOutside(false);
|
|
1668
|
+
const timer = setTimeout(() => {
|
|
1669
|
+
setCanClickOutside(true);
|
|
1670
|
+
}, TIMEOUTS.CLICK_OUTSIDE_DELAY);
|
|
1671
|
+
return () => clearTimeout(timer);
|
|
1672
|
+
} else {
|
|
1673
|
+
setConnectionStageStartTime(null);
|
|
1674
|
+
setCanClickOutside(false);
|
|
1675
|
+
}
|
|
1676
|
+
}, [connectionStage]);
|
|
1677
|
+
const handleModalClose = (0, import_react2.useCallback)((open) => {
|
|
1678
|
+
if (!open) {
|
|
1679
|
+
if (connectionStage === "idle" || connectionStage === "success" || connectionStage === "connected-not-signed" || connectionStage === "error" || canClickOutside && (connectionStage === "connecting" || connectionStage === "signing")) {
|
|
1680
|
+
setShowWalletModal(false);
|
|
1681
|
+
setSelectedWallet(null);
|
|
1682
|
+
setLoading(false);
|
|
1683
|
+
setCanClickOutside(false);
|
|
1684
|
+
setConnectionStageStartTime(null);
|
|
1685
|
+
setTimeout(() => {
|
|
1686
|
+
setConnectionStage("idle");
|
|
1687
|
+
}, 100);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
}, [connectionStage, canClickOutside]);
|
|
1691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1692
|
+
children({
|
|
1693
|
+
isConnected: starKeyWalletHook.accounts.length > 0,
|
|
1694
|
+
accounts: starKeyWalletHook.accounts,
|
|
1695
|
+
loading: loading || starKeyWalletHook.loading,
|
|
1696
|
+
balance: walletBalance,
|
|
1697
|
+
userProfile,
|
|
1698
|
+
handleConnect: handleConnectClick,
|
|
1699
|
+
handleDisconnect: handleDisconnectWallet
|
|
1700
|
+
}),
|
|
1701
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1702
|
+
Dialog,
|
|
1703
|
+
{
|
|
1704
|
+
open: showWalletModal,
|
|
1705
|
+
onOpenChange: handleModalClose,
|
|
1706
|
+
children: [
|
|
1707
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_visually_hidden.VisuallyHidden, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DialogTitle, { children: "Select a wallet" }) }),
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_visually_hidden.VisuallyHidden, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DialogDescription, { children: "Select a wallet to connect to MyDApp" }) }),
|
|
1709
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1710
|
+
DialogContent,
|
|
1711
|
+
{
|
|
1712
|
+
className: "z-[100] px-4 py-6 w-[90%] mx-auto max-w-sm bg-gradient-to-br from-brand-dark via-gray-900 to-brand-dark border border-brand-dark sm:rounded-3xl rounded-3xl",
|
|
1713
|
+
children: [
|
|
1714
|
+
canClickOutside && (connectionStage === "connecting" || connectionStage === "signing") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.X, { className: "h-5 w-5" }) }),
|
|
1715
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "", children: connectionStage === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-center text-sm text-brand-light/75 mb-6 text-white", children: "Select Wallet" }),
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-3", children: availableWallets.map((wallet) => {
|
|
1718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-full relative", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1719
|
+
import_framer_motion.motion.button,
|
|
1720
|
+
{
|
|
1721
|
+
initial: { opacity: 0, y: 20 },
|
|
1722
|
+
animate: { opacity: 1, y: 0 },
|
|
1723
|
+
transition: { duration: 0.05, ease: "easeInOut" },
|
|
1724
|
+
onClick: () => {
|
|
1725
|
+
wallet.isInstalled ? connectWallet(wallet.type) : window.open(WALLET_INFO[wallet.type].downloadUrl, "_blank");
|
|
1726
|
+
},
|
|
1727
|
+
type: "button",
|
|
1728
|
+
disabled: loading && wallet.isInstalled,
|
|
1729
|
+
onMouseEnter: () => setHoveredWallet(wallet.type),
|
|
1730
|
+
onMouseLeave: () => setHoveredWallet(null),
|
|
1731
|
+
className: "w-full px-4 py-2 rounded-2xl border border-gray-950/60 hover:border-gray-800/80 bg-gray-950/20 hover:bg-gray-900/40 transition-all duration-300 flex items-center gap-4 group",
|
|
1732
|
+
children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-shrink-0", children: WALLET_INFO[wallet.type].icon }),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex-1 text-left", children: [
|
|
1735
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-medium text-white", children: WALLET_INFO[wallet.type].name }),
|
|
1736
|
+
!wallet.isInstalled && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-400", children: "Not installed - Click to download" })
|
|
1737
|
+
] }),
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-shrink-0", children: recentWallet === wallet.type && wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "bg-gray-800/60 text-gray-300 text-xs px-3 py-1 rounded-full border border-gray-700/40", children: "Recent" }) : wallet.isInstalled ? loading && wallet.type === selectedWallet ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Loader2, { className: "h-4 w-4 animate-spin text-gray-400" }) : hoveredWallet === wallet.type && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-gray-400 text-sm font-medium", children: "Connect" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ExternalLink, { className: "h-4 w-4 text-gray-500" }) })
|
|
1739
|
+
]
|
|
1740
|
+
}
|
|
1741
|
+
) }, wallet.type);
|
|
1742
|
+
}) })
|
|
1743
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-full text-center py-8", children: (() => {
|
|
1744
|
+
const stageInfo = getConnectionStageInfo();
|
|
1745
|
+
const wallet = selectedWallet ? WALLET_INFO[selectedWallet] : null;
|
|
1746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "relative flex justify-center mb-6", children: connectionStage === "success" || connectionStage === "connected-not-signed" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-20 h-20 rounded-full border-4 border-green-500 flex items-center justify-center", children: wallet && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-12 flex items-center justify-center", children: wallet.icon }) }) : connectionStage === "error" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-20 h-20 rounded-full border-4 border-red-500 flex items-center justify-center", children: wallet && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-12 flex items-center justify-center", children: wallet.icon }) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", children: [
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-20 h-20 rounded-full border-4 border-gray-600 border-t-gray-400 animate-spin" }),
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: wallet && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-12 flex items-center justify-center", children: wallet.icon }) })
|
|
1750
|
+
] }) }),
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "text-lg font-semibold text-white mb-2", children: stageInfo == null ? void 0 : stageInfo.title }),
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-400 mb-6", children: stageInfo == null ? void 0 : stageInfo.subtitle }),
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1754
|
+
Button,
|
|
1755
|
+
{
|
|
1756
|
+
disabled: true,
|
|
1757
|
+
className: "w-full bg-gray-700 text-gray-400 cursor-not-allowed rounded-2xl py-3",
|
|
1758
|
+
children: stageInfo == null ? void 0 : stageInfo.buttonText
|
|
1759
|
+
}
|
|
1760
|
+
)
|
|
1761
|
+
] });
|
|
1762
|
+
})() }) })
|
|
1763
|
+
]
|
|
1764
|
+
}
|
|
1765
|
+
)
|
|
1766
|
+
]
|
|
1767
|
+
}
|
|
1768
|
+
)
|
|
1769
|
+
] });
|
|
1770
|
+
};
|
|
1771
|
+
|
|
1772
|
+
// src/hooks/useSupraMultiWallet.ts
|
|
1773
|
+
var import_react3 = require("react");
|
|
1774
|
+
var import_tweetnacl2 = __toESM(require("tweetnacl"));
|
|
1775
|
+
var import_navigation2 = require("next/navigation");
|
|
1776
|
+
var import_sonner3 = require("sonner");
|
|
1777
|
+
var import_ribbit_wallet_connect2 = require("ribbit-wallet-connect");
|
|
1778
|
+
var WALLET_CONFIGS2 = {
|
|
1779
|
+
starkey: {
|
|
1780
|
+
capabilities: {
|
|
1781
|
+
signMessage: true,
|
|
1782
|
+
accountSwitching: true,
|
|
1783
|
+
networkSwitching: true,
|
|
1784
|
+
rawTransactions: true,
|
|
1785
|
+
eventListeners: true,
|
|
1786
|
+
tokenRevalidation: true
|
|
1787
|
+
},
|
|
1788
|
+
provider: () => {
|
|
1789
|
+
var _a;
|
|
1790
|
+
return typeof window !== "undefined" && ((_a = window == null ? void 0 : window.starkey) == null ? void 0 : _a.supra);
|
|
1791
|
+
}
|
|
1792
|
+
},
|
|
1793
|
+
ribbit: {
|
|
1794
|
+
capabilities: {
|
|
1795
|
+
signMessage: true,
|
|
1796
|
+
accountSwitching: false,
|
|
1797
|
+
// Ribbit doesn't support account switching
|
|
1798
|
+
networkSwitching: false,
|
|
1799
|
+
// Ribbit network switching happens in-app
|
|
1800
|
+
rawTransactions: true,
|
|
1801
|
+
eventListeners: false,
|
|
1802
|
+
tokenRevalidation: false
|
|
1803
|
+
// Ribbit doesn't support token revalidation
|
|
1804
|
+
},
|
|
1805
|
+
provider: () => (0, import_ribbit_wallet_connect2.initSdk)()
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
var WALLET_EVENTS2 = {
|
|
1809
|
+
CONNECTED: "wallet-connected",
|
|
1810
|
+
PRESIGNED_STATE: "presigned-state",
|
|
1811
|
+
POSTSIGNED_STATE: "postsigned-state",
|
|
1812
|
+
ERROR: "wallet-error"
|
|
1813
|
+
};
|
|
1814
|
+
var setStoredWalletType2 = (walletType) => {
|
|
1815
|
+
setStorageItem(STORAGE_KEYS.SELECTED_WALLET, walletType);
|
|
1816
|
+
};
|
|
1817
|
+
var getStoredWalletType2 = () => {
|
|
1818
|
+
const stored = getStorageItem(STORAGE_KEYS.SELECTED_WALLET);
|
|
1819
|
+
if (stored && ["starkey", "ribbit"].includes(stored)) {
|
|
1820
|
+
return stored;
|
|
1821
|
+
}
|
|
1822
|
+
return "starkey";
|
|
1823
|
+
};
|
|
1824
|
+
var clearStoredWalletType2 = () => {
|
|
1825
|
+
removeStorageItem(STORAGE_KEYS.SELECTED_WALLET);
|
|
1826
|
+
};
|
|
1827
|
+
var useSupraMultiWallet2 = () => {
|
|
1828
|
+
const router = (0, import_navigation2.useRouter)();
|
|
1829
|
+
const [selectedWallet, setSelectedWallet] = (0, import_react3.useState)("starkey");
|
|
1830
|
+
const [walletCapabilities, setWalletCapabilities] = (0, import_react3.useState)(
|
|
1831
|
+
WALLET_CONFIGS2["starkey"].capabilities
|
|
1832
|
+
);
|
|
1833
|
+
(0, import_react3.useEffect)(() => {
|
|
1834
|
+
const stored = getStoredWalletType2();
|
|
1835
|
+
if (stored !== "starkey") {
|
|
1836
|
+
setSelectedWallet(stored);
|
|
1837
|
+
setWalletCapabilities(WALLET_CONFIGS2[stored].capabilities);
|
|
1838
|
+
}
|
|
1839
|
+
}, []);
|
|
1840
|
+
const [supraProvider, setSupraProvider] = (0, import_react3.useState)(
|
|
1841
|
+
WALLET_CONFIGS2.starkey.provider()
|
|
1842
|
+
);
|
|
1843
|
+
const [ribbitProvider, setRibbitProvider] = (0, import_react3.useState)(
|
|
1844
|
+
WALLET_CONFIGS2.ribbit.provider()
|
|
1845
|
+
);
|
|
1846
|
+
const [isExtensionInstalled, setIsExtensionInstalled] = (0, import_react3.useState)(false);
|
|
1847
|
+
const [accounts, setAccounts] = (0, import_react3.useState)([]);
|
|
1848
|
+
const [networkData, setNetworkData] = (0, import_react3.useState)();
|
|
1849
|
+
const [balance, setBalance] = (0, import_react3.useState)("");
|
|
1850
|
+
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
1851
|
+
const [justRequestedRelative, setJustRequestedRelative] = (0, import_react3.useState)(false);
|
|
1852
|
+
const [transactions, setTransactions] = (0, import_react3.useState)([]);
|
|
1853
|
+
const [selectedChainId, setSelectedChainId] = (0, import_react3.useState)("");
|
|
1854
|
+
const addTransactions = (hash) => {
|
|
1855
|
+
setTransactions((prev) => [{ hash }, ...prev]);
|
|
1856
|
+
};
|
|
1857
|
+
const getCurrentProvider = () => {
|
|
1858
|
+
switch (selectedWallet) {
|
|
1859
|
+
case "starkey": {
|
|
1860
|
+
return supraProvider;
|
|
1861
|
+
}
|
|
1862
|
+
case "ribbit": {
|
|
1863
|
+
return ribbitProvider;
|
|
1864
|
+
}
|
|
1865
|
+
default: {
|
|
1866
|
+
return supraProvider;
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
};
|
|
1870
|
+
const checkExtensionInstalled = (0, import_react3.useCallback)(async () => {
|
|
1871
|
+
switch (selectedWallet) {
|
|
1872
|
+
case "starkey": {
|
|
1873
|
+
const provider = WALLET_CONFIGS2.starkey.provider();
|
|
1874
|
+
setSupraProvider(provider);
|
|
1875
|
+
setIsExtensionInstalled(!!provider);
|
|
1876
|
+
return !!provider;
|
|
1877
|
+
}
|
|
1878
|
+
case "ribbit": {
|
|
1879
|
+
const provider = WALLET_CONFIGS2.ribbit.provider();
|
|
1880
|
+
if (!provider) {
|
|
1881
|
+
setRibbitProvider(null);
|
|
1882
|
+
setIsExtensionInstalled(false);
|
|
1883
|
+
return false;
|
|
1884
|
+
}
|
|
1885
|
+
try {
|
|
1886
|
+
setRibbitProvider(provider);
|
|
1887
|
+
setIsExtensionInstalled(true);
|
|
1888
|
+
return true;
|
|
1889
|
+
} catch (error) {
|
|
1890
|
+
logger.error("Error checking Ribbit wallet readiness", error);
|
|
1891
|
+
setRibbitProvider(null);
|
|
1892
|
+
setIsExtensionInstalled(false);
|
|
1893
|
+
return false;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
default: {
|
|
1897
|
+
return false;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}, [selectedWallet]);
|
|
1901
|
+
const updateAccounts = (0, import_react3.useCallback)(async () => {
|
|
1902
|
+
const provider = getCurrentProvider();
|
|
1903
|
+
if (!provider) return;
|
|
1904
|
+
try {
|
|
1905
|
+
switch (selectedWallet) {
|
|
1906
|
+
case "starkey": {
|
|
1907
|
+
const responseAcc = await provider.account();
|
|
1908
|
+
const newAccounts = responseAcc.length > 0 ? responseAcc : [];
|
|
1909
|
+
setAccounts(newAccounts);
|
|
1910
|
+
if (responseAcc.length > 0) {
|
|
1911
|
+
setStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS, responseAcc[0]);
|
|
1912
|
+
}
|
|
1913
|
+
if (newAccounts.length > 0) {
|
|
1914
|
+
const balance2 = await provider.balance();
|
|
1915
|
+
if (balance2) {
|
|
1916
|
+
setBalance(`${balance2.formattedBalance} ${balance2.displayUnit}`);
|
|
1917
|
+
}
|
|
1918
|
+
const networkData2 = await provider.getChainId();
|
|
1919
|
+
setNetworkData(networkData2 || {});
|
|
1920
|
+
}
|
|
1921
|
+
break;
|
|
1922
|
+
}
|
|
1923
|
+
case "ribbit": {
|
|
1924
|
+
const wallet = provider.getWalletInfo();
|
|
1925
|
+
if (wallet == null ? void 0 : wallet.connected) {
|
|
1926
|
+
setAccounts([wallet.walletAddress]);
|
|
1927
|
+
const walletBalanceRequest = {
|
|
1928
|
+
chainId: parseInt(getChainId()),
|
|
1929
|
+
resourceType: "0x1::supra_coin::SupraCoin",
|
|
1930
|
+
decimals: 8
|
|
1931
|
+
};
|
|
1932
|
+
const balanceStr = await provider.getWalletBalance(walletBalanceRequest);
|
|
1933
|
+
logger.debug("Ribbit balance response", { balance: balanceStr });
|
|
1934
|
+
setBalance(`${(balanceStr == null ? void 0 : balanceStr.balance) || 0} SUPRA`);
|
|
1935
|
+
} else {
|
|
1936
|
+
setAccounts([]);
|
|
1937
|
+
}
|
|
1938
|
+
break;
|
|
1939
|
+
}
|
|
1940
|
+
default: {
|
|
1941
|
+
setAccounts([]);
|
|
1942
|
+
break;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
} catch (error) {
|
|
1946
|
+
logger.error("Failed to update accounts", error, { walletType: selectedWallet });
|
|
1947
|
+
setAccounts([]);
|
|
1948
|
+
switch (selectedWallet) {
|
|
1949
|
+
case "starkey": {
|
|
1950
|
+
removeStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS);
|
|
1951
|
+
break;
|
|
1952
|
+
}
|
|
1953
|
+
case "ribbit": {
|
|
1954
|
+
break;
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
}, [selectedWallet]);
|
|
1959
|
+
(0, import_react3.useEffect)(() => {
|
|
1960
|
+
let mounted = true;
|
|
1961
|
+
const initProvider = async () => {
|
|
1962
|
+
const isInstalled = await checkExtensionInstalled();
|
|
1963
|
+
if (mounted && isInstalled) {
|
|
1964
|
+
updateAccounts();
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
initProvider();
|
|
1968
|
+
return () => {
|
|
1969
|
+
mounted = false;
|
|
1970
|
+
};
|
|
1971
|
+
}, [selectedWallet, checkExtensionInstalled, updateAccounts]);
|
|
1972
|
+
(0, import_react3.useEffect)(() => {
|
|
1973
|
+
const checkExtension = async () => {
|
|
1974
|
+
return await checkExtensionInstalled();
|
|
1975
|
+
};
|
|
1976
|
+
checkExtension().then((isInstalled) => {
|
|
1977
|
+
if (isInstalled && selectedWallet === "ribbit") {
|
|
1978
|
+
updateAccounts();
|
|
1979
|
+
}
|
|
1980
|
+
});
|
|
1981
|
+
const intv = setInterval(async () => {
|
|
1982
|
+
const isInstalled = await checkExtension();
|
|
1983
|
+
if (isInstalled) {
|
|
1984
|
+
clearInterval(intv);
|
|
1985
|
+
if (selectedWallet === "ribbit") {
|
|
1986
|
+
updateAccounts();
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
}, 1e3);
|
|
1990
|
+
setTimeout(() => {
|
|
1991
|
+
clearInterval(intv);
|
|
1992
|
+
}, TIMEOUTS.WALLET_DETECTION_POLL);
|
|
1993
|
+
return () => clearInterval(intv);
|
|
1994
|
+
}, [selectedWallet, updateAccounts, checkExtensionInstalled]);
|
|
1995
|
+
const checkIsExtensionInstalled = (0, import_react3.useCallback)(() => {
|
|
1996
|
+
const intervalId = setInterval(async () => {
|
|
1997
|
+
const isInstalled = await checkExtensionInstalled();
|
|
1998
|
+
if (isInstalled) {
|
|
1999
|
+
clearInterval(intervalId);
|
|
2000
|
+
updateAccounts();
|
|
2001
|
+
}
|
|
2002
|
+
}, 500);
|
|
2003
|
+
setTimeout(() => clearInterval(intervalId), TIMEOUTS.WALLET_DETECTION_POLL);
|
|
2004
|
+
}, [updateAccounts, checkExtensionInstalled]);
|
|
2005
|
+
const updateBalance = (0, import_react3.useCallback)(async () => {
|
|
2006
|
+
const provider = getCurrentProvider();
|
|
2007
|
+
if (!provider || !accounts.length) {
|
|
2008
|
+
setBalance("");
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
try {
|
|
2012
|
+
switch (selectedWallet) {
|
|
2013
|
+
case "starkey": {
|
|
2014
|
+
const balance2 = await provider.balance();
|
|
2015
|
+
if (balance2) {
|
|
2016
|
+
setBalance(`${balance2.formattedBalance} ${balance2.displayUnit}`);
|
|
2017
|
+
}
|
|
2018
|
+
break;
|
|
2019
|
+
}
|
|
2020
|
+
case "ribbit": {
|
|
2021
|
+
const walletBalanceRequest = {
|
|
2022
|
+
chainId: parseInt(getChainId()),
|
|
2023
|
+
resourceType: "0x1::supra_coin::SupraCoin",
|
|
2024
|
+
decimals: 8
|
|
2025
|
+
};
|
|
2026
|
+
const balanceStr = await provider.getWalletBalance(
|
|
2027
|
+
walletBalanceRequest
|
|
2028
|
+
);
|
|
2029
|
+
logger.debug("Ribbit balance response", { balance: balanceStr });
|
|
2030
|
+
setBalance(`${(balanceStr == null ? void 0 : balanceStr.balance) || 0} SUPRA`);
|
|
2031
|
+
break;
|
|
2032
|
+
}
|
|
2033
|
+
default: {
|
|
2034
|
+
setBalance("");
|
|
2035
|
+
break;
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
logger.error("Failed to update balance", error, { walletType: selectedWallet });
|
|
2040
|
+
setBalance("");
|
|
2041
|
+
}
|
|
2042
|
+
}, [selectedWallet, accounts]);
|
|
2043
|
+
const getNetworkData = (0, import_react3.useCallback)(async () => {
|
|
2044
|
+
const provider = getCurrentProvider();
|
|
2045
|
+
if (!provider) return {};
|
|
2046
|
+
try {
|
|
2047
|
+
switch (selectedWallet) {
|
|
2048
|
+
case "starkey": {
|
|
2049
|
+
const data = await provider.getChainId();
|
|
2050
|
+
setNetworkData(data || {});
|
|
2051
|
+
return data || {};
|
|
2052
|
+
}
|
|
2053
|
+
case "ribbit": {
|
|
2054
|
+
const chainId = parseInt(getChainId());
|
|
2055
|
+
const mockNetworkData = { chainId: chainId.toString() };
|
|
2056
|
+
setNetworkData(mockNetworkData);
|
|
2057
|
+
return mockNetworkData;
|
|
2058
|
+
}
|
|
2059
|
+
default: {
|
|
2060
|
+
setNetworkData({});
|
|
2061
|
+
return {};
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
} catch (error) {
|
|
2065
|
+
logger.error("Failed to get network data", error, { walletType: selectedWallet });
|
|
2066
|
+
setNetworkData({});
|
|
2067
|
+
return {};
|
|
2068
|
+
}
|
|
2069
|
+
}, [selectedWallet]);
|
|
2070
|
+
const connectWallet = async (walletType) => {
|
|
2071
|
+
if (walletType) {
|
|
2072
|
+
updateSelectedWallet(walletType);
|
|
2073
|
+
}
|
|
2074
|
+
const provider = walletType ? WALLET_CONFIGS2[walletType].provider() : getCurrentProvider();
|
|
2075
|
+
if (!provider) {
|
|
2076
|
+
const error = new WalletNotInstalledError(walletType || selectedWallet);
|
|
2077
|
+
logger.warn("Wallet not installed", { walletType: walletType || selectedWallet });
|
|
2078
|
+
import_sonner3.toast.error(ERROR_MESSAGES.WALLET_NOT_INSTALLED, {
|
|
2079
|
+
description: `Please install the ${walletType || selectedWallet} extension`
|
|
2080
|
+
});
|
|
2081
|
+
return false;
|
|
2082
|
+
}
|
|
2083
|
+
setLoading(true);
|
|
2084
|
+
try {
|
|
2085
|
+
switch (walletType || selectedWallet) {
|
|
2086
|
+
case "starkey": {
|
|
2087
|
+
await provider.connect();
|
|
2088
|
+
logger.info("Starkey wallet connection approved");
|
|
2089
|
+
await updateAccounts();
|
|
2090
|
+
const responseAcc = await provider.account();
|
|
2091
|
+
if (responseAcc.length === 0) {
|
|
2092
|
+
throw new WalletConnectionError(ERROR_MESSAGES.NO_ACCOUNT_FOUND);
|
|
2093
|
+
}
|
|
2094
|
+
if (responseAcc.length) {
|
|
2095
|
+
setAccounts(responseAcc);
|
|
2096
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2097
|
+
setStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS, responseAcc[0]);
|
|
2098
|
+
window.dispatchEvent(
|
|
2099
|
+
new CustomEvent(WALLET_EVENTS2.PRESIGNED_STATE, {
|
|
2100
|
+
detail: {
|
|
2101
|
+
timestamp: Date.now(),
|
|
2102
|
+
account: responseAcc[0]
|
|
2103
|
+
}
|
|
2104
|
+
})
|
|
2105
|
+
);
|
|
2106
|
+
window.dispatchEvent(
|
|
2107
|
+
new CustomEvent(WALLET_EVENTS2.CONNECTED, {
|
|
2108
|
+
detail: {
|
|
2109
|
+
timestamp: Date.now(),
|
|
2110
|
+
account: responseAcc[0],
|
|
2111
|
+
wallet: "starkey"
|
|
2112
|
+
}
|
|
2113
|
+
})
|
|
2114
|
+
);
|
|
2115
|
+
try {
|
|
2116
|
+
const message = "To verify your account, please sign this message.";
|
|
2117
|
+
const nonce = generateNonce();
|
|
2118
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
2119
|
+
logger.debug("Signature request initiated", { account: responseAcc[0] });
|
|
2120
|
+
const signatureResponse = await provider.signMessage({
|
|
2121
|
+
message: hexMessage,
|
|
2122
|
+
nonce
|
|
2123
|
+
});
|
|
2124
|
+
if (signatureResponse) {
|
|
2125
|
+
logger.info("Signature approved", { account: responseAcc[0] });
|
|
2126
|
+
window.dispatchEvent(
|
|
2127
|
+
new CustomEvent(WALLET_EVENTS2.POSTSIGNED_STATE, {
|
|
2128
|
+
detail: {
|
|
2129
|
+
timestamp: Date.now(),
|
|
2130
|
+
account: responseAcc[0]
|
|
2131
|
+
}
|
|
2132
|
+
})
|
|
2133
|
+
);
|
|
2134
|
+
}
|
|
2135
|
+
} catch (signError) {
|
|
2136
|
+
const error = new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, signError);
|
|
2137
|
+
logger.error("Signing failed", error, { account: responseAcc[0] });
|
|
2138
|
+
window.dispatchEvent(
|
|
2139
|
+
new CustomEvent(WALLET_EVENTS2.ERROR, {
|
|
2140
|
+
detail: {
|
|
2141
|
+
timestamp: Date.now(),
|
|
2142
|
+
error
|
|
2143
|
+
}
|
|
2144
|
+
})
|
|
2145
|
+
);
|
|
2146
|
+
throw error;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
break;
|
|
2150
|
+
}
|
|
2151
|
+
case "ribbit": {
|
|
2152
|
+
const dappMetadata = {
|
|
2153
|
+
name: "multiwallet",
|
|
2154
|
+
description: "NFT Marketplace and Lootbox Platform",
|
|
2155
|
+
logo: window.location.origin + "/favicon.ico",
|
|
2156
|
+
url: window.location.origin
|
|
2157
|
+
};
|
|
2158
|
+
const response = await provider.connectToWallet(
|
|
2159
|
+
dappMetadata
|
|
2160
|
+
);
|
|
2161
|
+
if (response == null ? void 0 : response.connected) {
|
|
2162
|
+
logger.info("Ribbit wallet connection approved");
|
|
2163
|
+
}
|
|
2164
|
+
if (response.walletAddress == null) {
|
|
2165
|
+
throw new WalletConnectionError(ERROR_MESSAGES.NO_ACCOUNT_FOUND);
|
|
2166
|
+
}
|
|
2167
|
+
if (response == null ? void 0 : response.connected) {
|
|
2168
|
+
await updateAccounts();
|
|
2169
|
+
if (response.walletAddress) {
|
|
2170
|
+
setAccounts([response.walletAddress]);
|
|
2171
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2172
|
+
window.dispatchEvent(
|
|
2173
|
+
new CustomEvent(WALLET_EVENTS2.PRESIGNED_STATE, {
|
|
2174
|
+
detail: {
|
|
2175
|
+
timestamp: Date.now(),
|
|
2176
|
+
account: response.walletAddress
|
|
2177
|
+
}
|
|
2178
|
+
})
|
|
2179
|
+
);
|
|
2180
|
+
window.dispatchEvent(
|
|
2181
|
+
new CustomEvent(WALLET_EVENTS2.CONNECTED, {
|
|
2182
|
+
detail: {
|
|
2183
|
+
timestamp: Date.now(),
|
|
2184
|
+
account: response.walletAddress,
|
|
2185
|
+
wallet: "ribbit"
|
|
2186
|
+
}
|
|
2187
|
+
})
|
|
2188
|
+
);
|
|
2189
|
+
try {
|
|
2190
|
+
const message = "To verify your account, please sign this message.";
|
|
2191
|
+
const nonce = generateNonce();
|
|
2192
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
2193
|
+
logger.debug("Signature request initiated", { account: response.walletAddress });
|
|
2194
|
+
const signatureResponse = await provider.signMessage({
|
|
2195
|
+
message: hexMessage,
|
|
2196
|
+
nonce: parseInt(nonce),
|
|
2197
|
+
chainId: parseInt(getChainId())
|
|
2198
|
+
});
|
|
2199
|
+
if (signatureResponse && signatureResponse.approved) {
|
|
2200
|
+
logger.info("Signature approved", { account: response.walletAddress });
|
|
2201
|
+
window.dispatchEvent(
|
|
2202
|
+
new CustomEvent(WALLET_EVENTS2.POSTSIGNED_STATE, {
|
|
2203
|
+
detail: {
|
|
2204
|
+
timestamp: Date.now(),
|
|
2205
|
+
account: response.walletAddress
|
|
2206
|
+
}
|
|
2207
|
+
})
|
|
2208
|
+
);
|
|
2209
|
+
} else {
|
|
2210
|
+
throw new SignMessageError(signatureResponse.error || ERROR_MESSAGES.SIGNING_REJECTED);
|
|
2211
|
+
}
|
|
2212
|
+
} catch (signError) {
|
|
2213
|
+
const error = new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, signError);
|
|
2214
|
+
logger.error("Signing failed", error, { account: response.walletAddress });
|
|
2215
|
+
window.dispatchEvent(
|
|
2216
|
+
new CustomEvent(WALLET_EVENTS2.ERROR, {
|
|
2217
|
+
detail: {
|
|
2218
|
+
timestamp: Date.now(),
|
|
2219
|
+
error
|
|
2220
|
+
}
|
|
2221
|
+
})
|
|
2222
|
+
);
|
|
2223
|
+
throw error;
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
} else {
|
|
2227
|
+
throw new WalletConnectionError(ERROR_MESSAGES.CONNECTION_REJECTED);
|
|
2228
|
+
}
|
|
2229
|
+
break;
|
|
2230
|
+
}
|
|
2231
|
+
default: {
|
|
2232
|
+
throw new WalletConnectionError(
|
|
2233
|
+
`${ERROR_MESSAGES.UNSUPPORTED_WALLET}: ${walletType || selectedWallet}`
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
return true;
|
|
2238
|
+
} catch (error) {
|
|
2239
|
+
const walletError = error instanceof WalletConnectionError ? error : new WalletConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
|
|
2240
|
+
logger.error("Wallet connection failed", walletError, {
|
|
2241
|
+
walletType: walletType || selectedWallet
|
|
2242
|
+
});
|
|
2243
|
+
window.dispatchEvent(
|
|
2244
|
+
new CustomEvent(WALLET_EVENTS2.ERROR, {
|
|
2245
|
+
detail: {
|
|
2246
|
+
timestamp: Date.now(),
|
|
2247
|
+
error: walletError
|
|
2248
|
+
}
|
|
2249
|
+
})
|
|
2250
|
+
);
|
|
2251
|
+
return false;
|
|
2252
|
+
} finally {
|
|
2253
|
+
setLoading(false);
|
|
2254
|
+
}
|
|
2255
|
+
};
|
|
2256
|
+
const disconnectWallet = async () => {
|
|
2257
|
+
const provider = getCurrentProvider();
|
|
2258
|
+
if (!provider) return;
|
|
2259
|
+
try {
|
|
2260
|
+
switch (selectedWallet) {
|
|
2261
|
+
case "starkey": {
|
|
2262
|
+
await provider.disconnect();
|
|
2263
|
+
break;
|
|
2264
|
+
}
|
|
2265
|
+
case "ribbit": {
|
|
2266
|
+
await provider.disconnect();
|
|
2267
|
+
break;
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
resetWalletData();
|
|
2271
|
+
clearStoredWalletType2();
|
|
2272
|
+
router.push("/");
|
|
2273
|
+
} catch (error) {
|
|
2274
|
+
logger.error("Wallet disconnect failed", error, { walletType: selectedWallet });
|
|
2275
|
+
resetWalletData();
|
|
2276
|
+
clearStoredWalletType2();
|
|
2277
|
+
}
|
|
2278
|
+
};
|
|
2279
|
+
const resetWalletData = () => {
|
|
2280
|
+
setAccounts([]);
|
|
2281
|
+
setBalance("");
|
|
2282
|
+
setNetworkData({});
|
|
2283
|
+
switch (selectedWallet) {
|
|
2284
|
+
case "starkey": {
|
|
2285
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2286
|
+
removeStorageItem(STORAGE_KEYS.STARKEY_ACCOUNTS);
|
|
2287
|
+
break;
|
|
2288
|
+
}
|
|
2289
|
+
case "ribbit": {
|
|
2290
|
+
break;
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
};
|
|
2294
|
+
const getSequenceNumber = async (address) => {
|
|
2295
|
+
const rpcUrl = getRpcUrl();
|
|
2296
|
+
const data = await fetch(`${rpcUrl}/rpc/v1/accounts/${address}`);
|
|
2297
|
+
if (!data.ok) {
|
|
2298
|
+
throw new NetworkError(`Failed to fetch sequence number for ${address}`);
|
|
2299
|
+
}
|
|
2300
|
+
const accountData = await data.json();
|
|
2301
|
+
return accountData.sequence_number;
|
|
2302
|
+
};
|
|
2303
|
+
const sendRawTransaction = async (moduleAddress, moduleName, functionName, params, runTimeParams = [], txExpiryTime = Math.ceil(Date.now() / 1e3) + 3e3) => {
|
|
2304
|
+
const provider = getCurrentProvider();
|
|
2305
|
+
if (!provider || !accounts.length || !moduleAddress || !moduleName || !functionName)
|
|
2306
|
+
return;
|
|
2307
|
+
try {
|
|
2308
|
+
switch (selectedWallet) {
|
|
2309
|
+
case "starkey": {
|
|
2310
|
+
if (!walletCapabilities.rawTransactions) {
|
|
2311
|
+
throw new TransactionError("Raw transactions not supported by current wallet");
|
|
2312
|
+
}
|
|
2313
|
+
let networkData2 = await getNetworkData();
|
|
2314
|
+
const currentChainId = getChainId();
|
|
2315
|
+
if (networkData2.chainId !== currentChainId) {
|
|
2316
|
+
setSelectedChainId(currentChainId);
|
|
2317
|
+
await provider.changeNetwork({
|
|
2318
|
+
chainId: currentChainId
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
const rawTxPayload = [
|
|
2322
|
+
accounts[0],
|
|
2323
|
+
0,
|
|
2324
|
+
// sequence number
|
|
2325
|
+
moduleAddress,
|
|
2326
|
+
moduleName,
|
|
2327
|
+
functionName,
|
|
2328
|
+
runTimeParams,
|
|
2329
|
+
params,
|
|
2330
|
+
{}
|
|
2331
|
+
];
|
|
2332
|
+
const data = await provider.createRawTransactionData(rawTxPayload);
|
|
2333
|
+
const txHash = await provider.sendTransaction({
|
|
2334
|
+
data,
|
|
2335
|
+
from: accounts[0],
|
|
2336
|
+
to: moduleAddress,
|
|
2337
|
+
chainId: currentChainId,
|
|
2338
|
+
value: ""
|
|
2339
|
+
});
|
|
2340
|
+
addTransactions(txHash || "failed");
|
|
2341
|
+
logger.info("Transaction sent successfully", { txHash, walletType: "starkey" });
|
|
2342
|
+
return txHash;
|
|
2343
|
+
}
|
|
2344
|
+
case "ribbit": {
|
|
2345
|
+
if (!walletCapabilities.rawTransactions) {
|
|
2346
|
+
throw new TransactionError("Raw transactions not supported by current wallet");
|
|
2347
|
+
}
|
|
2348
|
+
const currentChainId = getChainId();
|
|
2349
|
+
let chainId = import_ribbit_wallet_connect2.SupraChainId.TESTNET;
|
|
2350
|
+
if (currentChainId === DEFAULT_CHAIN_IDS.TESTNET) {
|
|
2351
|
+
chainId = import_ribbit_wallet_connect2.SupraChainId.TESTNET;
|
|
2352
|
+
} else if (currentChainId === DEFAULT_CHAIN_IDS.MAINNET) {
|
|
2353
|
+
chainId = import_ribbit_wallet_connect2.SupraChainId.MAINNET;
|
|
2354
|
+
}
|
|
2355
|
+
const rawTxnRequest = {
|
|
2356
|
+
sender: accounts[0],
|
|
2357
|
+
// Use actual sender address
|
|
2358
|
+
moduleAddress,
|
|
2359
|
+
// Use provided module address
|
|
2360
|
+
moduleName,
|
|
2361
|
+
// Use provided module name
|
|
2362
|
+
functionName,
|
|
2363
|
+
// Use provided function name
|
|
2364
|
+
typeArgs: runTimeParams,
|
|
2365
|
+
// Use converted runtime parameters
|
|
2366
|
+
args: params || [],
|
|
2367
|
+
// Use provided parameters
|
|
2368
|
+
chainId
|
|
2369
|
+
};
|
|
2370
|
+
const rawTxnBase64 = await provider.createRawTransactionBuffer(rawTxnRequest);
|
|
2371
|
+
const response = await provider.signAndSendRawTransaction({
|
|
2372
|
+
rawTxn: rawTxnBase64,
|
|
2373
|
+
chainId,
|
|
2374
|
+
meta: {
|
|
2375
|
+
description: `Call ${moduleName}::${functionName}`
|
|
2376
|
+
// Dynamic description
|
|
2377
|
+
}
|
|
2378
|
+
});
|
|
2379
|
+
if (response.approved) {
|
|
2380
|
+
const txHash = response.txHash || response.result || "success";
|
|
2381
|
+
addTransactions(txHash);
|
|
2382
|
+
logger.info("Transaction sent successfully", { txHash, walletType: "ribbit" });
|
|
2383
|
+
return txHash;
|
|
2384
|
+
} else {
|
|
2385
|
+
throw new TransactionError(response.error || ERROR_MESSAGES.TRANSACTION_REJECTED);
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
default: {
|
|
2389
|
+
throw new TransactionError(
|
|
2390
|
+
`Raw transactions not supported for wallet: ${selectedWallet}`
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
} catch (error) {
|
|
2395
|
+
const txError = error instanceof TransactionError ? error : new TransactionError(ERROR_MESSAGES.TRANSACTION_FAILED, void 0, error);
|
|
2396
|
+
logger.error("Transaction failed", txError, {
|
|
2397
|
+
walletType: selectedWallet,
|
|
2398
|
+
moduleAddress,
|
|
2399
|
+
moduleName,
|
|
2400
|
+
functionName
|
|
2401
|
+
});
|
|
2402
|
+
throw txError;
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
const signMessage = async (message, nonce, account, forceSign = false) => {
|
|
2406
|
+
const provider = getCurrentProvider();
|
|
2407
|
+
if (!provider) return;
|
|
2408
|
+
const secureNonce = nonce || generateNonce();
|
|
2409
|
+
switch (selectedWallet) {
|
|
2410
|
+
case "starkey": {
|
|
2411
|
+
if (!walletCapabilities.signMessage) {
|
|
2412
|
+
throw new SignMessageError("Message signing not supported by current wallet");
|
|
2413
|
+
}
|
|
2414
|
+
if (!accounts.length && !account) return;
|
|
2415
|
+
if (!accounts.length && account) {
|
|
2416
|
+
accounts[0] = account;
|
|
2417
|
+
}
|
|
2418
|
+
if (getStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET) === "true" && !forceSign) {
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "true");
|
|
2422
|
+
try {
|
|
2423
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
2424
|
+
const response = await provider.signMessage({
|
|
2425
|
+
message: hexMessage,
|
|
2426
|
+
nonce: secureNonce
|
|
2427
|
+
});
|
|
2428
|
+
const { publicKey, signature } = response;
|
|
2429
|
+
const verified = import_tweetnacl2.default.sign.detached.verify(
|
|
2430
|
+
new TextEncoder().encode(message),
|
|
2431
|
+
Uint8Array.from(Buffer.from(signature.slice(2), "hex")),
|
|
2432
|
+
Uint8Array.from(Buffer.from(publicKey.slice(2), "hex"))
|
|
2433
|
+
);
|
|
2434
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2435
|
+
logger.info("Message signed successfully", { walletType: "starkey" });
|
|
2436
|
+
return __spreadProps(__spreadValues({}, response), { verified });
|
|
2437
|
+
} catch (error) {
|
|
2438
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2439
|
+
throw new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, error);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
case "ribbit": {
|
|
2443
|
+
if (!walletCapabilities.signMessage) {
|
|
2444
|
+
throw new SignMessageError("Message signing not supported by current wallet");
|
|
2445
|
+
}
|
|
2446
|
+
if (!accounts.length && !account) return;
|
|
2447
|
+
if (!accounts.length && account) {
|
|
2448
|
+
accounts[0] = account;
|
|
2449
|
+
}
|
|
2450
|
+
if (getStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET) === "true" && !forceSign) {
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "true");
|
|
2454
|
+
try {
|
|
2455
|
+
const hexMessage = "0x" + Buffer.from(message, "utf8").toString("hex");
|
|
2456
|
+
const response = await provider.signMessage({
|
|
2457
|
+
message: hexMessage,
|
|
2458
|
+
nonce: parseInt(secureNonce),
|
|
2459
|
+
chainId: parseInt(getChainId())
|
|
2460
|
+
});
|
|
2461
|
+
if (response.approved && response.publicKey && response.signature) {
|
|
2462
|
+
const { publicKey, signature } = response;
|
|
2463
|
+
const verified = import_tweetnacl2.default.sign.detached.verify(
|
|
2464
|
+
new TextEncoder().encode(message),
|
|
2465
|
+
Uint8Array.from(Buffer.from(signature.slice(2), "hex")),
|
|
2466
|
+
Uint8Array.from(Buffer.from(publicKey.slice(2), "hex"))
|
|
2467
|
+
);
|
|
2468
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2469
|
+
logger.info("Message signed successfully", { walletType: "ribbit" });
|
|
2470
|
+
return __spreadProps(__spreadValues({}, response), { verified });
|
|
2471
|
+
} else {
|
|
2472
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2473
|
+
throw new SignMessageError(response.error || ERROR_MESSAGES.SIGNING_REJECTED);
|
|
2474
|
+
}
|
|
2475
|
+
} catch (error) {
|
|
2476
|
+
setStorageItem(STORAGE_KEYS.IS_SIGNING_WALLET, "false");
|
|
2477
|
+
throw new SignMessageError(ERROR_MESSAGES.SIGNING_FAILED, error);
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
default: {
|
|
2481
|
+
throw new SignMessageError(
|
|
2482
|
+
`Message signing not supported for wallet: ${selectedWallet}`
|
|
2483
|
+
);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
};
|
|
2487
|
+
(0, import_react3.useEffect)(() => {
|
|
2488
|
+
if (selectedWallet === "starkey" && walletCapabilities.eventListeners) {
|
|
2489
|
+
const handleExtensionEvents = (event) => {
|
|
2490
|
+
var _a, _b, _c;
|
|
2491
|
+
if ((_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("starkey-")) {
|
|
2492
|
+
switch ((_c = event == null ? void 0 : event.data) == null ? void 0 : _c.name) {
|
|
2493
|
+
case "starkey-extension-installed": {
|
|
2494
|
+
checkIsExtensionInstalled();
|
|
2495
|
+
break;
|
|
2496
|
+
}
|
|
2497
|
+
case "starkey-wallet-updated": {
|
|
2498
|
+
(async () => {
|
|
2499
|
+
const responseAcc = await supraProvider.account();
|
|
2500
|
+
if (responseAcc.length) {
|
|
2501
|
+
setAccounts(responseAcc);
|
|
2502
|
+
window.dispatchEvent(
|
|
2503
|
+
new CustomEvent(WALLET_EVENTS2.CONNECTED, {
|
|
2504
|
+
detail: {
|
|
2505
|
+
timestamp: Date.now(),
|
|
2506
|
+
account: responseAcc[0]
|
|
2507
|
+
}
|
|
2508
|
+
})
|
|
2509
|
+
);
|
|
2510
|
+
await updateBalance();
|
|
2511
|
+
await getNetworkData();
|
|
2512
|
+
} else {
|
|
2513
|
+
logger.debug("Starkey wallet updated: No accounts found - Resetting");
|
|
2514
|
+
resetWalletData();
|
|
2515
|
+
}
|
|
2516
|
+
setLoading(false);
|
|
2517
|
+
})();
|
|
2518
|
+
break;
|
|
2519
|
+
}
|
|
2520
|
+
case "starkey-wallet-disconnected": {
|
|
2521
|
+
resetWalletData();
|
|
2522
|
+
router.push("/");
|
|
2523
|
+
setLoading(false);
|
|
2524
|
+
break;
|
|
2525
|
+
}
|
|
2526
|
+
case "starkey-window-removed": {
|
|
2527
|
+
setLoading(false);
|
|
2528
|
+
break;
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
checkIsExtensionInstalled();
|
|
2534
|
+
window.addEventListener("message", handleExtensionEvents);
|
|
2535
|
+
return () => window.removeEventListener("message", handleExtensionEvents);
|
|
2536
|
+
}
|
|
2537
|
+
}, [selectedWallet, walletCapabilities, supraProvider]);
|
|
2538
|
+
const getAvailableWallets = (0, import_react3.useCallback)(() => {
|
|
2539
|
+
const availableWallets = [];
|
|
2540
|
+
Object.entries(WALLET_CONFIGS2).forEach(([walletType, config2]) => {
|
|
2541
|
+
const provider = config2.provider();
|
|
2542
|
+
const isInstalled = !!provider;
|
|
2543
|
+
switch (walletType) {
|
|
2544
|
+
case "starkey": {
|
|
2545
|
+
availableWallets.push({
|
|
2546
|
+
type: "starkey",
|
|
2547
|
+
name: "Starkey Wallet",
|
|
2548
|
+
isInstalled,
|
|
2549
|
+
capabilities: config2.capabilities
|
|
2550
|
+
});
|
|
2551
|
+
break;
|
|
2552
|
+
}
|
|
2553
|
+
case "ribbit": {
|
|
2554
|
+
availableWallets.push({
|
|
2555
|
+
type: "ribbit",
|
|
2556
|
+
name: "Ribbit Wallet",
|
|
2557
|
+
isInstalled,
|
|
2558
|
+
capabilities: config2.capabilities
|
|
2559
|
+
});
|
|
2560
|
+
break;
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
});
|
|
2564
|
+
return availableWallets;
|
|
2565
|
+
}, []);
|
|
2566
|
+
const updateSelectedWallet = (walletType) => {
|
|
2567
|
+
setSelectedWallet(walletType);
|
|
2568
|
+
setWalletCapabilities(WALLET_CONFIGS2[walletType].capabilities);
|
|
2569
|
+
setStoredWalletType2(walletType);
|
|
2570
|
+
};
|
|
2571
|
+
return {
|
|
2572
|
+
// New wallet selection functionality
|
|
2573
|
+
selectedWallet,
|
|
2574
|
+
walletCapabilities,
|
|
2575
|
+
getAvailableWallets,
|
|
2576
|
+
// Add this new function
|
|
2577
|
+
// Existing interface (unchanged)
|
|
2578
|
+
getCurrentProvider,
|
|
2579
|
+
isExtensionInstalled,
|
|
2580
|
+
accounts,
|
|
2581
|
+
networkData,
|
|
2582
|
+
balance,
|
|
2583
|
+
transactions,
|
|
2584
|
+
selectedChainId,
|
|
2585
|
+
connectWallet,
|
|
2586
|
+
// Now accepts optional walletType parameter
|
|
2587
|
+
disconnectWallet,
|
|
2588
|
+
sendRawTransaction,
|
|
2589
|
+
signMessage,
|
|
2590
|
+
setSelectedChainId,
|
|
2591
|
+
// switchToChain,
|
|
2592
|
+
loading
|
|
2593
|
+
// authFetch,
|
|
2594
|
+
// checkAndRevalidateToken,
|
|
2595
|
+
// signIn,
|
|
2596
|
+
};
|
|
2597
|
+
};
|
|
2598
|
+
var useSupraMultiWallet_default2 = useSupraMultiWallet2;
|
|
2599
|
+
|
|
2600
|
+
// src/hooks/useConversionUtils.ts
|
|
2601
|
+
var import_react4 = require("react");
|
|
2602
|
+
var import_supra_l1_sdk_core = require("supra-l1-sdk-core");
|
|
2603
|
+
|
|
2604
|
+
// src/lib/abis/supra_account.ts
|
|
2605
|
+
var supraAccountABI = {
|
|
2606
|
+
address: "0x1",
|
|
2607
|
+
name: "supra_account",
|
|
2608
|
+
friends: [
|
|
2609
|
+
"0x1::genesis",
|
|
2610
|
+
"0x1::resource_account",
|
|
2611
|
+
"0x1::transaction_fee",
|
|
2612
|
+
"0x1::transaction_validation"
|
|
2613
|
+
],
|
|
2614
|
+
exposed_functions: [
|
|
2615
|
+
{
|
|
2616
|
+
name: "assert_account_exists",
|
|
2617
|
+
visibility: "public",
|
|
2618
|
+
is_entry: false,
|
|
2619
|
+
is_view: false,
|
|
2620
|
+
generic_type_params: [],
|
|
2621
|
+
params: ["address"],
|
|
2622
|
+
return: []
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
name: "assert_account_is_registered_for_apt",
|
|
2626
|
+
visibility: "public",
|
|
2627
|
+
is_entry: false,
|
|
2628
|
+
is_view: false,
|
|
2629
|
+
generic_type_params: [],
|
|
2630
|
+
params: ["address"],
|
|
2631
|
+
return: []
|
|
2632
|
+
},
|
|
2633
|
+
{
|
|
2634
|
+
name: "assert_account_is_registered_for_supra",
|
|
2635
|
+
visibility: "public",
|
|
2636
|
+
is_entry: false,
|
|
2637
|
+
is_view: false,
|
|
2638
|
+
generic_type_params: [],
|
|
2639
|
+
params: ["address"],
|
|
2640
|
+
return: []
|
|
2641
|
+
},
|
|
2642
|
+
{
|
|
2643
|
+
name: "batch_transfer",
|
|
2644
|
+
visibility: "public",
|
|
2645
|
+
is_entry: true,
|
|
2646
|
+
is_view: false,
|
|
2647
|
+
generic_type_params: [],
|
|
2648
|
+
params: ["&signer", "vector<address>", "vector<u64>"],
|
|
2649
|
+
return: []
|
|
2650
|
+
},
|
|
2651
|
+
{
|
|
2652
|
+
name: "batch_transfer_coins",
|
|
2653
|
+
visibility: "public",
|
|
2654
|
+
is_entry: true,
|
|
2655
|
+
is_view: false,
|
|
2656
|
+
generic_type_params: [{ constraints: [] }],
|
|
2657
|
+
params: ["&signer", "vector<address>", "vector<u64>"],
|
|
2658
|
+
return: []
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
name: "burn_from_fungible_store",
|
|
2662
|
+
visibility: "friend",
|
|
2663
|
+
is_entry: false,
|
|
2664
|
+
is_view: false,
|
|
2665
|
+
generic_type_params: [],
|
|
2666
|
+
params: ["&0x1::fungible_asset::BurnRef", "address", "u64"],
|
|
2667
|
+
return: []
|
|
2668
|
+
},
|
|
2669
|
+
{
|
|
2670
|
+
name: "can_receive_direct_coin_transfers",
|
|
2671
|
+
visibility: "public",
|
|
2672
|
+
is_entry: false,
|
|
2673
|
+
is_view: true,
|
|
2674
|
+
generic_type_params: [],
|
|
2675
|
+
params: ["address"],
|
|
2676
|
+
return: ["bool"]
|
|
2677
|
+
},
|
|
2678
|
+
{
|
|
2679
|
+
name: "create_account",
|
|
2680
|
+
visibility: "public",
|
|
2681
|
+
is_entry: true,
|
|
2682
|
+
is_view: false,
|
|
2683
|
+
generic_type_params: [],
|
|
2684
|
+
params: ["address"],
|
|
2685
|
+
return: []
|
|
2686
|
+
},
|
|
2687
|
+
{
|
|
2688
|
+
name: "deposit_coins",
|
|
2689
|
+
visibility: "public",
|
|
2690
|
+
is_entry: false,
|
|
2691
|
+
is_view: false,
|
|
2692
|
+
generic_type_params: [{ constraints: [] }],
|
|
2693
|
+
params: ["address", "0x1::coin::Coin<T0>"],
|
|
2694
|
+
return: []
|
|
2695
|
+
},
|
|
2696
|
+
{
|
|
2697
|
+
name: "is_fungible_balance_at_least",
|
|
2698
|
+
visibility: "friend",
|
|
2699
|
+
is_entry: false,
|
|
2700
|
+
is_view: false,
|
|
2701
|
+
generic_type_params: [],
|
|
2702
|
+
params: ["address", "u64"],
|
|
2703
|
+
return: ["bool"]
|
|
2704
|
+
},
|
|
2705
|
+
{
|
|
2706
|
+
name: "register_supra",
|
|
2707
|
+
visibility: "friend",
|
|
2708
|
+
is_entry: false,
|
|
2709
|
+
is_view: false,
|
|
2710
|
+
generic_type_params: [],
|
|
2711
|
+
params: ["&signer"],
|
|
2712
|
+
return: []
|
|
2713
|
+
},
|
|
2714
|
+
{
|
|
2715
|
+
name: "set_allow_direct_coin_transfers",
|
|
2716
|
+
visibility: "public",
|
|
2717
|
+
is_entry: true,
|
|
2718
|
+
is_view: false,
|
|
2719
|
+
generic_type_params: [],
|
|
2720
|
+
params: ["&signer", "bool"],
|
|
2721
|
+
return: []
|
|
2722
|
+
},
|
|
2723
|
+
{
|
|
2724
|
+
name: "transfer",
|
|
2725
|
+
visibility: "public",
|
|
2726
|
+
is_entry: true,
|
|
2727
|
+
is_view: false,
|
|
2728
|
+
generic_type_params: [],
|
|
2729
|
+
params: ["&signer", "address", "u64"],
|
|
2730
|
+
return: []
|
|
2731
|
+
},
|
|
2732
|
+
{
|
|
2733
|
+
name: "transfer_coins",
|
|
2734
|
+
visibility: "public",
|
|
2735
|
+
is_entry: true,
|
|
2736
|
+
is_view: false,
|
|
2737
|
+
generic_type_params: [{ constraints: [] }],
|
|
2738
|
+
params: ["&signer", "address", "u64"],
|
|
2739
|
+
return: []
|
|
2740
|
+
}
|
|
2741
|
+
],
|
|
2742
|
+
structs: [
|
|
2743
|
+
{
|
|
2744
|
+
name: "DirectCoinTransferConfigUpdated",
|
|
2745
|
+
is_native: false,
|
|
2746
|
+
abilities: ["drop", "store"],
|
|
2747
|
+
generic_type_params: [],
|
|
2748
|
+
fields: [
|
|
2749
|
+
{ name: "account", type: "address" },
|
|
2750
|
+
{ name: "new_allow_direct_transfers", type: "bool" }
|
|
2751
|
+
]
|
|
2752
|
+
},
|
|
2753
|
+
{
|
|
2754
|
+
name: "DirectCoinTransferConfigUpdatedEvent",
|
|
2755
|
+
is_native: false,
|
|
2756
|
+
abilities: ["drop", "store"],
|
|
2757
|
+
generic_type_params: [],
|
|
2758
|
+
fields: [{ name: "new_allow_direct_transfers", type: "bool" }]
|
|
2759
|
+
},
|
|
2760
|
+
{
|
|
2761
|
+
name: "DirectTransferConfig",
|
|
2762
|
+
is_native: false,
|
|
2763
|
+
abilities: ["key"],
|
|
2764
|
+
generic_type_params: [],
|
|
2765
|
+
fields: [
|
|
2766
|
+
{ name: "allow_arbitrary_coin_transfers", type: "bool" },
|
|
2767
|
+
{
|
|
2768
|
+
name: "update_coin_transfer_events",
|
|
2769
|
+
type: "0x1::event::EventHandle<0x1::supra_account::DirectCoinTransferConfigUpdatedEvent>"
|
|
2770
|
+
}
|
|
2771
|
+
]
|
|
2772
|
+
}
|
|
2773
|
+
]
|
|
2774
|
+
};
|
|
2775
|
+
|
|
2776
|
+
// src/lib/utils.ts
|
|
2777
|
+
var import_clsx2 = require("clsx");
|
|
2778
|
+
var import_tailwind_merge2 = require("tailwind-merge");
|
|
2779
|
+
function cn2(...inputs) {
|
|
2780
|
+
return (0, import_tailwind_merge2.twMerge)((0, import_clsx2.clsx)(inputs));
|
|
2781
|
+
}
|
|
2782
|
+
function standardizeAddress(address) {
|
|
2783
|
+
let cleanAddress = address.replace(/^0x/, "");
|
|
2784
|
+
if (cleanAddress.length < 64) {
|
|
2785
|
+
cleanAddress = cleanAddress.padStart(64, "0");
|
|
2786
|
+
}
|
|
2787
|
+
if (cleanAddress.length > 64) {
|
|
2788
|
+
throw new Error(`Address ${address} is not a valid address`);
|
|
2789
|
+
}
|
|
2790
|
+
return `0x${cleanAddress}`;
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
// src/lib/abiStorage.ts
|
|
2794
|
+
var abiStorage = {
|
|
2795
|
+
[standardizeAddress("0x1")]: {
|
|
2796
|
+
supra_account: supraAccountABI
|
|
2797
|
+
}
|
|
2798
|
+
};
|
|
2799
|
+
function getStoredABI(moduleAddress, moduleName) {
|
|
2800
|
+
var _a;
|
|
2801
|
+
const standardizedAddress = standardizeAddress(moduleAddress);
|
|
2802
|
+
const normalizedName = moduleName;
|
|
2803
|
+
if ((_a = abiStorage[standardizedAddress]) == null ? void 0 : _a[normalizedName]) {
|
|
2804
|
+
return abiStorage[standardizedAddress][normalizedName];
|
|
2805
|
+
}
|
|
2806
|
+
return null;
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
// src/hooks/useConversionUtils.ts
|
|
2810
|
+
var useConversionUtils = () => {
|
|
2811
|
+
const stringToUint8Array = (0, import_react4.useCallback)((humanReadableStr) => {
|
|
2812
|
+
return import_supra_l1_sdk_core.BCS.bcsToBytes(new import_supra_l1_sdk_core.TxnBuilderTypes.Identifier(humanReadableStr));
|
|
2813
|
+
}, []);
|
|
2814
|
+
const serializeString = (0, import_react4.useCallback)((humanReadableStr) => {
|
|
2815
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeStr(humanReadableStr);
|
|
2816
|
+
}, []);
|
|
2817
|
+
const addressToUint8Array = (0, import_react4.useCallback)((cryptoAddress) => {
|
|
2818
|
+
return import_supra_l1_sdk_core.BCS.bcsToBytes(import_supra_l1_sdk_core.TxnBuilderTypes.AccountAddress.fromHex(cryptoAddress));
|
|
2819
|
+
}, []);
|
|
2820
|
+
const deserializeString = (uint8Array) => {
|
|
2821
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeStr(uint8Array);
|
|
2822
|
+
};
|
|
2823
|
+
const deserializeVector = (uint8Array) => {
|
|
2824
|
+
const deserializer = new import_supra_l1_sdk_core.BCS.Deserializer(uint8Array);
|
|
2825
|
+
return import_supra_l1_sdk_core.BCS.deserializeVector(deserializer, import_supra_l1_sdk_core.BCS.bcsSerializeU8);
|
|
2826
|
+
};
|
|
2827
|
+
const serializeUint8 = (0, import_react4.useCallback)((value) => {
|
|
2828
|
+
const num = typeof value === "string" ? parseInt(value, 10) : value;
|
|
2829
|
+
if (num < 0 || num > 255) {
|
|
2830
|
+
throw new Error(`u8 value out of range: ${num}`);
|
|
2831
|
+
}
|
|
2832
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeU8(num);
|
|
2833
|
+
}, []);
|
|
2834
|
+
const serializeUint16 = (0, import_react4.useCallback)((value) => {
|
|
2835
|
+
let num;
|
|
2836
|
+
if (typeof value === "string") {
|
|
2837
|
+
num = parseInt(value, 10);
|
|
2838
|
+
} else if (typeof value === "bigint") {
|
|
2839
|
+
num = Number(value);
|
|
2840
|
+
} else {
|
|
2841
|
+
num = value;
|
|
2842
|
+
}
|
|
2843
|
+
if (num < 0 || num > 65535) {
|
|
2844
|
+
throw new Error(`u16 value out of range: ${num}`);
|
|
2845
|
+
}
|
|
2846
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeU16(num);
|
|
2847
|
+
}, []);
|
|
2848
|
+
const serializeUint32 = (0, import_react4.useCallback)((value) => {
|
|
2849
|
+
let num;
|
|
2850
|
+
if (typeof value === "string") {
|
|
2851
|
+
num = parseInt(value, 10);
|
|
2852
|
+
} else if (typeof value === "bigint") {
|
|
2853
|
+
num = Number(value);
|
|
2854
|
+
} else {
|
|
2855
|
+
num = value;
|
|
2856
|
+
}
|
|
2857
|
+
if (num < 0 || num > 4294967295) {
|
|
2858
|
+
throw new Error(`u32 value out of range: ${num}`);
|
|
2859
|
+
}
|
|
2860
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeU32(num);
|
|
2861
|
+
}, []);
|
|
2862
|
+
const serializeUint64 = (0, import_react4.useCallback)((value) => {
|
|
2863
|
+
let num;
|
|
2864
|
+
if (typeof value === "string") {
|
|
2865
|
+
num = BigInt(value);
|
|
2866
|
+
} else if (typeof value === "number") {
|
|
2867
|
+
num = BigInt(value);
|
|
2868
|
+
} else {
|
|
2869
|
+
num = value;
|
|
2870
|
+
}
|
|
2871
|
+
if (num < 0) {
|
|
2872
|
+
throw new Error(`u64 value cannot be negative: ${num}`);
|
|
2873
|
+
}
|
|
2874
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeUint64(num);
|
|
2875
|
+
}, []);
|
|
2876
|
+
const serializeUint128 = (0, import_react4.useCallback)((value) => {
|
|
2877
|
+
let num;
|
|
2878
|
+
if (typeof value === "string") {
|
|
2879
|
+
num = BigInt(value);
|
|
2880
|
+
} else if (typeof value === "number") {
|
|
2881
|
+
num = BigInt(value);
|
|
2882
|
+
} else {
|
|
2883
|
+
num = value;
|
|
2884
|
+
}
|
|
2885
|
+
if (num < 0) {
|
|
2886
|
+
throw new Error(`u128 value cannot be negative: ${num}`);
|
|
2887
|
+
}
|
|
2888
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeU128(num);
|
|
2889
|
+
}, []);
|
|
2890
|
+
const serializeU256 = (0, import_react4.useCallback)((value) => {
|
|
2891
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeU256(value);
|
|
2892
|
+
}, []);
|
|
2893
|
+
const serializeBool = (0, import_react4.useCallback)((value) => {
|
|
2894
|
+
return import_supra_l1_sdk_core.BCS.bcsSerializeBool(value);
|
|
2895
|
+
}, []);
|
|
2896
|
+
const serializeVector = (0, import_react4.useCallback)((values, type) => {
|
|
2897
|
+
const serializer = new import_supra_l1_sdk_core.BCS.Serializer();
|
|
2898
|
+
serializer.serializeU32AsUleb128(values.length);
|
|
2899
|
+
values.forEach((value) => {
|
|
2900
|
+
if (type === "u64") {
|
|
2901
|
+
serializer.serializeU64(value);
|
|
2902
|
+
} else if (type === "bool") {
|
|
2903
|
+
serializer.serializeBool(value);
|
|
2904
|
+
} else if (type === "string") {
|
|
2905
|
+
serializer.serializeStr(value);
|
|
2906
|
+
} else if (type === "address") {
|
|
2907
|
+
const accountAddress = import_supra_l1_sdk_core.TxnBuilderTypes.AccountAddress.fromHex(value);
|
|
2908
|
+
serializer.serializeFixedBytes(accountAddress.address);
|
|
2909
|
+
} else {
|
|
2910
|
+
serializer.serializeStr(value);
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
return serializer.getBytes();
|
|
2914
|
+
}, []);
|
|
2915
|
+
const hexToString = (hex, type) => {
|
|
2916
|
+
if (!hex) {
|
|
2917
|
+
return "";
|
|
2918
|
+
}
|
|
2919
|
+
if (type !== "String") {
|
|
2920
|
+
try {
|
|
2921
|
+
return BigInt(hex).toString();
|
|
2922
|
+
} catch (error) {
|
|
2923
|
+
console.error("Error converting hex to string:", error);
|
|
2924
|
+
return hex;
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
try {
|
|
2928
|
+
const cleanHex = hex.slice(2);
|
|
2929
|
+
return Buffer.from(cleanHex, "hex").toString().slice(1);
|
|
2930
|
+
} catch (error) {
|
|
2931
|
+
console.error("Error converting hex to string:", error);
|
|
2932
|
+
return hex;
|
|
2933
|
+
}
|
|
2934
|
+
};
|
|
2935
|
+
const stringToHex = (str) => {
|
|
2936
|
+
const encoder = new TextEncoder();
|
|
2937
|
+
const bytes = encoder.encode(str);
|
|
2938
|
+
let hexString = "";
|
|
2939
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2940
|
+
const hex = bytes[i].toString(16).padStart(2, "0");
|
|
2941
|
+
hexString += hex;
|
|
2942
|
+
}
|
|
2943
|
+
return hexString;
|
|
2944
|
+
};
|
|
2945
|
+
const serializeValueByType = (0, import_react4.useCallback)(
|
|
2946
|
+
(value, type, serializer) => {
|
|
2947
|
+
var _a;
|
|
2948
|
+
const ser = serializer || new import_supra_l1_sdk_core.BCS.Serializer();
|
|
2949
|
+
const shouldReturnBytes = !serializer;
|
|
2950
|
+
if (type.startsWith("0x1::option::Option<")) {
|
|
2951
|
+
if (value === null || value === void 0) {
|
|
2952
|
+
ser.serializeU8(0);
|
|
2953
|
+
} else {
|
|
2954
|
+
ser.serializeU8(1);
|
|
2955
|
+
const innerType = type.slice(21, -1);
|
|
2956
|
+
serializeValueByType(value, innerType, ser);
|
|
2957
|
+
}
|
|
2958
|
+
return shouldReturnBytes ? ser.getBytes() : new Uint8Array(0);
|
|
2959
|
+
}
|
|
2960
|
+
if (type.startsWith("vector<")) {
|
|
2961
|
+
const vectorMatch = type.match(/vector<(.+)>$/);
|
|
2962
|
+
if (!vectorMatch) {
|
|
2963
|
+
throw new Error(`Invalid vector type format: ${type}`);
|
|
2964
|
+
}
|
|
2965
|
+
const innerType = vectorMatch[1];
|
|
2966
|
+
if (innerType === "u8") {
|
|
2967
|
+
let bytes;
|
|
2968
|
+
if (typeof value === "string") {
|
|
2969
|
+
const cleanHex = value.startsWith("0x") ? value.slice(2) : value;
|
|
2970
|
+
bytes = new Uint8Array(
|
|
2971
|
+
((_a = cleanHex.match(/.{1,2}/g)) == null ? void 0 : _a.map((byte) => parseInt(byte, 16))) || []
|
|
2972
|
+
);
|
|
2973
|
+
} else if (value instanceof Uint8Array) {
|
|
2974
|
+
bytes = value;
|
|
2975
|
+
} else if (Array.isArray(value)) {
|
|
2976
|
+
bytes = new Uint8Array(
|
|
2977
|
+
value.map((item) => {
|
|
2978
|
+
const u8 = typeof item === "string" ? parseInt(item, 10) : item;
|
|
2979
|
+
if (u8 < 0 || u8 > 255) {
|
|
2980
|
+
throw new Error(`u8 value out of range in vector: ${u8}`);
|
|
2981
|
+
}
|
|
2982
|
+
return u8;
|
|
2983
|
+
})
|
|
2984
|
+
);
|
|
2985
|
+
} else {
|
|
2986
|
+
throw new Error(
|
|
2987
|
+
`Expected string, Uint8Array, or number[] for vector<u8>, got ${typeof value}`
|
|
2988
|
+
);
|
|
2989
|
+
}
|
|
2990
|
+
ser.serializeU32AsUleb128(bytes.length);
|
|
2991
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2992
|
+
ser.serializeU8(bytes[i]);
|
|
2993
|
+
}
|
|
2994
|
+
} else {
|
|
2995
|
+
if (!Array.isArray(value)) {
|
|
2996
|
+
throw new Error(
|
|
2997
|
+
`Expected array for vector<${innerType}>, got ${typeof value}`
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
ser.serializeU32AsUleb128(value.length);
|
|
3001
|
+
for (const item of value) {
|
|
3002
|
+
serializeValueByType(item, innerType, ser);
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
return shouldReturnBytes ? ser.getBytes() : new Uint8Array(0);
|
|
3006
|
+
}
|
|
3007
|
+
if (type.startsWith("0x1::object::Object")) {
|
|
3008
|
+
if (typeof value !== "string") {
|
|
3009
|
+
throw new Error(`Expected string for Object, got ${typeof value}`);
|
|
3010
|
+
}
|
|
3011
|
+
const objectAddress = import_supra_l1_sdk_core.TxnBuilderTypes.AccountAddress.fromHex(value);
|
|
3012
|
+
ser.serializeFixedBytes(objectAddress.address);
|
|
3013
|
+
return shouldReturnBytes ? ser.getBytes() : new Uint8Array(0);
|
|
3014
|
+
}
|
|
3015
|
+
switch (type) {
|
|
3016
|
+
case "address":
|
|
3017
|
+
if (typeof value !== "string") {
|
|
3018
|
+
throw new Error(`Expected string for address, got ${typeof value}`);
|
|
3019
|
+
}
|
|
3020
|
+
const accountAddress = import_supra_l1_sdk_core.TxnBuilderTypes.AccountAddress.fromHex(value);
|
|
3021
|
+
ser.serializeFixedBytes(accountAddress.address);
|
|
3022
|
+
break;
|
|
3023
|
+
case "u8":
|
|
3024
|
+
const u8 = typeof value === "string" ? parseInt(value, 10) : value;
|
|
3025
|
+
if (u8 < 0 || u8 > 255) {
|
|
3026
|
+
throw new Error(`u8 value out of range: ${u8}`);
|
|
3027
|
+
}
|
|
3028
|
+
ser.serializeU8(u8);
|
|
3029
|
+
break;
|
|
3030
|
+
case "u16":
|
|
3031
|
+
const u16 = typeof value === "string" ? parseInt(value, 10) : typeof value === "bigint" ? Number(value) : value;
|
|
3032
|
+
if (u16 < 0 || u16 > 65535) {
|
|
3033
|
+
throw new Error(`u16 value out of range: ${u16}`);
|
|
3034
|
+
}
|
|
3035
|
+
ser.serializeU16(u16);
|
|
3036
|
+
break;
|
|
3037
|
+
case "u32":
|
|
3038
|
+
const u32 = typeof value === "string" ? parseInt(value, 10) : typeof value === "bigint" ? Number(value) : value;
|
|
3039
|
+
if (u32 < 0 || u32 > 4294967295) {
|
|
3040
|
+
throw new Error(`u32 value out of range: ${u32}`);
|
|
3041
|
+
}
|
|
3042
|
+
ser.serializeU32(u32);
|
|
3043
|
+
break;
|
|
3044
|
+
case "u64":
|
|
3045
|
+
const u64 = typeof value === "string" ? BigInt(value) : typeof value === "number" ? BigInt(value) : value;
|
|
3046
|
+
if (u64 < 0) {
|
|
3047
|
+
throw new Error(`u64 value cannot be negative: ${u64}`);
|
|
3048
|
+
}
|
|
3049
|
+
ser.serializeU64(u64);
|
|
3050
|
+
break;
|
|
3051
|
+
case "u128":
|
|
3052
|
+
const u128 = typeof value === "string" ? BigInt(value) : typeof value === "number" ? BigInt(value) : value;
|
|
3053
|
+
if (u128 < 0) {
|
|
3054
|
+
throw new Error(`u128 value cannot be negative: ${u128}`);
|
|
3055
|
+
}
|
|
3056
|
+
ser.serializeU128(u128);
|
|
3057
|
+
break;
|
|
3058
|
+
case "u256":
|
|
3059
|
+
if (typeof value !== "bigint") {
|
|
3060
|
+
throw new Error(`Expected bigint for u256, got ${typeof value}`);
|
|
3061
|
+
}
|
|
3062
|
+
ser.serializeU256(value);
|
|
3063
|
+
break;
|
|
3064
|
+
case "bool":
|
|
3065
|
+
if (typeof value !== "boolean") {
|
|
3066
|
+
throw new Error(`Expected boolean, got ${typeof value}`);
|
|
3067
|
+
}
|
|
3068
|
+
ser.serializeBool(value);
|
|
3069
|
+
break;
|
|
3070
|
+
case "0x1::string::String":
|
|
3071
|
+
if (typeof value !== "string") {
|
|
3072
|
+
throw new Error(`Expected string, got ${typeof value}`);
|
|
3073
|
+
}
|
|
3074
|
+
ser.serializeStr(value);
|
|
3075
|
+
break;
|
|
3076
|
+
default:
|
|
3077
|
+
throw new Error(`Unsupported type: ${type}`);
|
|
3078
|
+
}
|
|
3079
|
+
return shouldReturnBytes ? ser.getBytes() : new Uint8Array(0);
|
|
3080
|
+
},
|
|
3081
|
+
[]
|
|
3082
|
+
);
|
|
3083
|
+
const serializeArgsFromTypes = (0, import_react4.useCallback)(
|
|
3084
|
+
(args, paramTypes) => {
|
|
3085
|
+
if (args.length !== paramTypes.length) {
|
|
3086
|
+
throw new Error(
|
|
3087
|
+
`Argument count mismatch: expected ${paramTypes.length}, got ${args.length}`
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
3090
|
+
return args.map((arg, index) => {
|
|
3091
|
+
try {
|
|
3092
|
+
const paramType = paramTypes[index].replace("&signer", "").trim();
|
|
3093
|
+
return serializeValueByType(arg, paramType);
|
|
3094
|
+
} catch (error) {
|
|
3095
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3096
|
+
throw new Error(
|
|
3097
|
+
`Failed to serialize argument ${index} (${paramTypes[index]}): ${errorMessage}`
|
|
3098
|
+
);
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
},
|
|
3102
|
+
[serializeValueByType]
|
|
3103
|
+
);
|
|
3104
|
+
const fetchModuleABI = (0, import_react4.useCallback)(
|
|
3105
|
+
async (moduleAddress, moduleName, rpcUrl) => {
|
|
3106
|
+
const storedABI = getStoredABI(moduleAddress, moduleName);
|
|
3107
|
+
if (storedABI) {
|
|
3108
|
+
return storedABI;
|
|
3109
|
+
}
|
|
3110
|
+
const baseUrl = rpcUrl || (process.env.NEXT_PUBLIC_SUPRA_CHAIN_ID === "8" ? "https://rpc-mainnet.supra.com" : "https://rpc-testnet.supra.com");
|
|
3111
|
+
const url = `${baseUrl}/rpc/v3/accounts/${moduleAddress}/modules/${moduleName}`;
|
|
3112
|
+
try {
|
|
3113
|
+
const response = await fetch(url);
|
|
3114
|
+
if (!response.ok) {
|
|
3115
|
+
throw new Error(`Failed to fetch ABI: ${response.statusText}`);
|
|
3116
|
+
}
|
|
3117
|
+
const data = await response.json();
|
|
3118
|
+
return data.abi;
|
|
3119
|
+
} catch (error) {
|
|
3120
|
+
console.error("Error fetching module ABI:", error);
|
|
3121
|
+
throw new Error(
|
|
3122
|
+
`Failed to fetch module ABI: ${error instanceof Error ? error.message : String(error)}`
|
|
3123
|
+
);
|
|
3124
|
+
}
|
|
3125
|
+
},
|
|
3126
|
+
[]
|
|
3127
|
+
);
|
|
3128
|
+
const getFunctionParamTypes = (0, import_react4.useCallback)(
|
|
3129
|
+
async (moduleAddress, moduleName, functionName, rpcUrl) => {
|
|
3130
|
+
const moduleABI = await fetchModuleABI(moduleAddress, moduleName, rpcUrl);
|
|
3131
|
+
if (!moduleABI.exposed_functions) {
|
|
3132
|
+
throw new Error("Invalid module ABI response");
|
|
3133
|
+
}
|
|
3134
|
+
const functionDef = moduleABI.exposed_functions.find(
|
|
3135
|
+
(func) => func.name === functionName
|
|
3136
|
+
);
|
|
3137
|
+
if (!functionDef) {
|
|
3138
|
+
throw new Error(`Function ${functionName} not found in module ${moduleName}`);
|
|
3139
|
+
}
|
|
3140
|
+
return functionDef.params.filter((param) => {
|
|
3141
|
+
const trimmed = param.trim();
|
|
3142
|
+
return trimmed !== "signer" && trimmed !== "&signer";
|
|
3143
|
+
});
|
|
3144
|
+
},
|
|
3145
|
+
[fetchModuleABI]
|
|
3146
|
+
);
|
|
3147
|
+
const serializeTransactionArgs = (0, import_react4.useCallback)(
|
|
3148
|
+
async (args, moduleAddress, moduleName, functionName, rpcUrl) => {
|
|
3149
|
+
const paramTypes = await getFunctionParamTypes(
|
|
3150
|
+
moduleAddress,
|
|
3151
|
+
moduleName,
|
|
3152
|
+
functionName,
|
|
3153
|
+
rpcUrl
|
|
3154
|
+
);
|
|
3155
|
+
return serializeArgsFromTypes(args, paramTypes);
|
|
3156
|
+
},
|
|
3157
|
+
[getFunctionParamTypes, serializeArgsFromTypes]
|
|
3158
|
+
);
|
|
3159
|
+
return {
|
|
3160
|
+
stringToUint8Array,
|
|
3161
|
+
addressToUint8Array,
|
|
3162
|
+
serializeString,
|
|
3163
|
+
serializeUint8,
|
|
3164
|
+
serializeUint16,
|
|
3165
|
+
serializeUint32,
|
|
3166
|
+
serializeUint64,
|
|
3167
|
+
serializeUint128,
|
|
3168
|
+
serializeU256,
|
|
3169
|
+
serializeBool,
|
|
3170
|
+
serializeVector,
|
|
3171
|
+
deserializeString,
|
|
3172
|
+
deserializeVector,
|
|
3173
|
+
hexToString,
|
|
3174
|
+
stringToHex,
|
|
3175
|
+
// ABI-based serialization
|
|
3176
|
+
serializeValueByType,
|
|
3177
|
+
serializeArgsFromTypes,
|
|
3178
|
+
fetchModuleABI,
|
|
3179
|
+
getFunctionParamTypes,
|
|
3180
|
+
serializeTransactionArgs
|
|
3181
|
+
// Main function to use
|
|
3182
|
+
};
|
|
3183
|
+
};
|
|
3184
|
+
var useConversionUtils_default = useConversionUtils;
|
|
3185
|
+
|
|
3186
|
+
// src/components/ui/button.tsx
|
|
3187
|
+
var React3 = __toESM(require("react"));
|
|
3188
|
+
var import_react_slot2 = require("@radix-ui/react-slot");
|
|
3189
|
+
var import_class_variance_authority2 = require("class-variance-authority");
|
|
3190
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3191
|
+
var buttonVariants2 = (0, import_class_variance_authority2.cva)(
|
|
3192
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
3193
|
+
{
|
|
3194
|
+
variants: {
|
|
3195
|
+
variant: {
|
|
3196
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
3197
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
3198
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
3199
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
3200
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
3201
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
3202
|
+
},
|
|
3203
|
+
size: {
|
|
3204
|
+
default: "h-10 px-4 py-2",
|
|
3205
|
+
sm: "h-9 rounded-md px-3",
|
|
3206
|
+
lg: "h-11 rounded-md px-8",
|
|
3207
|
+
icon: "h-10 w-10"
|
|
3208
|
+
}
|
|
3209
|
+
},
|
|
3210
|
+
defaultVariants: {
|
|
3211
|
+
variant: "default",
|
|
3212
|
+
size: "default"
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
);
|
|
3216
|
+
var Button2 = React3.forwardRef(
|
|
3217
|
+
(_a, ref) => {
|
|
3218
|
+
var _b = _a, { className, variant, size, asChild = false } = _b, props = __objRest(_b, ["className", "variant", "size", "asChild"]);
|
|
3219
|
+
const Comp = asChild ? import_react_slot2.Slot : "button";
|
|
3220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3221
|
+
Comp,
|
|
3222
|
+
__spreadValues({
|
|
3223
|
+
className: cn2(buttonVariants2({ variant, size, className })),
|
|
3224
|
+
ref
|
|
3225
|
+
}, props)
|
|
3226
|
+
);
|
|
3227
|
+
}
|
|
3228
|
+
);
|
|
3229
|
+
Button2.displayName = "Button";
|
|
3230
|
+
|
|
3231
|
+
// src/components/ui/dialog.tsx
|
|
3232
|
+
var React4 = __toESM(require("react"));
|
|
3233
|
+
var DialogPrimitive2 = __toESM(require("@radix-ui/react-dialog"));
|
|
3234
|
+
var import_lucide_react3 = require("lucide-react");
|
|
3235
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3236
|
+
var Dialog2 = DialogPrimitive2.Root;
|
|
3237
|
+
var DialogTrigger = DialogPrimitive2.Trigger;
|
|
3238
|
+
var DialogPortal2 = DialogPrimitive2.Portal;
|
|
3239
|
+
var DialogClose = DialogPrimitive2.Close;
|
|
3240
|
+
var DialogOverlay2 = React4.forwardRef((_a, ref) => {
|
|
3241
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
3242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPortal2, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3243
|
+
DialogPrimitive2.Overlay,
|
|
3244
|
+
__spreadValues({
|
|
3245
|
+
ref,
|
|
3246
|
+
className: cn2(
|
|
3247
|
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
3248
|
+
className
|
|
3249
|
+
)
|
|
3250
|
+
}, props)
|
|
3251
|
+
) });
|
|
3252
|
+
});
|
|
3253
|
+
DialogOverlay2.displayName = DialogPrimitive2.Overlay.displayName;
|
|
3254
|
+
var DialogContent2 = React4.forwardRef((_a, ref) => {
|
|
3255
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
3256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DialogPortal2, { children: [
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogOverlay2, {}),
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3259
|
+
DialogPrimitive2.Content,
|
|
3260
|
+
__spreadProps(__spreadValues({
|
|
3261
|
+
ref,
|
|
3262
|
+
className: cn2(
|
|
3263
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
3264
|
+
className
|
|
3265
|
+
)
|
|
3266
|
+
}, props), {
|
|
3267
|
+
children: [
|
|
3268
|
+
children,
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DialogPrimitive2.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
3270
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.X, { className: "h-4 w-4" }),
|
|
3271
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sr-only", children: "Close" })
|
|
3272
|
+
] })
|
|
3273
|
+
]
|
|
3274
|
+
})
|
|
3275
|
+
)
|
|
3276
|
+
] });
|
|
3277
|
+
});
|
|
3278
|
+
DialogContent2.displayName = DialogPrimitive2.Content.displayName;
|
|
3279
|
+
var DialogHeader2 = (_a) => {
|
|
3280
|
+
var _b = _a, {
|
|
3281
|
+
className
|
|
3282
|
+
} = _b, props = __objRest(_b, [
|
|
3283
|
+
"className"
|
|
3284
|
+
]);
|
|
3285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3286
|
+
"div",
|
|
3287
|
+
__spreadValues({
|
|
3288
|
+
className: cn2(
|
|
3289
|
+
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
3290
|
+
className
|
|
3291
|
+
)
|
|
3292
|
+
}, props)
|
|
3293
|
+
);
|
|
3294
|
+
};
|
|
3295
|
+
DialogHeader2.displayName = "DialogHeader";
|
|
3296
|
+
var DialogFooter2 = (_a) => {
|
|
3297
|
+
var _b = _a, {
|
|
3298
|
+
className
|
|
3299
|
+
} = _b, props = __objRest(_b, [
|
|
3300
|
+
"className"
|
|
3301
|
+
]);
|
|
3302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3303
|
+
"div",
|
|
3304
|
+
__spreadValues({
|
|
3305
|
+
className: cn2(
|
|
3306
|
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
3307
|
+
className
|
|
3308
|
+
)
|
|
3309
|
+
}, props)
|
|
3310
|
+
);
|
|
3311
|
+
};
|
|
3312
|
+
DialogFooter2.displayName = "DialogFooter";
|
|
3313
|
+
var DialogTitle2 = React4.forwardRef((_a, ref) => {
|
|
3314
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
3315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3316
|
+
DialogPrimitive2.Title,
|
|
3317
|
+
__spreadValues({
|
|
3318
|
+
ref,
|
|
3319
|
+
className: cn2(
|
|
3320
|
+
"text-lg font-semibold leading-none tracking-tight",
|
|
3321
|
+
className
|
|
3322
|
+
)
|
|
3323
|
+
}, props)
|
|
3324
|
+
);
|
|
3325
|
+
});
|
|
3326
|
+
DialogTitle2.displayName = DialogPrimitive2.Title.displayName;
|
|
3327
|
+
var DialogDescription2 = React4.forwardRef((_a, ref) => {
|
|
3328
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
3329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3330
|
+
DialogPrimitive2.Description,
|
|
3331
|
+
__spreadValues({
|
|
3332
|
+
ref,
|
|
3333
|
+
className: cn2("text-sm text-muted-foreground", className)
|
|
3334
|
+
}, props)
|
|
3335
|
+
);
|
|
3336
|
+
});
|
|
3337
|
+
DialogDescription2.displayName = DialogPrimitive2.Description.displayName;
|
|
3338
|
+
|
|
3339
|
+
// src/components/ui/sonner.tsx
|
|
3340
|
+
var import_sonner4 = require("sonner");
|
|
3341
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
3342
|
+
var Toaster = (_a) => {
|
|
3343
|
+
var _b = _a, { theme = "system" } = _b, props = __objRest(_b, ["theme"]);
|
|
3344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3345
|
+
import_sonner4.Toaster,
|
|
3346
|
+
__spreadValues({
|
|
3347
|
+
theme,
|
|
3348
|
+
className: "toaster group",
|
|
3349
|
+
toastOptions: {
|
|
3350
|
+
classNames: {
|
|
3351
|
+
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
|
|
3352
|
+
description: "group-[.toast]:text-muted-foreground",
|
|
3353
|
+
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
3354
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground"
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
}, props)
|
|
3358
|
+
);
|
|
3359
|
+
};
|
|
3360
|
+
|
|
3361
|
+
// src/assets/walletIcons/index.ts
|
|
3362
|
+
var WALLET_ICONS = {
|
|
3363
|
+
starkey: Starkey_default,
|
|
3364
|
+
ribbit: Ribbit_default
|
|
3365
|
+
};
|
|
3366
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3367
|
+
0 && (module.exports = {
|
|
3368
|
+
Button,
|
|
3369
|
+
ConnectWalletHandler,
|
|
3370
|
+
Dialog,
|
|
3371
|
+
DialogClose,
|
|
3372
|
+
DialogContent,
|
|
3373
|
+
DialogDescription,
|
|
3374
|
+
DialogFooter,
|
|
3375
|
+
DialogHeader,
|
|
3376
|
+
DialogOverlay,
|
|
3377
|
+
DialogPortal,
|
|
3378
|
+
DialogTitle,
|
|
3379
|
+
DialogTrigger,
|
|
3380
|
+
Toaster,
|
|
3381
|
+
WALLET_EVENTS,
|
|
3382
|
+
WALLET_ICONS,
|
|
3383
|
+
buttonVariants,
|
|
3384
|
+
cn,
|
|
3385
|
+
getStoredABI,
|
|
3386
|
+
ribbitIcon,
|
|
3387
|
+
standardizeAddress,
|
|
3388
|
+
starkeyIcon,
|
|
3389
|
+
useConversionUtils,
|
|
3390
|
+
useSupraMultiWallet
|
|
3391
|
+
});
|
|
3392
|
+
//# sourceMappingURL=index.js.map
|