Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace assert with invariant in code to not require node environment #30

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}"`
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

closes #20

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
Loading