Transaction Signing Callback Handler
POST /v2/tx_sign_request
This request is used for transaction signing and approval and expects a CallbackResponse object from the callback handler. If the callback handler does not respond within 30 seconds, Fireblocks fails the request.
If both approval and signing are requested for a transaction, one callback handles both requests.
To differentiate whether this request is for signing, approving, or both signing and approving a transaction, these parameters are included only with transaction signing requests:
fee
displayDstAddress
within the transaction's destinations array
Request parameters
Parameter | Type | Description |
---|---|---|
txId | string | The transaction's internal ID in Fireblocks. |
operation | string | The transaction operation type. The default is TRANSFER . |
sourceType | string | The source of the transaction. |
sourceId | string | The transaction’s source vault account ID or exchange account UUID. |
destType | string | The transaction's destination type. The type can be VAULT, EXCHANGE, or UNMANAGED. |
destId | string | The destination's vault account ID or exchange account UUID. |
asset | string | The asset ID in Fireblocks. |
amount (Deprecated) | number | Please use the amountStr field for accuracy. (If the transfer is a withdrawal from an exchange, the actual transfer amount. Otherwise, the requested amount.) |
amountStr | string | The amount of the transfer in string format. |
requestedAmount (Deprecated) | number | Please use the requestedAmountStr field for accuracy. (The requested transfer amount. In gross transactions, transaction fees are deducted from this amount.) |
requestedAmountStr | string | The requested transfer amount in string format. In gross transactions, transaction fees are deducted from this amount. |
fee | string | (Optional) The transaction's estimated fee. |
destAddressType | string | The destination's address type. For one-time addresses on EVM-compatible blockchains, this is the smart contract address. |
destAddress | string | The destination address of the transaction. |
destinations | array | An array of TransactionRequestCallbackDestination objects with all details for all destination(s). |
players | array (string) | A list of the Co-Signers that signed the transaction. (Two Fireblocks SaaS and at least one user device or one API Co-Signer). Each signer is represented by a Device ID. |
requestId | string | A unique identifier of this request; is returned in the response. |
signerId | string | The user that signed the transaction. |
extraParameters | object | (Optional) Parameters that are specific to some transaction operation types and blockchain networks. Learn more below. |
note | string | (Optional) Custom note that describes this transaction in your Fireblocks workspace. The note isn’t sent to the blockchain. |
rawTx | array | An array of RawTX. Contains a list of the actual transactions sent to the blockchain. Note that some signing requests represent multiple transactions. When this occurs, the list contains more than one object. Additionally, this parameter is not included in the CallbackResponse object when using a Fireblocks EU cloud environment. |
action (deprecated) | object | Includes information about the transaction authorization policy rule that matched this transaction. This field and its contents are not officially supported or maintained. Fireblocks may delete or change the contents of this field at any time. |
TransactionOperation
Parameter | Type | Description |
---|---|---|
operation | string | [TRANSFER , MINT , BURN , CONTRACT_CALL , TYPED_MESSAGE , RAW , ENABLE_ASSET , STAKE , UNSTAKE , WITHDRAW ]Not all operations are available in all workspaces. Contact your account manager to enable additional features. TRANSFER - Default. Transfers funds from one account to another. UTXO blockchains allow multi-input and multi-output transfers. All other blockchains allow transfers with one source address and one destination address.MINT - Mints new tokens. Supported for Stellar, Ripple, and EVM-based blockchains.BURN - Burns tokens. Supported for Stellar, Ripple, and EVM-based blockchains.CONTRACT_CALL - Calls a smart contract method for web3 operations on any EVM blockchain. The Fireblocks development libraries are recommended for building contract call transactions.TYPED_MESSAGE - An off-chain message in either Ethereum Personal Message or EIP712 format. Use it to sign specific readable messages that are not actual transactions. Learn more about typed messages.RAW - An off-chain message with no predefined format. Use it to sign any message with your private key, including protocols such as blockchains and custom transaction types that are not natively supported by Fireblocks. Learn more about raw signing transactions.ENABLE_ASSET - Algorand, DigitalBits, Solana, and Stellar require an on-chain transaction to create an asset wallet and enable the deposit address. This transaction is automatically created when adding assets on these blockchains to a vault account.STAKE - Assign assets to a staking pool managed by a staking validator. Learn more about staking transactions and supported blockchains. This transaction is automatically created when performing staking operations.UNSTAKE - Remove assets from a staking pool managed by a staking validator. Learn more about staking transactions and supported blockchains. This transaction is automatically created when performing staking operations.WITHDRAW - Transfer assets from a dedicated staking vault account to another address. Learn more about staking transactions and supported blockchains. This transaction is automatically created when performing staking operations.Note: Fireblocks will rename this type from WITHDRAW to a different name soon. There will be at minimum a 7-day notice regarding the new type name. |
TransactionRequestCallbackDestination
Parameter | Type | Description |
---|---|---|
amountNative | string | Deprecated. The amount transferred to this destination as a number. Use the amountNativeStr parameter for accurate precision. |
amountNativeStr | number | The amount transferred to this destination represented as a string. |
amountUSD | number | The USD value of the transfer to this destination. |
dstAddressType | WHITELISTED or ONE_TIME | WHITELISTED or ONE_TIME |
dstId | string | The ID of the destination. |
dstName | string | The name of the destination. |
dstSubType | string | The specific exchange, fiat account, or unmanaged wallet. For exchange accounts: ( BINANCE , BINANCEUS , BITFINEX , BITHUMB , BITMEX , BITSO , BITSTAMP , BITTREX , BYBIT , CIRCLE , COINBASEEXCHANGE , COINBASEPRO , COINMETRO , COINSPRO , CRYPTOCOM , DERIBIT , GEMINI , HITBTC , HUOBI , INDEPENDENTRESERVE , KORBIT , KRAKEN , KRAKENINTL , KUCOIN , LIQUID , OKCOIN , OKEX , PAXOS , POLONIEX )For fiat accounts: ( BLINC )For unmanaged wallets: ( INTERNAL , EXTERNAL , or CONTRACT ) |
dstType | string | The destination of the transaction (VAULT , EXCHANGE_ACCOUNT , FIAT_ACCOUNT , or UNMANAGED ). |
displayDstAddress | string | The address of this specific destination |
action | string | Includes information about the Transaction Authorization Policy rule that matched this transaction. |
TransactionExtraParameters
Parameter | Type | Description |
---|---|---|
inputsSelection | InputsSelection object | For UTXO-based blockchain multi-input selection, use the inputsSelection field with values set to the input selection structure. The inputs can be retrieved using the Retrieve Unspent Inputs endpoint. |
rawMessageData | RawMessageData object | For RAW operations, use the rawMessageData field with the values set to the raw message data structure. Only included with raw signing transactions on Bitcoin and Ethereum.This is an opt-in feature. Please contact Fireblocks Support to include this feature in your workspace. |
contractCallData | string | For CONTRACT_CALL operations, use the contractCallData field with the value set to the Ethereum smart contract Application Binary Interface (ABI) payload. The Fireblocks development libraries are recommended for building contract call transactions |
RawTX
Parameter | Type | Description |
---|---|---|
rawTx | string | Hex-encoded details of a transaction sent to the blockchain |
keyDerivationPath | Array of numbers | Location of the encryption key within the customer’s HD Wallet URL used to sign this transaction. |
Checkout API Co-Signer Callback Handler examples:
API Co-Signer callback code example
const express = require("express");
const bodyParser = require("body-parser");
const fs = require("fs");
const jwt = require("jsonwebtoken");
const privateKey = fs.readFileSync("callback_private.pem");
const cosignerPubKey = fs.readFileSync("cosigner_public.pem");
const app = express();
app.use(
express.urlencoded({
extended: true
})
);
app.use(express.json());
app.use(function (req) {
req.rawBody = "";
req.setEncoding("utf8");
req.on("data", function(chunk) {
req.rawBody += chunk;
});
req.on("end", function () {
req.next();
});
});
app.post("/v2/tx_sign_request", async (req, res) => {
let verified;
try {
const tx = jwt.decode(req.rawBody);
const { requestId } = tx;
verified = jwt.verify(req.rawBody, cosignerPubKey);
if (verified) {
let action = "REJECT";
let rejectionReason = "Logic returned false";
const signedRes = jwt.sign(
{
action,
requestId,
rejectionReason
},
privateKey,
{ algorithm: "RS256" }
);
res.send(signedRes);
}
} catch (e) {
res.sendStatus(401);
}
});
app.listen(3000);
from pathlib import Path
from wsgiref.simple_server import make_server
import falcon
import jwt
callback_handler_prikey = None
cosigner_pubkey = None
# Load keys.
f1 = Path("callback_private.pem")
if f1.is_file(): callback_handler_prikey = f1.read_bytes()
f2 = Path("cosigner_public.pem")
if f2.is_file(): cosigner_pubkey = f2.read_bytes()
class JWTTransferRequest(object):
def on_post(self, req, resp):
raw_req = req.bounded_stream.read()
req = jwt.decode(raw_req, cosigner_pubkey, algorithms=["RS256"])
resp.body = jwt.encode({'action': 'APPROVE', 'requestId': req['requestId']}, callback_handler_prikey, algorithm="RS256")
resp.status = falcon.HTTP_200
# Create falcon app
app = falcon.App()
app.add_route('/v2/tx_sign_request', JWTTransferRequest())
app.add_route('/v2/config_change_sign_request', JWTTransferRequest())
if __name__ == '__main__':
with make_server('', 80, app) as httpd:
print('Serving on port 80...')
# Serve until process is killed
httpd.serve_forever()
JWTTransferRequest()