Skip to content

Commit

Permalink
feat: replace assert with invariant in code to not require node envir…
Browse files Browse the repository at this point in the history
…onment
  • Loading branch information
frontendphil committed Jan 9, 2025
1 parent 2ed336c commit 13cc2f9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 36 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"wait-on": "8.0.1"
},
"dependencies": {
"@epic-web/invariant": "1.0.0",
"@safe-global/api-kit": "^2.5.6",
"@safe-global/protocol-kit": "^5.1.1",
"@safe-global/safe-deployments": "^1.37.22",
Expand Down
92 changes: 62 additions & 30 deletions src/execute/plan.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import assert from 'assert'
import { decodeFunctionData, hashTypedData, parseAbi, zeroAddress } from 'viem'
import { Eip1193Provider } from '@safe-global/protocol-kit'

Expand Down Expand Up @@ -37,6 +36,7 @@ import {
type Route,
type Waypoint,
} from '../types'
import { invariant } from '@epic-web/invariant'

interface Options {
/** Allows specifying which role to choose at any Roles node in the route in case multiple roles are available. */
Expand Down Expand Up @@ -120,8 +120,11 @@ const planAsEOA = async (
index: number
): Promise<ExecutionAction[]> => {
const { waypoint, right } = pointers(waypoints, index)
assert(waypoint.account.type == AccountType.EOA)
assert(right != null)
invariant(
waypoint.account.type == AccountType.EOA,
`Expected account type to be "${AccountType.EOA}" but got "${waypoint.account.type}"`
)
invariant(right != null, 'Expected next waypoint to not be undefined')

if (
request.type === ExecutionActionType.SAFE_TRANSACTION ||
Expand Down Expand Up @@ -158,19 +161,24 @@ const planAsSafe = async (
): Promise<ExecutionAction[]> => {
const { waypoint, connection, left, right } = pointers(waypoints, index)

assert(waypoint.account.type == AccountType.SAFE)
invariant(
waypoint.account.type == AccountType.SAFE,
`Expected account type to be "${AccountType.SAFE}" but got "${waypoint.account.type}"`
)

if (left !== null) {
assert(
invariant(
connection?.type == ConnectionType.IS_ENABLED ||
connection?.type == ConnectionType.OWNS
connection?.type == ConnectionType.OWNS,
`Connection type must be "${ConnectionType.IS_ENABLED}" or "${ConnectionType.OWNS}" but got "${connection?.type}"`
)
}

assert(
invariant(
request.type == ExecutionActionType.SAFE_TRANSACTION ||
request.type == ExecutionActionType.PROPOSE_TRANSACTION ||
request.type == ExecutionActionType.EXECUTE_TRANSACTION
request.type == ExecutionActionType.EXECUTE_TRANSACTION,
`Request type must be "${ExecutionActionType.SAFE_TRANSACTION}", "${ExecutionActionType.PROPOSE_TRANSACTION}", or "${ExecutionActionType.EXECUTE_TRANSACTION}" nut was "${request.type}"`
)

const isAnchor = right == null
Expand Down Expand Up @@ -203,7 +211,10 @@ const planAsSafe = async (
request.type == ExecutionActionType.PROPOSE_TRANSACTION) &&
!isAnchor
) {
assert(right.account.type == AccountType.SAFE)
invariant(
right.account.type == AccountType.SAFE,
`Expected account type "${AccountType.SAFE}" but got "${right.account.type}"`
)
const typedData = typedDataForSafeTransaction({
chainId: right.account.chain,
safeAddress: right.account.address,
Expand Down Expand Up @@ -250,7 +261,9 @@ const planAsSafe = async (
},
...result,
]
} else if (isUpstreamModule) {
}

if (isUpstreamModule) {
return [
{
type: ExecutionActionType.EXECUTE_TRANSACTION,
Expand All @@ -264,18 +277,19 @@ const planAsSafe = async (
},
...result,
]
} else {
assert(isInitiator)
return [
{
type: ExecutionActionType.EXECUTE_TRANSACTION,
chain: waypoint.account.chain,
from: waypoint.account.address,
transaction,
},
...result,
]
}

invariant(isInitiator, 'Expected isInitiator to be "true"')

return [
{
type: ExecutionActionType.EXECUTE_TRANSACTION,
chain: waypoint.account.chain,
from: waypoint.account.address,
transaction,
},
...result,
]
}

const planAsRoles = async (
Expand All @@ -288,7 +302,10 @@ const planAsRoles = async (
* coming soon: relays for Modules
*/
const { waypoint, left, right } = pointers(waypoints, index)
assert(waypoint.account.type == AccountType.ROLES)
invariant(
waypoint.account.type == AccountType.ROLES,
`Expected account type to be "${AccountType.ROLES}" but got "${waypoint.account.type}"`
)

const validUpstream =
left != null &&
Expand All @@ -297,7 +314,10 @@ const planAsRoles = async (
if (!validUpstream) {
throw new Error(`Invalid Roles upstream relationship`)
}
assert(waypoint.connection.type == ConnectionType.IS_MEMBER)
invariant(
waypoint.connection.type == ConnectionType.IS_MEMBER,
`Expected connection type to be "${ConnectionType.IS_MEMBER}" but got "${waypoint.connection.type}"`
)

const validDownstream =
right?.connection.type == ConnectionType.IS_ENABLED &&
Expand Down Expand Up @@ -344,8 +364,11 @@ const planAsDelay = async (
* coming soon: relays for Modules
*/
const { waypoint, left } = pointers(waypoints, index)
assert(waypoint.account.type == AccountType.DELAY)
assert(left != null)
invariant(
waypoint.account.type == AccountType.DELAY,
`Expected account type to be "${AccountType.DELAY}" but got "${waypoint.account.type}"`
)
invariant(left != null, 'Expected waypoint to have a predecessor')

const transaction = unwrapExecuteTransaction(
request as ExecuteTransactionAction
Expand Down Expand Up @@ -376,7 +399,10 @@ const planAsDelay = async (
}

function shouldPropose(waypoint: Waypoint | StartingPoint, options?: Options) {
assert(waypoint.account.type == AccountType.SAFE)
invariant(
waypoint.account.type == AccountType.SAFE,
`Expected account type to be "${AccountType.SAFE}" but got "${waypoint.account.type}"`
)
const safeTransactionProperties =
options?.safeTransactionProperties?.[waypoint.account.prefixedAddress]

Expand Down Expand Up @@ -414,18 +440,24 @@ function pointers(waypoints: Route['waypoints'], index: number) {

const left = index > 0 ? waypoints[index - 1] : null
if (left) {
assert(
invariant(
'connection' in waypoint &&
waypoint.connection.from == left.account.prefixedAddress
waypoint.connection.from == left.account.prefixedAddress,
'connection' in waypoint
? `Expected "${waypoint.connection.from}" to equal "${left.account.prefixedAddress}"`
: 'Expected waypoint to contain a connection but it did not.'
)
}

const right = index < waypoints.length + 1 ? waypoints[index + 1] : null
if (right) {
assert(
invariant(
'connection' in right &&
(right.connection as Connection).from ==
waypoint.account.prefixedAddress
waypoint.account.prefixedAddress,
'connection' in right
? `Expected "${(right.connection as Connection).from}" to equal "${waypoint.account.prefixedAddress}"`
: 'Expected waypoint to contain a connection but it did not'
)
}

Expand Down
16 changes: 10 additions & 6 deletions src/execute/safeTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import assert from 'assert'
import {
Address,
encodeFunctionData,
Expand All @@ -18,6 +17,7 @@ import {
PrefixedAddress,
SafeTransactionRequest,
} from '../types'
import { invariant } from '@epic-web/invariant'

export async function prepareSafeTransaction({
chainId,
Expand Down Expand Up @@ -63,13 +63,17 @@ async function nonce({
const config = nonceConfig({ chainId, safe, options })
if (config == 'enqueue') {
return fetchQueueNonce({ chainId, safe })
} else if (config == 'override') {
}

if (config == 'override') {
return fetchOnChainNonce({ chainId, safe, options })
} else {
const nonce = config
assert(typeof nonce == 'number')
return nonce
}
const nonce = config
invariant(
typeof nonce == 'number',
`Expected nonce to have type "number" but got "${typeof nonce}"`
)
return nonce
}

async function fetchOnChainNonce({
Expand Down

0 comments on commit 13cc2f9

Please sign in to comment.