Skip to main content
This guide explains how clients with Fireblocks custody can integrate with the Smart Wallet and Strategy system, including deposits, withdrawals, position tracking, and recommended security best practices.

Overview

The integration leverages Smart Wallets to provide segregated user accounts while keeping your Omnibus wallet isolated from strategy bytecode execution. This architecture ensures maximum security by preventing your main operational wallet from signing potentially untrusted transactions.

Architecture Flows

Depending on how you custody user funds on Fireblocks, the integration has two possible entry points. Both paths converge into the same flow after the owner vault is defined.
  • Omnibus Account — all users share a single Fireblocks vault. You must create a dedicated Vault Owner that will act as the signer for every Smart Wallet. This isolates strategy execution risk from the vault that actually holds funds (Omnibus).
  • Segregated Vaults — each user already has their own Fireblocks vault. That vault is used directly as the Smart Wallet owner, so no additional setup is required.
Fireblocks integration flow: Omnibus Account vs Segregated Vaults
In the Omnibus model, the Vault Owner created in step 1 is the signer for every Smart Wallet you provision. In the Segregated model, each user’s own vault plays that role — there is no shared owner vault to create.

Prerequisites

Before starting the integration, ensure you have:
  • A Fireblocks account with API access
  • Understanding of Fireblocks Transaction Authorization Policy (TAP)
  • Familiarity with the Architecture Overview

1. Fireblocks Setup

To safely interact with strategy bytecode while isolating your Omnibus wallet, Fireblocks must be configured with dedicated roles and policies.

Creating Roles

To ensure clean separation of responsibilities and secure execution:
RoleDescription
InitiatorThe API user or service responsible for submitting strategy-related transactions to Fireblocks.
Vault OwnerA dedicated vault that acts as the Smart Wallet Owner. This address serves as the signer for smart wallet transactions, providing security segmentation from your main operational wallet.

Creating Policies

Two policies must be configured in Fireblocks to ensure automated, safe signing of transactions:

Contract Call Policy

SettingValue
InitiatorThe API user created for calling Fireblocks strategy operations
SourceVault Owner
SignerCo-signer (for automatic signing)

2. Smart Wallet Creation

Each user receives their own segregated smart wallet. Smart wallets (Gnosis Safe accounts) can be provisioned via the API:
POST /fireblocks-smart-account
Request Body:
ParameterTypeRequiredDescription
ownerstringThe Vault address that will own the Gnosis Safe
chainIdnumberChain ID on which to deploy the Safe
Example Request:
curl --request POST \
  --url https://api.deframe.io/fireblocks-smart-account \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_API_KEY' \
  --data '{"owner": "0xYourVaultOwnerAddress", "chainId": 137}'
Example Response:
{
  "address": "0xDeployedSafeAddress",
  "owner": "0xYourVaultOwnerAddress",
  "chainId": 137
}
The Safe address is computed deterministically via CREATE2 and returned immediately. Actual on-chain deployment happens asynchronously in the background. If the Safe is already deployed, the existing address is returned.
Once provisioned, store the mapping between your internal user IDs and their smart wallet addresses:
userId → smartWalletAddress
This mapping enables you to:
  • Display user balances and yield
  • Track user performance
  • Execute operations on behalf of users

3. Deposit Flow

When a user wants to deposit into a strategy (e.g., 100 USDC):
1

Transfer Funds to Smart Wallet

Transfer the deposit amount from your Omnibus wallet to the user’s smartWalletAddress.
2

Request Strategy Bytecode

Fetch the bytecode for the deposit operation:
GET /strategies/:id/bytecode?action=lend&amount=100000000&wallet=0x...&output=fireblocks&accountId=YOUR_VAULT_ACCOUNT_ID
When using Fireblocks, set output=fireblocks and provide accountId (the Fireblocks vault account ID). The response will include a transactionData object ready to submit directly to the Fireblocks API instead of a raw bytecode array.See How to Deposit for detailed parameter information.
3

