Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wip): improve ensjs-react api #214

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/ensjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@
"!src/**/*.test.ts",
"!src/test"
],
"repository": "[email protected]:ensdomains/ensjs.git",
"repository": {
"type": "git",
"url": "git+https://github.com/ensdomains/ensjs.git",
"directory": "packages/ensjs"
},
"author": "TateB <[email protected]>",
"license": "MIT",
"scripts": {
Expand Down Expand Up @@ -137,7 +141,7 @@
"typedoc": "^0.24.8",
"typedoc-plugin-markdown": "^4.0.0-next.16",
"typescript": "5.3.2",
"viem": "^2.9.2",
"viem": "2.9.2",
"vitest": "^1.3.1",
"wait-on": "^6.0.1"
},
Expand Down
27 changes: 27 additions & 0 deletions packages/ensjs/src/clients/decorators/public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import getContentHashRecord, {
type GetContentHashRecordParameters,
type GetContentHashRecordReturnType,
} from '../../functions/public/getContentHashRecord.js'
import getCredentials, {
type GetCredentialsParameters,
type GetCredentialsReturnType,
} from '../../functions/public/getCredentials.js'
import getExpiry, {
type GetExpiryParameters,
type GetExpiryReturnType,
Expand Down Expand Up @@ -187,6 +191,28 @@ export type EnsPublicActions = {
* const result = await client.getExpiry({ name: 'ens.eth' })
* // { expiry: { date: Date, value: 1913933217n }, gracePeriod: 7776000, status: 'active' }
*/
getCredentials: ({
name,
gatewayUrls,
strict,
}: GetCredentialsParameters) => Promise<GetCredentialsReturnType>
/**
* Gets credentials for a name.
* @param parameters - {@link GetCredentialsParameters}
* @returns Credentials, or null if none are found. {@link GetCredentialsReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { addEnsContracts, ensPublicActions } from '@ensdomains/ensjs'
*
* const client = createPublicClient({
* chain: addEnsContracts(mainnet),
* transport: http(),
* }).extend(ensPublicActions)
* const result = await client.getCredentials({ name: 'ens.eth' })
* // [{ url: 'https://example.com' }]
*/
getExpiry: ({
name,
contract,
Expand Down Expand Up @@ -408,6 +434,7 @@ export const ensPublicActions = <
getAvailable: (parameters) => getAvailable(client, parameters),
getContentHashRecord: (parameters) =>
getContentHashRecord(client, parameters),
getCredentials: (parameters) => getCredentials(client, parameters),
getExpiry: (parameters) => getExpiry(client, parameters),
getName: (parameters) => getName(client, parameters),
getOwner: (parameters) => getOwner(client, parameters),
Expand Down
4 changes: 4 additions & 0 deletions packages/ensjs/src/dns.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
export {
default as getDnsImportData,
type GetDnsImportDataErrorType,
type GetDnsImportDataParameters,
type GetDnsImportDataReturnType,
} from './functions/dns/getDnsImportData.js'
export {
default as getDnsOffchainData,
type GetDnsOffchainDataErrorType,
type GetDnsOffchainDataParameters,
type GetDnsOffchainDataReturnType,
} from './functions/dns/getDnsOffchainData.js'
export {
default as getDnsOwner,
type GetDnsOwnerErrorType,
type GetDnsOwnerParameters,
type GetDnsOwnerReturnType,
} from './functions/dns/getDnsOwner.js'
export {
default as importDnsName,
type ImportDnsNameDataParameters,
type ImportDnsNameDataReturnType,
type ImportDnsNameErrorType,
type ImportDnsNameParameters,
type ImportDnsNameReturnType,
} from './functions/dns/importDnsName.js'
Expand Down
8 changes: 5 additions & 3 deletions packages/ensjs/src/functions/dns/getDnsImportData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { readContract } from 'viem/actions'
import type { ChainWithEns } from '../../contracts/consts.js'
import { dnssecImplVerifyRrSetSnippet } from '../../contracts/dnssecImpl.js'
import { getChainContractAddress } from '../../contracts/getChainContractAddress.js'
import { DnsNewerRecordTypeAvailableError } from '../../index.js'
import { DnsNewerRecordTypeAvailableError } from '../../errors/dns.js'
import type { Endpoint } from './types.js'

export type GetDnsImportDataParameters = {
Expand All @@ -15,13 +15,15 @@ export type GetDnsImportDataParameters = {
endpoint?: Endpoint
}

export type GetDnsImportDataReturnType = RrSetWithSig[]

export type GetDnsImportDataErrorType = DnsNewerRecordTypeAvailableError | Error

export type RrSetWithSig = {
rrset: Hex
sig: Hex
}

export type GetDnsImportDataReturnType = RrSetWithSig[]

// Compares two serial numbers using RFC1982 serial number math.
const serialNumberGt = (i1: number, i2: number): boolean =>
(i1 < i2 && i2 - i1 > 0x7fffffff) || (i1 > i2 && i1 - i2 < 0x7fffffff)
Expand Down
9 changes: 9 additions & 0 deletions packages/ensjs/src/functions/dns/getDnsOffchainData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ export type GetDnsOffchainDataReturnType = {
extraData: string | null
} | null

export type GetDnsOffchainDataErrorType =
| DnsDnssecVerificationFailedError
| DnsDnssecWildcardExpansionError
| DnsInvalidTxtRecordError
| DnsNoTxtRecordError
| DnsResponseStatusError
| UnsupportedNameTypeError
| Error

type ValidTextRecord = {
isValid: true
resolverAddress: Address
Expand Down
9 changes: 9 additions & 0 deletions packages/ensjs/src/functions/dns/getDnsOwner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ export type GetDnsOwnerParameters = {

export type GetDnsOwnerReturnType = Address | null

export type GetDnsOwnerErrorType =
| DnsDnssecVerificationFailedError
| DnsInvalidAddressChecksumError
| DnsInvalidTxtRecordError
| DnsNoTxtRecordError
| DnsResponseStatusError
| UnsupportedNameTypeError
| Error

/**
* Gets the DNS owner of a name, via DNS record lookup
* @param parameters - {@link GetDnsOwnerParameters}
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/dns/importDnsName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export type ImportDnsNameParameters<

export type ImportDnsNameReturnType = Hash

export type ImportDnsNameErrorType = AdditionalParameterSpecifiedError | Error

export const makeFunctionData = <
TChain extends ChainWithEns,
TAccount extends Account | undefined,
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/_getAbi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export type InternalGetAbiParameters = {

export type InternalGetAbiReturnType = Prettify<DecodedAbi | null>

export type InternalGetAbiErrorType = Error

const encode = (
_client: ClientWithEns,
{
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/_getAddr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export type InternalGetAddrParameters = {

export type InternalGetAddrReturnType = Prettify<DecodedAddr | null>

export type InternalGetAddrErrorType = Error

const encode = (
_client: ClientWithEns,
{ name, coin = 60, bypassFormat }: Omit<InternalGetAddrParameters, 'strict'>,
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/_getContentHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export type InternalGetContentHashParameters = {
export type InternalGetContentHashReturnType =
Prettify<DecodedContentHash | null>

export type InternalGetContentHashErrorType = Error

const encode = (
_client: ClientWithEns,
{ name }: Omit<InternalGetContentHashParameters, 'strict'>,
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/_getText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export type InternalGetTextParameters = {

export type InternalGetTextReturnType = string | null

export type InternalGetTextErrorType = Error

const encode = (
_client: ClientWithEns,
{ name, key }: Omit<InternalGetTextParameters, 'strict'>,
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export type BatchReturnType<TFunctions extends BatchFunctionResult[]> = {
[TFunctionName in keyof TFunctions]: ExtractResult<TFunctions[TFunctionName]>
}

export type BatchErrorType = Error

const encode = (
client: ClientWithEns,
...items: BatchFunctionResult[]
Expand Down
3 changes: 3 additions & 0 deletions packages/ensjs/src/functions/public/getAbiRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type GeneratedFunction,
} from '../../utils/generateFunction.js'
import _getAbi, {
type InternalGetAbiErrorType,
type InternalGetAbiParameters,
type InternalGetAbiReturnType,
} from './_getAbi.js'
Expand All @@ -24,6 +25,8 @@ export type GetAbiRecordParameters = Prettify<

export type GetAbiRecordReturnType = Prettify<InternalGetAbiReturnType>

export type GetAbiRecordErrorType = InternalGetAbiErrorType

const encode = (
client: ClientWithEns,
{
Expand Down
3 changes: 3 additions & 0 deletions packages/ensjs/src/functions/public/getAddressRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type GeneratedFunction,
} from '../../utils/generateFunction.js'
import _getAddr, {
type InternalGetAddrErrorType,
type InternalGetAddrParameters,
type InternalGetAddrReturnType,
} from './_getAddr.js'
Expand All @@ -24,6 +25,8 @@ export type GetAddressRecordParameters = Prettify<

export type GetAddressRecordReturnType = Prettify<InternalGetAddrReturnType>

export type GetAddressRecordErrorType = InternalGetAddrErrorType

const encode = (
client: ClientWithEns,
{
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/getAvailable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export type GetAvailableParameters = {

export type GetAvailableReturnType = boolean

export type GetAvailableErrorType = UnsupportedNameTypeError | Error

const encode = (
client: ClientWithEns,
{ name }: GetAvailableParameters,
Expand Down
3 changes: 3 additions & 0 deletions packages/ensjs/src/functions/public/getContentHashRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type GeneratedFunction,
} from '../../utils/generateFunction.js'
import _getContentHash, {
type InternalGetContentHashErrorType,
type InternalGetContentHashParameters,
type InternalGetContentHashReturnType,
} from './_getContentHash.js'
Expand All @@ -25,6 +26,8 @@ export type GetContentHashRecordParameters = Prettify<
export type GetContentHashRecordReturnType =
Prettify<InternalGetContentHashReturnType>

export type GetContentHashRecordErrorType = InternalGetContentHashErrorType

const encode = (
client: ClientWithEns,
{ name, gatewayUrls }: Omit<GetContentHashRecordParameters, 'strict'>,
Expand Down
96 changes: 96 additions & 0 deletions packages/ensjs/src/functions/public/getCredentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import type { BaseError, Hex } from 'viem'
import type { ClientWithEns } from '../../contracts/consts.js'
import type {
GenericPassthrough,
Prettify,
SimpleTransactionRequest,
} from '../../types.js'
import {
generateFunction,
type GeneratedFunction,
} from '../../utils/generateFunction.js'
import type {
GetTextRecordErrorType,
GetTextRecordParameters,
} from './getTextRecord.js'
import getTextRecord from './getTextRecord.js'

export type GetCredentialsParameters = Prettify<
Omit<GetTextRecordParameters, 'key'>
>

export type GetCredentialsReturnType = ExternalCredential[] | null

export type GetCredentialsErrorType = GetTextRecordErrorType

export type ExternalCredential = {
url: string
}

const encode = (
client: ClientWithEns,
{ name, gatewayUrls }: Omit<GetCredentialsParameters, 'strict'>,
): SimpleTransactionRequest => {
return getTextRecord.encode(client, {
name,
key: 'verifications',
gatewayUrls,
})
}

const parseCredentials = (credentials: string[]) => {
const externalCredentials: ExternalCredential[] = []
for (const credential of credentials) {
if (URL.canParse(credential)) externalCredentials.push({ url: credential })
}

return externalCredentials
}

const decode = async (
client: ClientWithEns,
data: Hex | BaseError,
passthrough: GenericPassthrough,
{
strict,
gatewayUrls,
}: Pick<GetCredentialsParameters, 'strict' | 'gatewayUrls'>,
): Promise<GetCredentialsReturnType> => {
const result = await getTextRecord.decode(client, data, passthrough, {
strict,
gatewayUrls,
})
if (!result) return null

const credentials = JSON.parse(result) as string[]
return parseCredentials(credentials)
}

type BatchableFunctionObject = GeneratedFunction<typeof encode, typeof decode>

/**
* Gets credentials for a name.
* @param client - {@link ClientWithEns}
* @param parameters - {@link GetCredentialsParameters}
* @returns Credentials, or null if none are found. {@link GetCredentialsReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { addEnsContracts } from '@ensdomains/ensjs'
* import { getCredentials } from '@ensdomains/ensjs/public'
*
* const client = createPublicClient({
* chain: addEnsContracts(mainnet),
* transport: http(),
* })
* const result = await getCredentials(client, { name: 'ens.eth' })
* // [{ url: 'https://example.com' }]
*/
const getCredentials = generateFunction({ encode, decode }) as ((
client: ClientWithEns,
{ name, strict, gatewayUrls }: GetCredentialsParameters,
) => Promise<GetCredentialsReturnType>) &
BatchableFunctionObject

export default getCredentials
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/getExpiry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export type GetExpiryReturnType = Prettify<{
status: ExpiryStatus
} | null>

export type GetExpiryErrorType = Error

const getContractToUse = (
contract: ContractOption | undefined,
labels: string[],
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/getName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export type GetNameReturnType = {
resolverAddress: Address
}

export type GetNameErrorType = Error

const encode = (
client: ClientWithEns,
{ address, gatewayUrls }: Omit<GetNameParameters, 'allowMismatch' | 'strict'>,
Expand Down
2 changes: 2 additions & 0 deletions packages/ensjs/src/functions/public/getOwner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export type GetOwnerReturnType<
: WrappedOwnership | UnwrappedEth2ldOwnership | UnwrappedOwnership))
| null

export type GetOwnerErrorType = Error

const encode = <TContract extends OwnerContract | undefined = undefined>(
client: ClientWithEns,
{ name, contract }: GetOwnerParameters<TContract>,
Expand Down
Loading
Loading