From a4c33063443696dec9bf36f11ec9902a1a738b43 Mon Sep 17 00:00:00 2001 From: Sam McCord Date: Fri, 28 Jun 2024 11:04:34 -0600 Subject: [PATCH 1/3] chore: createBoost and retrieve payload in tests --- packages/sdk/src/Actions/ContractAction.ts | 1 + packages/sdk/src/Boost.ts | 16 +- ...{BoostClient.test.ts => BoostCore.test.ts} | 0 packages/sdk/src/BoostCore.ts | 163 ++++++++++-------- packages/sdk/test/viem.ts | 2 +- 5 files changed, 110 insertions(+), 72 deletions(-) rename packages/sdk/src/{BoostClient.test.ts => BoostCore.test.ts} (100%) diff --git a/packages/sdk/src/Actions/ContractAction.ts b/packages/sdk/src/Actions/ContractAction.ts index 7085d2b97..383858f1c 100644 --- a/packages/sdk/src/Actions/ContractAction.ts +++ b/packages/sdk/src/Actions/ContractAction.ts @@ -10,6 +10,7 @@ import { } from '@boostxyz/evm'; import ContractActionArtifact from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json'; import type { Hex } from 'viem'; +import { simulateContract } from 'viem/actions'; import type { DeployableOptions, GenericDeployableParams, diff --git a/packages/sdk/src/Boost.ts b/packages/sdk/src/Boost.ts index 7e6cd04a2..973ed0ab5 100644 --- a/packages/sdk/src/Boost.ts +++ b/packages/sdk/src/Boost.ts @@ -5,7 +5,7 @@ import type { Budget } from './Budgets/Budget'; import type { Incentive } from './Incentives/Incentive'; import type { Validator } from './Validators/Validator'; -export type BoostPayload = { +export interface BoostPayload { address?: Address; budget: Budget; action: Action; @@ -16,7 +16,19 @@ export type BoostPayload = { referralFee?: bigint; maxParticipants?: bigint; owner?: Address; -}; +} + +export interface LibBoost { + action: Address; + validator: Address; + allowList: Address; + budget: Address; + incentives: Array
; + protocolFee: bigint; + referralFee: bigint; + maxParticipants: bigint; + owner: Address; +} export class Boost { readonly action: Action; diff --git a/packages/sdk/src/BoostClient.test.ts b/packages/sdk/src/BoostCore.test.ts similarity index 100% rename from packages/sdk/src/BoostClient.test.ts rename to packages/sdk/src/BoostCore.test.ts diff --git a/packages/sdk/src/BoostCore.ts b/packages/sdk/src/BoostCore.ts index 5e9c4aa90..f0b9d78c8 100644 --- a/packages/sdk/src/BoostCore.ts +++ b/packages/sdk/src/BoostCore.ts @@ -1,11 +1,19 @@ import BoostCoreArtifact from '@boostxyz/evm/artifacts/contracts/BoostCore.sol/BoostCore.json'; -import { getAccount, waitForTransactionReceipt } from '@wagmi/core'; +import { + getAccount, + getTransaction, + getTransactionReceipt, + simulateContract, + waitForTransactionReceipt, +} from '@wagmi/core'; import { createWriteContract } from '@wagmi/core/codegen'; import { type Address, type Hash, type Hex, decodeAbiParameters, + decodeFunctionData, + decodeFunctionResult, zeroAddress, zeroHash, } from 'viem'; @@ -14,6 +22,9 @@ import { type Target, boostCoreAbi, prepareBoostPayload, + readBoostCoreGetBoost, + readBoostCoreGetBoostCount, + simulateBoostCoreCreateBoost, } from '../../evm/artifacts'; import type { Action } from './Actions/Action'; @@ -34,6 +45,7 @@ import { SimpleDenyList, type SimpleDenyListPayload, } from './AllowLists/SimpleDenyList'; +import { Boost } from './Boost'; import type { Budget } from './Budgets/Budget'; import { SimpleBudget, type SimpleBudgetPayload } from './Budgets/SimpleBudget'; import { @@ -100,7 +112,7 @@ export type BoostClientConfig = | BoostCoreDeployedOptions | BoostCoreOptionsWithPayload; -export type CreatBoostPayload = { +export type CreateBoostPayload = { budget: Budget | Address; action: Action | Target; validator: Validator | Target; @@ -137,16 +149,17 @@ export class BoostCore extends Deployable<[Address, Address]> { // TODO make this transactional? if any deployment fails what do we do with the previously deployed deployables? public async createBoost( - _boostPayload: CreatBoostPayload, + _boostPayload: CreateBoostPayload, _options: DeployableOptions = { config: this._config, account: this._account, }, ) { - const [payload, options] = this.validateDeploymentConfig( - _boostPayload, - _options, - ); + const [payload, options] = + this.validateDeploymentConfig( + _boostPayload, + _options, + ); let { budget, @@ -157,7 +170,7 @@ export class BoostCore extends Deployable<[Address, Address]> { protocolFee = 0n, referralFee = 0n, maxParticipants = 0n, - owner = zeroAddress, + owner, } = payload; const boostFactory = createWriteContract({ @@ -345,71 +358,83 @@ export class BoostCore extends Deployable<[Address, Address]> { owner, }; - const encodedBoost = await boostFactory(options.config, { + const boostHash = await boostFactory(options.config, { args: [prepareBoostPayload(onChainPayload)], ...this.optionallyAttachAccount(options.account), }); + await waitForTransactionReceipt(options.config, { + hash: boostHash, + }); + const tx = await getTransaction(options.config, { + hash: boostHash, + }); + const { args } = decodeFunctionData({ + abi: boostCoreAbi, + data: tx.input, + }); + const boostCreation = await simulateBoostCoreCreateBoost(options.config, { + address: this.address!, + args: args as [Hex], + ...this.optionallyAttachAccount(), + }); - console.log(encodedBoost); - const values = decodeAbiParameters( - [ - { - components: [ - { - internalType: 'contract Action', - name: 'action', - type: 'address', - }, - { - internalType: 'contract Validator', - name: 'validator', - type: 'address', - }, - { - internalType: 'contract AllowList', - name: 'allowList', - type: 'address', - }, - { - internalType: 'contract Budget', - name: 'budget', - type: 'address', - }, - { - internalType: 'contract Incentive[]', - name: 'incentives', - type: 'address[]', - }, - { - internalType: 'uint64', - name: 'protocolFee', - type: 'uint64', - }, - { - internalType: 'uint64', - name: 'referralFee', - type: 'uint64', - }, - { - internalType: 'uint256', - name: 'maxParticipants', - type: 'uint256', - }, - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - internalType: 'struct BoostLib.Boost', - name: '', - type: 'tuple', - }, - ], - encodedBoost, - ); - - console.log(values); + // const values = decodeAbiParameters( + // [ + // { + // components: [ + // { + // internalType: 'contract Action', + // name: 'action', + // type: 'address', + // }, + // { + // internalType: 'contract Validator', + // name: 'validator', + // type: 'address', + // }, + // { + // internalType: 'contract AllowList', + // name: 'allowList', + // type: 'address', + // }, + // { + // internalType: 'contract Budget', + // name: 'budget', + // type: 'address', + // }, + // { + // internalType: 'contract Incentive[]', + // name: 'incentives', + // type: 'address[]', + // }, + // { + // internalType: 'uint64', + // name: 'protocolFee', + // type: 'uint64', + // }, + // { + // internalType: 'uint64', + // name: 'referralFee', + // type: 'uint64', + // }, + // { + // internalType: 'uint256', + // name: 'maxParticipants', + // type: 'uint256', + // }, + // { + // internalType: 'address', + // name: 'owner', + // type: 'address', + // }, + // ], + // internalType: 'struct BoostLib.Boost', + // name: '', + // type: 'tuple', + // }, + // ], + // encodedBoost, + // ); } ContractAction( diff --git a/packages/sdk/test/viem.ts b/packages/sdk/test/viem.ts index 86550f059..244b5bd12 100644 --- a/packages/sdk/test/viem.ts +++ b/packages/sdk/test/viem.ts @@ -23,7 +23,7 @@ export const mockWalletClient = createTestClient({ transport: http(), chain: hardhat, mode: 'hardhat', - account, + account: testAccount, key, }) .extend(publicActions) From 37a3316f0a33b1cf2e09b2660e585194f95669a2 Mon Sep 17 00:00:00 2001 From: Sam McCord Date: Mon, 1 Jul 2024 09:57:48 -0600 Subject: [PATCH 2/3] chore: try to genericize result retrieval from write calls --- packages/sdk/src/Actions/ContractAction.ts | 29 ++- packages/sdk/src/Actions/ERC721MintAction.ts | 22 ++- packages/sdk/src/Boost.ts | 17 +- packages/sdk/src/BoostCore.test.ts | 98 +++++----- packages/sdk/src/BoostCore.ts | 196 ++++++------------- packages/sdk/src/Deployable/Contract.ts | 32 ++- packages/sdk/test/helpers.ts | 21 +- packages/sdk/test/viem.ts | 23 ++- 8 files changed, 208 insertions(+), 230 deletions(-) diff --git a/packages/sdk/src/Actions/ContractAction.ts b/packages/sdk/src/Actions/ContractAction.ts index 383858f1c..1f35ac4fd 100644 --- a/packages/sdk/src/Actions/ContractAction.ts +++ b/packages/sdk/src/Actions/ContractAction.ts @@ -6,11 +6,12 @@ import { readContractActionSelector, readContractActionTarget, readContractActionValue, + simulateContractActionExecute, writeContractActionExecute, } from '@boostxyz/evm'; import ContractActionArtifact from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json'; -import type { Hex } from 'viem'; -import { simulateContract } from 'viem/actions'; +import { getTransaction, waitForTransactionReceipt } from '@wagmi/core'; +import { type Hex, decodeFunctionData } from 'viem'; import type { DeployableOptions, GenericDeployableParams, @@ -62,6 +63,30 @@ export class ContractAction extends DeployableTarget { public async execute( data: Hex, params: CallParams = {}, + ) { + const hash = await this.executeRaw(data, params); + const receipt = await waitForTransactionReceipt(this._config, { + hash, + }); + const tx = await getTransaction(this._config, { hash }); + const { args } = decodeFunctionData({ + abi: ContractActionArtifact.abi, + data: tx.input, + }); + const { result } = await simulateContractActionExecute(this._config, { + account: tx.from, + address: tx.to!, + args: args as [Hex], + // value: tx.value, // TS doesn't like me to including this + blockNumber: receipt.blockNumber, + // do we need to include nonce, gas price, etc. to properly simulate? + }); + return result; + } + + public async executeRaw( + data: Hex, + params: CallParams = {}, ) { return writeContractActionExecute(this._config, { address: this.assertValidAddress(), diff --git a/packages/sdk/src/Actions/ERC721MintAction.ts b/packages/sdk/src/Actions/ERC721MintAction.ts index 1be39e81b..7c3414881 100644 --- a/packages/sdk/src/Actions/ERC721MintAction.ts +++ b/packages/sdk/src/Actions/ERC721MintAction.ts @@ -1,13 +1,18 @@ import { type ERC721MintActionPayload, + erc721MintActionAbi, prepareERC721MintActionPayload, readErc721MintActionPrepare, + simulateErc721MintActionExecute, writeErc721MintActionExecute, writeErc721MintActionValidate, } from '@boostxyz/evm'; -import ERC721MintActionArtifact from '@boostxyz/evm/artifacts/contracts/actions/ERC721MintAction.sol/ERC721MintAction.json'; -import type { Config } from '@wagmi/core'; -import type { Hex } from 'viem'; +import { + type Config, + getTransaction, + waitForTransactionReceipt, +} from '@wagmi/core'; +import { type Hex, decodeFunctionData } from 'viem'; import { Deployable, type DeployableOptions, @@ -22,6 +27,17 @@ export class ERC721MintAction extends ContractAction { public override async execute( data: Hex, params: CallParams = {}, + ) { + return this.awaitResult( + this.executeRaw(data, params), + erc721MintActionAbi, + simulateErc721MintActionExecute, + ); + } + + public override async executeRaw( + data: Hex, + params: CallParams = {}, ) { return writeErc721MintActionExecute(this._config, { address: this.assertValidAddress(), diff --git a/packages/sdk/src/Boost.ts b/packages/sdk/src/Boost.ts index 973ed0ab5..cbfc4076a 100644 --- a/packages/sdk/src/Boost.ts +++ b/packages/sdk/src/Boost.ts @@ -6,7 +6,6 @@ import type { Incentive } from './Incentives/Incentive'; import type { Validator } from './Validators/Validator'; export interface BoostPayload { - address?: Address; budget: Budget; action: Action; validator: Validator; @@ -18,23 +17,11 @@ export interface BoostPayload { owner?: Address; } -export interface LibBoost { - action: Address; - validator: Address; - allowList: Address; - budget: Address; - incentives: Array
; - protocolFee: bigint; - referralFee: bigint; - maxParticipants: bigint; - owner: Address; -} - export class Boost { + readonly budget: Budget; readonly action: Action; readonly validator: Validator; readonly allowList: AllowList; - readonly budget: Budget; readonly incentives: Array; readonly protocolFee: bigint; readonly referralFee: bigint; @@ -42,10 +29,10 @@ export class Boost { readonly owner: Address; constructor(payload: BoostPayload) { + this.budget = payload.budget; this.action = payload.action; this.validator = payload.validator; this.allowList = payload.allowList; - this.budget = payload.budget; this.incentives = payload.incentives; this.protocolFee = payload.protocolFee || 0n; this.referralFee = payload.referralFee || 0n; diff --git a/packages/sdk/src/BoostCore.test.ts b/packages/sdk/src/BoostCore.test.ts index 0271a3d1e..fe06e6f90 100644 --- a/packages/sdk/src/BoostCore.test.ts +++ b/packages/sdk/src/BoostCore.test.ts @@ -1,63 +1,59 @@ -import { zeroAddress, zeroHash } from 'viem'; -import { beforeAll, test } from 'vitest'; +import { beforeAll, describe, test } from 'vitest'; import { type Fixtures, deployFixtures } from '../test/helpers'; import { setupConfig, testAccount } from '../test/viem'; -import { ContractAction } from './Actions/ContractAction'; -import { SimpleAllowList } from './AllowLists/SimpleAllowList'; import { BoostCore } from './BoostCore'; -import { SimpleBudget } from './Budgets/Budget'; -import { SignerValidator } from './Validators/SignerValidator'; -let fixtures: Fixtures, - config = setupConfig(); +let fixtures: Fixtures; beforeAll(async () => { fixtures = await deployFixtures(); }); -test('expect true', async () => { - console.log(fixtures); - const { core, bases } = fixtures; - const client = new BoostCore({ - config: config, - address: core, - account: testAccount, - }); - await client.createBoost({ - budget: client - .SimpleBudget({ - owner: testAccount.address, - authorized: [], - }) - .at(bases.SimpleBudget.base), - action: client - .ContractAction( - { - chainId: BigInt(31_337), - target: core, - selector: '0xdeadbeef', - value: 0n, - }, - true, - ) - .at(bases.ContractAction.base), - validator: client - .SignerValidator( - { - signers: [testAccount.address], - }, - true, - ) - .at(bases.SignerValidator.base), - allowList: client - .SimpleAllowList( - { +describe('BoostCore', () => { + test('can successfully create a boost', async () => { + const config = setupConfig(); + const { core, bases } = fixtures; + const client = new BoostCore({ + config: config, + address: core, + account: testAccount, + }); + await client.createBoost({ + budget: client + .SimpleBudget({ owner: testAccount.address, - allowed: [], - }, - true, - ) - .at(bases.SimpleAllowList.base), - incentives: [], + authorized: [], + }) + .at(bases.SimpleBudget.base), + action: client + .ContractAction( + { + chainId: BigInt(31_337), + target: core, + selector: '0xdeadbeef', + value: 0n, + }, + true, + ) + .at(bases.ContractAction.base), + validator: client + .SignerValidator( + { + signers: [testAccount.address], + }, + true, + ) + .at(bases.SignerValidator.base), + allowList: client + .SimpleAllowList( + { + owner: testAccount.address, + allowed: [], + }, + true, + ) + .at(bases.SimpleAllowList.base), + incentives: [], + }); }); }); diff --git a/packages/sdk/src/BoostCore.ts b/packages/sdk/src/BoostCore.ts index f0b9d78c8..018d8b234 100644 --- a/packages/sdk/src/BoostCore.ts +++ b/packages/sdk/src/BoostCore.ts @@ -2,8 +2,6 @@ import BoostCoreArtifact from '@boostxyz/evm/artifacts/contracts/BoostCore.sol/B import { getAccount, getTransaction, - getTransactionReceipt, - simulateContract, waitForTransactionReceipt, } from '@wagmi/core'; import { createWriteContract } from '@wagmi/core/codegen'; @@ -11,9 +9,7 @@ import { type Address, type Hash, type Hex, - decodeAbiParameters, decodeFunctionData, - decodeFunctionResult, zeroAddress, zeroHash, } from 'viem'; @@ -22,8 +18,6 @@ import { type Target, boostCoreAbi, prepareBoostPayload, - readBoostCoreGetBoost, - readBoostCoreGetBoostCount, simulateBoostCoreCreateBoost, } from '../../evm/artifacts'; @@ -113,26 +107,17 @@ export type BoostClientConfig = | BoostCoreOptionsWithPayload; export type CreateBoostPayload = { - budget: Budget | Address; - action: Action | Target; - validator: Validator | Target; - allowList: AllowList | Target; - incentives: Array; + budget: Budget; + action: Action; + validator: Validator; + allowList: AllowList; + incentives: Array; protocolFee?: bigint; referralFee?: bigint; maxParticipants?: bigint; owner?: Address; }; -// biome-ignore lint/suspicious/noExplicitAny: is a typeguard for generic target -export function isTarget(t: any): t is Target { - return ( - t?.instance !== undefined && - t?.instance !== undefined && - t?.parameters !== undefined - ); -} - export class BoostCore extends Deployable<[Address, Address]> { constructor({ config, account, ...options }: BoostClientConfig) { if (isBoostCoreDeployed(options) && options.address) { @@ -199,79 +184,60 @@ export class BoostCore extends Deployable<[Address, Address]> { } } - console.log(JSON.stringify({ budgetPayload })); - let actionPayload: OnChainBoostPayload['action'] = { instance: zeroAddress, isBase: false, parameters: zeroHash, }, actionHash: Hash | undefined = undefined; - if (isTarget(action)) actionPayload = action; + if (action.address) + actionPayload = { + isBase: action.isBase, + instance: action.address, + parameters: action.isBase + ? action.buildParameters(undefined, options).args.at(0) || zeroHash + : zeroHash, + }; else { - if (action.address) - actionPayload = { - isBase: action.isBase, - instance: action.address, - parameters: action.isBase - ? action.buildParameters(undefined, options).args.at(0) || zeroHash - : zeroHash, - }; - else { - actionHash = await action.deploy(undefined, options); - } + actionHash = await action.deploy(undefined, options); } - console.log(JSON.stringify({ actionPayload })); - let validatorPayload: OnChainBoostPayload['validator'] = { instance: zeroAddress, isBase: false, parameters: zeroHash, }, validatorHash: Hash | undefined = undefined; - if (isTarget(validator)) validatorPayload = validator; + if (validator.address) + validatorPayload = { + isBase: validator.isBase, + instance: validator.address, + parameters: validator.isBase + ? validator.buildParameters(undefined, options).args.at(0) || zeroHash + : zeroHash, + }; else { - if (validator.address) - validatorPayload = { - isBase: validator.isBase, - instance: validator.address, - parameters: validator.isBase - ? validator.buildParameters(undefined, options).args.at(0) || - zeroHash - : zeroHash, - }; - else { - validatorHash = await validator.deploy(undefined, options); - } + validatorHash = await validator.deploy(undefined, options); } - console.log(JSON.stringify({ validatorPayload })); - let allowListPayload: OnChainBoostPayload['allowList'] = { instance: zeroAddress, isBase: false, parameters: zeroHash, }, allowListHash: Hash | undefined = undefined; - if (isTarget(allowList)) allowListPayload = allowList; + if (allowList.address) + allowListPayload = { + isBase: allowList.isBase, + instance: allowList.address, + parameters: allowList.isBase + ? allowList.buildParameters(undefined, options).args.at(0) || zeroHash + : zeroHash, + }; else { - if (allowList.address) - allowListPayload = { - isBase: allowList.isBase, - instance: allowList.address, - parameters: allowList.isBase - ? allowList.buildParameters(undefined, options).args.at(0) || - zeroHash - : zeroHash, - }; - else { - allowListHash = await allowList.deploy(undefined, options); - } + allowListHash = await allowList.deploy(undefined, options); } - console.log(JSON.stringify({ allowListPayload })); - let incentivesPayloads: Array = incentives.map(() => ({ instance: zeroAddress, isBase: false, @@ -281,20 +247,17 @@ export class BoostCore extends Deployable<[Address, Address]> { for (let i = 0; i < incentives.length; i++) { // biome-ignore lint/style/noNonNullAssertion: this will never be undefined const incentive = incentives.at(i)!; - if (isTarget(incentive)) incentivesPayloads[i] = incentive; + if (incentive.address) + incentivesPayloads[i] = { + isBase: incentive.isBase, + instance: incentive.address, + parameters: incentive.isBase + ? incentive.buildParameters(undefined, options).args.at(0) || + zeroHash + : zeroHash, + }; else { - if (incentive.address) - incentivesPayloads[i] = { - isBase: incentive.isBase, - instance: incentive.address, - parameters: incentive.isBase - ? incentive.buildParameters(undefined, options).args.at(0) || - zeroHash - : zeroHash, - }; - else { - incentiveHashes[i] = await incentive.deploy(undefined, options); - } + incentiveHashes[i] = await incentive.deploy(undefined, options); } } @@ -372,69 +335,26 @@ export class BoostCore extends Deployable<[Address, Address]> { abi: boostCoreAbi, data: tx.input, }); - const boostCreation = await simulateBoostCoreCreateBoost(options.config, { + const { result } = await simulateBoostCoreCreateBoost(options.config, { address: this.address!, args: args as [Hex], ...this.optionallyAttachAccount(), }); - // const values = decodeAbiParameters( - // [ - // { - // components: [ - // { - // internalType: 'contract Action', - // name: 'action', - // type: 'address', - // }, - // { - // internalType: 'contract Validator', - // name: 'validator', - // type: 'address', - // }, - // { - // internalType: 'contract AllowList', - // name: 'allowList', - // type: 'address', - // }, - // { - // internalType: 'contract Budget', - // name: 'budget', - // type: 'address', - // }, - // { - // internalType: 'contract Incentive[]', - // name: 'incentives', - // type: 'address[]', - // }, - // { - // internalType: 'uint64', - // name: 'protocolFee', - // type: 'uint64', - // }, - // { - // internalType: 'uint64', - // name: 'referralFee', - // type: 'uint64', - // }, - // { - // internalType: 'uint256', - // name: 'maxParticipants', - // type: 'uint256', - // }, - // { - // internalType: 'address', - // name: 'owner', - // type: 'address', - // }, - // ], - // internalType: 'struct BoostLib.Boost', - // name: '', - // type: 'tuple', - // }, - // ], - // encodedBoost, - // ); + // TODO we need to figure out how to ensure the boost has the correct component instances, ie SimpleAllowList vs SimpleDenyList + return new Boost({ + budget: budget.at(result.budget), + action: action.at(result.action), + validator: validator.at(result.validator), + allowList: allowList.at(result.allowList), + incentives: incentives.map((incentive, i) => + incentive.at(result.incentives.at(i)!), + ), + protocolFee: result.protocolFee, + referralFee: result.referralFee, + maxParticipants: result.maxParticipants, + owner: result.owner, + }); } ContractAction( @@ -550,7 +470,7 @@ export class BoostCore extends Deployable<[Address, Address]> { ); } - public override buildParameters( + protected override buildParameters( _payload?: [Address, Address], _options?: DeployableOptions, ): GenericDeployableParams { diff --git a/packages/sdk/src/Deployable/Contract.ts b/packages/sdk/src/Deployable/Contract.ts index 9975994c6..a5bb1ea2f 100644 --- a/packages/sdk/src/Deployable/Contract.ts +++ b/packages/sdk/src/Deployable/Contract.ts @@ -1,5 +1,10 @@ -import type { Config } from '@wagmi/core'; -import type { Address } from 'viem'; +import { + type Config, + getTransaction, + waitForTransactionReceipt, +} from '@wagmi/core'; +import type { CreateSimulateContractReturnType } from '@wagmi/core/codegen'; +import { type Abi, type Address, type Hash, decodeFunctionData } from 'viem'; import { ContractAddressRequiredError } from '../errors'; export class Contract { @@ -30,4 +35,27 @@ export class Contract { if (!address) throw new ContractAddressRequiredError(); return address; } + + protected async awaitResult( + hashPromise: Promise, + abi: A, + fn: CreateSimulateContractReturnType, + ) { + const hash = await hashPromise; + const receipt = await waitForTransactionReceipt(this._config, { + hash, + }); + const tx = await getTransaction(this._config, { hash }); + const { args } = decodeFunctionData({ + abi, + data: tx.input, + }); + const { result } = await fn(this._config, { + account: tx.from, + address: tx.to!, + args, + blockNumber: receipt.blockNumber, + }); + return result; + } } diff --git a/packages/sdk/test/helpers.ts b/packages/sdk/test/helpers.ts index 99594ad80..5545d28ee 100644 --- a/packages/sdk/test/helpers.ts +++ b/packages/sdk/test/helpers.ts @@ -1,5 +1,4 @@ -import { RegistryType } from '@boostxyz/evm'; -import { writeBoostRegistryRegister } from '@boostxyz/evm'; +import { RegistryType, writeBoostRegistryRegister } from '@boostxyz/evm'; import BoostCore from '@boostxyz/evm/artifacts/contracts/BoostCore.sol/BoostCore.json'; import BoostRegistry from '@boostxyz/evm/artifacts/contracts/BoostRegistry.sol/BoostRegistry.json'; import ContractAction from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json'; @@ -15,12 +14,16 @@ import ERC1155Incentive from '@boostxyz/evm/artifacts/contracts/incentives/ERC11 import PointsIncentive from '@boostxyz/evm/artifacts/contracts/incentives/PointsIncentive.sol/PointsIncentive.json'; import SignerValidator from '@boostxyz/evm/artifacts/contracts/validators/SignerValidator.sol/SignerValidator.json'; import type { Address, Hex } from 'viem'; -import { accounts } from './accounts'; -import { mockWalletClient, setupConfig, testAccount } from './viem'; +import { + type TestClient, + makeTestClient, + setupConfig, + testAccount, +} from './viem'; export async function deployContract( - client: typeof mockWalletClient, - ...params: Parameters + client: TestClient, + ...params: Parameters ) { const tx = await client.waitForTransactionReceipt({ hash: await client.deployContract(...params), @@ -31,8 +34,8 @@ export async function deployContract( export type Fixtures = Awaited>; export async function deployFixtures( - account: Address = accounts.at(0)?.account, - client = mockWalletClient, + account = testAccount, + client = makeTestClient(), ) { const registry = await deployContract(client, { abi: BoostRegistry.abi, @@ -44,7 +47,7 @@ export async function deployFixtures( abi: BoostCore.abi, bytecode: BoostCore.bytecode as Hex, account, - args: [registry, account], + args: [registry, account.address], }); const bases = { diff --git a/packages/sdk/test/viem.ts b/packages/sdk/test/viem.ts index 244b5bd12..32dbd0149 100644 --- a/packages/sdk/test/viem.ts +++ b/packages/sdk/test/viem.ts @@ -19,17 +19,20 @@ const { account, key } = accounts.at(0) || { export { account, key }; export const testAccount = privateKeyToAccount(key); -export const mockWalletClient = createTestClient({ - transport: http(), - chain: hardhat, - mode: 'hardhat', - account: testAccount, - key, -}) - .extend(publicActions) - .extend(walletActions); +export const makeTestClient = () => + createTestClient({ + transport: http(), + chain: hardhat, + mode: 'hardhat', + account: testAccount, + key, + }) + .extend(publicActions) + .extend(walletActions); -export function setupConfig(walletClient = mockWalletClient) { +export type TestClient = ReturnType; + +export function setupConfig(walletClient = makeTestClient()) { return createConfig({ chains: [hardhat], client: () => walletClient, From 12daea3d5648ade72f058d5074c75b0cf521a965 Mon Sep 17 00:00:00 2001 From: Sam McCord Date: Mon, 1 Jul 2024 13:35:31 -0600 Subject: [PATCH 3/3] feat: expose raw/awaited api for all write methods --- packages/sdk/src/Actions/ContractAction.ts | 30 ++----- packages/sdk/src/Actions/ERC721MintAction.ts | 33 +++++--- .../sdk/src/AllowLists/SimpleAllowList.ts | 23 ++++- packages/sdk/src/AllowLists/SimpleDenyList.ts | 20 ++++- packages/sdk/src/Budgets/SimpleBudget.ts | 76 +++++++++++++++-- packages/sdk/src/Budgets/VestingBudget.ts | 84 +++++++++++++++---- packages/sdk/src/Deployable/Contract.ts | 26 ++++-- .../sdk/src/Incentives/AllowListIncentive.ts | 20 ++++- packages/sdk/src/Incentives/CGDAIncentive.ts | 33 ++++++-- .../sdk/src/Incentives/ERC1155Incentive.ts | 31 ++++++- packages/sdk/src/Incentives/ERC20Incentive.ts | 44 ++++++++-- .../sdk/src/Incentives/PointsIncentive.ts | 20 ++++- .../sdk/src/Validators/SignerValidator.ts | 32 ++++++- packages/sdk/src/index.ts | 2 + 14 files changed, 381 insertions(+), 93 deletions(-) diff --git a/packages/sdk/src/Actions/ContractAction.ts b/packages/sdk/src/Actions/ContractAction.ts index 1f35ac4fd..b5924e3fd 100644 --- a/packages/sdk/src/Actions/ContractAction.ts +++ b/packages/sdk/src/Actions/ContractAction.ts @@ -1,5 +1,6 @@ import { type ContractActionPayload, + contractActionAbi, prepareContractActionPayload, readContractActionChainId, readContractActionPrepare, @@ -9,7 +10,7 @@ import { simulateContractActionExecute, writeContractActionExecute, } from '@boostxyz/evm'; -import ContractActionArtifact from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/actions/ContractAction.sol/ContractAction.json'; import { getTransaction, waitForTransactionReceipt } from '@wagmi/core'; import { type Hex, decodeFunctionData } from 'viem'; import type { @@ -64,24 +65,11 @@ export class ContractAction extends DeployableTarget { data: Hex, params: CallParams = {}, ) { - const hash = await this.executeRaw(data, params); - const receipt = await waitForTransactionReceipt(this._config, { - hash, - }); - const tx = await getTransaction(this._config, { hash }); - const { args } = decodeFunctionData({ - abi: ContractActionArtifact.abi, - data: tx.input, - }); - const { result } = await simulateContractActionExecute(this._config, { - account: tx.from, - address: tx.to!, - args: args as [Hex], - // value: tx.value, // TS doesn't like me to including this - blockNumber: receipt.blockNumber, - // do we need to include nonce, gas price, etc. to properly simulate? - }); - return result; + return this.awaitResult( + this.executeRaw(data, params), + contractActionAbi, + simulateContractActionExecute, + ); } public async executeRaw( @@ -117,8 +105,8 @@ export class ContractAction extends DeployableTarget { _options, ); return { - abi: ContractActionArtifact.abi, - bytecode: ContractActionArtifact.bytecode as Hex, + abi: contractActionAbi, + bytecode: bytecode as Hex, args: [prepareContractActionPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Actions/ERC721MintAction.ts b/packages/sdk/src/Actions/ERC721MintAction.ts index 7c3414881..e2aefa016 100644 --- a/packages/sdk/src/Actions/ERC721MintAction.ts +++ b/packages/sdk/src/Actions/ERC721MintAction.ts @@ -4,19 +4,15 @@ import { prepareERC721MintActionPayload, readErc721MintActionPrepare, simulateErc721MintActionExecute, + simulateErc721MintActionValidate, writeErc721MintActionExecute, writeErc721MintActionValidate, } from '@boostxyz/evm'; -import { - type Config, - getTransaction, - waitForTransactionReceipt, -} from '@wagmi/core'; -import { type Hex, decodeFunctionData } from 'viem'; -import { - Deployable, - type DeployableOptions, - type GenericDeployableParams, +import { bytecode } from '@boostxyz/evm/artifacts/contracts/actions/ERC721MintAction.sol/ERC721MintAction.json'; +import type { Hex } from 'viem'; +import type { + DeployableOptions, + GenericDeployableParams, } from '../Deployable/Deployable'; import type { CallParams } from '../utils'; import { ContractAction } from './ContractAction'; @@ -28,7 +24,7 @@ export class ERC721MintAction extends ContractAction { data: Hex, params: CallParams = {}, ) { - return this.awaitResult( + return this.awaitResult( this.executeRaw(data, params), erc721MintActionAbi, simulateErc721MintActionExecute, @@ -62,6 +58,17 @@ export class ERC721MintAction extends ContractAction { public async validate( data: Hex, params: CallParams = {}, + ) { + return this.awaitResult( + this.validateRaw(data, params), + erc721MintActionAbi, + simulateErc721MintActionValidate, + ); + } + + public async validateRaw( + data: Hex, + params: CallParams = {}, ) { return writeErc721MintActionValidate(this._config, { address: this.assertValidAddress(), @@ -80,8 +87,8 @@ export class ERC721MintAction extends ContractAction { _options, ); return { - abi: ERC721MintActionArtifact.abi, - bytecode: ERC721MintActionArtifact.bytecode as Hex, + abi: erc721MintActionAbi, + bytecode: bytecode as Hex, args: [prepareERC721MintActionPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/AllowLists/SimpleAllowList.ts b/packages/sdk/src/AllowLists/SimpleAllowList.ts index 8c9d08076..4ee0f97c8 100644 --- a/packages/sdk/src/AllowLists/SimpleAllowList.ts +++ b/packages/sdk/src/AllowLists/SimpleAllowList.ts @@ -2,9 +2,11 @@ import { type SimpleAllowListPayload, prepareSimpleAllowListPayload, readSimpleAllowListIsAllowed, + simpleAllowListAbi, + simulateSimpleAllowListSetAllowed, writeSimpleAllowListSetAllowed, } from '@boostxyz/evm'; -import SimpleAllowListArtifact from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleAllowList.sol/SimpleAllowList.json'; +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 { @@ -33,7 +35,19 @@ export class SimpleAllowList extends DeployableTarget { public async setAllowed( addresses: Address[], allowed: boolean[], - params: CallParams = {}, + params: CallParams = {}, + ) { + return this.awaitResult( + this.setAllowedRaw(addresses, allowed, params), + simpleAllowListAbi, + simulateSimpleAllowListSetAllowed, + ); + } + + public async setAllowedRaw( + addresses: Address[], + allowed: boolean[], + params: CallParams = {}, ) { return await writeSimpleAllowListSetAllowed(this._config, { address: this.assertValidAddress(), @@ -41,6 +55,7 @@ export class SimpleAllowList extends DeployableTarget { ...params, }); } + public override buildParameters( _payload?: SimpleAllowListPayload, _options?: DeployableOptions, @@ -62,8 +77,8 @@ export class SimpleAllowList extends DeployableTarget { } } return { - abi: SimpleAllowListArtifact.abi, - bytecode: SimpleAllowListArtifact.bytecode as Hex, + abi: simpleAllowListAbi, + bytecode: bytecode as Hex, args: [prepareSimpleAllowListPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/AllowLists/SimpleDenyList.ts b/packages/sdk/src/AllowLists/SimpleDenyList.ts index 7ee22aa3e..7c89d8697 100644 --- a/packages/sdk/src/AllowLists/SimpleDenyList.ts +++ b/packages/sdk/src/AllowLists/SimpleDenyList.ts @@ -2,9 +2,11 @@ import { type SimpleDenyListPayload, prepareSimpleDenyListPayload, readSimpleDenyListIsAllowed, + simpleDenyListAbi, + simulateSimpleDenyListSetDenied, writeSimpleDenyListSetDenied, } from '@boostxyz/evm'; -import SimpleDenyListArtifact from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleDenyList.sol/SimpleDenyList.json'; +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 { @@ -33,6 +35,18 @@ export class SimpleDenyList extends DeployableTarget { addresses: Address[], allowed: boolean[], params: CallParams = {}, + ) { + return this.awaitResult( + this.setAllowedRaw(addresses, allowed, params), + simpleDenyListAbi, + simulateSimpleDenyListSetDenied, + ); + } + + public async setAllowedRaw( + addresses: Address[], + allowed: boolean[], + params: CallParams = {}, ) { return await writeSimpleDenyListSetDenied(this._config, { address: this.assertValidAddress(), @@ -62,8 +76,8 @@ export class SimpleDenyList extends DeployableTarget { } } return { - abi: SimpleDenyListArtifact.abi, - bytecode: SimpleDenyListArtifact.bytecode as Hex, + abi: simpleDenyListAbi, + bytecode: bytecode as Hex, args: [prepareSimpleDenyListPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Budgets/SimpleBudget.ts b/packages/sdk/src/Budgets/SimpleBudget.ts index 8c9091509..fc1da5be8 100644 --- a/packages/sdk/src/Budgets/SimpleBudget.ts +++ b/packages/sdk/src/Budgets/SimpleBudget.ts @@ -8,13 +8,19 @@ import { readSimpleBudgetIsAuthorized, readSimpleBudgetTotal, readVestingBudgetStart, + simpleAllowListAbi, + simulateSimpleBudgetAllocate, + simulateSimpleBudgetDisburse, + simulateSimpleBudgetDisburseBatch, + simulateSimpleBudgetReclaim, + simulateSimpleBudgetSetAuthorized, writeSimpleBudgetAllocate, writeSimpleBudgetDisburse, writeSimpleBudgetDisburseBatch, writeSimpleBudgetReclaim, writeSimpleBudgetSetAuthorized, } from '@boostxyz/evm'; -import SimpleBudgetArtifact from '@boostxyz/evm/artifacts/contracts/budgets/SimpleBudget.sol/SimpleBudget.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/budgets/SimpleBudget.sol/SimpleBudget.json'; import { getAccount } from '@wagmi/core'; import { type Address, type Hex, zeroAddress } from 'viem'; import { @@ -35,7 +41,18 @@ export class SimpleBudget extends Deployable { }); } - public allocate( + public async allocate( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.allocateRaw(transfer, params), + simpleAllowListAbi, + simulateSimpleBudgetAllocate, + ); + } + + public allocateRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -46,7 +63,18 @@ export class SimpleBudget extends Deployable { }); } - public reclaim( + public async reclaim( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.reclaimRaw(transfer, params), + simpleAllowListAbi, + simulateSimpleBudgetReclaim, + ); + } + + public reclaimRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -57,7 +85,18 @@ export class SimpleBudget extends Deployable { }); } - public disburse( + public async disburse( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.disburseRaw(transfer, params), + simpleAllowListAbi, + simulateSimpleBudgetDisburse, + ); + } + + public disburseRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -68,9 +107,20 @@ export class SimpleBudget extends Deployable { }); } + public async disburseBatch( + transfers: TransferPayload[], + params: CallParams = {}, + ) { + return this.awaitResult( + this.disburseBatchRaw(transfers, params), + simpleAllowListAbi, + simulateSimpleBudgetDisburseBatch, + ); + } + // use prepareFungibleTransfer or prepareERC1155Transfer // TODO use data structure - public disburseBatch( + public disburseBatchRaw( transfers: TransferPayload[], params: CallParams = {}, ) { @@ -85,6 +135,18 @@ export class SimpleBudget extends Deployable { addresses: Address[], allowed: boolean[], params: CallParams = {}, + ) { + return this.awaitResult( + this.setAuthorizedRaw(addresses, allowed, params), + simpleAllowListAbi, + simulateSimpleBudgetSetAuthorized, + ); + } + + public async setAuthorizedRaw( + addresses: Address[], + allowed: boolean[], + params: CallParams = {}, ) { return await writeSimpleBudgetSetAuthorized(this._config, { address: this.assertValidAddress(), @@ -161,8 +223,8 @@ export class SimpleBudget extends Deployable { } } return { - abi: SimpleBudgetArtifact.abi, - bytecode: SimpleBudgetArtifact.bytecode as Hex, + abi: simpleAllowListAbi, + bytecode: bytecode as Hex, args: [prepareSimpleBudgetPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Budgets/VestingBudget.ts b/packages/sdk/src/Budgets/VestingBudget.ts index abd826733..47a4a9549 100644 --- a/packages/sdk/src/Budgets/VestingBudget.ts +++ b/packages/sdk/src/Budgets/VestingBudget.ts @@ -8,14 +8,20 @@ import { readVestingBudgetEnd, readVestingBudgetIsAuthorized, readVestingBudgetTotal, + simulateVestingBudgetAllocate, + simulateVestingBudgetDisburse, + simulateVestingBudgetDisburseBatch, + simulateVestingBudgetReclaim, + simulateVestingBudgetSetAuthorized, + vestingBudgetAbi, writeVestingBudgetAllocate, writeVestingBudgetDisburse, writeVestingBudgetDisburseBatch, writeVestingBudgetReclaim, writeVestingBudgetSetAuthorized, } from '@boostxyz/evm'; -import VestingBudgetArtifact from '@boostxyz/evm/artifacts/contracts/budgets/VestingBudget.sol/VestingBudget.json'; -import { type Config, getAccount } from '@wagmi/core'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/budgets/VestingBudget.sol/VestingBudget.json'; +import { getAccount } from '@wagmi/core'; import { type Address, type Hex, zeroAddress } from 'viem'; import { Deployable, @@ -28,7 +34,18 @@ import type { CallParams } from '../utils'; export type { VestingBudgetPayload }; export class VestingBudget extends Deployable { - public allocate( + public async allocate( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.allocateRaw(transfer, params), + vestingBudgetAbi, + simulateVestingBudgetAllocate, + ); + } + + public allocateRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -39,9 +56,18 @@ export class VestingBudget extends Deployable { }); } - // use prepareFungibleTransfer or prepareERC1155Transfer - // TODO use data structure - public reclaim( + public async reclaim( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.reclaimRaw(transfer, params), + vestingBudgetAbi, + simulateVestingBudgetReclaim, + ); + } + + public reclaimRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -52,9 +78,18 @@ export class VestingBudget extends Deployable { }); } - // use prepareFungibleTransfer or prepareERC1155Transfer - // TODO use data structure - public disburse( + public async disburse( + transfer: TransferPayload, + params: CallParams = {}, + ) { + return this.awaitResult( + this.disburseRaw(transfer, params), + vestingBudgetAbi, + simulateVestingBudgetDisburse, + ); + } + + public disburseRaw( transfer: TransferPayload, params: CallParams = {}, ) { @@ -65,9 +100,18 @@ export class VestingBudget extends Deployable { }); } - // use prepareFungibleTransfer or prepareERC1155Transfer - // TODO use data structure - public disburseBatch( + public async disburseBatch( + transfers: TransferPayload[], + params: CallParams = {}, + ) { + return this.awaitResult( + this.disburseBatchRaw(transfers, params), + vestingBudgetAbi, + simulateVestingBudgetDisburseBatch, + ); + } + + public disburseBatchRaw( transfers: TransferPayload[], params: CallParams = {}, ) { @@ -82,6 +126,18 @@ export class VestingBudget extends Deployable { addresses: Address[], allowed: boolean[], params: CallParams = {}, + ) { + return this.awaitResult( + this.setAuthorizedRaw(addresses, allowed, params), + vestingBudgetAbi, + simulateVestingBudgetSetAuthorized, + ); + } + + public async setAuthorizedRaw( + addresses: Address[], + allowed: boolean[], + params: CallParams = {}, ) { return await writeVestingBudgetSetAuthorized(this._config, { address: this.assertValidAddress(), @@ -163,8 +219,8 @@ export class VestingBudget extends Deployable { } } return { - abi: VestingBudgetArtifact.abi, - bytecode: VestingBudgetArtifact.bytecode as Hex, + abi: vestingBudgetAbi, + bytecode: bytecode as Hex, args: [prepareVestingBudgetPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Deployable/Contract.ts b/packages/sdk/src/Deployable/Contract.ts index a5bb1ea2f..da2c5bc71 100644 --- a/packages/sdk/src/Deployable/Contract.ts +++ b/packages/sdk/src/Deployable/Contract.ts @@ -4,7 +4,15 @@ import { waitForTransactionReceipt, } from '@wagmi/core'; import type { CreateSimulateContractReturnType } from '@wagmi/core/codegen'; -import { type Abi, type Address, type Hash, decodeFunctionData } from 'viem'; +import { + type Abi, + type AbiStateMutability, + type Address, + type ContractFunctionArgs, + type ContractFunctionName, + type Hash, + decodeFunctionData, +} from 'viem'; import { ContractAddressRequiredError } from '../errors'; export class Contract { @@ -36,10 +44,13 @@ export class Contract { return address; } - protected async awaitResult( + protected async awaitResult< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + >( hashPromise: Promise, - abi: A, - fn: CreateSimulateContractReturnType, + abi: abi, + fn: CreateSimulateContractReturnType, ) { const hash = await hashPromise; const receipt = await waitForTransactionReceipt(this._config, { @@ -52,10 +63,11 @@ export class Contract { }); const { result } = await fn(this._config, { account: tx.from, - address: tx.to!, - args, + address: tx.to, + args: args as ContractFunctionArgs, blockNumber: receipt.blockNumber, - }); + // biome-ignore lint/suspicious/noExplicitAny: TODO this is an extremely complex type, but this method is intended for internal use and as such is alright for now + } as any); return result; } } diff --git a/packages/sdk/src/Incentives/AllowListIncentive.ts b/packages/sdk/src/Incentives/AllowListIncentive.ts index 162948632..c448f28e6 100644 --- a/packages/sdk/src/Incentives/AllowListIncentive.ts +++ b/packages/sdk/src/Incentives/AllowListIncentive.ts @@ -1,14 +1,16 @@ import { type AllowListIncentivePayload, type ClaimPayload, + allowListIncentiveAbi, prepareAllowListIncentivePayload, prepareClaimPayload, readAllowListIncentiveAllowList, readAllowListIncentiveIsClaimable, readAllowListIncentiveLimit, + simulateAllowListIncentiveClaim, writeAllowListIncentiveClaim, } from '@boostxyz/evm'; -import AllowListIncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/AllowListIncentive.sol/AllowListIncentive.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/AllowListIncentive.sol/AllowListIncentive.json'; import type { Hex } from 'viem'; import { SimpleAllowList } from '../AllowLists/AllowList'; import type { @@ -43,10 +45,20 @@ export class AllowListIncentive extends DeployableTarget = {}, + ) { + return this.awaitResult( + this.claimRaw(payload, params), + allowListIncentiveAbi, + simulateAllowListIncentiveClaim, + ); + } + + public async claimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeAllowListIncentiveClaim(this._config, { address: this.assertValidAddress(), @@ -76,8 +88,8 @@ export class AllowListIncentive extends DeployableTarget { }); } - //prepareClaimPayload public async claim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.claimRaw(payload, params), + cgdaIncentiveAbi, + simulateCgdaIncentiveClaim, + ); + } + + public async claimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeCgdaIncentiveClaim(this._config, { address: this.assertValidAddress(), @@ -68,10 +81,20 @@ export class CGDAIncentive extends DeployableTarget { }); } - //prepareClaimPayload public async reclaim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.reclaimRaw(payload, params), + cgdaIncentiveAbi, + simulateCgdaIncentiveReclaim, + ); + } + + public async reclaimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeCgdaIncentiveReclaim(this._config, { address: this.assertValidAddress(), @@ -120,8 +143,8 @@ export class CGDAIncentive extends DeployableTarget { _options, ); return { - abi: CGDAIncentiveArtifact.abi, - bytecode: CGDAIncentiveArtifact.bytecode as Hex, + abi: cgdaIncentiveAbi, + bytecode: bytecode as Hex, args: [prepareCGDAIncentivePayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Incentives/ERC1155Incentive.ts b/packages/sdk/src/Incentives/ERC1155Incentive.ts index 550e0baec..d6ab3b3c3 100644 --- a/packages/sdk/src/Incentives/ERC1155Incentive.ts +++ b/packages/sdk/src/Incentives/ERC1155Incentive.ts @@ -2,6 +2,7 @@ import { type ClaimPayload, type ERC1155IncentivePayload, type StrategyType, + erc1155IncentiveAbi, prepareClaimPayload, prepareERC1155IncentivePayload, readErc1155IncentiveAsset, @@ -12,10 +13,12 @@ import { readErc1155IncentiveStrategy, readErc1155IncentiveTokenId, readErc1155SupportsInterface, + simulateErc1155IncentiveClaim, + simulateErc1155IncentiveReclaim, writeErc1155IncentiveClaim, writeErc1155IncentiveReclaim, } from '@boostxyz/evm'; -import ERC1155IncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/ERC1155Incentive.sol/ERC1155Incentive.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/ERC1155Incentive.sol/ERC1155Incentive.json'; import type { Hex } from 'viem'; import type { DeployableOptions, @@ -75,6 +78,17 @@ export class ERC1155Incentive extends DeployableTarget public async claim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.claimRaw(payload, params), + erc1155IncentiveAbi, + simulateErc1155IncentiveClaim, + ); + } + + public async claimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeErc1155IncentiveClaim(this._config, { address: this.assertValidAddress(), @@ -86,6 +100,17 @@ export class ERC1155Incentive extends DeployableTarget public async reclaim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.reclaimRaw(payload, params), + erc1155IncentiveAbi, + simulateErc1155IncentiveReclaim, + ); + } + + public async reclaimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeErc1155IncentiveReclaim(this._config, { address: this.assertValidAddress(), @@ -136,8 +161,8 @@ export class ERC1155Incentive extends DeployableTarget _options, ); return { - abi: ERC1155IncentiveArtifact.abi, - bytecode: ERC1155IncentiveArtifact.bytecode as Hex, + abi: erc1155IncentiveAbi, + bytecode: bytecode as Hex, args: [prepareERC1155IncentivePayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Incentives/ERC20Incentive.ts b/packages/sdk/src/Incentives/ERC20Incentive.ts index 7bc017032..a5f8f138b 100644 --- a/packages/sdk/src/Incentives/ERC20Incentive.ts +++ b/packages/sdk/src/Incentives/ERC20Incentive.ts @@ -2,6 +2,7 @@ import { type ClaimPayload, type ERC20IncentivePayload, type StrategyType, + erc20IncentiveAbi, prepareClaimPayload, prepareERC20IncentivePayload, readErc20IncentiveAsset, @@ -11,11 +12,14 @@ import { readErc20IncentivePreflight, readErc20IncentiveReward, readErc20IncentiveStrategy, + simulateErc20IncentiveClaim, + simulateErc20IncentiveDrawRaffle, + simulateErc20IncentiveReclaim, writeErc20IncentiveClaim, writeErc20IncentiveDrawRaffle, writeErc20IncentiveReclaim, } from '@boostxyz/evm'; -import ERC20IncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/ERC20Incentive.sol/ERC20Incentive.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/ERC20Incentive.sol/ERC20Incentive.json'; import type { Hex } from 'viem'; import { Deployable, @@ -74,6 +78,17 @@ export class ERC20Incentive extends DeployableTarget { public async claim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.claimRaw(payload, params), + erc20IncentiveAbi, + simulateErc20IncentiveClaim, + ); + } + + public async claimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeErc20IncentiveClaim(this._config, { address: this.assertValidAddress(), @@ -82,10 +97,20 @@ export class ERC20Incentive extends DeployableTarget { }); } - //prepareClaimPayload public async reclaim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.reclaimRaw(payload, params), + erc20IncentiveAbi, + simulateErc20IncentiveReclaim, + ); + } + + public async reclaimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writeErc20IncentiveReclaim(this._config, { address: this.assertValidAddress(), @@ -94,7 +119,6 @@ export class ERC20Incentive extends DeployableTarget { }); } - //prepareClaimPayload public async isClaimable( payload: ClaimPayload, params: CallParams = {}, @@ -119,6 +143,16 @@ export class ERC20Incentive extends DeployableTarget { public async drawRaffle( params: CallParams = {}, + ) { + return this.awaitResult( + this.drawRaffleRaw(params), + erc20IncentiveAbi, + simulateErc20IncentiveDrawRaffle, + ); + } + + public async drawRaffleRaw( + params: CallParams = {}, ) { return writeErc20IncentiveDrawRaffle(this._config, { address: this.assertValidAddress(), @@ -135,8 +169,8 @@ export class ERC20Incentive extends DeployableTarget { _options, ); return { - abi: ERC20IncentiveArtifact.abi, - bytecode: ERC20IncentiveArtifact.bytecode as Hex, + abi: erc20IncentiveAbi, + bytecode: bytecode as Hex, args: [prepareERC20IncentivePayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Incentives/PointsIncentive.ts b/packages/sdk/src/Incentives/PointsIncentive.ts index ccb43c16f..20d9a59b6 100644 --- a/packages/sdk/src/Incentives/PointsIncentive.ts +++ b/packages/sdk/src/Incentives/PointsIncentive.ts @@ -1,6 +1,7 @@ import { type ClaimPayload, type PointsIncentivePayload, + pointsIncentiveAbi, prepareClaimPayload, preparePointsIncentivePayload, readPointsIncentiveIsClaimable, @@ -8,9 +9,10 @@ import { readPointsIncentiveQuantity, readPointsIncentiveSelector, readPointsIncentiveVenue, + simulatePointsIncentiveClaim, writePointsIncentiveClaim, } from '@boostxyz/evm'; -import PointsIncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/PointsIncentive.sol/PointsIncentive.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/PointsIncentive.sol/PointsIncentive.json'; import type { Hex } from 'viem'; import type { DeployableOptions, @@ -54,10 +56,20 @@ export class PointsIncentive extends DeployableTarget { }); } - //prepareClaimPayload public async claim( payload: ClaimPayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.claimRaw(payload, params), + pointsIncentiveAbi, + simulatePointsIncentiveClaim, + ); + } + + public async claimRaw( + payload: ClaimPayload, + params: CallParams = {}, ) { return writePointsIncentiveClaim(this._config, { address: this.assertValidAddress(), @@ -87,8 +99,8 @@ export class PointsIncentive extends DeployableTarget { _options, ); return { - abi: PointsIncentiveArtifact.abi, - bytecode: PointsIncentiveArtifact.bytecode as Hex, + abi: pointsIncentiveAbi, + bytecode: bytecode as Hex, args: [preparePointsIncentivePayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/Validators/SignerValidator.ts b/packages/sdk/src/Validators/SignerValidator.ts index 76ba1f590..02dc17c1f 100644 --- a/packages/sdk/src/Validators/SignerValidator.ts +++ b/packages/sdk/src/Validators/SignerValidator.ts @@ -4,10 +4,13 @@ import { prepareSignerValidatorPayload, prepareSignerValidatorValidatePayload, readSignerValidatorSigners, + signerValidatorAbi, + simulateSignerValidatorSetAuthorized, + simulateSignerValidatorValidate, writeSignerValidatorSetAuthorized, writeSignerValidatorValidate, } from '@boostxyz/evm'; -import SignerValidatorArtifact from '@boostxyz/evm/artifacts/contracts/validators/SignerValidator.sol/SignerValidator.json'; +import { bytecode } from '@boostxyz/evm/artifacts/contracts/validators/SignerValidator.sol/SignerValidator.json'; import type { Address, Hex } from 'viem'; import type { DeployableOptions, @@ -33,6 +36,17 @@ export class SignerValidator extends DeployableTarget { public async validate( payload: SignerValidatorValidatePayload, params: CallParams = {}, + ) { + return this.awaitResult( + this.validateRaw(payload, params), + signerValidatorAbi, + simulateSignerValidatorValidate, + ); + } + + public async validateRaw( + payload: SignerValidatorValidatePayload, + params: CallParams = {}, ) { return writeSignerValidatorValidate(this._config, { address: this.assertValidAddress(), @@ -45,6 +59,18 @@ export class SignerValidator extends DeployableTarget { addresses: Address[], allowed: boolean[], params: CallParams = {}, + ) { + return this.awaitResult( + this.setAuthorizedRaw(addresses, allowed, params), + signerValidatorAbi, + simulateSignerValidatorSetAuthorized, + ); + } + + public async setAuthorizedRaw( + addresses: Address[], + allowed: boolean[], + params: CallParams = {}, ) { return await writeSignerValidatorSetAuthorized(this._config, { address: this.assertValidAddress(), @@ -62,8 +88,8 @@ export class SignerValidator extends DeployableTarget { _options, ); return { - abi: SignerValidatorArtifact.abi, - bytecode: SignerValidatorArtifact.bytecode as Hex, + abi: signerValidatorAbi, + bytecode: bytecode as Hex, args: [prepareSignerValidatorPayload(payload)], ...this.optionallyAttachAccount(options.account), }; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index fe80af532..4b5b3e6fd 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -23,6 +23,8 @@ export * from './Budgets/VestingBudget'; // Deployable export * from './Deployable/Deployable'; +export * from './Deployable/Contract'; +export * from './Deployable/DeployableTarget'; // Incentives