Examples
Propose a transaction to a Safe wallet
1. Set up clients
ts
import { http, createPublicClient, parseEther, getAddress, createWalletClient, Hex } from 'viem'
import { goerli } from 'viem/chains'
import { publicSafeActions, walletSafeActions } from '@stauro/piggybank/actions'
const safeAddress = getAddress('0x_MY_SAFE_ADDRESS')
const publicClient = createPublicClient({
transport: http(),
chain: goerli,
}).extend(publicSafeActions(safeAddress))
const walletClient = createWalletClient({
transport: http(),
chain: goerli,
account: privateKeyToAccount(process.env. PK as Hex),
}).extend(walletSafeActions())
import { http, createPublicClient, parseEther, getAddress, createWalletClient, Hex } from 'viem'
import { goerli } from 'viem/chains'
import { publicSafeActions, walletSafeActions } from '@stauro/piggybank/actions'
const safeAddress = getAddress('0x_MY_SAFE_ADDRESS')
const publicClient = createPublicClient({
transport: http(),
chain: goerli,
}).extend(publicSafeActions(safeAddress))
const walletClient = createWalletClient({
transport: http(),
chain: goerli,
account: privateKeyToAccount(process.env. PK as Hex),
}).extend(walletSafeActions())
2. Set up base transaction data
ts
import { parseEther, getAddress, type Hex } from 'viem'
const txData = {
to: getAddress(process.env. TO_ADDRESS as Hex),
value: parseEther('0.001'),
operation: OperationType.Call,
}
import { parseEther, getAddress, type Hex } from 'viem'
const txData = {
to: getAddress(process.env. TO_ADDRESS as Hex),
value: parseEther('0.001'),
operation: OperationType.Call,
}
3. Calculate gas (tx and base)
ts
const safeTxGas = await publicClient.estimateSafeTransactionGas(txData)
const baseGas = await publicClient.estimateSafeTransactionBaseGas({ ...txData, safeTxGas })
const safeTxGas = await publicClient.estimateSafeTransactionGas(txData)
const baseGas = await publicClient.estimateSafeTransactionBaseGas({ ...txData, safeTxGas })
4. Get nonce, transaction hash and signature
ts
const nonce = await publicClient.getSafeNonce()
const safeTxHash = await publicClient.getSafeTransactionHash({ ...txData, safeTxGas, baseGas, nonce })
const senderSignature = await walletClient.generateSafeTransactionSignature({
...txData,
nonce,
safeTxGas,
baseGas,
})
const nonce = await publicClient.getSafeNonce()
const safeTxHash = await publicClient.getSafeTransactionHash({ ...txData, safeTxGas, baseGas, nonce })
const senderSignature = await walletClient.generateSafeTransactionSignature({
...txData,
nonce,
safeTxGas,
baseGas,
})
5. Propose the transaction
ts
import { ApiClient } from '@stauro/piggybank/api'
const apiClient = new ApiClient({ url: 'https://safe-transaction-goerli.safe.global', safeAddress })
await apiClient.proposeTransaction({
safeTransactionData: { ...txData, safeTxGas, baseGas, nonce },
senderAddress: walletClient.account.address,
safeTxHash,
senderSignature,
chainId: goerli.id,
origin: 'Piggybank',
nonce,
})
import { ApiClient } from '@stauro/piggybank/api'
const apiClient = new ApiClient({ url: 'https://safe-transaction-goerli.safe.global', safeAddress })
await apiClient.proposeTransaction({
safeTransactionData: { ...txData, safeTxGas, baseGas, nonce },
senderAddress: walletClient.account.address,
safeTxHash,
senderSignature,
chainId: goerli.id,
origin: 'Piggybank',
nonce,
})