@thenamespace/ens-components 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,541 +1 @@
1
- # @thenamespace/ens-components
2
-
3
- React components for ENS (Ethereum Name Service) name registration and subname minting.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @thenamespace/ens-components
9
- ```
10
-
11
- ## Peer Dependencies
12
-
13
- This package requires the following peer dependencies:
14
-
15
- ```bash
16
- npm install wagmi @rainbow-me/rainbowkit @tanstack/react-query viem react react-dom
17
- ```
18
-
19
- ## Quick Start
20
-
21
- ### 1. Setup Required Providers
22
-
23
- Wrap your application with the required providers:
24
-
25
- ```tsx
26
- import React from "react";
27
- import { WagmiProvider } from "wagmi";
28
- import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
29
- import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit";
30
- import { mainnet, sepolia } from "wagmi/chains";
31
- import { http } from "wagmi";
32
-
33
- // Import styles
34
- import "@thenamespace/ens-components/index.css";
35
- import "@rainbow-me/rainbowkit/styles.css";
36
-
37
- const wagmiConfig = getDefaultConfig({
38
- appName: "My ENS App",
39
- projectId: "YOUR_WALLETCONNECT_PROJECT_ID", // Get from https://cloud.walletconnect.com
40
- chains: [mainnet, sepolia],
41
- transports: {
42
- [mainnet.id]: http(),
43
- [sepolia.id]: http(),
44
- },
45
- });
46
-
47
- const queryClient = new QueryClient();
48
-
49
- function AppProviders({ children }: { children: React.ReactNode }) {
50
- return (
51
- <WagmiProvider config={wagmiConfig}>
52
- <QueryClientProvider client={queryClient}>
53
- <RainbowKitProvider>{children}</RainbowKitProvider>
54
- </QueryClientProvider>
55
- </WagmiProvider>
56
- );
57
- }
58
- ```
59
-
60
- ### 2. Use the Components
61
-
62
- ```tsx
63
- import {
64
- ENSNamesRegistrarComponent,
65
- SubnameOnChainRegistrarModal,
66
- } from "@thenamespace/ens-components";
67
-
68
- function MyApp() {
69
- return <AppProviders>{/* Your components here */}</AppProviders>;
70
- }
71
- ```
72
-
73
- ## Components
74
-
75
- ### ENSNamesRegistrarComponent
76
-
77
- Component for registering top-level ENS names (e.g., `myname.eth`).
78
-
79
- #### Basic Usage
80
-
81
- ```tsx
82
- import { useState } from "react";
83
- import { ENSNamesRegistrarComponent } from "@thenamespace/ens-components";
84
-
85
- function RegisterENSName() {
86
- const [name, setName] = useState("");
87
- const [duration, setDuration] = useState(1);
88
-
89
- return (
90
- <ENSNamesRegistrarComponent
91
- name={name}
92
- duration={duration}
93
- onNameChange={setName}
94
- onDurationChange={setDuration}
95
- onCompleteRegistration={() => {
96
- console.log("Registration complete!");
97
- }}
98
- />
99
- );
100
- }
101
- ```
102
-
103
- #### Component Flow
104
-
105
- The component has 4 main steps:
106
-
107
- 1. **NameSearch** - User searches for an available ENS name
108
- 2. **RegistrationForm** - User reviews details and sets registration duration
109
- 3. **RegistrationProcess** - Transaction processing with multiple steps
110
- 4. **SuccessScreen** - Registration completion confirmation
111
-
112
- #### Props
113
-
114
- | Prop | Type | Required | Default | Description |
115
- | ------------------------ | ---------------------------- | -------- | -------------- | ------------------------------------------- |
116
- | `name` | `string` | No | `"brightwave"` | Initial ENS name (without .eth suffix) |
117
- | `duration` | `number` | No | `1` | Registration duration in years |
118
- | `onNameChange` | `(name: string) => void` | No | - | Callback when name changes |
119
- | `onDurationChange` | `(duration: number) => void` | No | - | Callback when duration changes |
120
- | `onBack` | `() => void` | No | - | Callback when back button is clicked |
121
- | `onClose` | `() => void` | No | - | Callback when close button is clicked |
122
- | `onNext` | `() => void` | No | - | Callback when next button is clicked |
123
- | `onCompleteProfile` | `() => void` | No | - | Callback when "Complete Profile" is clicked |
124
- | `onOpenWallet` | `() => void` | No | - | Callback when wallet needs to be opened |
125
- | `onCompleteRegistration` | `() => void` | No | - | Callback when registration completes |
126
- | `onRegisterAnother` | `() => void` | No | - | Callback when "Register Another" is clicked |
127
- | `onViewName` | `() => void` | No | - | Callback when "View Name" is clicked |
128
-
129
- #### Complete Example
130
-
131
- ```tsx
132
- import { useState } from "react";
133
- import { ENSNamesRegistrarComponent } from "@thenamespace/ens-components";
134
-
135
- function ENSRegistrationExample() {
136
- const [name, setName] = useState("");
137
- const [duration, setDuration] = useState(1);
138
- const [registeredNames, setRegisteredNames] = useState<string[]>([]);
139
-
140
- const handleCompleteRegistration = () => {
141
- if (name) {
142
- setRegisteredNames([...registeredNames, name]);
143
- alert(`Successfully registered ${name}.eth!`);
144
- }
145
- };
146
-
147
- return (
148
- <div>
149
- <ENSNamesRegistrarComponent
150
- name={name}
151
- duration={duration}
152
- onNameChange={setName}
153
- onDurationChange={setDuration}
154
- onBack={() => console.log("Back clicked")}
155
- onClose={() => console.log("Close clicked")}
156
- onNext={() => console.log("Next clicked")}
157
- onCompleteProfile={() => {
158
- console.log("Complete profile clicked");
159
- // Navigate to profile completion page
160
- }}
161
- onOpenWallet={() => console.log("Open wallet clicked")}
162
- onCompleteRegistration={handleCompleteRegistration}
163
- onRegisterAnother={() => {
164
- setName("");
165
- setDuration(1);
166
- }}
167
- onViewName={() => {
168
- if (name) {
169
- window.open(`https://app.ens.domains/${name}`, "_blank");
170
- }
171
- }}
172
- />
173
-
174
- {registeredNames.length > 0 && (
175
- <div>
176
- <h3>Registered Names:</h3>
177
- <ul>
178
- {registeredNames.map(n => (
179
- <li key={n}>{n}.eth</li>
180
- ))}
181
- </ul>
182
- </div>
183
- )}
184
- </div>
185
- );
186
- }
187
- ```
188
-
189
- ---
190
-
191
- ### SubnameOnChainRegistrarModal
192
-
193
- Component for registering on-chain subnames (e.g., `mysubname.mydomain.eth`).
194
-
195
- #### Basic Usage
196
-
197
- ```tsx
198
- import { useState } from "react";
199
- import { SubnameOnChainRegistrarModal } from "@thenamespace/ens-components";
200
-
201
- function RegisterSubname() {
202
- const [step, setStep] = useState(0);
203
- const [name, setName] = useState("");
204
- const [parentName] = useState("mydomain.eth");
205
- const [profileComplete, setProfileComplete] = useState(false);
206
- const [owner, setOwner] = useState("");
207
- const [duration, setDuration] = useState(1);
208
- const [useAsPrimary, setUseAsPrimary] = useState(false);
209
-
210
- return (
211
- <SubnameOnChainRegistrarModal
212
- step={step}
213
- name={name}
214
- parentName={parentName}
215
- profileComplete={profileComplete}
216
- owner={owner}
217
- duration={duration}
218
- useAsPrimary={useAsPrimary}
219
- onStepChange={setStep}
220
- onNameChange={setName}
221
- onProfileCompleteChange={setProfileComplete}
222
- onOwnerChange={setOwner}
223
- onDurationChange={setDuration}
224
- onUseAsPrimaryChange={setUseAsPrimary}
225
- onCompleteRegistration={() => {
226
- setStep(2); // Move to success screen
227
- }}
228
- />
229
- );
230
- }
231
- ```
232
-
233
- #### Component Flow
234
-
235
- The component has 3 main steps:
236
-
237
- 1. **InitialStep** (step 0) - User enters subname label
238
- 2. **RegistrationStep** (step 1) - User reviews details and registers
239
- 3. **SuccessScreen** (step 2) - Registration completion confirmation
240
-
241
- #### Props
242
-
243
- | Prop | Type | Required | Default | Description |
244
- | ------------------------- | --------------------------------- | -------- | --------------------- | ------------------------------------------------------- |
245
- | `step` | `number` | No | `0` | Current step (0: Initial, 1: Registration, 2: Success) |
246
- | `name` | `string` | No | `""` | Subname label (without parent domain) |
247
- | `parentName` | `string` | No | `"celotest.eth"` | Parent domain name |
248
- | `profileComplete` | `boolean` | No | `false` | Whether profile is complete |
249
- | `domainSuffix` | `string` | No | `"eth"` | Domain suffix |
250
- | `owner` | `string` | No | `"0x035eB...24117D3"` | Owner address for the subname |
251
- | `duration` | `number` | No | `1` | Registration duration in years |
252
- | `registrationFee` | `string` | No | - | Registration fee (optional) |
253
- | `networkFee` | `string` | No | - | Network fee (optional) |
254
- | `totalCost` | `string` | No | - | Total cost (optional) |
255
- | `useAsPrimary` | `boolean` | No | `false` | Whether to use as primary name |
256
- | `profileImageUrl` | `string` | No | - | Profile image URL (optional) |
257
- | `onStepChange` | `(step: number) => void` | No | - | Callback when step changes |
258
- | `onNameChange` | `(name: string) => void` | No | - | Callback when name changes |
259
- | `onProfileCompleteChange` | `(complete: boolean) => void` | No | - | Callback when profile complete status changes |
260
- | `onOwnerChange` | `(owner: string) => void` | No | - | Callback when owner changes |
261
- | `onDurationChange` | `(duration: number) => void` | No | - | Callback when duration changes |
262
- | `onUseAsPrimaryChange` | `(useAsPrimary: boolean) => void` | No | - | Callback when useAsPrimary changes |
263
- | `onRegister` | `() => void` | No | - | Callback when register button is clicked |
264
- | `onCancel` | `() => void` | No | - | Callback when cancel button is clicked |
265
- | `onClose` | `() => void` | No | - | Callback when close button is clicked |
266
- | `onCompleteProfile` | `() => void` | No | - | Callback when "Complete Profile" is clicked |
267
- | `onOpenWallet` | `() => void` | No | - | Callback when wallet needs to be opened |
268
- | `onCompleteRegistration` | `() => void` | No | - | Callback when registration completes |
269
- | `onRegisterAnother` | `() => void` | No | - | Callback when "Register Another" is clicked |
270
- | `onViewName` | `() => void` | No | - | Callback when "View Name" is clicked |
271
- | `onFinish` | `() => void` | No | - | Callback when finish button is clicked (success screen) |
272
-
273
- #### Complete Example
274
-
275
- ```tsx
276
- import { useState } from "react";
277
- import { SubnameOnChainRegistrarModal } from "@thenamespace/ens-components";
278
-
279
- function SubnameRegistrationExample() {
280
- const [isOpen, setIsOpen] = useState(false);
281
- const [step, setStep] = useState(0);
282
- const [name, setName] = useState("");
283
- const [parentName] = useState("mydomain.eth");
284
- const [profileComplete, setProfileComplete] = useState(false);
285
- const [owner, setOwner] = useState("");
286
- const [duration, setDuration] = useState(1);
287
- const [useAsPrimary, setUseAsPrimary] = useState(false);
288
- const [registeredSubnames, setRegisteredSubnames] = useState<string[]>([]);
289
-
290
- const handleCompleteRegistration = () => {
291
- const fullName = name ? `${name}.${parentName}` : "";
292
- if (fullName) {
293
- setRegisteredSubnames([...registeredSubnames, fullName]);
294
- setStep(2); // Move to success screen
295
- alert(`Successfully registered ${fullName}!`);
296
- }
297
- };
298
-
299
- const handleFinish = () => {
300
- setIsOpen(false);
301
- setStep(0);
302
- setName("");
303
- setProfileComplete(false);
304
- setDuration(1);
305
- setUseAsPrimary(false);
306
- };
307
-
308
- if (!isOpen) {
309
- return (
310
- <div>
311
- <button onClick={() => setIsOpen(true)}>Register Subname</button>
312
- {registeredSubnames.length > 0 && (
313
- <div>
314
- <h3>Registered Subnames:</h3>
315
- <ul>
316
- {registeredSubnames.map(n => (
317
- <li key={n}>{n}</li>
318
- ))}
319
- </ul>
320
- </div>
321
- )}
322
- </div>
323
- );
324
- }
325
-
326
- return (
327
- <div
328
- style={{
329
- position: "fixed",
330
- inset: 0,
331
- backgroundColor: "rgba(0, 0, 0, 0.5)",
332
- display: "flex",
333
- alignItems: "center",
334
- justifyContent: "center",
335
- zIndex: 1000,
336
- }}
337
- >
338
- <div
339
- style={{
340
- backgroundColor: "white",
341
- borderRadius: "8px",
342
- padding: "20px",
343
- maxWidth: "600px",
344
- width: "90%",
345
- maxHeight: "90vh",
346
- overflow: "auto",
347
- }}
348
- >
349
- <SubnameOnChainRegistrarModal
350
- step={step}
351
- name={name}
352
- parentName={parentName}
353
- profileComplete={profileComplete}
354
- owner={owner}
355
- duration={duration}
356
- useAsPrimary={useAsPrimary}
357
- onStepChange={setStep}
358
- onNameChange={setName}
359
- onProfileCompleteChange={setProfileComplete}
360
- onOwnerChange={setOwner}
361
- onDurationChange={setDuration}
362
- onUseAsPrimaryChange={setUseAsPrimary}
363
- onRegister={() => console.log("Register clicked")}
364
- onCancel={() => {
365
- console.log("Cancel clicked");
366
- setStep(0);
367
- }}
368
- onClose={handleFinish}
369
- onCompleteProfile={() => {
370
- console.log("Complete profile clicked");
371
- setProfileComplete(true);
372
- }}
373
- onCompleteRegistration={handleCompleteRegistration}
374
- onFinish={handleFinish}
375
- />
376
- </div>
377
- </div>
378
- );
379
- }
380
- ```
381
-
382
- ## Full Example with Both Components
383
-
384
- ```tsx
385
- import React, { useState } from "react";
386
- import { WagmiProvider } from "wagmi";
387
- import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
388
- import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit";
389
- import { mainnet, sepolia } from "wagmi/chains";
390
- import { http } from "wagmi";
391
- import {
392
- ENSNamesRegistrarComponent,
393
- SubnameOnChainRegistrarModal,
394
- } from "@thenamespace/ens-components";
395
- import "@thenamespace/ens-components/index.css";
396
- import "@rainbow-me/rainbowkit/styles.css";
397
-
398
- const wagmiConfig = getDefaultConfig({
399
- appName: "My ENS App",
400
- projectId: "YOUR_WALLETCONNECT_PROJECT_ID",
401
- chains: [mainnet, sepolia],
402
- transports: {
403
- [mainnet.id]: http(),
404
- [sepolia.id]: http(),
405
- },
406
- });
407
-
408
- const queryClient = new QueryClient();
409
-
410
- function AppProviders({ children }: { children: React.ReactNode }) {
411
- return (
412
- <WagmiProvider config={wagmiConfig}>
413
- <QueryClientProvider client={queryClient}>
414
- <RainbowKitProvider>{children}</RainbowKitProvider>
415
- </QueryClientProvider>
416
- </WagmiProvider>
417
- );
418
- }
419
-
420
- function App() {
421
- const [activeTab, setActiveTab] = useState<"ens" | "subname">("ens");
422
-
423
- // ENS Name Registration State
424
- const [ensName, setEnsName] = useState("");
425
- const [ensDuration, setEnsDuration] = useState(1);
426
-
427
- // Subname Registration State
428
- const [subnameStep, setSubnameStep] = useState(0);
429
- const [subname, setSubname] = useState("");
430
- const [parentName] = useState("mydomain.eth");
431
- const [profileComplete, setProfileComplete] = useState(false);
432
- const [owner, setOwner] = useState("");
433
- const [duration, setDuration] = useState(1);
434
- const [useAsPrimary, setUseAsPrimary] = useState(false);
435
-
436
- return (
437
- <AppProviders>
438
- <div style={{ padding: "20px" }}>
439
- <div style={{ marginBottom: "20px" }}>
440
- <button
441
- onClick={() => setActiveTab("ens")}
442
- style={{
443
- marginRight: "10px",
444
- padding: "10px",
445
- backgroundColor: activeTab === "ens" ? "#007bff" : "#ccc",
446
- color: "white",
447
- border: "none",
448
- borderRadius: "4px",
449
- cursor: "pointer",
450
- }}
451
- >
452
- Register ENS Name
453
- </button>
454
- <button
455
- onClick={() => setActiveTab("subname")}
456
- style={{
457
- padding: "10px",
458
- backgroundColor: activeTab === "subname" ? "#007bff" : "#ccc",
459
- color: "white",
460
- border: "none",
461
- borderRadius: "4px",
462
- cursor: "pointer",
463
- }}
464
- >
465
- Register Subname
466
- </button>
467
- </div>
468
-
469
- {activeTab === "ens" && (
470
- <div>
471
- <h2>Register ENS Name</h2>
472
- <ENSNamesRegistrarComponent
473
- name={ensName}
474
- duration={ensDuration}
475
- onNameChange={setEnsName}
476
- onDurationChange={setEnsDuration}
477
- onCompleteRegistration={() => {
478
- alert(`Successfully registered ${ensName}.eth!`);
479
- }}
480
- />
481
- </div>
482
- )}
483
-
484
- {activeTab === "subname" && (
485
- <div>
486
- <h2>Register On-Chain Subname</h2>
487
- <SubnameOnChainRegistrarModal
488
- step={subnameStep}
489
- name={subname}
490
- parentName={parentName}
491
- profileComplete={profileComplete}
492
- owner={owner}
493
- duration={duration}
494
- useAsPrimary={useAsPrimary}
495
- onStepChange={setSubnameStep}
496
- onNameChange={setSubname}
497
- onProfileCompleteChange={setProfileComplete}
498
- onOwnerChange={setOwner}
499
- onDurationChange={setDuration}
500
- onUseAsPrimaryChange={setUseAsPrimary}
501
- onCompleteRegistration={() => {
502
- setSubnameStep(2);
503
- alert(`Successfully registered ${subname}.${parentName}!`);
504
- }}
505
- onFinish={() => {
506
- setSubnameStep(0);
507
- setSubname("");
508
- }}
509
- />
510
- </div>
511
- )}
512
- </div>
513
- </AppProviders>
514
- );
515
- }
516
-
517
- export default App;
518
- ```
519
-
520
- ## Styling
521
-
522
- The components come with their own CSS. Make sure to import the styles:
523
-
524
- ```tsx
525
- import "@thenamespace/ens-components/index.css";
526
- import "@rainbow-me/rainbowkit/styles.css";
527
- ```
528
-
529
- ## Requirements
530
-
531
- - React 18+
532
- - Node.js 16+
533
- - A WalletConnect Project ID (get one at https://cloud.walletconnect.com)
534
-
535
- ## License
536
-
537
- ISC
538
-
539
- ## Support
540
-
541
- For issues and questions, please visit the package repository.
1
+ // TODO