Skip to content

Commit

Permalink
[BOOST-3885] Typesafe .getLogs, .subscribe methods for contracts (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sammccord authored Aug 30, 2024
2 parents 6d85f96 + 935f712 commit 44a02f3
Show file tree
Hide file tree
Showing 27 changed files with 756 additions and 64 deletions.
3 changes: 2 additions & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
},
"peerDependencies": {
"@wagmi/core": "2",
"viem": "2"
"viem": "2",
"abitype": "1"
}
}
26 changes: 24 additions & 2 deletions packages/sdk/src/Actions/ContractAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,39 @@ import {
writeContractActionExecute,
} from '@boostxyz/evm';
import { bytecode } from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json';
import type { Address, Hex } from 'viem';
import type { Abi, Address, ContractEventName, Hex } from 'viem';
import type {
DeployableOptions,
GenericDeployableParams,
} from '../Deployable/Deployable';
import { DeployableTarget } from '../Deployable/DeployableTarget';
import {
type ContractActionPayload,
type GenericLog,
type ReadParams,
RegistryType,
type WriteParams,
prepareContractActionPayload,
} from '../utils';

export { contractActionAbi };
export type { ContractActionPayload };

/**
* A generic `viem.Log` event with support for `ContractAction` event types.
*
* @export
* @typedef {ContractActionLog}
* @template {ContractEventName<typeof contractActionAbi>} [event=ContractEventName<
* typeof contractActionAbi
* >]
*/
export type ContractActionLog<
event extends ContractEventName<typeof contractActionAbi> = ContractEventName<
typeof contractActionAbi
>,
> = GenericLog<typeof contractActionAbi, event>;

