-
-
Notifications
You must be signed in to change notification settings - Fork 872
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
266 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,157 @@ | ||
import type { Address } from 'abitype' | ||
|
||
import type { Account } from '../../accounts/types.js' | ||
import { | ||
type ParseAccountErrorType, | ||
parseAccount, | ||
} from '../../accounts/utils/parseAccount.js' | ||
import type { Client } from '../../clients/createClient.js' | ||
import type { Transport } from '../../clients/transports/createTransport.js' | ||
import type { ErrorType } from '../../errors/utils.js' | ||
import type { BlockTag } from '../../types/block.js' | ||
import type { Chain } from '../../types/chain.js' | ||
import type { RpcTransactionRequest } from '../../types/rpc.js' | ||
import type { AccessList, TransactionRequest } from '../../types/transaction.js' | ||
import type { ExactPartial, UnionOmit } from '../../types/utils.js' | ||
import type { RequestErrorType } from '../../utils/buildRequest.js' | ||
import { | ||
type NumberToHexErrorType, | ||
numberToHex, | ||
} from '../../utils/encoding/toHex.js' | ||
import { getCallError } from '../../utils/errors/getCallError.js' | ||
import type { GetCreateAccessListErrorReturnType } from '../../utils/errors/getCreateAccessList.js' | ||
import { extract } from '../../utils/formatters/extract.js' | ||
import { | ||
type FormatTransactionRequestErrorType, | ||
type FormattedTransactionRequest, | ||
formatTransactionRequest, | ||
} from '../../utils/formatters/transactionRequest.js' | ||
import { assertRequest } from '../../utils/transaction/assertRequest.js' | ||
import type { | ||
AssertRequestErrorType, | ||
AssertRequestParameters, | ||
} from '../../utils/transaction/assertRequest.js' | ||
|
||
export type CreateAccessListParameters< | ||
chain extends Chain | undefined = Chain | undefined, | ||
> = UnionOmit< | ||
FormattedTransactionRequest<chain>, | ||
'from' | 'nonce' | 'accessList' | ||
> & { | ||
/** Account attached to the call (msg.sender). */ | ||
account?: Account | Address | undefined | ||
} & ( | ||
| { | ||
/** The balance of the account at a block number. */ | ||
blockNumber?: bigint | undefined | ||
blockTag?: undefined | ||
} | ||
| { | ||
blockNumber?: undefined | ||
/** | ||
* The balance of the account at a block tag. | ||
* @default 'latest' | ||
*/ | ||
blockTag?: BlockTag | undefined | ||
} | ||
) | ||
|
||
export type CreateAccessListReturnType = { | ||
accessList: AccessList | ||
gasUsed: bigint | ||
} | ||
|
||
export type CreateAccessListErrorType = GetCreateAccessListErrorReturnType< | ||
| ParseAccountErrorType | ||
| AssertRequestErrorType | ||
| NumberToHexErrorType | ||
| FormatTransactionRequestErrorType | ||
| RequestErrorType | ||
> | ||
|
||
/** | ||
* Creates an EIP-2930 access list that you can include in a transaction. | ||
* | ||
* - Docs: https://viem.sh/docs/actions/public/call | ||
* - JSON-RPC Methods: [`eth_createAccessList`](https://docs.infura.io/api/networks/ethereum/json-rpc-methods/eth_createaccesslist) | ||
* | ||
* @param client - Client to use | ||
* @param parameters - {@link CreateAccessListParameters} | ||
* @returns The access list. {@link CreateAccessListReturnType} | ||
* | ||
* @example | ||
* import { createPublicClient, http } from 'viem' | ||
* import { mainnet } from 'viem/chains' | ||
* import { createAccessList } from 'viem/public' | ||
* | ||
* const client = createPublicClient({ | ||
* chain: mainnet, | ||
* transport: http(), | ||
* }) | ||
* const data = await createAccessList(client, { | ||
* account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', | ||
* data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', | ||
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', | ||
* }) | ||
*/ | ||
export async function createAccessList<chain extends Chain | undefined>( | ||
client: Client<Transport, chain>, | ||
args: CreateAccessListParameters<chain>, | ||
): Promise<CreateAccessListReturnType> { | ||
const { | ||
account: account_ = client.account, | ||
blockNumber, | ||
blockTag = 'latest', | ||
blobs, | ||
data, | ||
gas, | ||
gasPrice, | ||
maxFeePerBlobGas, | ||
maxFeePerGas, | ||
maxPriorityFeePerGas, | ||
to, | ||
value, | ||
...rest | ||
} = args | ||
const account = account_ ? parseAccount(account_) : undefined | ||
|
||
try { | ||
assertRequest(args as AssertRequestParameters) | ||
|
||
const blockNumberHex = blockNumber ? numberToHex(blockNumber) : undefined | ||
const block = blockNumberHex || blockTag | ||
|
||
const chainFormat = client.chain?.formatters?.transactionRequest?.format | ||
const format = chainFormat || formatTransactionRequest | ||
|
||
const request = format({ | ||
// Pick out extra data that might exist on the chain's transaction request type. | ||
...extract(rest, { format: chainFormat }), | ||
from: account?.address, | ||
blobs, | ||
data, | ||
gas, | ||
gasPrice, | ||
maxFeePerBlobGas, | ||
maxFeePerGas, | ||
maxPriorityFeePerGas, | ||
to, | ||
value, | ||
} as TransactionRequest) as TransactionRequest | ||
|
||
const response = await client.request({ | ||
method: 'eth_createAccessList', | ||
params: [request as ExactPartial<RpcTransactionRequest>, block], | ||
}) | ||
return { | ||
accessList: response.accessList, | ||
gasUsed: BigInt(response.gasUsed), | ||
} | ||
} catch (err) { | ||
throw getCallError(err as ErrorType, { | ||
...args, | ||
account, | ||
chain: client.chain, | ||
}) | ||
} | ||
} |
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,46 @@ | ||
import type { CreateAccessListParameters } from '../../actions/public/createAccessList.js' | ||
import type { BaseError } from '../../errors/base.js' | ||
import { | ||
CallExecutionError, | ||
type CallExecutionErrorType, | ||
} from '../../errors/contract.js' | ||
import { UnknownNodeError } from '../../errors/node.js' | ||
import type { ErrorType } from '../../errors/utils.js' | ||
import type { Chain } from '../../types/chain.js' | ||
|
||
import { | ||
type GetNodeErrorParameters, | ||
type GetNodeErrorReturnType, | ||
getNodeError, | ||
} from './getNodeError.js' | ||
|
||
export type GetCreateAccessListErrorReturnType<cause = ErrorType> = Omit< | ||
CallExecutionErrorType, | ||
'cause' | ||
> & { | ||
cause: cause | GetNodeErrorReturnType | ||
} | ||
|
||
export function getCreateAccessListError<err extends ErrorType<string>>( | ||
err: err, | ||
{ | ||
docsPath, | ||
...args | ||
}: CreateAccessListParameters & { | ||
chain?: Chain | undefined | ||
docsPath?: string | undefined | ||
}, | ||
): GetCreateAccessListErrorReturnType<err> { | ||
const cause = (() => { | ||
const cause = getNodeError( | ||
err as {} as BaseError, | ||
args as GetNodeErrorParameters, | ||
) | ||
if (cause instanceof UnknownNodeError) return err as {} as BaseError | ||
return cause | ||
})() | ||
return new CallExecutionError(cause, { | ||
docsPath, | ||
...args, | ||
}) as GetCreateAccessListErrorReturnType<err> | ||
} |