Skip to main content

Transaction Lego



Name of the contract service we'll be interacting with.

If you would like to add another contract to interact with, head to src/data/contracts.js and add a new Contract Lego



Name of the service or abi function the txLego will use. This can be found in the Contract Service. In future version, this will use the name of the function in the ABI.



For simple poll types. Currently the only option is subgraph. This can be used for the main DAOhaus subgraph. In the next update there will be options for other DAOhaus subgraphs and contract entities.



Until then, we can use specialPoll to interact with the many customPolls in PollService.js. Just add the name of the poll to this field.

Note: Many custom polls require arguments that are not implicit to the usual transaction flow. You can solve this by:

  • Adding the required values directly to the values object.
const unlock = async (token) => {
const unlockAmount = MaxUint256.toString();
await submitTransaction({
args: [daoid, unlockAmount],
values: { tokenAddress: token, unlockAmount },

Or ensuring that the argument name matches the name that's' implicitly passed into the values object, as in the case of PROPOSAL_FORMS. Do this by changing the named arguments passed into PollService and adapt it to the values currently passed in.



onTxHash is a lifecycle method that is used so commonly in functions that it has it's own field, keyword strings, and constants.

onTxHash always takes an array of strings. It's looking for keywords that control the UI when the transaction is fired. Current UI events are

  • 'openTxModal'
  • 'closeProposalModal'

If you would like to add an action:

  • Go to src/data/onTxHashActions.js



String for displaying the current transaction to users. Will be used in txList and txModal in the next update.



String that is displayed in the success toast when the transaction completes.



String that is displayed in the error toast when the transaction completes.



PROPOSAL_FORMS (and likely other transactions) require a details field to hold arbitrary JSON data. However, the app relies on this field to deliver consistent UI to the app. Because the data in this field is immutable, there are considerable consequences for passing data in here the wrong way.

The solution is to have a premade API to handle it. So now each transaction that has a details JSON string as an argument will use the detailsJSON field on its TX object.

This field:

  • Takes an array of strings.
  • Searches the values object for fields with the same name as those strings.
  • Copies those fields into a new object.
  • Stringifies that object and turns and passes it to the argument slot as directed by the gatherArgs field.


  • To keep the shape of detailsToJSON strings consistent, there is a DETAILS constant inside of src/data/details.js.

Here's an example:

export const DETAILS = {
title: `.values.title`,
description: `.values.description || ${HASH.EMPTY_FIELD}`,
link: ` || ${HASH.EMPTY_FIELD}`,
proposalType: '.formData.type',
title: `.values.title`,
description: `.values.description || ${HASH.EMPTY_FIELD}`,
link: ` || ${HASH.EMPTY_FIELD}`,
proposalType: '.formData.type',
minionType: '.formData.minionType',



Search API for finding function arguments within the application. There are many ways to use gatherArgs. Takes an array that handles strings or objects (search params).

Shallow Search (values)#

Searches the values object for string keywords. Used by default if the search param is a string. ex.

gatherArgs: ['tokenAddress', 'tokenValue']
Deep Search (application-wide)#

Uses it's own search notation to find application state for within the React Context stores.

  • Exists in a search param object.
  • Initiated by using 'search' in the type field.
  • Depth of the search is controlled by an array that looks for nested fields with a matching name (can also do numerical array values).
  • Requires a strong understanding of the application data structure.
  • To be used in the most tricky situations.


gatherArgs: [
{type: 'search', fields: ['contextData', 'daoOverview', 'depositToken']},
{type: 'search', fields: ['values', 'nestedObject', 'nestedArray', '0']},
Static values#

For hardcoded static values.

  • Exists in a search param object.
  • Initiated by using the keyword 'static' in the field type.


gatherArgs: [{type: 'static' value: 42}],

String keyword that turns anything in the detailsJSON array into a JSON object.

Read more about how this works in tx.detailsJSON.

Mix'n Match Approach#
  • Args don't need to be of one type.
  • They can use any combination of search types.
gatherArgs: [
{type: 'search', fields: ['contextData', 'daoOverview', 'depositToken']},
{type: 'static' value: 42},



Indicates that args will not be gathered from either the React Component or using the gatherArgs field.

Instead, this transaction will use a callback function that is declared inside of argBuilderCallback{}inside of txHelpers.js.

  • Each field in this object is a callback function.
  • The name of the callback function must be the same as the name of the transaction.
  • Each callback has access to values, tx (tx lego data), contextData (application State) formData (form lego data), a hash, each as named arguments.

Because these callbacks are non-composable, their uses are limited to:

  • Fast protoyping (temporary; not pushed to prod).
  • last resort (no other option).

In every case, a TXs arg from callback will eventually need to be refactored into static data, either through refactoring a fast protoype or improving the txLego system.



Used mostly for proposals. Will create a discourse onPollSuccess.



A way to pass contract arguments directly into the tx at the component level (see tutorial).



In cases where a form isn't creating it's own values object from react-hook-form, values can be passed into the transaction manually at the component level.

This can be useful in cases where a transaction is using a customPoll.


Lifecycle functions that execute functions at different stages in a transaction's execution. This is for special situations where a custom, non-standard UI event needs to be triggered at a certian stage.

There are five lifecycle functions in total.

await submitTransaction({
args: ['example],
lifeCycleFns: {
beforeTx: () => doThis
onTxHash: () => doThat
onTxFire: () => thenDoThis
afterTx: () => finallyDoThat
onCatch: () => If fail, do this