/**
* A generic contract action
*
Expand All @@ -33,7 +50,12 @@ export type { ContractActionPayload };
* @typedef {ContractAction}
* @extends {DeployableTarget<ContractActionPayload>}
*/
export class ContractAction extends DeployableTarget<ContractActionPayload> {
export class ContractAction<
ContractActionAbi extends Abi = typeof contractActionAbi,
> extends DeployableTarget<ContractActionPayload, ContractActionAbi> {
//@ts-expect-error should never be constructed with variant typ
public override readonly abi = contractActionAbi;

/**
* @inheritdoc
*
Expand Down
27 changes: 24 additions & 3 deletions packages/sdk/src/Actions/ERC721MintAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
writeErc721MintActionValidate,
} from '@boostxyz/evm';
import { bytecode } from '@boostxyz/evm/artifacts/contracts/actions/ERC721MintAction.sol/ERC721MintAction.json';
import type { Address, Hex } from 'viem';
import type { Address, ContractEventName, Hex } from 'viem';
import type {
DeployableOptions,
GenericDeployableParams,
} from '../Deployable/Deployable';
import {
type ERC721MintActionPayload,
type GenericLog,
type ReadParams,
RegistryType,
type WriteParams,
Expand All @@ -23,9 +24,24 @@ import {
} from '../utils';
import { ContractAction } from './ContractAction';

export { prepareERC721MintActionPayload };
export { erc721MintActionAbi, prepareERC721MintActionPayload };
export type { ERC721MintActionPayload };

/**
* A generic `viem.Log` event with support for `ERC721MintAction` event types.
*
* @export
* @typedef {ERC721MintActionLog}
* @template {ContractEventName<
* typeof erc721MintActionAbi
* >} [event=ContractEventName<typeof erc721MintActionAbi>]
*/
export type ERC721MintActionLog<
event extends ContractEventName<
typeof erc721MintActionAbi
> = ContractEventName<typeof erc721MintActionAbi>,
> = GenericLog<typeof erc721MintActionAbi, event>;

/**
* A primitive action to mint and/or validate that an ERC721 token has been minted
* The action is expected to be prepared with the data payload for the minting of the token
Expand All @@ -37,7 +53,12 @@ export type { ERC721MintActionPayload };
* @typedef {ERC721MintAction}
* @extends {ContractAction}
*/
export class ERC721MintAction extends ContractAction {
export class ERC721MintAction extends ContractAction<
typeof erc721MintActionAbi
> {
//@ts-expect-error should never be constructed with variant typ
public override readonly abi = erc721MintActionAbi;

/**
* @inheritdoc
*
Expand Down
6 changes: 5 additions & 1 deletion packages/sdk/src/Actions/EventAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ export type { EventActionPayload };
* @typedef {EventAction}
* @extends {DeployableTarget<EventActionPayload>}
*/
export class EventAction extends DeployableTarget<EventActionPayload> {
export class EventAction extends DeployableTarget<
EventActionPayload,
typeof eventActionAbi
> {
public override readonly abi = eventActionAbi;
/**
* @inheritdoc
*
Expand Down
31 changes: 29 additions & 2 deletions packages/sdk/src/AllowLists/SimpleAllowList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,45 @@ import {
} from '@boostxyz/evm';
import { bytecode } from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleAllowList.sol/SimpleAllowList.json';
import { getAccount } from '@wagmi/core';
import { type Address, type Hex, zeroAddress, zeroHash } from 'viem';
import {
type Address,
type ContractEventName,
type Hex,
zeroAddress,
zeroHash,
} from 'viem';
import type {
DeployableOptions,
GenericDeployableParams,
} from '../Deployable/Deployable';
import { DeployableTarget } from '../Deployable/DeployableTarget';
import { DeployableUnknownOwnerProvidedError } from '../errors';
import {
type GenericLog,
type ReadParams,
RegistryType,
type SimpleAllowListPayload,
prepareSimpleAllowListPayload,
} from '../utils';

export { simpleAllowListAbi };
export type { SimpleAllowListPayload };

/**
* A generic `viem.Log` event with support for `SimpleAllowList` event types.
*
* @export
* @typedef {SimpleAllowListLog}
* @template {ContractEventName<
* typeof simpleAllowListAbi
* >} [event=ContractEventName<typeof simpleAllowListAbi>]
*/
export type SimpleAllowListLog<
event extends ContractEventName<
typeof simpleAllowListAbi
> = ContractEventName<typeof simpleAllowListAbi>,
> = GenericLog<typeof simpleAllowListAbi, event>;

/**
* A constant representing the list manager's role
*
Expand All @@ -38,7 +61,11 @@ export const LIST_MANAGER_ROLE = 2n;
* @typedef {SimpleAllowList}
* @extends {DeployableTarget<SimpleAllowListPayload>}
*/
export class SimpleAllowList extends DeployableTarget<SimpleAllowListPayload> {
export class SimpleAllowList extends DeployableTarget<
SimpleAllowListPayload,
typeof simpleAllowListAbi
> {
public override readonly abi = simpleAllowListAbi;
/**
* @inheritdoc
*
Expand Down
136 changes: 134 additions & 2 deletions packages/sdk/src/AllowLists/SimpleDenyList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,46 @@ import {
} from '@boostxyz/evm';
import { bytecode } from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleDenyList.sol/SimpleDenyList.json';
import { getAccount } from '@wagmi/core';
import { type Address, type Hex, zeroAddress, zeroHash } from 'viem';
import {
type Address,
type ContractEventName,
type Hex,
zeroAddress,
zeroHash,
} from 'viem';
import type {
DeployableOptions,
GenericDeployableParams,
} from '../Deployable/Deployable';
import { DeployableTarget } from '../Deployable/DeployableTarget';
import { DeployableUnknownOwnerProvidedError } from '../errors';
import {
type GenericLog,
type ReadParams,
RegistryType,
type SimpleDenyListPayload,
type WriteParams,
prepareSimpleDenyListPayload,
} from '../utils';

export { simpleDenyListAbi };
export type { SimpleDenyListPayload };

/**
* A generic `viem.Log` event with support for `SimpleDenyList` event types.
*
* @export
* @typedef {SimpleDenyListLog}
* @template {ContractEventName<typeof simpleDenyListAbi>} [event=ContractEventName<
* typeof simpleDenyListAbi
* >]
*/
export type SimpleDenyListLog<
event extends ContractEventName<typeof simpleDenyListAbi> = ContractEventName<
typeof simpleDenyListAbi
>,
> = GenericLog<typeof simpleDenyListAbi, event>;

/**
* A simple implementation of an AllowList that implicitly allows all addresses except those explicitly added to the deny list
*
Expand All @@ -31,7 +54,11 @@ export type { SimpleDenyListPayload };
* @typedef {SimpleDenyList}
* @extends {DeployableTarget<SimpleDenyListPayload>}
*/
export class SimpleDenyList extends DeployableTarget<SimpleDenyListPayload> {
export class SimpleDenyList extends DeployableTarget<
SimpleDenyListPayload,
typeof simpleDenyListAbi
> {
public override readonly abi = simpleDenyListAbi;
/**
* @inheritdoc
*
Expand Down Expand Up @@ -119,6 +146,111 @@ export class SimpleDenyList extends DeployableTarget<SimpleDenyListPayload> {
return { hash, result };
}

// /**
// * A typed wrapper for (viem.getLogs)[https://viem.sh/docs/actions/public/getLogs#getlogs].
// * Accepts `eventName` and `eventNames` as optional parameters to narrow the returned log types.
// * @example
// * ```ts
// * const logs = contract.getLogs({ eventName: 'EventName' })
// * const logs = contract.getLogs({ eventNames: ['EventName'] })
// * ```
// * @public
// * @async
// * @template {ContractEventName<typeof simpleDenyListAbi>} event
// * @template {ExtractAbiEvent<
// * typeof simpleDenyListAbi,
// * event
// * >} [abiEvent=ExtractAbiEvent<typeof simpleDenyListAbi, event>]
// * @param {?Omit<
// * GetLogsParams<typeof simpleDenyListAbi, event, abiEvent, abiEvent[]>,
// * 'event' | 'events'
// * > & {
// * eventName?: event;
// * eventNames?: event[];
// * }} [params]
// * @returns {Promise<GetLogsReturnType<abiEvent, abiEvent[]>>}
// */
// public async getLogs<
// event extends ContractEventName<typeof simpleDenyListAbi>,
// const abiEvent extends ExtractAbiEvent<
// typeof simpleDenyListAbi,
// event
// > = ExtractAbiEvent<typeof simpleDenyListAbi, event>,
// >(
// params?: Omit<
// GetLogsParams<typeof simpleDenyListAbi, event, abiEvent, abiEvent[]>,
// 'event' | 'events'
// > & {
// eventName?: event;
// eventNames?: event[];
// },
// ): Promise<GetLogsReturnType<abiEvent, abiEvent[]>> {
// return getLogs(this._config.getClient({ chainId: params?.chainId }), {
// // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wag
// ...(params as any),
// ...(params?.eventName
// ? {
// event: getAbiItem({
// abi: simpleDenyListAbi,
// name: params.eventName,
// // biome-ignore lint/suspicious/noExplicitAny: awkward abi intersection issue
// } as any),
// }
// : {}),
// ...(params?.eventNames
// ? {
// events: params.eventNames.map((name) =>
// getAbiItem({
// abi: simpleDenyListAbi,
// name,
// // biome-ignore lint/suspicious/noExplicitAny: awkward abi intersection issue
// } as any),
// ),
// }
// : {}),
// address: this.assertValidAddress(),
// });
// }

// /**
// * A typed wrapper for `wagmi.watchContractEvent`
// *
// * @public
// * @async
// * @template {ContractEventName<typeof simpleDenyListAbi>} event
// * @param {(log: SimpleDenyListLog<event>) => unknown} cb
// * @param {?WatchParams<typeof simpleDenyListAbi, event> & {
// * eventName?: event;
// * }} [params]
// * @returns {unknown, params?: any) => unknown} Unsubscribe function
// */
// public async subscribe<
// event extends ContractEventName<typeof simpleDenyListAbi>,
// >(
// cb: (log: SimpleDenyListLog<event>) => unknown,
// params?: WatchParams<typeof simpleDenyListAbi, event> & {
// eventName?: event;
// },
// ) {
// return watchContractEvent<
// typeof this._config,
// (typeof this._config)['chains'][number]['id'],
// typeof simpleDenyListAbi,
// event
// >(this._config, {
// // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
// ...(params as any),
// eventName: params?.eventName,
// abi: simpleDenyListAbi,
// address: this.assertValidAddress(),
// onLogs: (logs) => {
// for (let l of logs) {
// cb(l as unknown as SimpleDenyListLog<event>);
// }
// },
// });
// }

/**
* @inheritdoc
*
Expand Down
Loading

0 comments on commit 44a02f3

Please sign in to comment.