diff --git a/packages/ensjs/src/clients/public.ts b/packages/ensjs/src/clients/public.ts index 7ffcb798..cef5b41f 100644 --- a/packages/ensjs/src/clients/public.ts +++ b/packages/ensjs/src/clients/public.ts @@ -1,13 +1,15 @@ import { createClient, - type Chain, type Client, type ClientConfig, type PublicRpcSchema, type Transport, } from 'viem' import { addEnsContracts } from '../contracts/addEnsContracts.js' -import type { ChainWithEns } from '../contracts/consts.js' +import type { + ChainWithBaseContracts, + ChainWithEns, +} from '../contracts/consts.js' import type { Prettify } from '../types.js' import { ensPublicActions, type EnsPublicActions } from './decorators/public.js' import { @@ -17,7 +19,7 @@ import { export type EnsPublicClientConfig< TTransport extends Transport = Transport, - TChain extends Chain = Chain, + TChain extends ChainWithBaseContracts = ChainWithBaseContracts, > = Pick< ClientConfig, 'batch' | 'key' | 'name' | 'pollingInterval' | 'transport' @@ -56,7 +58,7 @@ export type EnsPublicClient< */ export const createEnsPublicClient = < TTransport extends Transport, - TChain extends Chain, + TChain extends ChainWithBaseContracts, >({ batch, chain, diff --git a/packages/ensjs/src/clients/subgraph.ts b/packages/ensjs/src/clients/subgraph.ts index 0bab8117..3ac51395 100644 --- a/packages/ensjs/src/clients/subgraph.ts +++ b/packages/ensjs/src/clients/subgraph.ts @@ -1,13 +1,15 @@ import { createClient, - type Chain, type Client, type ClientConfig, type PublicRpcSchema, type Transport, } from 'viem' import { addEnsContracts } from '../contracts/addEnsContracts.js' -import type { ChainWithEns } from '../contracts/consts.js' +import type { + ChainWithBaseContracts, + ChainWithEns, +} from '../contracts/consts.js' import type { Prettify } from '../types.js' import { ensSubgraphActions, @@ -16,7 +18,7 @@ import { export type EnsSubgraphClientConfig< TTransport extends Transport = Transport, - TChain extends Chain = Chain, + TChain extends ChainWithBaseContracts = ChainWithBaseContracts, > = Pick< ClientConfig, 'batch' | 'key' | 'name' | 'pollingInterval' | 'transport' @@ -49,7 +51,7 @@ export type EnsSubgraphClient< */ export const createEnsSubgraphClient = < TTransport extends Transport, - TChain extends Chain, + TChain extends ChainWithBaseContracts, >({ batch, chain, diff --git a/packages/ensjs/src/clients/wallet.ts b/packages/ensjs/src/clients/wallet.ts index 7a4c4d25..4f2c4b99 100644 --- a/packages/ensjs/src/clients/wallet.ts +++ b/packages/ensjs/src/clients/wallet.ts @@ -2,7 +2,6 @@ import { createWalletClient, type Account, type Address, - type Chain, type Client, type ClientConfig, type ParseAccount, @@ -11,23 +10,30 @@ import { type WalletRpcSchema, } from 'viem' import { addEnsContracts } from '../contracts/addEnsContracts.js' -import type { ChainWithEns } from '../contracts/consts.js' -import type { Prettify } from '../types.js' +import type { + ChainWithBaseContracts, + ChainWithEns, + CheckedChainWithEns, +} from '../contracts/consts.js' +import type { Assign, Prettify } from '../types.js' import { ensWalletActions, type EnsWalletActions } from './decorators/wallet.js' export type EnsWalletClientConfig< TTransport extends Transport, - TChain extends Chain, + TChain extends ChainWithBaseContracts, TAccountOrAddress extends Account | Address | undefined = | Account | Address | undefined, -> = Pick< - ClientConfig, - 'account' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport' -> & { - chain: TChain -} +> = Assign< + Pick< + ClientConfig, + 'account' | 'chain' | 'key' | 'name' | 'pollingInterval' | 'transport' + >, + { + chain: TChain + } +> export type EnsWalletClient< TTransport extends Transport = Transport, @@ -61,7 +67,7 @@ export type EnsWalletClient< */ export const createEnsWalletClient = < TTransport extends Transport, - TChain extends Chain, + TChain extends ChainWithBaseContracts, TAccountOrAddress extends Account | Address | undefined = undefined, >({ account, @@ -76,12 +82,12 @@ export const createEnsWalletClient = < TAccountOrAddress >): EnsWalletClient< TTransport, - ChainWithEns, + CheckedChainWithEns, ParseAccount > => { return createWalletClient({ account, - chain: addEnsContracts(chain), + chain: addEnsContracts(chain), key, name, pollingInterval, diff --git a/packages/ensjs/src/contracts/addEnsContracts.ts b/packages/ensjs/src/contracts/addEnsContracts.ts index 68bebdd5..7765f766 100644 --- a/packages/ensjs/src/contracts/addEnsContracts.ts +++ b/packages/ensjs/src/contracts/addEnsContracts.ts @@ -4,7 +4,7 @@ import { addresses, subgraphs, supportedChains, - type ChainWithEns, + type CheckedChainWithEns, type SupportedChain, } from './consts.js' @@ -22,7 +22,7 @@ import { * transport: http(), * }) */ -export const addEnsContracts = (chain: TChain) => { +export const addEnsContracts = (chain: TChain) => { if (!chain) throw new NoChainError() if (!supportedChains.includes(chain.network as SupportedChain)) throw new UnsupportedNetworkError({ @@ -38,5 +38,5 @@ export const addEnsContracts = (chain: TChain) => { subgraphs: { ...subgraphs[chain.network as SupportedChain], }, - } as ChainWithEns + } as unknown as CheckedChainWithEns } diff --git a/packages/ensjs/src/contracts/consts.ts b/packages/ensjs/src/contracts/consts.ts index 647e94af..74b58337 100644 --- a/packages/ensjs/src/contracts/consts.ts +++ b/packages/ensjs/src/contracts/consts.ts @@ -6,6 +6,7 @@ import type { Transport, WalletClient, } from 'viem' +import type { Assign, Prettify } from '../types.js' type ChainContract = { address: Address @@ -177,12 +178,21 @@ export type ChainWithEns = TChain & { subgraphs: Subgraphs } +export type ChainWithBaseContracts = Assign< + Omit, + { + contracts: BaseChainContracts + } +> + export type CheckedChainWithEns = TChain['network'] extends SupportedChain - ? TChain & { - contracts: (typeof addresses)[TChain['network']] - subgraphs: (typeof subgraphs)[TChain['network']] - } + ? TChain['contracts'] extends BaseChainContracts + ? TChain & { + contracts: Prettify<(typeof addresses)[TChain['network']]> + subgraphs: (typeof subgraphs)[TChain['network']] + } + : never : never export type ClientWithEns< diff --git a/packages/ensjs/src/contracts/getChainContractAddress.ts b/packages/ensjs/src/contracts/getChainContractAddress.ts index 5595a415..a11015a3 100644 --- a/packages/ensjs/src/contracts/getChainContractAddress.ts +++ b/packages/ensjs/src/contracts/getChainContractAddress.ts @@ -1,13 +1,18 @@ +import type { Chain } from 'viem' import { getChainContractAddress as _getChainContractAddress } from 'viem/utils' -import type { ChainWithEns } from './consts.js' -type ChainClient = { - chain: TChain +type ExtractContract = TClient extends { + chain: { contracts: infer C } } + ? C extends Record + ? C + : never + : never export const getChainContractAddress = < - TChain extends ChainWithEns, - TClient extends ChainClient, + const TClient extends { chain: Chain }, + TContracts extends ExtractContract = ExtractContract, + TContract extends keyof TContracts = keyof TContracts, >({ blockNumber, client, @@ -15,5 +20,10 @@ export const getChainContractAddress = < }: { blockNumber?: bigint client: TClient - contract: Extract -}) => _getChainContractAddress({ blockNumber, chain: client.chain, contract }) + contract: TContract +}) => + _getChainContractAddress({ + blockNumber, + chain: client.chain, + contract: contract as string, + }) as TContracts[TContract]['address'] diff --git a/packages/ensjs/src/types.ts b/packages/ensjs/src/types.ts index da663a17..f44153f0 100644 --- a/packages/ensjs/src/types.ts +++ b/packages/ensjs/src/types.ts @@ -11,6 +11,16 @@ export type Prettify = { [K in keyof T]: T[K] } & {} +type AssignI = { + [K in keyof T as K extends keyof U + ? U[K] extends void + ? never + : K + : K]: K extends keyof U ? U[K] : T[K] +} + +export type Assign = AssignI & U + export type SimpleTransactionRequest = { [P in keyof Pick]-?: Exclude< TransactionRequest[P],