import { Tabs, Callout } from 'nextra/components'
Adds a new ERC-4337 Safe operation for a given Safe account.
The SafeOperations methods are currently compatible with Entrypoint v0.6, which corresponds to `safeModuleVersion` v0.2.0. If you need to use v0.7, you should use the `relay-kit` `Safe4337Pack` class with `safeModuleVersion` v0.3.0, and collect the signatures yourself.Examples of how to use the Safe4337Pack
are provided in the following links:
A Safe operation can be created by using the createTransaction method from the Safe4337Pack
.
{/* */}
<Tabs items={['example.ts', 'exampleWith4337Pack.ts', 'setup.ts']}> <Tabs.Tab> ```typescript import { AddSafeOperationProps } from '@safe-global/api-kit' import { apiKit } from './setup.ts'
const userOperation = {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
const config: AddSafeOperationProps = {
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation,
options: { // Optional
validAfter: currentTimestamp - 60_000, // Optional
validUntil: currentTimestamp + 60_000 // Optional
}
}
await apiKit.addSafeOperation(config)
```
</Tabs.Tab> <Tabs.Tab> ```typescript import { addSafeOperationProps } from '@safe-global/api-kit' import { MetaTransactionData } from '@safe-global/relay-kit' import { apiKit, safe4337Pack } from './setup.ts'
const transactionData: MetaTransactionData = {
to: '0x...',
value: '0',
data: '0x...',
operation: 0 // Optional
}
const safeOperation = await safe4337Pack.createTransaction({
transactions: [transaction]
})
const signedSafeOperation = await safe4337Pack.signSafeOperation(
safeOperation
)
await apiKit.addSafeOperation(signedSafeOperation)
```
</Tabs.Tab> <Tabs.Tab> ```typescript import SafeApiKit from '@safe-global/api-kit' import Safe4337Pack from '@safe-global/relay-kit'
export const apiKit = new SafeApiKit({
chainId: 1n // Mainnet
})
export const safe4337Pack = await Safe4337Pack.init({
// options
})
```
</Tabs.Tab>
{/* */}
- Type:
string
Address of the EntryPoint
contract.
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation
})
- Type:
string
Address of the Safe4337Module
contract.
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation
})
- Type:
string
Address of the Safe to add a Safe operation for.
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
bigint
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
bigint
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
bigint
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
bigint
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
bigint
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
string
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation: {
sender: '0x...',
nonce: '10',
initCode: '0x...',
callData: '0x...',
callGasLimit: 123n,
verificationGasLimit: 123n,
preVerificationGas: 123n,
maxFeePerGas: 123n,
maxPriorityFeePerGas: 123n,
paymasterAndData: '0x...',
signature: '0x...'
}
})
- Type:
number
The user operation will be valid after this block's timestamp.
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation,
options: {
validAfter: currentTimestamp - 60_000
}
})
- Type:
number
The user operation will remain valid until this block's timestamp.
await apiKit.addSafeOperation({
entryPoint: '0x...',
moduleAddress: '0x...',
safeAddress: '0x...',
userOperation,
options: {
validUntil: currentTimestamp + 60_000
}
})