Merge pull request #511 from kinode-dao/dr/reset-node-tlz-agnostic

feat: let user reset any node name, not just `.os`
This commit is contained in:
doria 2024-08-29 15:48:29 +09:00 committed by GitHub
commit 601803ba84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 52 additions and 65 deletions

0
kinode/src/register-ui/build.sh Normal file → Executable file
View File

View File

@ -6,7 +6,7 @@ import MintDotOsName from "./pages/MintDotOsName";
import MintCustom from "./pages/MintCustom";
import SetPassword from "./pages/SetPassword";
import Login from './pages/Login'
import ResetDotOsName from './pages/ResetDotOsName'
import ResetName from './pages/ResetName'
import KinodeHome from "./pages/KinodeHome"
import ImportKeyfile from "./pages/ImportKeyfile";
import { UnencryptedIdentity } from "./lib/types";
@ -112,7 +112,7 @@ function App() {
<Route path="/commit-os-name" element={<CommitDotOsName {...props} />} />
<Route path="/mint-os-name" element={<MintDotOsName {...props} />} />
<Route path="/set-password" element={<SetPassword {...props} />} />
<Route path="/reset" element={<ResetDotOsName {...props} />} />
<Route path="/reset" element={<ResetName {...props} />} />
<Route path="/import-keyfile" element={<ImportKeyfile {...props} />} />
<Route path="/login" element={<Login {...props} />} />
<Route path="/custom-register" element={<MintCustom {...props} />} />

View File

@ -1,5 +1,4 @@
import React, { useEffect, useRef, useState } from "react";
import isValidDomain from "is-valid-domain";
import { toAscii } from "idna-uts46-hx";
import { usePublicClient } from 'wagmi'
@ -13,9 +12,10 @@ export const NAME_INVALID_PUNY = "Unsupported punycode character";
export const NAME_NOT_OWNER = "Name already exists and does not belong to this wallet";
export const NAME_NOT_REGISTERED = "Name is not registered";
type ClaimOsNameProps = {
type EnterNameProps = {
address?: `0x${string}`;
name: string;
fixedTlz?: string;
setName: React.Dispatch<React.SetStateAction<string>>;
nameValidities: string[];
setNameValidities: React.Dispatch<React.SetStateAction<string[]>>;
@ -28,12 +28,13 @@ function EnterKnsName({
address,
name,
setName,
fixedTlz,
nameValidities,
setNameValidities,
triggerNameCheck,
setTba,
isReset = false,
}: ClaimOsNameProps) {
}: EnterNameProps) {
const client = usePublicClient();
const debouncer = useRef<NodeJS.Timeout | null>(null);
@ -43,7 +44,6 @@ function EnterKnsName({
if (debouncer.current) clearTimeout(debouncer.current);
debouncer.current = setTimeout(async () => {
let index: number;
let validities: string[] = [];
setIsPunyfied('');
@ -54,87 +54,75 @@ function EnterKnsName({
}
let normalized = ''
index = validities.indexOf(NAME_INVALID_PUNY);
try {
normalized = toAscii(name + ".os");
if (index !== -1) validities.splice(index, 1);
normalized = toAscii(fixedTlz ? name + fixedTlz : name);
} catch (e) {
if (index === -1) validities.push(NAME_INVALID_PUNY);
validities.push(NAME_INVALID_PUNY);
}
const len = [...normalized].length - 3;
index = validities.indexOf(NAME_LENGTH);
if (len < 9 && len !== 0) {
if (index === -1) validities.push(NAME_LENGTH);
} else if (index !== -1) validities.splice(index, 1);
if (normalized !== (name + ".os")) setIsPunyfied(normalized);
// only check if name is valid punycode
if (normalized && normalized !== '.os') {
index = validities.indexOf(NAME_URL);
if (name !== "" && !isValidDomain(normalized)) {
if (index === -1) validities.push(NAME_URL);
} else if (index !== -1) {
validities.splice(index, 1);
// length check, only for .os
if (fixedTlz === '.os') {
const len = [...normalized].length - 3;
if (len < 9 && len !== 0) {
validities.push(NAME_LENGTH);
}
}
index = validities.indexOf(NAME_CLAIMED);
if (normalized !== (fixedTlz ? name + fixedTlz : name)) {
setIsPunyfied(normalized);
}
// only check if name is valid and long enough
if (validities.length === 0 || index !== -1 && normalized.length > 2) {
try {
const namehash = kinohash(normalized)
// maybe separate into helper function for readability?
// also note picking the right chain ID & address!
const data = await client?.readContract({
address: KIMAP,
abi: kimapAbi,
functionName: "get",
args: [namehash]
})
// only check ownership if name is otherwise valid
if (validities.length === 0 && normalized.length > 2) {
try {
const namehash = kinohash(normalized)
const tba = data?.[0];
if (tba !== undefined) {
setTba ? (setTba(tba)) : null;
} else {
validities.push(NAME_NOT_REGISTERED);
}
const data = await client?.readContract({
address: KIMAP,
abi: kimapAbi,
functionName: "get",
args: [namehash]
})
const owner = data?.[1];
const owner_is_zero = owner === "0x0000000000000000000000000000000000000000";
if (!owner_is_zero && !isReset) validities.push(NAME_CLAIMED);
if (!owner_is_zero && isReset && address && owner !== address) validities.push(NAME_NOT_OWNER);
if (isReset && owner_is_zero) validities.push(NAME_NOT_REGISTERED);
} catch (e) {
console.error({ e })
if (index !== -1) validities.splice(index, 1);
const tba = data?.[0];
if (tba !== undefined) {
setTba ? (setTba(tba)) : null;
} else if (isReset) {
validities.push(NAME_NOT_REGISTERED);
}
const owner = data?.[1];
const owner_is_zero = owner === "0x0000000000000000000000000000000000000000";
if (!owner_is_zero && !isReset) validities.push(NAME_CLAIMED);
if (!owner_is_zero && isReset && address && owner !== address) validities.push(NAME_NOT_OWNER);
if (isReset && owner_is_zero) validities.push(NAME_NOT_REGISTERED);
} catch (e) {
console.error({ e })
}
}
setNameValidities(validities);
}, 500);
}, [name, triggerNameCheck, isReset]);
const noDotsOrSpaces = (e: any) =>
e.target.value.indexOf(".") === -1 && e.target.value.indexOf(" ") === -1 && setName(e.target.value);
const noSpaces = (e: any) =>
e.target.value.indexOf(" ") === -1 && setName(e.target.value);
return (
<div className="enter-kns-name">
<div className="input-wrapper">
<input
value={name}
onChange={noDotsOrSpaces}
onChange={noSpaces}
type="text"
required
name="dot-os-name"
name="kns-name"
placeholder="mynode123"
className="kns-input"
/>
<span className="kns-suffix">.os</span>
{fixedTlz && <span className="kns-suffix">{fixedTlz}</span>}
</div>
{nameValidities.map((x, i) => (
<p key={i} className="error-message">{x}</p>

View File

@ -52,7 +52,7 @@ function CommitDotOsName({
useEffect(() => setTriggerNameCheck(!triggerNameCheck), [address])
const enterOsNameProps = { address, name, setName, nameValidities, setNameValidities, triggerNameCheck }
const enterOsNameProps = { address, name, setName, fixedTlz: ".os", nameValidities, setNameValidities, triggerNameCheck }
useEffect(() => {
if (!address) {

View File

@ -36,7 +36,7 @@ function ResetKnsName({
const { data: hash, writeContract, isPending, isError, error } = useWriteContract({
mutation: {
onSuccess: (data) => {
addRecentTransaction({ hash: data, description: `Reset KNS ID: ${name}.os` });
addRecentTransaction({ hash: data, description: `Reset KNS ID: ${name}` });
}
}
});
@ -46,12 +46,11 @@ function ResetKnsName({
});
const addRecentTransaction = useAddRecentTransaction();
const [name, setName] = useState<string>(knsName.slice(0, -3));
const [name, setName] = useState<string>(knsName);
const [nameValidities, setNameValidities] = useState<string[]>([])
const [tba, setTba] = useState<string>("");
const [triggerNameCheck, setTriggerNameCheck] = useState<boolean>(false);
useEffect(() => {
document.title = "Reset";
}, []);
@ -75,7 +74,7 @@ function ResetKnsName({
return;
}
setKnsName(name + ".os");
setKnsName(name);
try {
const data = await generateNetworkingKeys({