Blind Macro Forwarder
API reference for the Blind Macro Forwarder (BlindMacroForwarder)
The Blind Macro Forwarder is the minimal, legacy macro forwarder (formerly MacroForwarder). It executes user-defined "macro" contracts as a single atomic batch of protocol operations. Unlike the Clear Macro Forwarder, there is no EIP-712 clear signing or relaying — the caller is the operator, and approves the macro's calldata directly.
Its address is sourced from the metadata contractsV1.macroForwarder key and is the same deterministic address across all supported networks.
Contract Addresses
import { blindMacroForwarderAddress } from "@sfpro/sdk/abi"
import { mainnet } from "viem/chains"
// Get Blind Macro Forwarder address for a specific chain
const forwarderAddress = blindMacroForwarderAddress[mainnet.id]Read Functions
buildBatchOperations
Simulate a macro and return the batch operations it would execute. Useful for previewing or encoding a macro call before sending it.
import { useReadBlindMacroForwarder } from "@sfpro/sdk/hook"
const { data: operations } = useReadBlindMacroForwarder({
functionName: "buildBatchOperations",
args: ["0x...", "0x..."] // Macro contract address, encoded params
}) import { blindMacroForwarderAbi, blindMacroForwarderAddress } from "@sfpro/sdk/abi"
import { createPublicClient, http } from "viem"
import { mainnet } from "viem/chains"
const client = createPublicClient({
chain: mainnet,
transport: http()
})
const operations = await client.readContract({
address: blindMacroForwarderAddress[mainnet.id],
abi: blindMacroForwarderAbi,
functionName: "buildBatchOperations",
args: [
"0x...", // Macro contract address
"0x..." // Encoded macro params
]
}) import { readBlindMacroForwarder } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { http } from "viem"
import { mainnet } from "viem/chains"
const config = createConfig({
chains: [mainnet],
transports: { [mainnet.id]: http() }
})
const operations = await readBlindMacroForwarder(config, {
chainId: mainnet.id,
functionName: "buildBatchOperations",
args: ["0x...", "0x..."] // Macro contract address, encoded params
}) Write Functions
runMacro
Run a user-defined macro: the forwarder builds the macro's operations and forwards them to the Host as an atomic batch call. Any native value sent is forwarded along with the operations. The caller is the operator of the batch.
import { useWriteBlindMacroForwarder } from "@sfpro/sdk/hook"
const { writeContract: runMacro } = useWriteBlindMacroForwarder({
functionName: "runMacro",
args: ["0x...", "0x..."] // Macro contract address, encoded params
}) import { blindMacroForwarderAbi, blindMacroForwarderAddress } from "@sfpro/sdk/abi"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http()
})
const hash = await walletClient.writeContract({
address: blindMacroForwarderAddress[mainnet.id],
abi: blindMacroForwarderAbi,
functionName: "runMacro",
args: [
"0x...", // Macro contract address
"0x..." // Encoded macro params
]
}) import { writeBlindMacroForwarder } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const config = createConfig({
chains: [mainnet],
client({ chain }) {
return createWalletClient({ account, chain, transport: http() })
},
})
const hash = await writeBlindMacroForwarder(config, {
chainId: mainnet.id,
functionName: "runMacro",
args: ["0x...", "0x..."] // Macro contract address, encoded params
}) Key Notes
- Blind vs clear signing: The caller approves the macro's calldata directly and is the operator of the batch. For human-readable EIP-712 signing, third-party relaying, and Permit2 support, use the Clear Macro Forwarder instead.
- User-defined macros: The first argument is the address of a macro contract that builds the batch operations from the encoded
params. - Atomic execution:
runMacroforwards all operations to the Host in a single batch call, so they succeed or revert together. - Events: The contract emits
MacroExecuted— subscribe withuseWatchBlindMacroForwarderEvent(/hook) orwatchBlindMacroForwarderEvent(/action). - Address source: Powered by metadata
contractsV1.macroForwarder, deployed at the same deterministic address on every supported network.