-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1348 from scroll-tech/sepolia
feat: Spanish support for blog, ens support for custom recipient
- Loading branch information
Showing
10 changed files
with
204 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
layout node | ||
|
||
dotenv_if_exists .env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { requireEnv } from "@/utils" | ||
|
||
const ensBaseURL = requireEnv("REACT_APP_ENS_API_URL") | ||
export function getEnsAddressURL(ens: string) { | ||
return `${ensBaseURL}/name/${ens}/address` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { isAddress } from "ethers" | ||
import { identity } from "lodash" | ||
import { useEffect } from "react" | ||
import { namehash, normalize } from "viem/ens" | ||
import { create } from "zustand" | ||
|
||
import { getEnsAddressURL } from "@/apis/ens" | ||
|
||
/** | ||
* Fetches Ethereum address for an ENS name | ||
* @param ens ENS name to resolve | ||
* @returns Resolved Ethereum address or null if not found | ||
*/ | ||
async function getEnsAddress(ens: string): Promise<string | null> { | ||
return await scrollRequest(getEnsAddressURL(ens)).then(data => data?.address) | ||
} | ||
|
||
interface InputAddressStore { | ||
inputValue: string | ||
isValidInput: boolean | ||
address: string | null | ||
isValidAddress: boolean | ||
ens: string | null | ||
isValidEns: boolean | ||
resolvingEns: boolean | ||
ensServerError: string | null | ||
validateAddress: () => void | ||
validateEnsFormat: () => void | ||
resolveEnsAddress: () => Promise<void> | ||
validateEns: () => Promise<void> | ||
setInputValue: (v: string) => void | ||
setValidationStatus: () => void | ||
} | ||
|
||
const useInputAddressStore = create<InputAddressStore>((set, get) => ({ | ||
inputValue: "", | ||
isValidInput: true, | ||
address: null, | ||
isValidAddress: false, | ||
ens: null, | ||
isValidEns: false, | ||
resolvingEns: false, | ||
ensServerError: null, | ||
validateAddress() { | ||
const addr = get().inputValue.trim() | ||
if (isAddress(addr)) set({ address: addr }) | ||
else set({ address: null }) | ||
}, | ||
validateEnsFormat() { | ||
set({ ens: null }) | ||
const ens = get().inputValue.trim() | ||
if (!ens.endsWith(".eth")) return | ||
try { | ||
namehash(normalize(ens)) | ||
} catch (err) { | ||
return | ||
} | ||
set({ ens }) | ||
}, | ||
async resolveEnsAddress() { | ||
const { ens } = get() | ||
if (!ens) return | ||
set({ resolvingEns: true }) | ||
const address = await getEnsAddress(ens).catch(() => set({ ensServerError: "Failed to fetch ENS address" })) | ||
set({ resolvingEns: false }) | ||
if (address !== undefined) return set({ ens, address, ensServerError: null }) | ||
}, | ||
async validateEns() { | ||
set({ ensServerError: null, resolvingEns: false }) | ||
|
||
get().validateEnsFormat() | ||
await get().resolveEnsAddress() | ||
}, | ||
async setInputValue(v) { | ||
if (v === get().inputValue) return | ||
set({ inputValue: v || "" }) | ||
|
||
get().validateAddress() | ||
await get().validateEns() | ||
get().setValidationStatus() | ||
}, | ||
setValidationStatus() { | ||
const { inputValue, address, ens } = get() | ||
// Empty input is valid | ||
if (!inputValue) return set({ isValidAddress: false, isValidEns: false, isValidInput: true }) | ||
// Valid address + ENS is valid | ||
if (address && ens) return set({ isValidAddress: true, isValidEns: true, isValidInput: true }) | ||
// Valid address but invalid ENS | ||
if (address && !ens) return set({ isValidAddress: true, isValidEns: false, isValidInput: true }) | ||
return set({ isValidAddress: false, isValidEns: false, isValidInput: false }) | ||
}, | ||
})) | ||
|
||
/** | ||
* Hook for managing and validating Ethereum address/ENS input | ||
* @param options.onValidAddress Callback when valid address is resolved | ||
* @param options.onValidEnsName Callback when valid ENS name is resolved | ||
* @returns Input address store state and methods | ||
*/ | ||
export default function useInputAddress({ | ||
onValidAddress = identity, | ||
onValidEnsName = identity, | ||
onAddressChange = identity, | ||
onEnsChange = identity, | ||
} = {}) { | ||
const store = useInputAddressStore() | ||
|
||
useEffect(() => { | ||
try { | ||
if (store.address) { | ||
onValidAddress(store.address) | ||
onAddressChange(store.address) | ||
} else { | ||
onAddressChange(null) | ||
} | ||
} catch (err) {} | ||
}, [store.address]) | ||
|
||
useEffect(() => { | ||
try { | ||
if (store.ens) { | ||
onValidEnsName(store.ens) | ||
onEnsChange(store.ens) | ||
} else { | ||
onEnsChange(null) | ||
} | ||
} catch (err) {} | ||
}, [store.ens]) | ||
|
||
return store | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters