feat: integrate ins - #297
Conversation
|
Note
|
| Layer / File(s) | Summary |
|---|---|
INS API hooks hooks/ins/useIns.ts |
New module with fetchDomainOwner, useInsDomainsByAddress, and useInsResolve hooks backed by SWR, plus extractDomainNames normalization and InsResolveResponse type. |
Dashboard INS/KNS unification components/dashboard/INSItem.tsx, components/dashboard/Names.tsx, components/dashboard/KNS.tsx, components/screens/Dashboard.tsx |
Adds INSItem row and Names component combining paginated KNS and INS domain lists with infinite scroll and empty state; removes standalone KNS component; Dashboard tab renamed and rewired to render Names. |
INS asset screen and routing components/screens/INSAsset.tsx, entrypoints/popup/router.tsx |
New INSAsset screen displaying resolved domain details, registered at route ins/:name. |
INS domain resolution in send flows lib/layer2.ts, components/send/evm/erc20-send/DetailsStep.tsx, components/send/evm/erc20-send/Erc20Send.tsx, components/send/evm/evm-kas-send/DetailsStep.tsx, components/send/evm/evm-kas-send/EvmKasSend.tsx |
Adds isIgraChain helper; extends Erc20Send/EvmKasSend form schemas with optional domain; address validators in both DetailsStep components resolve INS domains to addresses when enabled and updates placeholder/UI text. |
Estimated code review effort: 3 (Moderate) | ~30 minutes
Sequence Diagram(s)
sequenceDiagram
participant User
participant DetailsStep
participant useIns
participant InsApi
User->>DetailsStep: enters address or domain
DetailsStep->>DetailsStep: addressValidator(input)
alt input contains dot and insEnabled
DetailsStep->>useIns: fetchDomainOwner(input)
useIns->>InsApi: GET /resolve?name=input
InsApi-->>useIns: exists, address
useIns-->>DetailsStep: resolved address
DetailsStep->>DetailsStep: set address and domain fields
else direct EVM address
DetailsStep->>DetailsStep: validate address format
end
sequenceDiagram
participant Names
participant useAssetsByAddress
participant useInsDomainsByAddress
participant IntersectionObserver
Names->>useAssetsByAddress: fetch KNS assets page
Names->>useInsDomainsByAddress: fetch INS domains
IntersectionObserver->>Names: sentinel intersecting
Names->>useAssetsByAddress: setKnsSize(next page)
useAssetsByAddress-->>Names: additional KNS page data
Names->>Names: render KNSItem and INSItem lists
Possibly related PRs
- forbole/kastle#260: Both PRs modify
lib/layer2.tsfor IGRA network support, with this PR adding theisIgraChainhelper that depends on IGRA chain definitions.
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title matches the main change, which adds INS support across navigation, screens, and send flows. |
| Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
feat/impl-ins
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
hooks/ins/useIns.ts (2)
31-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider using the shared
fetcherinfetchDomainOwner.
fetchDomainOwneruses rawfetchwhile the SWR hooks in this same file use the sharedfetcherfrom@/lib/utils. Iffetcherincludes common headers, error handling, or retries, this path bypasses them. Additionally, the coding guidelines state hooks should useuseSWRfor API data fetching. If on-demand resolution outside React render is needed, consider extracting this as a non-hook utility function rather than auseInshook that doesn't call any React hooks.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@hooks/ins/useIns.ts` around lines 31 - 56, `useIns` currently performs API access in `fetchDomainOwner` with raw `fetch`, bypassing the shared request behavior used elsewhere in this module. Update `fetchDomainOwner` to use the shared `fetcher` from `@/lib/utils` so it benefits from the same headers/error handling/retry behavior, and if this logic is meant for on-demand use outside React rendering, move it out of `useIns` into a plain utility instead of keeping a hook that doesn’t use React hooks.Source: Coding guidelines
58-62: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueURL-encode
addressin the SWR key for consistency.
useInsResolveandfetchDomainOwnerboth useencodeURIComponentfor thenameparameter, butuseInsDomainsByAddresspassesaddressraw into the URL. While EVM addresses are hex and unlikely to contain special characters, this is inconsistent and could break if the function is reused with non-hex inputs.♻️ Proposed fix
- address ? `${INS_API_URL}/names/by-owner?address=${address}` : null, + address ? `${INS_API_URL}/names/by-owner?address=${encodeURIComponent(address)}` : null,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@hooks/ins/useIns.ts` around lines 58 - 62, The SWR key in useInsDomainsByAddress currently appends address without encoding, which is inconsistent with useInsResolve and fetchDomainOwner. Update the URL construction in useInsDomainsByAddress to URL-encode the address value before interpolating it into the names/by-owner query string, so the hook matches the encoding approach used elsewhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/dashboard/INSItem.tsx`:
- Line 14: The navigation in INSItem’s onClick handler interpolates name
directly into the route, which can break for domain names containing URL-special
characters. Update the navigate call to encode the dynamic name segment before
building the /ins route so the path is always safe and resolves correctly.
In `@components/screens/INSAsset.tsx`:
- Around line 9-12: The INSAsset screen currently only uses detail from
useInsResolve, so loading and missing-domain cases fall through to an empty
view. Update INSAsset to also destructure isLoading and error from
useInsResolve, then render a loading skeleton or placeholder while loading and a
clear not-found state when error or missing detail is returned. Keep the
existing navigate/useParams flow intact and handle these states before the main
detail render so the screen never appears blank.
In `@components/send/evm/erc20-send/DetailsStep.tsx`:
- Around line 108-119: The async INS validation in DetailsStep can write stale
recipient data after user input changes. Update the validator around the
fetchDomainOwner flow to verify the current input still matches the value being
validated before calling setValue for address or domain, or otherwise
cancel/ignore outdated lookups. Use the existing DetailsStep validation path and
the userInput/value state involved in the INS lookup to ensure only the latest
recipient input can update form state.
In `@components/send/evm/evm-kas-send/DetailsStep.tsx`:
- Around line 86-97: The INS resolution path in DetailsStep’s recipient
validation can apply an outdated async result and overwrite the current
address/domain after the user changes input. Update the fetchDomainOwner branch
to verify the latest recipient value still matches the looked-up value before
calling setValue, or otherwise cancel/ignore stale validations. Use the existing
validation logic around insEnabled, value.includes("."), fetchDomainOwner, and
setValue to keep the current input authoritative.
In `@hooks/ins/useIns.ts`:
- Around line 6-13: The INS response type is currently only a plain interface,
and `useInsResolve` is accepting SWR data without runtime validation. Add a Zod
schema for `InsResolveResponse` and use it to parse the resolved payload before
returning it from `useInsResolve`, so malformed INS API responses are caught at
runtime. Keep the schema colocated with `InsResolveResponse` and update the SWR
response handling to use the parsed result instead of a direct cast.
---
Nitpick comments:
In `@hooks/ins/useIns.ts`:
- Around line 31-56: `useIns` currently performs API access in
`fetchDomainOwner` with raw `fetch`, bypassing the shared request behavior used
elsewhere in this module. Update `fetchDomainOwner` to use the shared `fetcher`
from `@/lib/utils` so it benefits from the same headers/error handling/retry
behavior, and if this logic is meant for on-demand use outside React rendering,
move it out of `useIns` into a plain utility instead of keeping a hook that
doesn’t use React hooks.
- Around line 58-62: The SWR key in useInsDomainsByAddress currently appends
address without encoding, which is inconsistent with useInsResolve and
fetchDomainOwner. Update the URL construction in useInsDomainsByAddress to
URL-encode the address value before interpolating it into the names/by-owner
query string, so the hook matches the encoding approach used elsewhere.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: ee9f35e4-d6d6-4470-99d3-1a139b44d607
📒 Files selected for processing (12)
components/dashboard/INSItem.tsxcomponents/dashboard/KNS.tsxcomponents/dashboard/Names.tsxcomponents/screens/Dashboard.tsxcomponents/screens/INSAsset.tsxcomponents/send/evm/erc20-send/DetailsStep.tsxcomponents/send/evm/erc20-send/Erc20Send.tsxcomponents/send/evm/evm-kas-send/DetailsStep.tsxcomponents/send/evm/evm-kas-send/EvmKasSend.tsxentrypoints/popup/router.tsxhooks/ins/useIns.tslib/layer2.ts
💤 Files with no reviewable changes (1)
- components/dashboard/KNS.tsx
| return ( | ||
| <div | ||
| className="flex cursor-pointer items-center gap-3 rounded-xl border border-daintree-700 bg-daintree-800 p-3 hover:border-white" | ||
| onClick={() => navigate(`/ins/${name}`)} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Encode name in the navigation URL.
name is interpolated directly into the route path without encodeURIComponent. If a domain name contains URL-special characters (e.g., /, ?, #), the route will break or navigate to the wrong path.
🐛 Proposed fix
- onClick={() => navigate(`/ins/${name}`)}
+ onClick={() => navigate(`/ins/${encodeURIComponent(name)}`)}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onClick={() => navigate(`/ins/${name}`)} | |
| onClick={() => navigate(`/ins/${encodeURIComponent(name)}`)} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/dashboard/INSItem.tsx` at line 14, The navigation in INSItem’s
onClick handler interpolates name directly into the route, which can break for
domain names containing URL-special characters. Update the navigate call to
encode the dynamic name segment before building the /ins route so the path is
always safe and resolves correctly.
| export default function INSAsset() { | ||
| const navigate = useNavigate(); | ||
| const { name } = useParams(); | ||
| const { detail } = useInsResolve(name); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add loading and not-found states to INSAsset screen.
Only detail is destructured from useInsResolve, ignoring isLoading and error. When the domain is loading or doesn't exist, the user sees a blank screen with only a header. Destructure isLoading and render a loading skeleton or "not found" message accordingly.
💚 Proposed fix
export default function INSAsset() {
const navigate = useNavigate();
const { name } = useParams();
- const { detail } = useInsResolve(name);
+ const { detail, isLoading } = useInsResolve(name);
return (
<div className="flex h-full flex-col p-4">
<Header
title="INS Asset"
showClose={false}
onBack={() => navigate("/dashboard")}
/>
+ {isLoading && (
+ <div className="flex flex-1 items-center justify-center">
+ <div className="size-6 animate-spin rounded-full border-[6px] border-current border-t-[`#A2F5FF`] text-icy-blue-600" />
+ </div>
+ )}
+
+ {!isLoading && !detail && (
+ <div className="flex flex-1 items-center justify-center text-sm text-daintree-400">
+ Domain not found
+ </div>
+ )}
+
{detail && (📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export default function INSAsset() { | |
| const navigate = useNavigate(); | |
| const { name } = useParams(); | |
| const { detail } = useInsResolve(name); | |
| export default function INSAsset() { | |
| const navigate = useNavigate(); | |
| const { name } = useParams(); | |
| const { detail, isLoading } = useInsResolve(name); | |
| return ( | |
| <div className="flex h-full flex-col p-4"> | |
| <Header | |
| title="INS Asset" | |
| showClose={false} | |
| onBack={() => navigate("/dashboard")} | |
| /> | |
| {isLoading && ( | |
| <div className="flex flex-1 items-center justify-center"> | |
| <div className="size-6 animate-spin rounded-full border-[6px] border-current border-t-[`#A2F5FF`] text-icy-blue-600" /> | |
| </div> | |
| )} | |
| {!isLoading && !detail && ( | |
| <div className="flex flex-1 items-center justify-center text-sm text-daintree-400"> | |
| Domain not found | |
| </div> | |
| )} | |
| {detail && ( |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/screens/INSAsset.tsx` around lines 9 - 12, The INSAsset screen
currently only uses detail from useInsResolve, so loading and missing-domain
cases fall through to an empty view. Update INSAsset to also destructure
isLoading and error from useInsResolve, then render a loading skeleton or
placeholder while loading and a clear not-found state when error or missing
detail is returned. Keep the existing navigate/useParams flow intact and handle
these states before the main detail render so the screen never appears blank.
| if (insEnabled && value.includes(".")) { | ||
| const resolved = await fetchDomainOwner(value); | ||
| if (resolved && isAddress(resolved)) { | ||
| setValue("address", resolved); | ||
| setValue("domain", value); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| setValue("address", undefined); | ||
| setValue("domain", undefined); | ||
| return genericErrorMessage; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the target file, then inspect the relevant region and related symbols.
ast-grep outline components/send/evm/erc20-send/DetailsStep.tsx --view expanded
printf '\n--- file excerpt ---\n'
sed -n '1,220p' components/send/evm/erc20-send/DetailsStep.tsx | cat -n
printf '\n--- fetchDomainOwner references ---\n'
rg -n "fetchDomainOwner|userInput|setValue\\(\" components/send/evm/erc20-send -S
printf '\n--- related form fields and validators ---\n'
rg -n "useFormContext|trigger\\(|validatingFields|address|domain|userInput" components/send/evm/erc20-send -SRepository: forbole/kastle
Length of output: 8720
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- form definition ---'
ast-grep outline components/send/evm/erc20-send/Erc20Send.tsx --view expanded
printf '\n%s\n' '--- form file excerpt ---'
sed -n '1,260p' components/send/evm/erc20-send/Erc20Send.tsx | cat -n
printf '\n%s\n' '--- userInput / address / domain references in the send flow ---'
rg -n "userInput|address|domain|fetchDomainOwner|trigger\\(|setValue\\(" components/send/evm/erc20-send -S
printf '\n%s\n' '--- react-hook-form config references ---'
rg -n "useForm\\(|mode:|reValidateMode:|resolver:|defaultValues:" components/send/evm/erc20-send -SRepository: forbole/kastle
Length of output: 11269
Guard the INS lookup against stale recipient input. The async validator can still call setValue("address") / setValue("domain") after userInput has changed, so an older lookup can overwrite or clear the current recipient state. Compare against the latest input, or cancel the in-flight lookup, before writing back.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/send/evm/erc20-send/DetailsStep.tsx` around lines 108 - 119, The
async INS validation in DetailsStep can write stale recipient data after user
input changes. Update the validator around the fetchDomainOwner flow to verify
the current input still matches the value being validated before calling
setValue for address or domain, or otherwise cancel/ignore outdated lookups. Use
the existing DetailsStep validation path and the userInput/value state involved
in the INS lookup to ensure only the latest recipient input can update form
state.
| if (insEnabled && value.includes(".")) { | ||
| const resolved = await fetchDomainOwner(value); | ||
| if (resolved && isAddress(resolved)) { | ||
| setValue("address", resolved); | ||
| setValue("domain", value); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| setValue("address", undefined); | ||
| setValue("domain", undefined); | ||
| return genericErrorMessage; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the target file and nearby related flows, then inspect the relevant slices.
echo "== target file outline =="
ast-grep outline components/send/evm/evm-kas-send/DetailsStep.tsx --view expanded || true
echo
echo "== search for ERC20 flow and stale-input guards =="
rg -n "getValues\\(|fetchDomainOwner|userInput|domain|address|stale|race|ERC20|erc20" components/send/evm -S
echo
echo "== read the relevant section of target file =="
sed -n '1,220p' components/send/evm/evm-kas-send/DetailsStep.tsx
echo
echo "== locate ERC20-related comparator in repository =="
rg -n "fetchDomainOwner|getValues\\(\"userInput\"\\)|setValue\\(\"address\"|setValue\\(\"domain\"" components -SRepository: forbole/kastle
Length of output: 23813
Guard INS resolution against stale input.
fetchDomainOwner can resolve after the user has already changed the recipient, and this branch will still overwrite address/domain with the old result. Check the current input before applying the async lookup result, or cancel the in-flight validation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/send/evm/evm-kas-send/DetailsStep.tsx` around lines 86 - 97, The
INS resolution path in DetailsStep’s recipient validation can apply an outdated
async result and overwrite the current address/domain after the user changes
input. Update the fetchDomainOwner branch to verify the latest recipient value
still matches the looked-up value before calling setValue, or otherwise
cancel/ignore stale validations. Use the existing validation logic around
insEnabled, value.includes("."), fetchDomainOwner, and setValue to keep the
current input authoritative.
| export interface InsResolveResponse { | ||
| exists: boolean; | ||
| address?: string; | ||
| owner?: string; | ||
| registry_version?: string; | ||
| tenure?: string; | ||
| expires_at?: string; | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Use Zod schemas for INS API payload validation.
As per coding guidelines, all API payloads should be validated with Zod. InsResolveResponse is a plain interface and the SWR responses are cast without schema validation. Define a Zod schema and parse the response data through it to catch malformed API responses at runtime.
♻️ Proposed Zod schema and validation
+import { z } from "zod";
+
+export const InsResolveResponseSchema = z.object({
+ exists: z.boolean(),
+ address: z.string().optional(),
+ owner: z.string().optional(),
+ registry_version: z.string().optional(),
+ tenure: z.string().optional(),
+ expires_at: z.string().optional(),
+});
+
+export type InsResolveResponse = z.infer<typeof InsResolveResponseSchema>;Then update useInsResolve to parse through the schema:
export function useInsResolve(name?: string) {
- const { data, isLoading, error } = useSWR<InsResolveResponse, Error>(
+ const { data, isLoading, error } = useSWR<InsResolveResponse, Error>(
name ? `${INS_API_URL}/resolve?name=${encodeURIComponent(name)}` : null,
- fetcher,
+ async (url: string) => InsResolveResponseSchema.parse(await fetcher(url)),
);
return { detail: data?.exists ? data : undefined, isLoading, error };
}Also applies to: 59-64
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/ins/useIns.ts` around lines 6 - 13, The INS response type is currently
only a plain interface, and `useInsResolve` is accepting SWR data without
runtime validation. Add a Zod schema for `InsResolveResponse` and use it to
parse the resolved payload before returning it from `useInsResolve`, so
malformed INS API responses are caught at runtime. Keep the schema colocated
with `InsResolveResponse` and update the SWR response handling to use the parsed
result instead of a direct cast.
Source: Coding guidelines
There was a problem hiding this comment.
Pull request overview
This PR adds INS (insdomains.org) name support to the Kastle extension popup, including listing INS names on the dashboard, a dedicated INS asset details screen, and the ability to resolve INS domains when sending on IGRA EVM networks.
Changes:
- Added INS API hooks for resolving names and listing names by owner address.
- Introduced a unified “Names” dashboard tab combining KNS + INS listings and added an INS asset details route/screen.
- Enabled INS-domain-to-address resolution in EVM send flows on IGRA chains (and added
isIgraChainhelper).
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
lib/layer2.ts |
Adds isIgraChain helper to gate INS features to IGRA networks. |
hooks/ins/useIns.ts |
New INS API hooks for name resolution and listing domains by address. |
entrypoints/popup/router.tsx |
Registers a new ins/:name route for the INS asset page. |
components/send/evm/evm-kas-send/EvmKasSend.tsx |
Extends the EVM KAS send form schema to track resolved domain. |
components/send/evm/evm-kas-send/DetailsStep.tsx |
Adds INS-domain validation/resolution for IGRA EVM KAS sends. |
components/send/evm/erc20-send/Erc20Send.tsx |
Extends the ERC20 send form schema to track resolved domain. |
components/send/evm/erc20-send/DetailsStep.tsx |
Adds INS-domain validation/resolution for IGRA ERC20 sends. |
components/screens/INSAsset.tsx |
New INS asset detail screen using INS resolution hook. |
components/screens/Dashboard.tsx |
Renames KNS tab to “Names” and renders the new consolidated names view. |
components/dashboard/Names.tsx |
New dashboard tab combining KNS + INS listings with pagination for KNS. |
components/dashboard/KNS.tsx |
Removed in favor of the consolidated Names tab. |
components/dashboard/INSItem.tsx |
New dashboard list item for INS names linking into the INS asset route. |
Comments suppressed due to low confidence (2)
components/send/evm/evm-kas-send/DetailsStep.tsx:206
- The loading spinner is keyed off
validatingFields.address, but the validated/registered field isuserInput. As written, the spinner will never show during async validation/domain resolution.
<div className="pointer-events-none absolute end-0 top-10 flex h-16 items-center pe-3">
{validatingFields.address && (
<img
components/send/evm/erc20-send/DetailsStep.tsx:230
- The loading spinner is keyed off
validatingFields.address, but the validated/registered field isuserInput. As written, the spinner will never show during async validation/domain resolution.
<div className="pointer-events-none absolute end-0 top-10 flex h-16 items-center pe-3">
{validatingFields.address && (
<img
| function extractDomainNames(raw: unknown): string[] { | ||
| if (Array.isArray(raw)) { | ||
| return raw.map((entry) => | ||
| typeof entry === "string" ? entry : (entry?.name ?? entry?.domain), | ||
| ); | ||
| } | ||
|
|
||
| const container = raw as | ||
| | { names?: unknown[]; domains?: unknown[]; data?: unknown[] } | ||
| | undefined; | ||
|
|
||
| return extractDomainNames( | ||
| container?.names ?? container?.domains ?? container?.data ?? [], | ||
| ); | ||
| } |
| export function useInsDomainsByAddress(address?: string) { | ||
| const { data, isLoading, error, mutate } = useSWR<unknown, Error>( | ||
| address ? `${INS_API_URL}/names/by-owner?address=${address}` : null, | ||
| fetcher, | ||
| ); | ||
|
|
||
| return { domains: extractDomainNames(data), isLoading, error, mutate }; | ||
| } |
| export function useInsResolve(name?: string) { | ||
| const { data, isLoading, error } = useSWR<InsResolveResponse, Error>( | ||
| name ? `${INS_API_URL}/resolve?name=${encodeURIComponent(name)}` : null, | ||
| fetcher, | ||
| ); | ||
|
|
||
| return { detail: data?.exists ? data : undefined, isLoading, error }; | ||
| } |
| const fetchDomainOwner = async ( | ||
| name: string, | ||
| ): Promise<string | undefined> => { |
| if (insEnabled && value.includes(".")) { | ||
| const resolved = await fetchDomainOwner(value); | ||
| if (resolved && isAddress(resolved)) { | ||
| setValue("address", resolved); | ||
| setValue("domain", value); | ||
| return true; | ||
| } | ||
| } |
| if (insEnabled && value.includes(".")) { | ||
| const resolved = await fetchDomainOwner(value); | ||
| if (resolved && isAddress(resolved)) { | ||
| setValue("address", resolved); | ||
| setValue("domain", value); | ||
| return true; | ||
| } | ||
| } |
| return ( | ||
| <div | ||
| className="flex cursor-pointer items-center gap-3 rounded-xl border border-daintree-700 bg-daintree-800 p-3 hover:border-white" | ||
| onClick={() => navigate(`/ins/${name}`)} |
| const { name } = useParams(); | ||
| const { detail } = useInsResolve(name); |
| onBack={() => navigate("/dashboard")} | ||
| /> | ||
|
|
||
| {detail && ( |
| {detail.expires_at | ||
| ? new Date(detail.expires_at).toLocaleString("en-GB", { | ||
| month: "short", | ||
| day: "2-digit", | ||
| year: "numeric", | ||
| hour: "2-digit", | ||
| minute: "2-digit", | ||
| timeZoneName: "short", | ||
| }) | ||
| : "-"} |
Pull Request Checklist
Before Submission
Description
Additional Notes
By submitting this pull request, I confirm that:
project's
license terms
Summary by CodeRabbit
New Features
Bug Fixes