Skip to main content

Billing

This page explains how billing works for on-chain requests (e.g. conditional encryption) made via the dcipher network, including gas cost calculations, funding options, configuration examples, and request cost estimation.

Funding Options

Option 1: Direct Contract Funding

Alternatively, you can fund your smart contract directly with native tokens.

  • No subscription account needed.
  • Your contract must manage its own balance.
  • Request costs are deducted directly from your contract's or wallet's balance when making a request.

Option 2: Subscription-Based Funding

To make requests, create and fund a subscription account and register your contract as an allowed consumer under a subscriptionId.

  • Funds are pooled under a shared subscription.
  • Multiple contracts (consumers) can be added under a single subscription account and share the same balance.
  • Request costs are deducted from the subscription when the request is being fulfilled.

️ Example Billing Configuration

MAX_GAS_LIMIT                     = 500_000     # Max gas allowed per callback
GAS_AFTER_PAYMENT_CALCULATION = 400_000 # Protocol post-callback processing
FULFILLMENT_FLAT_FEE_NATIVE_PPM = 100_000 # Fee in PPM (parts per million of 1 ether; e.g., 0.1 Ether or 10% = 100_000 PPM). To derive the fee in Wei from PPM = 1e12 * fee in PPM
WEI_PER_UNIT_GAS = 3_000_000 # Default gas price in wei (0.000003 ETH)
BLS_PAIRING_CHECK_OVERHEAD = 800_000 # Signature verification overhead
NATIVE_PREMIUM_PERCENTAGE = 10 # 10% premium on base gas cost
GAS_FOR_CALL_EXACT_CHECK = 5_000 # Additional safety check overhead to ensure that a
# user-specified callback gas limit is sufficient for
# executing the callback

The current configuration values for each supported network can be retrieved by calling the getConfig() function in BlocklockSender (for conditional encryption requests) or RandomnessSender (for randomness requests) contract:

function getConfig()
external
view
returns (
uint32 maxGasLimit,
uint32 gasAfterPaymentCalculation,
uint32 fulfillmentFlatFeeNativePPM,
uint32 weiPerUnitGas,
uint32 blsPairingCheckOverhead,
uint8 nativePremiumPercentage,
uint32 gasForCallExactCheck
);

️ How Billing Works

Cost Formula

totalCost = ((baseFeeWei + l1CostWei) * (100 + nativePremiumPercentage) / 100) + flatFeeWei;

Base Fee Calculation

baseFeeWei = gasPrice * (
gasAfterPaymentCalculation + callbackGasLimit + blsPairingCheckOverhead + eip150Overhead
)

Where:

  • callbackGasLimit: Gas used by your callback logic.
  • gasPrice: Current gas price or manually set in the request.
  • gasAfterPaymentCalculation: Internal overhead for post-callback processing.
  • blsPairingCheckOverhead: Cost of on-chain cryptographic signature verification.
  • eip150Overhead: Extra gas reserved due to satisfy EIP-150, which limits how much gas can be forwarded in a call. This ensures contracts can complete clean-up operations after internal calls.
  • l1CostWei: Additional L1 calldata publishing cost (applicable to L2s).
  • flatFeeWei: Fixed fee in wei based on PPM.
  • nativePremiumPercentage: Premium markup on total cost (e.g., 10%).
note

EIP-150 is an Ethereum upgrade that limits how much gas can be forwarded in internal calls to 63/64 of the remaining gas.

This was introduced to prevent denial-of-service (DoS) attacks by ensuring that contracts always retain a small amount of gas after making a call, allowing them to clean up or revert safely.

Estimating Request Cost

You can estimate the total request cost (in wei) before sending a transaction using the following view function:

/// @notice Calculates the total request price in native tokens, considering the provided callback gas limit and the current gas price
/// @param _callbackGasLimit The gas limit allocated for the callback execution
/// @return The total price for the request in native tokens (wei)
/// @dev This function calls the internal `_calculateRequestPriceNative` function, passing in the provided callback gas limit and the current
/// transaction gas price (`tx.gasprice`) to calculate the total request price. It overrides the function from both `BlocklockFeeCollector`
/// and `IBlocklockSender` contracts to provide the request price calculation.
function calculateRequestPriceNative(uint32 _callbackGasLimit)
public
view
override (BlocklockFeeCollector, IBlocklockSender)
returns (uint256)

Parameters

  • _callbackGasLimit: The max gas you expect your callback to use.

Returns

  • Estimated total cost in wei, including all overheads, premium, and flat fee.
note

This is only an estimate. Actual billing depends on execution gas used and the gas price at the time of fulfillment.

Add some buffer to the estimated cost to account for network gas price fluctuations and/or congestion between blocks.

Example (Ethers.js)

const estimatedCost = await contract.calculateRequestPriceNative(200000);
console.log(`Estimated cost (wei): ${estimatedCost.toString()}`);

Billing Flow Summary

  1. User sends a request with callbackGasLimit.
  2. Estimated gas usage: Includes callbackGasLimit, blsPairingCheckOverhead, gasAfterPaymentCalculation, and eip150Overhead.
  3. Gas price is either set by the user or pulled from the current network state.
  4. Total cost is calculated using the billing formula.
  5. Deduction:
    • From a subscription balance, if using a subscription.
    • From the contract balance, if using direct funding.

Billing Breakdown

ComponentDescription
Gas priceCurrent network gas price or user-supplied
Callback gasGas used by your callback logic
Verification gasOverhead for cryptographic signature verification (e.g., BLS pairing)
EIP-150 OverheadExtra gas held back for call safety margins
gasAfterPaymentCalculationGas used by the protocol after fulfilling the request
nativePremiumPercentageMarkup percentage (e.g., 10%) applied to total base cost
flatFeeWeiFixed flat fee based on fulfillmentFlatFeeNativePPM
l1CostWeiAdditional L1 data publishing fee (used on L2s like Arbitrum, Optimism)

️ Recommendations

  • Overestimate your callbackGasLimit slightly to avoid out-of-gas errors.
  • Use calculateRequestPriceNative to estimate cost ahead of time.
  • Monitor your balances regularly—subscription or contract—depending on your funding model.
  • Maintain a buffer to absorb gas price spikes and avoid request failures.

Additional Notes

  • For subscription-based requests, the final fee is only known after the request is fulfilled.
  • If the subscription balance is insufficient, the callback will fail or be delayed.