Skip to content

Commit

Permalink
Fix typing
Browse files Browse the repository at this point in the history
Allow arbOwnerPublicActions to be either called:
- without parameters (`.extend(arbOwnerPublicActions)`)
- with parameters (`.extend(arbOwnerPublicActions({ arbOsVersion: X}))`)
  • Loading branch information
chrstph-dvx committed May 15, 2024
1 parent a4bb1c2 commit 2043107
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 14 deletions.
56 changes: 44 additions & 12 deletions src/decorators/arbOwnerPublicActions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Transport, Chain, PrepareTransactionRequestReturnType, PublicClient } from 'viem';
import { Transport, Chain, PrepareTransactionRequestReturnType, Client, Account } from 'viem';

import {
arbOwnerReadContract,
Expand All @@ -13,7 +13,7 @@ import {
import { ArbOSVersions } from '../contracts';

export type ArbOwnerPublicActions<
TArbOsVersion extends ArbOSVersions,
TArbOsVersion extends ArbOSVersions = 20,
TChain extends Chain | undefined = Chain | undefined,
> = {
arbOwnerReadContract: <TFunctionName extends ArbOwnerPublicFunctionName<TArbOsVersion>>(
Expand All @@ -24,26 +24,58 @@ export type ArbOwnerPublicActions<
TFunctionName extends ArbOwnerPublicFunctionName<TArbOsVersion>,
>(
args: ArbOwnerPrepareTransactionRequestParameters<TArbOsVersion, TFunctionName>,
) => Promise<PrepareTransactionRequestReturnType<TChain> & { chainId: number }>;
) => Promise<PrepareTransactionRequestReturnType<TChain>>;
};

const defaultArbOsVersion = 20;

// arbOsVersion is passed as a parameter `client.extend(arbOwnerPublicActions({ arbOsVersion: 10 }))`
export function arbOwnerPublicActions<
TArbOsVersion extends ArbOSVersions,
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
>({ arbOsVersion }: { arbOsVersion: TArbOsVersion }) {
return (
client: PublicClient<TTransport, TChain>,
): ArbOwnerPublicActions<TArbOsVersion, TChain> => {
return {
arbOwnerReadContract: (args) => arbOwnerReadContract(client, { ...args, arbOsVersion }),

TAccount extends Account | undefined = Account | undefined,
>(param: {
arbOsVersion: TArbOsVersion;
}): (client: Client) => ArbOwnerPublicActions<TArbOsVersion, TChain>;
// No parameter are passed `client.extend(arbOwnerPublicActions)`
export function arbOwnerPublicActions<
TArbOsVersion extends ArbOSVersions,
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends Account | undefined = Account | undefined,
>(param: Client<TTransport, TChain, TAccount>): ArbOwnerPublicActions<typeof defaultArbOsVersion, TChain>;
export function arbOwnerPublicActions<
TArbOsVersion extends ArbOSVersions,
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends Account | undefined = Account | undefined,
>(paramOrClient: { arbOsVersion: TArbOsVersion } | Client<TTransport, TChain, TAccount>) {
if ('arbOsVersion' in paramOrClient) {
const result: (client: Client) => ArbOwnerPublicActions<TArbOsVersion, TChain> = (client) => ({
arbOwnerReadContract: (args) =>
arbOwnerReadContract(client, { ...args, arbOsVersion: paramOrClient.arbOsVersion }),

Check failure on line 57 in src/decorators/arbOwnerPublicActions.ts

View workflow job for this annotation

GitHub Actions / Test (Unit)

Argument of type 'Client' is not assignable to parameter of type '{ account: undefined; batch?: { multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined; } | undefined; } | undefined; cacheTime: number; chain: Chain | undefined; ... 53 more ...; extend: <const client extends { ...; } & Partial<...>>(fn: (client: Client<...>) => client) => Client<...>; }'.
arbOwnerPrepareTransactionRequest: (args) =>
// @ts-ignore (todo: fix viem type issue)
arbOwnerPrepareTransactionRequest(client, {
...args,
arbOsVersion,
arbOsVersion: paramOrClient.arbOsVersion,
}),
};
});

return result;
}

const result: ArbOwnerPublicActions<typeof defaultArbOsVersion, TChain> = {
arbOwnerReadContract: (args) =>
// @ts-ignore (todo: fix viem type issue)
arbOwnerReadContract(paramOrClient, { ...args, arbOsVersion: defaultArbOsVersion }),
arbOwnerPrepareTransactionRequest: (args) =>
// @ts-ignore (todo: fix viem type issue)
arbOwnerPrepareTransactionRequest(paramOrClient, {
...args,
arbOsVersion: defaultArbOsVersion,
}),
};
return result;
}
43 changes: 41 additions & 2 deletions src/decorators/arbOwnerPublicActions.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { nitroTestnodeL2 } from '../chains';
import { arbOwnerPublicActions } from './arbOwnerPublicActions';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';

const clientWithoutParam = createPublicClient({
chain: nitroTestnodeL2,
transport: http(),
}).extend(arbOwnerPublicActions);
const client10 = createPublicClient({
chain: nitroTestnodeL2,
transport: http(),
Expand All @@ -19,6 +23,10 @@ const client20 = createPublicClient({
}).extend(arbOwnerPublicActions({ arbOsVersion: 20 }));
const randomAccount = privateKeyToAccount(generatePrivateKey());
const upgradeExecutorAddress = '0x24198F8A339cd3C47AEa3A764A20d2dDaB4D1b5b';
const client = createPublicClient({
chain: nitroTestnodeL2,
transport: http(),
})

describe('Accept function name based on arbOSVersion', async () => {
it('Version 10', () => {
Expand Down Expand Up @@ -86,6 +94,31 @@ describe('Accept function name based on arbOSVersion', async () => {
}),
).rejects.toThrowError(AbiFunctionNotFoundError);
});

it('Default version (20)', () => {
// arbOwnerPublicActions without params is defaulted to arbOsVersion 20
expectTypeOf<
typeof clientWithoutParam.arbOwnerReadContract<'getInfraFeeAccount'>
>().toBeCallableWith({
functionName: 'getInfraFeeAccount',
});

expectTypeOf<
typeof clientWithoutParam.arbOwnerPrepareTransactionRequest<'setL1PricingRewardRecipient'>
>().toBeCallableWith({
functionName: 'setL1PricingRewardRecipient',
account: randomAccount.address,
upgradeExecutor: upgradeExecutorAddress,
args: [randomAccount.address],
});

expect(
clientWithoutParam.arbOwnerReadContract({
// @ts-expect-error Not available for version 20
functionName: 'onlyOnArbOS10',
}),
).rejects.toThrowError(AbiFunctionNotFoundError);
});
});

// Those tests won't fail if the return type is wrong
Expand All @@ -98,19 +131,25 @@ describe('Type return values for function in multiple versions', () => {
}),
).resolves.toEqualTypeOf<`0x${string}`>();
});

it('Version 11', () => {
expectTypeOf(
client11.arbOwnerReadContract({
functionName: 'getAllChainOwners',
}),
).resolves.toEqualTypeOf<bigint>();
});
it('Version 11', () => {
it('Version 20', () => {
expectTypeOf(
client20.arbOwnerReadContract({
functionName: 'getAllChainOwners',
}),
).resolves.toEqualTypeOf<readonly `0x${string}`[]>();
});
it('Default version (20)', () => {
expectTypeOf(
clientWithoutParam.arbOwnerReadContract({
functionName: 'getAllChainOwners',
}),
).resolves.toEqualTypeOf<readonly `0x${string}`[]>();
});
});

0 comments on commit 2043107

Please sign in to comment.