mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-22 16:11:38 +03:00
Merge pull request #477 from kinode-dao/dr/update-kimap
Update kimap contract
This commit is contained in:
commit
ebd5374c95
@ -2,9 +2,9 @@ import { parseAbi } from "viem";
|
||||
|
||||
export { encodeMulticalls, encodeIntoMintCall } from "./helpers";
|
||||
|
||||
export const KINOMAP: `0x${string}` = "0x7290Aa297818d0b9660B2871Bb87f85a3f9B4559";
|
||||
export const KINOMAP: `0x${string}` = "0xAfA2e57D3cBA08169b416457C14eBA2D6021c4b5";
|
||||
export const MULTICALL: `0x${string}` = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0x58790D9957ECE58607A4b58308BBD5FE1a2e4789";
|
||||
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0xd30217e86A4910f4D7cB3E73fC3CfD28a2C33e4e";
|
||||
|
||||
|
||||
export const multicallAbi = parseAbi([
|
||||
|
@ -21,7 +21,7 @@ import './index.css'
|
||||
|
||||
const config = getDefaultConfig({
|
||||
appName: 'Kinode App Store',
|
||||
projectId: 'YOUR_PROJECT_ID',
|
||||
projectId: 'KINODE_APP_STORE',
|
||||
chains: [optimism],
|
||||
ssr: false,
|
||||
transports: {
|
||||
|
@ -21,17 +21,17 @@ wit_bindgen::generate!({
|
||||
});
|
||||
|
||||
#[cfg(not(feature = "simulation-mode"))]
|
||||
const KIMAP_ADDRESS: &'static str = "0x7290Aa297818d0b9660B2871Bb87f85a3f9B4559"; // optimism
|
||||
const KIMAP_ADDRESS: &'static str = kimap::KIMAP_ADDRESS; // optimism
|
||||
#[cfg(feature = "simulation-mode")]
|
||||
const KIMAP_ADDRESS: &'static str = "0xEce71a05B36CA55B895427cD9a440eEF7Cf3669D"; // local
|
||||
|
||||
#[cfg(not(feature = "simulation-mode"))]
|
||||
const CHAIN_ID: u64 = 10; // optimism
|
||||
const CHAIN_ID: u64 = kimap::KIMAP_CHAIN_ID; // optimism
|
||||
#[cfg(feature = "simulation-mode")]
|
||||
const CHAIN_ID: u64 = 31337; // local
|
||||
|
||||
#[cfg(not(feature = "simulation-mode"))]
|
||||
const KIMAP_FIRST_BLOCK: u64 = 114_923_786; // optimism
|
||||
const KIMAP_FIRST_BLOCK: u64 = kimap::KIMAP_FIRST_BLOCK; // optimism
|
||||
#[cfg(feature = "simulation-mode")]
|
||||
const KIMAP_FIRST_BLOCK: u64 = 1; // local
|
||||
|
||||
|
@ -53,7 +53,7 @@ pub const CHAIN_ID: u64 = 10;
|
||||
#[cfg(feature = "simulation-mode")]
|
||||
pub const CHAIN_ID: u64 = 31337;
|
||||
#[cfg(not(feature = "simulation-mode"))]
|
||||
pub const KIMAP_ADDRESS: &str = "0x7290Aa297818d0b9660B2871Bb87f85a3f9B4559";
|
||||
pub const KIMAP_ADDRESS: &str = "0xAfA2e57D3cBA08169b416457C14eBA2D6021c4b5";
|
||||
#[cfg(feature = "simulation-mode")]
|
||||
pub const KIMAP_ADDRESS: &str = "0x0165878A594ca255338adfa4d48449f69242Eb8F";
|
||||
pub const MULTICALL_ADDRESS: &str = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||
|
4929
kinode/src/register-ui/package-lock.json
generated
4929
kinode/src/register-ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,8 @@
|
||||
"react-icons": "^5.0.1",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"viem": "^2.15.1",
|
||||
"wagmi": "^2.10.3"
|
||||
"viem": "^2.19.0",
|
||||
"wagmi": "^2.12.5"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Navigate, BrowserRouter as Router, Route, Routes, useParams } from 'react-router-dom';
|
||||
|
||||
import RegisterKnsName from "./pages/RegisterKnsName";
|
||||
import CommitDotOsName from "./pages/CommitDotOsName";
|
||||
import MintDotOsName from "./pages/MintDotOsName";
|
||||
import SetPassword from "./pages/SetPassword";
|
||||
import Login from './pages/Login'
|
||||
import ResetKnsName from './pages/ResetKnsName'
|
||||
import ResetDotOsName from './pages/ResetDotOsName'
|
||||
import KinodeHome from "./pages/KinodeHome"
|
||||
import ImportKeyfile from "./pages/ImportKeyfile";
|
||||
import { UnencryptedIdentity } from "./lib/types";
|
||||
import Header from "./components/Header";
|
||||
|
||||
|
||||
function App() {
|
||||
const params = useParams()
|
||||
|
||||
@ -35,7 +35,6 @@ function App() {
|
||||
const openConnect = () => setConnectOpen(true)
|
||||
const closeConnect = () => setConnectOpen(false)
|
||||
|
||||
|
||||
useEffect(() => setAppSizeOnLoad(
|
||||
(window.performance.getEntriesByType('navigation') as any)[0].transferSize
|
||||
), []);
|
||||
@ -109,9 +108,10 @@ function App() {
|
||||
? <Navigate to="/login" replace />
|
||||
: <KinodeHome {...props} />
|
||||
} />
|
||||
<Route path="/register-name" element={<RegisterKnsName {...props} />} />
|
||||
<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={<ResetKnsName {...props} />} />
|
||||
<Route path="/reset" element={<ResetDotOsName {...props} />} />
|
||||
<Route path="/import-keyfile" element={<ImportKeyfile {...props} />} />
|
||||
<Route path="/login" element={<Login {...props} />} />
|
||||
</Routes>
|
||||
|
@ -76,6 +76,16 @@ export const generateNetworkingKeys = async ({
|
||||
]
|
||||
});
|
||||
|
||||
const tcp_port_call =
|
||||
encodeFunctionData({
|
||||
abi: kinomapAbi,
|
||||
functionName: 'note',
|
||||
args: [
|
||||
encodePacked(["bytes"], [stringToHex("~tcp-port")]),
|
||||
encodePacked(["bytes"], [bytesToHex(portToBytes(tcp_port || 0))]),
|
||||
]
|
||||
});
|
||||
|
||||
const ip_address_call =
|
||||
encodeFunctionData({
|
||||
abi: kinomapAbi,
|
||||
@ -103,6 +113,7 @@ export const generateNetworkingKeys = async ({
|
||||
const calls = direct ? [
|
||||
{ target: KINOMAP, callData: netkeycall },
|
||||
{ target: KINOMAP, callData: ws_port_call },
|
||||
{ target: KINOMAP, callData: tcp_port_call },
|
||||
{ target: KINOMAP, callData: ip_address_call },
|
||||
] : [
|
||||
{ target: KINOMAP, callData: netkeycall },
|
||||
|
@ -3,11 +3,11 @@ import { parseAbi } from "viem";
|
||||
export { generateNetworkingKeys } from "./helpers";
|
||||
|
||||
// move to constants? // also for anvil/optimism
|
||||
export const KINOMAP: `0x${string}` = "0x7290Aa297818d0b9660B2871Bb87f85a3f9B4559";
|
||||
export const KINOMAP: `0x${string}` = "0xAfA2e57D3cBA08169b416457C14eBA2D6021c4b5";
|
||||
export const MULTICALL: `0x${string}` = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0x58790D9957ECE58607A4b58308BBD5FE1a2e4789";
|
||||
export const DOTOS: `0x${string}` = "0xcf0af6048D42B2a8e18b1B062a6c4a027D8C5Ea6";
|
||||
export const DOTDEV: `0x${string}` = "0x3BA6AE3eca7ca88af8BbCc8A9d8EA5e665b69Eb3";
|
||||
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0xd30217e86A4910f4D7cB3E73fC3CfD28a2C33e4e";
|
||||
export const DOTOS: `0x${string}` = "0x4f0d377e66E4A2750A928495cE261A345e2f0557";
|
||||
// export const DOTDEV: `0x${string}` = "0x3BA6AE3eca7ca88af8BbCc8A9d8EA5e665b69Eb3";
|
||||
|
||||
export const multicallAbi = parseAbi([
|
||||
`function aggregate(Call[] calls) external payable returns (uint256 blockNumber, bytes[] returnData)`,
|
||||
@ -24,3 +24,29 @@ export const mechAbi = parseAbi([
|
||||
"function execute(address to, uint256 value, bytes calldata data, uint8 operation) returns (bytes memory returnData)",
|
||||
"function token() external view returns (uint256,address,uint256)"
|
||||
])
|
||||
|
||||
export const dotOsAbi = [
|
||||
{
|
||||
type: 'function',
|
||||
name: 'commit',
|
||||
stateMutability: 'nonpayable',
|
||||
inputs: [
|
||||
{ name: '_commit', type: 'bytes32' },
|
||||
],
|
||||
outputs: [],
|
||||
},
|
||||
{
|
||||
type: 'function',
|
||||
name: 'mint',
|
||||
stateMutability: 'nonpayable',
|
||||
inputs: [
|
||||
{ name: 'who', type: 'address' },
|
||||
{ name: 'name', type: 'bytes' },
|
||||
{ name: 'initialization', type: 'bytes' },
|
||||
{ name: 'erc721Data', type: 'bytes' },
|
||||
{ name: 'implementation', type: 'address' },
|
||||
{ name: 'secret', type: 'bytes32' },
|
||||
],
|
||||
outputs: [{ type: 'address' }],
|
||||
},
|
||||
] as const
|
@ -32,7 +32,7 @@
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: #555;
|
||||
color: #fff;
|
||||
color: var(--off-white);
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px;
|
||||
@ -66,7 +66,7 @@
|
||||
}
|
||||
|
||||
.section {
|
||||
background-color: var(--white);
|
||||
background-color: light-dark(var(--off-white), var(--tasteful-dark));
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
padding: 2rem;
|
||||
@ -127,14 +127,14 @@
|
||||
.kns-input {
|
||||
flex-grow: 1;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--gray);
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.kns-suffix {
|
||||
padding: 0.5rem;
|
||||
background-color: #f0f0f0;
|
||||
border: 1px solid #ccc;
|
||||
background-color: var(--gray);
|
||||
border: 1px solid var(--tasteful-dark);
|
||||
border-left: none;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
@ -146,7 +146,7 @@
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #ff0000;
|
||||
color: var(--ansi-red);
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@
|
||||
}
|
||||
|
||||
.checkbox-container:hover input~.checkmark {
|
||||
background-color: #ccc;
|
||||
background-color: var(--gray);
|
||||
}
|
||||
|
||||
.checkbox-container input:checked~.checkmark {
|
||||
@ -208,7 +208,7 @@
|
||||
top: 5px;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
border: solid white;
|
||||
border: solid var(--off-white);
|
||||
border-width: 0 3px 3px 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
@ -234,5 +234,5 @@
|
||||
|
||||
.file-input-label:hover .button {
|
||||
background-color: var(--dark-orange);
|
||||
color: white;
|
||||
color: var(--off-white);
|
||||
}
|
@ -26,7 +26,7 @@ window.Buffer = Buffer;
|
||||
|
||||
const config = getDefaultConfig({
|
||||
appName: 'Kinode Register UI',
|
||||
projectId: 'YOUR_PROJECT_ID',
|
||||
projectId: 'KINODE_REGISTER',
|
||||
chains: [optimism],
|
||||
ssr: false,
|
||||
transports: {
|
||||
|
@ -22,7 +22,7 @@ export interface PageProps {
|
||||
pw: string,
|
||||
setPw: React.Dispatch<React.SetStateAction<string>>,
|
||||
appSizeOnLoad: number,
|
||||
nodeChainId: string
|
||||
nodeChainId: string,
|
||||
}
|
||||
|
||||
export type NetworkingInfo = {
|
||||
|
130
kinode/src/register-ui/src/pages/CommitDotOsName.tsx
Normal file
130
kinode/src/register-ui/src/pages/CommitDotOsName.tsx
Normal file
@ -0,0 +1,130 @@
|
||||
import { useState, useEffect, FormEvent, useCallback } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import EnterKnsName from "../components/EnterKnsName";
|
||||
import Loader from "../components/Loader";
|
||||
import { PageProps } from "../lib/types";
|
||||
|
||||
import DirectCheckbox from "../components/DirectCheckbox";
|
||||
import { Tooltip } from "../components/Tooltip";
|
||||
|
||||
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
||||
import { useConnectModal, useAddRecentTransaction } from "@rainbow-me/rainbowkit"
|
||||
import { dotOsAbi, DOTOS } from "../abis";
|
||||
import { stringToHex, encodeAbiParameters, parseAbiParameters, keccak256 } from "viem";
|
||||
|
||||
interface RegisterOsNameProps extends PageProps { }
|
||||
|
||||
function CommitDotOsName({
|
||||
direct,
|
||||
setDirect,
|
||||
setOsName,
|
||||
setNetworkingKey,
|
||||
setIpAddress,
|
||||
setWsPort,
|
||||
setTcpPort,
|
||||
setRouters,
|
||||
}: RegisterOsNameProps) {
|
||||
let { address } = useAccount();
|
||||
let navigate = useNavigate();
|
||||
let { openConnectModal } = useConnectModal();
|
||||
|
||||
const { data: hash, writeContract, isPending, isError, error } = useWriteContract({
|
||||
mutation: {
|
||||
onSuccess: (data) => {
|
||||
addRecentTransaction({ hash: data, description: `Pre-commit to .os ID: ${name}.os` });
|
||||
}
|
||||
}
|
||||
});
|
||||
const { isLoading: isConfirming, isSuccess: isConfirmed } =
|
||||
useWaitForTransactionReceipt({
|
||||
hash,
|
||||
});
|
||||
const addRecentTransaction = useAddRecentTransaction();
|
||||
|
||||
const [name, setName] = useState('')
|
||||
const [nameValidities, setNameValidities] = useState<string[]>([])
|
||||
const [triggerNameCheck, setTriggerNameCheck] = useState<boolean>(false)
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Register"
|
||||
}, [])
|
||||
|
||||
useEffect(() => setTriggerNameCheck(!triggerNameCheck), [address])
|
||||
|
||||
const enterOsNameProps = { name, setName, nameValidities, setNameValidities, triggerNameCheck }
|
||||
|
||||
let handleCommit = useCallback(async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
if (!address) {
|
||||
openConnectModal?.()
|
||||
return
|
||||
}
|
||||
console.log("committing to .os name: ", name)
|
||||
const commitSecret = keccak256(stringToHex(name))
|
||||
const commit = keccak256(
|
||||
encodeAbiParameters(
|
||||
parseAbiParameters('bytes32, bytes32'),
|
||||
[keccak256(stringToHex(name)), commitSecret]
|
||||
)
|
||||
)
|
||||
writeContract({
|
||||
abi: dotOsAbi,
|
||||
address: DOTOS,
|
||||
functionName: 'commit',
|
||||
args: [commit],
|
||||
gas: 1000000n,
|
||||
})
|
||||
|
||||
}, [name, direct, address, writeContract, setNetworkingKey, setIpAddress, setWsPort, setTcpPort, setRouters, openConnectModal])
|
||||
|
||||
useEffect(() => {
|
||||
if (isConfirmed) {
|
||||
setOsName(`${name}.os`);
|
||||
navigate("/mint-os-name");
|
||||
}
|
||||
}, [isConfirmed, address, name, setOsName, navigate]);
|
||||
|
||||
return (
|
||||
<div className="container fade-in">
|
||||
<div className="section">
|
||||
{Boolean(address) && (
|
||||
<form className="form" onSubmit={handleCommit}>
|
||||
{isPending || isConfirming ? (
|
||||
<Loader msg={isConfirming ? 'Pre-committing to chosen ID...' : 'Please confirm the transaction in your wallet'} />
|
||||
) : (
|
||||
<>
|
||||
<h3 className="form-label">
|
||||
<Tooltip text="Kinodes need an onchain node identity in order to communicate with other nodes in the network.">
|
||||
Choose a name for your Kinode
|
||||
</Tooltip>
|
||||
</h3>
|
||||
<EnterKnsName {...enterOsNameProps} />
|
||||
<DirectCheckbox {...{ direct, setDirect }} />
|
||||
<div className="button-group">
|
||||
<button
|
||||
disabled={nameValidities.length !== 0 || isPending || isConfirming}
|
||||
type="submit"
|
||||
className="button"
|
||||
>
|
||||
Register .os name
|
||||
</button>
|
||||
<Link to="/reset" className="button secondary">
|
||||
Already have a dot-os-name?
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{isError && (
|
||||
<p className="error-message">
|
||||
Error: {error?.message || 'There was an error registering your dot-os-name, please try again.'}
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CommitDotOsName;
|
@ -8,7 +8,7 @@ type OsHomeProps = {
|
||||
|
||||
function KinodeHome({ knsName }: OsHomeProps) {
|
||||
const navigate = useNavigate()
|
||||
const registerRedir = () => navigate('/register-name')
|
||||
const registerRedir = () => navigate('/commit-os-name')
|
||||
const resetRedir = () => navigate('/reset')
|
||||
const importKeyfileRedir = () => navigate('/import-keyfile')
|
||||
const loginRedir = () => navigate('/login')
|
||||
|
135
kinode/src/register-ui/src/pages/MintDotOsName.tsx
Normal file
135
kinode/src/register-ui/src/pages/MintDotOsName.tsx
Normal file
@ -0,0 +1,135 @@
|
||||
import { useState, useEffect, FormEvent, useCallback } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Loader from "../components/Loader";
|
||||
import { PageProps } from "../lib/types";
|
||||
|
||||
import { useAccount, useWaitForTransactionReceipt, useSendTransaction } from "wagmi";
|
||||
import { useConnectModal, useAddRecentTransaction } from "@rainbow-me/rainbowkit"
|
||||
import { dotOsAbi, generateNetworkingKeys, KINO_ACCOUNT_IMPL, DOTOS } from "../abis";
|
||||
import { encodePacked, encodeFunctionData, stringToHex, keccak256 } from "viem";
|
||||
|
||||
interface RegisterOsNameProps extends PageProps { }
|
||||
|
||||
function MintDotOsName({
|
||||
direct,
|
||||
knsName,
|
||||
setNetworkingKey,
|
||||
setIpAddress,
|
||||
setWsPort,
|
||||
setTcpPort,
|
||||
setRouters,
|
||||
}: RegisterOsNameProps) {
|
||||
let { address } = useAccount();
|
||||
let navigate = useNavigate();
|
||||
let { openConnectModal } = useConnectModal();
|
||||
|
||||
const { data: hash, sendTransaction, isPending, isError, error } = useSendTransaction({
|
||||
mutation: {
|
||||
onSuccess: (data) => {
|
||||
addRecentTransaction({ hash: data, description: `Mint ${knsName}` });
|
||||
}
|
||||
}
|
||||
});
|
||||
const { isLoading: isConfirming, isSuccess: isConfirmed } =
|
||||
useWaitForTransactionReceipt({
|
||||
hash,
|
||||
});
|
||||
const addRecentTransaction = useAddRecentTransaction();
|
||||
|
||||
const [triggerNameCheck, setTriggerNameCheck] = useState<boolean>(false)
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Mint"
|
||||
}, [])
|
||||
|
||||
useEffect(() => setTriggerNameCheck(!triggerNameCheck), [address])
|
||||
|
||||
let handleMint = useCallback(async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if (!address) {
|
||||
openConnectModal?.()
|
||||
return
|
||||
}
|
||||
|
||||
const initCall = await generateNetworkingKeys({
|
||||
direct,
|
||||
our_address: address,
|
||||
label: knsName,
|
||||
setNetworkingKey,
|
||||
setIpAddress,
|
||||
setWsPort,
|
||||
setTcpPort,
|
||||
setRouters,
|
||||
reset: false,
|
||||
});
|
||||
|
||||
console.log("minting name: ", knsName)
|
||||
|
||||
// strip .os suffix
|
||||
const name = knsName.replace(/\.os$/, '');
|
||||
const commitSecret = keccak256(stringToHex(name))
|
||||
|
||||
const data = encodeFunctionData({
|
||||
abi: dotOsAbi,
|
||||
functionName: 'mint',
|
||||
args: [
|
||||
address,
|
||||
encodePacked(["bytes"], [stringToHex(name)]),
|
||||
initCall,
|
||||
"0x",
|
||||
KINO_ACCOUNT_IMPL,
|
||||
commitSecret
|
||||
],
|
||||
})
|
||||
|
||||
// use data to write to contract -- do NOT use writeContract
|
||||
// writeContract will NOT generate the correct selector for some reason
|
||||
// probably THEIR bug.. no abi works
|
||||
try {
|
||||
sendTransaction({
|
||||
to: DOTOS,
|
||||
data: data,
|
||||
gas: 1000000n,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to send transaction:', error)
|
||||
}
|
||||
}, [direct, address, sendTransaction, setNetworkingKey, setIpAddress, setWsPort, setTcpPort, setRouters, openConnectModal])
|
||||
|
||||
useEffect(() => {
|
||||
if (isConfirmed) {
|
||||
navigate("/set-password");
|
||||
}
|
||||
}, [isConfirmed, address, navigate]);
|
||||
|
||||
return (
|
||||
<div className="container fade-in">
|
||||
<div className="section">
|
||||
{Boolean(address) && (
|
||||
<form className="form" onSubmit={handleMint}>
|
||||
{isPending || isConfirming ? (
|
||||
<Loader msg={isConfirming ? 'Minting .os name...' : 'Please confirm the transaction in your wallet'} />
|
||||
) : (
|
||||
<>
|
||||
<div className="button-group">
|
||||
<button type="submit" className="button">
|
||||
Mint pre-committed .os name
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{isError && (
|
||||
<p className="error-message">
|
||||
Error: {error?.message || 'There was an error minting your dot-os-name, please try again.'}
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MintDotOsName;
|
@ -1,141 +0,0 @@
|
||||
import { useState, useEffect, FormEvent, useCallback } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import EnterKnsName from "../components/EnterKnsName";
|
||||
import Loader from "../components/Loader";
|
||||
import { PageProps } from "../lib/types";
|
||||
|
||||
import DirectCheckbox from "../components/DirectCheckbox";
|
||||
import { Tooltip } from "../components/Tooltip";
|
||||
|
||||
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
||||
import { useConnectModal, useAddRecentTransaction } from "@rainbow-me/rainbowkit"
|
||||
import { kinomapAbi, generateNetworkingKeys, KINO_ACCOUNT_IMPL, DOTOS } from "../abis";
|
||||
import { encodePacked, stringToHex } from "viem";
|
||||
|
||||
interface RegisterOsNameProps extends PageProps { }
|
||||
|
||||
function RegisterKnsName({
|
||||
direct,
|
||||
setDirect,
|
||||
setOsName,
|
||||
setNetworkingKey,
|
||||
setIpAddress,
|
||||
setWsPort,
|
||||
setTcpPort,
|
||||
setRouters,
|
||||
}: RegisterOsNameProps) {
|
||||
let { address } = useAccount();
|
||||
let navigate = useNavigate();
|
||||
let { openConnectModal } = useConnectModal();
|
||||
|
||||
const { data: hash, writeContract, isPending, isError, error } = useWriteContract({
|
||||
mutation: {
|
||||
onSuccess: (data) => {
|
||||
addRecentTransaction({ hash: data, description: `Register KNS ID: ${name}.os` });
|
||||
}
|
||||
}
|
||||
});
|
||||
const { isLoading: isConfirming, isSuccess: isConfirmed } =
|
||||
useWaitForTransactionReceipt({
|
||||
hash,
|
||||
});
|
||||
const addRecentTransaction = useAddRecentTransaction();
|
||||
|
||||
const [name, setName] = useState('')
|
||||
const [nameValidities, setNameValidities] = useState<string[]>([])
|
||||
const [triggerNameCheck, setTriggerNameCheck] = useState<boolean>(false)
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Register"
|
||||
}, [])
|
||||
|
||||
useEffect(() => setTriggerNameCheck(!triggerNameCheck), [address])
|
||||
|
||||
const enterOsNameProps = { name, setName, nameValidities, setNameValidities, triggerNameCheck }
|
||||
|
||||
let handleRegister = useCallback(async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if (!address) {
|
||||
openConnectModal?.()
|
||||
return
|
||||
}
|
||||
|
||||
const initCall = await generateNetworkingKeys({
|
||||
direct,
|
||||
our_address: address,
|
||||
label: name,
|
||||
setNetworkingKey,
|
||||
setIpAddress,
|
||||
setWsPort,
|
||||
setTcpPort,
|
||||
setRouters,
|
||||
reset: false,
|
||||
});
|
||||
|
||||
writeContract({
|
||||
abi: kinomapAbi,
|
||||
address: DOTOS,
|
||||
functionName: 'mint',
|
||||
args: [
|
||||
address,
|
||||
encodePacked(["bytes"], [stringToHex(name)]),
|
||||
initCall,
|
||||
"0x",
|
||||
KINO_ACCOUNT_IMPL,
|
||||
],
|
||||
gas: 1000000n,
|
||||
})
|
||||
}, [name, direct, address, writeContract, setNetworkingKey, setIpAddress, setWsPort, setTcpPort, setRouters, openConnectModal])
|
||||
|
||||
useEffect(() => {
|
||||
if (isConfirmed) {
|
||||
setOsName(`${name}.os`);
|
||||
navigate("/set-password");
|
||||
}
|
||||
}, [isConfirmed, name, setOsName, navigate]);
|
||||
|
||||
return (
|
||||
<div className="container fade-in">
|
||||
<div className="section">
|
||||
{Boolean(address) && (
|
||||
<form className="form" onSubmit={handleRegister}>
|
||||
{isPending || isConfirming ? (
|
||||
<Loader msg={isConfirming ? 'Registering KNS ID...' : 'Please confirm the transaction in your wallet'} />
|
||||
) : (
|
||||
<>
|
||||
<h3 className="form-label">
|
||||
<Tooltip text="Kinodes need an onchain node identity in order to communicate with other nodes in the network.">
|
||||
Choose a name for your Kinode
|
||||
</Tooltip>
|
||||
</h3>
|
||||
<EnterKnsName {...enterOsNameProps} />
|
||||
<DirectCheckbox {...{ direct, setDirect }} />
|
||||
<div className="button-group">
|
||||
<button
|
||||
disabled={nameValidities.length !== 0 || isPending || isConfirming}
|
||||
type="submit"
|
||||
className="button"
|
||||
>
|
||||
Register .os name
|
||||
</button>
|
||||
<Link to="/reset" className="button secondary">
|
||||
Already have a dot-os-name?
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{isError && (
|
||||
<p className="error-message">
|
||||
Error: {error?.message || 'There was an error registering your dot-os-name, please try again.'}
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default RegisterKnsName;
|
@ -99,7 +99,8 @@ pub async fn register(
|
||||
|
||||
let react_app = warp::path::end()
|
||||
.or(warp::path("login"))
|
||||
.or(warp::path("register-name"))
|
||||
.or(warp::path("commit-os-name"))
|
||||
.or(warp::path("mint-os-name"))
|
||||
.or(warp::path("claim-invite"))
|
||||
.or(warp::path("reset"))
|
||||
.or(warp::path("import-keyfile"))
|
||||
|
Loading…
Reference in New Issue
Block a user