Skip to main content

Subscription

This guide explains how to manage subscriptions for your custom contract to cover blocklock request fees for your users.

Overview

The subscription system allows you to pre-fund a subscription account that will automatically cover the request fees for all blocklock requests made through your custom YourBlocklockReceiver contract. This eliminates the need for users to pay for each request individually.

If your contract extends AbstractBlocklockReceiver, it automatically inherits all subscription-related functionality. You don't need to implement any additional code to use the subscription system. The inherited functions include:

  • Creating and funding a new dcipher subscription using native tokens (e.g., ETH, FIL)
  • Topping up the dcipher subscription using native tokens
  • Adding a list of consumer addresses to the dcipher subscription
  • Canceling an existing dcipher subscription
note

Multiple contracts (consumers) can be added under a single subscription account and share the same balance.

Guides

AbstractBlocklockReceiver implements the following functions to manage the dcipher subscription for blocklock requests. These functions can only be called by the smart contract owner.

Once you implement and deploy your YourBlocklockReceiver contract, you can manage the dcipher blocklock subscription by calling the corresponding functions.

1. Create and Fund a New Subscription

You can call this function from your deployed YourBlocklockReceiver contract and attach native tokens as subscription funds.

/// @notice Creates and funds a new dcipher subscription using native currency.
function createSubscriptionAndFundNative() external payable virtual onlyOwner {
subscriptionId = _subscribe();
blocklock.fundSubscriptionWithNative{value: msg.value}(subscriptionId);
}

2. Fund Your Subscription

If you have already created a subscription for your customized contract, you can call this function to top up the subscription.

/// @notice Tops up the dcipher subscription using native currency (e.g., ETH).
/// @dev The amount to top up should be sent along with the transaction as `msg.value`.
function topUpSubscriptionNative() external payable virtual {
require(subscriptionId != 0, "sub not set");
blocklock.fundSubscriptionWithNative{value: msg.value}(subscriptionId);
}

3. Add Consumer Addresses to the Subscription

Since multiple contracts (consumers) can be added under a single subscription account and share the same balance, your customized contract also includes the following function to add more consumer contract addresses.

/// @notice Adds a list of consumer addresses to the dcipher subscription.
/// @dev Requires the subscription ID to be set before calling.
/// @param consumers An array of addresses to be added as authorized consumers.
function updateSubscription(address[] calldata consumers) external virtual onlyOwner {
require(subscriptionId != 0, "subID not set");
for (uint256 i = 0; i < consumers.length; i++) {
blocklock.addConsumer(subscriptionId, consumers[i]);
}
}

4. Cancel the Subscription

There is an internal helper function that cancels the subscription and returns unused funds to a recipient address. You can implement a function in your customized contract to provide the subscription cancellation feature.

/// @notice Cancels an existing dcipher subscription if one exists.
/// @dev Internal helper that cancels the subscription.
/// @param to The recipient address that will receive the subscription balance.
function _cancelSubscription(address to) internal virtual {
require(subscriptionId != 0, "SubscriptionId is zero");
blocklock.cancelSubscription(subscriptionId, to);
}

Best Practices

  1. Balance Management

    • Monitor your subscription balance regularly
    • Set up alerts for low balance
    • Estimate required funds based on expected request volume
  2. Security

    • Only link trusted contracts to your subscription
    • Regularly audit authorized consumers
    • Use separate subscriptions for different environments (testnet/mainnet)