Sign and Execute via Fireblocks

  1. Use the Vault Owner signer (NOT the Omnibus signer) to sign the transaction
  2. If using output=fireblocks, the response contains a transactionData.transactionRequest object ready to submit directly to the Fireblocks Transactions API (POST /v1/transactions)
  3. If using output=bytecode (default), execute the returned bytecode through Fireblocks manually
  4. The transaction will deposit funds from the smart wallet into the strategy
Example: submitting the response to the Fireblocks SDK
import axios from 'axios'
import { BasePath, Fireblocks, TransactionOperation, TransferPeerPathType } from '@fireblocks/ts-sdk'

const fireblocks = new Fireblocks({
  apiKey: process.env.FIREBLOCKS_API_KEY,
  basePath: BasePath.US,
  secretKey: Buffer.from(process.env.FIREBLOCKS_SECRET_KEY, 'base64').toString('ascii')
})

const deframeResponse = await axios.get(
  'https://api.deframe.io/strategies/Aave-USDT-Polygon/bytecode',
  {
    params: {
      action: 'lend',
      amount: '100000000',
      wallet: '0xYourSmartWalletAddress',
      output: 'fireblocks',
      accountId: 'YOUR_VAULT_ACCOUNT_ID'
    },
    headers: {
      'x-api-key': process.env.DEFRAME_API_KEY
    }
  }
)
const transactionData = deframeResponse.data.transactionData

// Structure example
// const transactionData = {
//   transactionRequest: {
//     operation: TransactionOperation.ContractCall,
//     assetId: 'ETH',
//     source: {
//       type: TransferPeerPathType.VaultAccount,
//       id: '<vault_id>'
//     },
//     destination: {
//       type: TransferPeerPathType.OneTimeAddress,
//       oneTimeAddress: {
//         address: '<smart_wallet_address>'
//       }
//     },
//     amount: '0',
//     extraParameters: {
//       contractCallData: '<bytecode>'
//     },
//     failOnLowFee: true
//   }
// }

const contractCallTransaction = await fireblocks.transactions.createTransaction(transactionData)
console.debug('Transaction Result: ', contractCallTransaction.data)

4. View User Positions and Yield

To fetch a user’s position, balance, or yield:
GET /wallets/:smartWalletAddress
This endpoint provides all data needed for user-facing dashboards and reporting. See How to Check Open Positions for more details.

5. Withdrawal Flow

Withdrawals follow the reverse flow:
1

Request Withdrawal Bytecode

GET /strategies/:id/bytecode?action=withdraw&amount=100000000&wallet=0x...&output=fireblocks&accountId=YOUR_VAULT_ACCOUNT_ID
2

Sign and Execute

Sign and execute the transaction using the Vault Owner signer through Fireblocks.
3

Transfer Funds

After the withdrawal completes, transfer funds from the smart wallet to the destination:
  • Back to your Omnibus wallet, or
  • Any other target address

Trade-offs

Additional Transfers

Requires two separate transfers for deposits and withdrawals: Transfer IN (Omnibus to Smart Wallet) and Transfer OUT (Smart Wallet to destination)

Omnibus Isolation

Your Omnibus signer is never exposed to potentially malicious bytecode, preventing scenarios similar to known custody exploits

User Segregation

Each user operates through a fully segregated smart wallet

Auditability

Clean audit trail and easier accounting per user. Aggregated deposit analytics available via the /analytics endpoint

Optional: Additional Security Layer

For maximum security, you can integrate Blockaid to simulate and validate bytecode before signing it on Fireblocks.
This adds defense-in-depth by detecting unexpected contract behavior, malicious payloads, and incorrect calldata or parameters.

Next Steps

Deposit to Yield

Generate bytecode for depositing into yield positions

Withdraw

Learn how to withdraw from positions

Check Positions

Monitor your open yield positions

Privy Integration

Embedded wallet solution with social login