boostxyz / boost-protocol

A permissionless, trustless, and decentralized growth engine for protocol and application developers. It enables developers to bootstrap their projects by leveraging the power of community and the network effect.
https://boost-protocol.vercel.app
GNU General Public License v3.0
4 stars 2 forks source link

feat: RFC builder API for simple construction of EventAction steps #185

Open sammccord opened 1 day ago

sammccord commented 1 day ago

Description

Right now, SDK implementers creating Boosts with EventActions accept a non-zero amount of cognitive load and guesswork to build a correct ActionStep, including:

  1. Figuring out the fieldIndex of the parameter to compare against, which is potentially error prone and only resolved by cancelling and recreating the boost
  2. Figuring out how to properly encode the filterData, which involves using viem utilities and right-sizing the bytes for the type, which can be error prone - for example: filterData: toHex(1n, { size: 1 })

Suggested Solution

If the signature is supported in @boostxyz/signatures, we should be able to utilize typescript generics and type inference to know the types of arguments at each index, what the fieldType is, and how to correctly encode the filterData given the ABI type, removing two potential sources of human error in Boost construction, and moving errors that would normally occur during validation, like FieldValueNotComparableError and InvalidNumericalCriteriaError, into the construction step.

In pseudo code, the API could work like:

const actionStep = buildActionStep({ chainId, signatureType, targetContract, signature }, filterType: FilterType, fieldIndexOrEventOrFunctionName: number | string, data?: T)

function buildActionStep(base, filterType, indexOrName, data): ActionStep {
    const abi = knownEvents.abi[base.signature]
    const field = typeof indexOrName === 'number' ? abi[field] : abi.inputs[indexOrName]
    return { 
      ...base,
      actionParameter: { 
        filterType, 
        fieldIndex,
        fieldType: fieldTypeFromAbiType(field.type),
        filterData: encodeAbiItem(data, field.type) 
      }
}
Quazia commented 21 hours ago

The encodeAbiItem is particularly nice. If this isn't too difficult it seems like it's strictly better than how we're doing it right now. I forsee the most prickly part would be squaring the difference between the ABI typing and the typescript viem typing (i.e. uint256 = bigint uint8 = number Address = string etc etc)