Swap via Direct Access Providers (DeFi)
Beta FeatureThe Trading API is currently in beta and subject to change. For participation details, contact your Fireblocks Customer Success Manager or email [email protected].
This guide provides a step-by-step example of how to execute a swap using the Fireblocks Trading API via direct access providers, such as Uniswap. A swap is the process of exchanging one cryptocurrency for another on the same network. The guide demonstrates swapping ETH for USDC on Ethereum using Uniswap as the direct access provider.
Prerequisites
Before you begin, ensure you have completed the prerequisites outlined in the Trading API Overview:
- ✅ Fireblocks API credentials configured
- ✅ Vault accounts with sufficient assets
- ✅ Fireblocks TypeScript SDK installed (
@fireblocks/[email protected])
SDK Setup
First, set up your Fireblocks SDK client:
import { Fireblocks } from "@fireblocks/ts-sdk";
import * as fs from "fs";
// Initialize the Fireblocks SDK
const fireblocks = new Fireblocks({
apiKey: "your-api-key",
secretKey: fs.readFileSync("/path/to/your/secret.key", "utf8"),
basePath: "https://api.fireblocks.io"
});Swap Flow Overview
The following steps outline the process for executing a swap via direct access providers:
1. List Providers
2. Approve Terms (executed once per workspace and ONLY via the Fireblocks console)
3. Create Quote
4. Execute Order
5. Monitor Order
Step 1: List Available Providers
Before trading, retrieve the list of available providers and use the response to identify the id of your desired provider.
API Call
// List all available trading providers
const response = await fireblocks.trading.getTradingProviders({
pageSize: 20
});
// Filter for direct access providers only (accountBased: false)
const directAccessProviders = response.data.data.filter(
provider => !provider.accountBased
);Response Example
{
"data": [
{
"id": "UNISWAP_CLASSIC",
"name": "Uniswap Classic",
"logo": "https://example.com/logos/uniswap.png",
"accountBased": false,
"approved": false,
"hasTermsOfService": true,
"termsOfServiceUrl": "https://uniswap.org/terms"
}
],
"total": 1,
"next": null
}Key Fields Explained
| Field | Description |
|---|---|
id | Unique identifier for the provider (use this in subsequent API calls) |
name | Display name of the trading platform |
accountBased | false for direct access providers, true for account-based providers |
hasTermsOfService | Whether the provider requires Terms of Service approval |
termsOfServiceUrl | URL to review the Terms of Service |
approved | For direct access providers: indicates if Terms of Service have been approved |
Direct access providers may require one-time Terms of Service approval. The fields hasTermsOfService and approved indicate whether approval is required and whether your workspace already approved it. Approval must be done once per workspace via the Fireblocks Console.
For more details about this endpoint, see the Get Providers API Reference.
Step 2: Approve Terms of Service (Direct Access Providers Only)
Direct access providers require one-time Terms of Service approval before trading. Approval must be done in the Fireblocks Console (not available via SDK).
Check Approval Status
// Get provider details to check approval status
const providers = await fireblocks.trading.getTradingProviders({ pageSize: 20 });
const provider = providers.data.data.find(p => p.id === "UNISWAP_CLASSIC");
if (provider.hasTermsOfService && !provider.approved) {
throw new Error("Approve Terms of Service in Fireblocks Console before proceeding");
}Step 3: Create a Quote for the Swap
Creating a quote is required before executing a swap via direct access providers. A quote provides you with the exact exchange rate, expected amounts, fees, and price impact for the swap.
API Call
// Create a quote for swapping ETH to USDC on Ethereum with Uniswap
const response = await fireblocks.trading.createQuote({
createQuote: {
scope: [{ providerId: "UNISWAP_CLASSIC" }], // Direct access provider (no accountId)
baseAssetId: "ETH", // Asset you're selling
quoteAssetId: "USDC", // Asset you're receiving
baseAmount: "0.5", // Amount of ETH to sell
side: "SELL",
slippageBps: 50, // Optional - Defaults to 50 BPS (0.5%). Use BPS units, not decimals (e.g., 100 = 1%)
settlement: { // Required for direct access provider quotes
type: "DVP",
sourceAccount: { type: "VAULT_ACCOUNT", id: "0" },
destinationAccount: { type: "VAULT_ACCOUNT", id: "0" }
}
},
idempotencyKey: `quote-${Date.now()}`
});
const quote = response.data.quotes[0];Quote Response Example
{
"quotes": [
{
"id": "quote_8f2e4d1a9c5b7e3f",
"via": {
"type": "PROVIDER",
"providerId": "UNISWAP_CLASSIC"
},
"type": "COMMITTED",
"baseAssetId": "ETH",
"quoteAssetId": "USDC",
"baseAmount": "0.5",
"quoteAmount": "1247.50",
"quoteMinAmount": "1241.25",
"priceImpact": 0.005,
"expiresAt": "2024-01-15T10:35:00.000Z",
"generalFees": [
{
"feeType": "NETWORK",
"assetId": "ETH",
"amountType": "FIXED",
"amount": "0.01"
}
],
"executionSteps": [
{
"type": "APPROVE",
"fee": {
"feeType": "NETWORK",
"assetId": "ETH",
"amountType": "FIXED",
"amount": "0.005"
}
},
{
"type": "CONTRACT_CALL",
"fee": {
"feeType": "NETWORK",
"assetId": "ETH",
"amountType": "FIXED",
"amount": "0.005"
}
}
]
}
]
}Understanding Quote Fields
| Field | Description |
|---|---|
id | Unique quote identifier (use when creating order) |
type | Quote type: COMMITTED - the provider commits to the quote rates (guaranteed execution at the quoted price with respect to slippage boundaries), INDICATIVE - an indication of expected prices (rates may vary at execution time) |
baseAmount | Amount you're spending/selling |
quoteAmount | Expected amount you'll receive |
quoteMinAmount | Minimum amount guaranteed (accounting for slippage) |
priceImpact | Deviation from market price and execution price due to trade size or limited liquidity (as a decimal, e.g., 0.005 = 0.5%). A high price impact means your transaction will result in a substantial loss of funds |
expiresAt | Quote expiration time (typically 1-5 minutes) |
generalFees | Provider fees for the trade |
executionSteps | Array of steps required to complete the trade, each containing a type field that can be APPROVE (token approval), PERMIT (permit signature), CONTRACT_CALL (smart contract interaction), EXECUTE (main swap execution), SETTLEMENT (settling funds), or DELIVERY (delivering assets). Each step may include associated fees |
Note: Quotes expire quickly (typically within 1-5 minutes). Create your order promptly after receiving a quote.
For more details about this endpoint, see the Create Quote API Reference.
Step 4: Execute the Swap Order
Once you have a quote, execute the swap using that quote. Direct access providers like Uniswap require a quote to ensure you get the expected rate and protection against price slippage.
Execute Order with Quote
// Execute swap order using the quote from Step 3
const response = await fireblocks.trading.createOrder({
createOrderRequest: {
via: {
type: "PROVIDER", // For direct access providers like Uniswap
providerId: "UNISWAP_CLASSIC"
},
executionRequestDetails: {
type: "QUOTE",
quoteId: quote.id // Use the quote ID from Step 3
},
settlement: {
type: "DVP",
sourceAccount: { type: "VAULT_ACCOUNT", id: "0" },
destinationAccount: { type: "VAULT_ACCOUNT", id: "0" }
} // Direct access swaps always settle via DVP and always require specifying both source and destination vault accounts.
},
idempotencyKey: `order-${Date.now()}`
});
const order = response.data;Why direct access providers require quotes: Unlike some account-based providers, direct access providers (like Uniswap) through Fireblocks require creating a quote first. This ensures you know the exact exchange rate, fees, and slippage protection before the transaction executes on-chain.
For more details about this endpoint, see the Create Order API Reference.
Step 5: Monitor Order Status
After creating an order, monitor its execution status to track completion.
Get Order Details
// Get order status and details
const response = await fireblocks.trading.getOrder({
orderId: "order_id_here"
});
const order = response.data;
// Check: order.status, order.executionSteps, order.createdAt, etc.
For more details about this endpoint, see the Get Order Details API Reference.
List All Orders
// List orders with optional filters
const response = await fireblocks.trading.getOrders({
pageSize: 20,
order: "ASC", // order by createdAt
providerId: ["UNISWAP_CLASSIC"], // Optional filter
statuses: ["COMPLETED"] // Optional filter
});
const orders = response.data.data;
For more details about this endpoint, see the Get Orders (List) API Reference.
Order Status Values
| Status | Description |
|---|---|
CREATED | Order has been created and is being processed |
AWAITING_PAYMENT | Waiting for payment to be received |
PENDING_USER_ACTION | Requires user action (e.g., approval in console) |
PROCESSING | Order is being executed |
COMPLETED | Order has been successfully completed |
FAILED | Order execution failed |
CANCELED | Order was canceled |
Additional Resources
- Trading API Overview
- On-Ramp, Off-Ramp, and Bridge/Swap via Account-Based Providers (CeFi) - For on-ramp, off-ramp, and other account-based provider use cases
- Fireblocks SDKs: Python | TypeScript | Java
- Fireblocks Developer Portal
Support
For questions or issues with the Trading API:
- Contact your Fireblocks Customer Success Manager
- Email: [email protected]
- Check the Fireblocks Developer Portal for updates
Updated about 23 hours ago