Skip to content
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
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"packageManager": "pnpm@10.30.3",
"scripts": {
"prebuild": "rm -rf ./src/dist",
"build": "tsc --project ./tsconfig.json --module commonjs --outDir ./src/dist --declaration",
"build": "tsc --project ./tsconfig.json --outDir ./src/dist --declaration",
"dev": "pnpm build --watch",
"generate": "wagmi generate",
"generate:node-config-type": "pnpm build && node ./src/dist/scripts/generateNodeConfigType.js",
Expand All @@ -21,7 +21,7 @@
},
"devDependencies": {
"@offchainlabs/prettier-config": "0.2.1",
"@wagmi/cli": "^1.5.2",
"@wagmi/cli": "^2.10.0",
"audit-ci": "^7.0.1",
"dotenv": "^16.3.1",
"eslint": "^9.39.1",
Expand All @@ -30,14 +30,12 @@
"prettier": "^2.8.3",
"ts-morph": "^21.0.1",
"typescript-eslint": "^8.56.1",
"typescript": "^5.2.2",
"viem": "^1.20.0",
"typescript": "^5.9.3",
"viem": "^2.48.4",
"vitest": "^3.2.4"
},
"pnpm": {
"overrides": {
"viem": "1.20.0",
"viem>ws": "8.17.1",
"@wagmi/cli>esbuild": "0.25.1",
"@wagmi/cli>bundle-require": "5.1.0",
"@ethersproject/providers>ws": "7.5.10",
Expand Down
953 changes: 221 additions & 732 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions src/actions/buildInvalidateKeysetHash.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Chain, Hex, PrepareTransactionRequestParameters, PublicClient, Transport } from 'viem';
import {
Chain,
Hex,
PrepareTransactionRequestParameters,
PublicClient,
Transport,
encodeFunctionData,
} from 'viem';
import { sequencerInboxABI } from '../contracts/SequencerInbox';
import {
ActionParameters,
Expand Down Expand Up @@ -36,16 +43,23 @@ export async function buildInvalidateKeysetHash<TChain extends Chain | undefined
}: BuildInvalidateKeysetHashParameters,
): Promise<BuildInvalidateKeysetHashReturnType> {
const { chainId } = validateParentChain(client);
if (client.chain === undefined) {
throw new Error('[buildInvalidateKeysetHash] client.chain is undefined');
}
const chain: Chain = client.chain;

const encoded = encodeFunctionData({
abi: sequencerInboxABI,
functionName: 'invalidateKeysetHash',
args: [params.keysetHash],
});
const request = await client.prepareTransactionRequest({
chain: client.chain,
chain,
account,
...prepareUpgradeExecutorCallParameters({
type: 'eip1559',
...prepareUpgradeExecutorCallParameters(encoded, {
to: sequencerInboxAddress,
upgradeExecutor,
args: [params.keysetHash],
abi: sequencerInboxABI,
functionName: 'invalidateKeysetHash',
}),
} satisfies PrepareTransactionRequestParameters);

Expand Down
26 changes: 20 additions & 6 deletions src/actions/buildSetIsBatchPoster.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Address, Chain, PrepareTransactionRequestParameters, PublicClient, Transport } from 'viem';
import {
Address,
Chain,
PrepareTransactionRequestParameters,
PublicClient,
Transport,
encodeFunctionData,
} from 'viem';
import { sequencerInboxABI } from '../contracts/SequencerInbox';
import {
ActionParameters,
Expand Down Expand Up @@ -30,16 +37,23 @@ export async function buildSetIsBatchPoster<TChain extends Chain | undefined>(
}: BuildSetIsBatchPosterParameters & { params: { enable: boolean } },
): Promise<BuildSetIsBatchPosterReturnType> {
const { chainId } = validateParentChain(client);
if (client.chain === undefined) {
throw new Error('[buildSetIsBatchPoster] client.chain is undefined');
}
const chain: Chain = client.chain;

const encoded = encodeFunctionData({
abi: sequencerInboxABI,
functionName: 'setIsBatchPoster',
args: [params.batchPoster, params.enable],
});
const request = await client.prepareTransactionRequest({
chain: client.chain,
chain,
account,
...prepareUpgradeExecutorCallParameters({
type: 'eip1559',
...prepareUpgradeExecutorCallParameters(encoded, {
to: sequencerInboxAddress,
upgradeExecutor,
args: [params.batchPoster, params.enable],
abi: sequencerInboxABI,
functionName: 'setIsBatchPoster',
}),
} satisfies PrepareTransactionRequestParameters);

Expand Down
25 changes: 19 additions & 6 deletions src/actions/buildSetMaxTimeVariation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Chain, PrepareTransactionRequestParameters, PublicClient, Transport } from 'viem';
import {
Chain,
PrepareTransactionRequestParameters,
PublicClient,
Transport,
encodeFunctionData,
} from 'viem';
import { sequencerInboxABI } from '../contracts/SequencerInbox';
import {
ActionParameters,
Expand Down Expand Up @@ -32,16 +38,23 @@ export async function buildSetMaxTimeVariation<TChain extends Chain | undefined>
}: BuildSetMaxTimeVariationParameters,
): Promise<BuildSetMaxTimeVariationReturnType> {
const { chainId } = validateParentChain(client);
if (client.chain === undefined) {
throw new Error('[buildSetMaxTimeVariation] client.chain is undefined');
}
const chain: Chain = client.chain;

const encoded = encodeFunctionData({
abi: sequencerInboxABI,
functionName: 'setMaxTimeVariation',
args: [params],
});
const request = await client.prepareTransactionRequest({
chain: client.chain,
chain,
account,
...prepareUpgradeExecutorCallParameters({
type: 'eip1559',
...prepareUpgradeExecutorCallParameters(encoded, {
to: sequencerInboxAddress,
upgradeExecutor,
args: [params],
abi: sequencerInboxABI,
functionName: 'setMaxTimeVariation',
}),
} satisfies PrepareTransactionRequestParameters);

Expand Down
26 changes: 20 additions & 6 deletions src/actions/buildSetValidKeyset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Chain, Hex, PrepareTransactionRequestParameters, PublicClient, Transport } from 'viem';
import {
Chain,
Hex,
PrepareTransactionRequestParameters,
PublicClient,
Transport,
encodeFunctionData,
} from 'viem';
import { sequencerInboxABI } from '../contracts/SequencerInbox';
import {
ActionParameters,
Expand Down Expand Up @@ -36,16 +43,23 @@ export async function buildSetValidKeyset<TChain extends Chain | undefined>(
}: BuildSetValidKeysetParameters,
): Promise<BuildSetValidKeysetReturnType> {
const { chainId } = validateParentChain(client);
if (client.chain === undefined) {
throw new Error('[buildSetValidKeyset] client.chain is undefined');
}
const chain: Chain = client.chain;

const encoded = encodeFunctionData({
abi: sequencerInboxABI,
functionName: 'setValidKeyset',
args: [params.keyset],
});
const request = await client.prepareTransactionRequest({
chain: client.chain,
chain,
account,
...prepareUpgradeExecutorCallParameters({
type: 'eip1559',
...prepareUpgradeExecutorCallParameters(encoded, {
to: sequencerInboxAddress,
upgradeExecutor,
args: [params.keyset],
abi: sequencerInboxABI,
functionName: 'setValidKeyset',
}),
} satisfies PrepareTransactionRequestParameters);

Expand Down
118 changes: 51 additions & 67 deletions src/arbAggregatorPrepareTransactionRequest.ts
Original file line number Diff line number Diff line change
@@ -1,99 +1,83 @@
import type { AbiStateMutability } from 'abitype';
import {
PublicClient,
encodeFunctionData,
EncodeFunctionDataParameters,
Address,
Chain,
Transport,
ContractFunctionArgs,
ContractFunctionName,
} from 'viem';

import { arbAggregatorABI, arbAggregatorAddress } from './contracts/ArbAggregator';
import { upgradeExecutorEncodeFunctionData } from './upgradeExecutorEncodeFunctionData';
import { GetFunctionName } from './types/utils';
import { PrepareTransactionRequestReturnTypeWithChainId } from './types/Actions';

type ArbAggregatorAbi = typeof arbAggregatorABI;
export type ArbAggregatorPrepareTransactionRequestFunctionName = GetFunctionName<ArbAggregatorAbi>;
export type ArbAggregatorEncodeFunctionDataParameters<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
> = EncodeFunctionDataParameters<ArbAggregatorAbi, TFunctionName>;
// ArbAggregator callers go through write entry points; narrow `TFunctionName` to the
// `nonpayable | payable` subset — viem v2 constrains contract-function generics to the
// function names that match the requested `stateMutability`.
type ArbAggregatorWriteMutability = 'nonpayable' | 'payable';
export type ArbAggregatorPrepareTransactionRequestFunctionName = ContractFunctionName<
ArbAggregatorAbi,
ArbAggregatorWriteMutability
>;

function arbAggregatorEncodeFunctionData<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
>({ functionName, abi, args }: ArbAggregatorEncodeFunctionDataParameters<TFunctionName>) {
return encodeFunctionData({
abi,
functionName,
args,
});
}

export type ArbAggregatorPrepareFunctionDataParameters<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
> = ArbAggregatorEncodeFunctionDataParameters<TFunctionName> & {
upgradeExecutor: Address | false;
abi: ArbAggregatorAbi;
};

export function arbAggregatorPrepareFunctionData<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
>(params: ArbAggregatorPrepareFunctionDataParameters<TFunctionName>) {
const { upgradeExecutor } = params;

if (!upgradeExecutor) {
return {
to: arbAggregatorAddress,
data: arbAggregatorEncodeFunctionData(
params as ArbAggregatorEncodeFunctionDataParameters<TFunctionName>,
),
value: BigInt(0),
};
}

return {
to: upgradeExecutor,
data: upgradeExecutorEncodeFunctionData({
functionName: 'executeCall',
args: [
arbAggregatorAddress, // target
arbAggregatorEncodeFunctionData(
params as ArbAggregatorEncodeFunctionDataParameters<TFunctionName>,
), // targetCallData
],
}),
value: BigInt(0),
// Distributed union over every ArbAggregator write function. Each branch carries a
// concrete literal `functionName` + its matching `args` tuple so non-generic helpers that
// take this union can hand the fields to viem directly — viem's own correlated-union
// generic then resolves per-branch (microsoft/TypeScript#30581 is only triggered when
// `functionName` itself is still a generic).
type ArbAggregatorFunctionCall = {
[K in ArbAggregatorPrepareTransactionRequestFunctionName]: {
functionName: K;
args: ContractFunctionArgs<ArbAggregatorAbi, AbiStateMutability, K>;
};
}
}[ArbAggregatorPrepareTransactionRequestFunctionName];

export type ArbAggregatorPrepareTransactionRequestParameters<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
> = Omit<ArbAggregatorPrepareFunctionDataParameters<TFunctionName>, 'abi'> & {
export type ArbAggregatorPrepareTransactionRequestParameters = ArbAggregatorFunctionCall & {
upgradeExecutor: Address | false;
account: Address;
};
export async function arbAggregatorPrepareTransactionRequest<
TFunctionName extends ArbAggregatorPrepareTransactionRequestFunctionName,
TChain extends Chain | undefined,
>(

export async function arbAggregatorPrepareTransactionRequest<TChain extends Chain | undefined>(
client: PublicClient<Transport, TChain>,
params: ArbAggregatorPrepareTransactionRequestParameters<TFunctionName>,
) {
params: ArbAggregatorPrepareTransactionRequestParameters,
): Promise<PrepareTransactionRequestReturnTypeWithChainId> {
if (typeof client.chain === 'undefined') {
throw new Error('[arbAggregatorPrepareTransactionRequest] client.chain is undefined');
}
const chain: Chain = client.chain;

// params is extending ArbAggregatorPrepareFunctionDataParameters, it's safe to cast
const { to, data, value } = arbAggregatorPrepareFunctionData({
...params,
const encoded = encodeFunctionData({
abi: arbAggregatorABI,
} as unknown as ArbAggregatorPrepareFunctionDataParameters<TFunctionName>);
functionName: params.functionName,
args: params.args,
});

const { to, data, value } = params.upgradeExecutor
? {
to: params.upgradeExecutor,
data: upgradeExecutorEncodeFunctionData({
functionName: 'executeCall',
args: [arbAggregatorAddress, encoded],
}),
value: BigInt(0),
}
: {
to: arbAggregatorAddress,
data: encoded,
value: BigInt(0),
};

// @ts-expect-error -- todo: fix viem type issue
const request = await client.prepareTransactionRequest({
chain: client.chain,
chain,
to,
data,
value,
account: params.account,
type: 'eip1559',
});

return { ...request, chainId: client.chain.id };
return { ...request, chainId: chain.id };
}
Loading
Loading