| title | IBlueprintServiceManager |
|---|---|
| description | Auto-generated Solidity API reference. |
Source: https://github.com/tangle-network/tnt-core/blob/main/src/interfaces/IBlueprintServiceManager.sol
Full interface for blueprint-specific service managers
_Blueprint developers implement this to customize all aspects of their blueprint. This is the primary integration point for blueprint developers - implement the hooks you need and leave others as default (via BlueprintServiceManagerBase).
The lifecycle flow:
- Blueprint created → onBlueprintCreated
- Operators register → onRegister
- Service requested → onRequest
- Operators approve → onApprove
- Service activated → onServiceInitialized
- Jobs submitted → onJobCall
- Results submitted → onJobResult
- Service terminated → onServiceTermination_
function onBlueprintCreated(uint64 blueprintId, address owner, address tangleCore) externalCalled when blueprint is created
Store the blueprintId and tangleCore address for future reference
| Name | Type | Description |
|---|---|---|
| blueprintId | uint64 | The new blueprint ID |
| owner | address | The blueprint owner |
| tangleCore | address | The address of the Tangle core contract |
function onRegister(address operator, bytes registrationInputs) external payableCalled when an operator registers to this blueprint
Validate operator requirements here (stake, reputation, etc.)
| Name | Type | Description |
|---|---|---|
| operator | address | The operator's address |
| registrationInputs | bytes | Custom registration data (blueprint-specific encoding) |
function onUnregister(address operator) externalCalled when an operator unregisters from this blueprint
| Name | Type | Description |
|---|---|---|
| operator | address | The operator's address |
function onUpdatePreferences(address operator, bytes newPreferences) external payableCalled when an operator updates their preferences (RPC address, etc.)
| Name | Type | Description |
|---|---|---|
| operator | address | The operator's address |
| newPreferences | bytes | Updated preferences data |
function getHeartbeatInterval(uint64 serviceId) external view returns (bool useDefault, uint64 interval)Get the heartbeat interval for a service
Operators must submit heartbeats within this interval
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use protocol default, false to use custom value |
| interval | uint64 | Heartbeat interval in blocks (0 = disabled) |
function getHeartbeatThreshold(uint64 serviceId) external view returns (bool useDefault, uint8 threshold)Get the heartbeat threshold for a service
Percentage of operators that must respond within interval
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use protocol default |
| threshold | uint8 | Threshold percentage (0-100) |
function getSlashingWindow(uint64 serviceId) external view returns (bool useDefault, uint64 window)Get the slashing window for a service
Time window for disputes before slash is finalized
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use protocol default |
| window | uint64 | Slashing window in blocks |
function getExitConfig(uint64 serviceId) external view returns (bool useDefault, uint64 minCommitmentDuration, uint64 exitQueueDuration, bool forceExitAllowed)Get the exit configuration for operator departures
Defines minimum commitment and exit queue timing
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use protocol default |
| minCommitmentDuration | uint64 | Minimum time operator must stay after joining (seconds) |
| exitQueueDuration | uint64 | Time between scheduling exit and completing it (seconds) |
| forceExitAllowed | bool | Whether service owner can force-exit operators |
function getNonPaymentTerminationPolicy(uint64 serviceId) external view returns (bool useDefault, uint64 graceIntervals)Get the non-payment termination policy for subscription services.
Core computes eligibility as
lastPaymentAt + subscriptionInterval + (subscriptionInterval * graceIntervals).
graceIntervals = 0 means termination is eligible immediately at the first missed
billing tick. Implementations should return useDefault = true unless they need
custom grace behavior. Default implementation in BlueprintServiceManagerBase returns
(true, 0).
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use the protocol default policy |
| graceIntervals | uint64 | Additional full intervals to wait after the first missed payment |
function forceRemoveAllowsBelowMin(uint64 serviceId) external view returns (bool ok)Whether forceRemoveOperator may drop the service below minOperators.
By default the protocol enforces operatorCount > minOperators even when a blueprint
manager calls forceRemoveOperator. A blueprint that genuinely needs
emergency-eviction-below-min must self-document by returning true. Reverting or
unimplemented => the protocol enforces the floor (fail-closed). The default
implementation in BlueprintServiceManagerBase returns false; custom managers that
do not inherit BlueprintServiceManagerBase MUST implement this hook explicitly
or forceRemoveOperator will revert as soon as the eviction would push the operator
count below minOperators.
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| ok | bool | True to allow eviction below the minimum operator count |
function onRequest(uint64 requestId, address requester, address[] operators, bytes requestInputs, uint64 ttl, address paymentAsset, uint256 paymentAmount) external payableCalled when a service is requested
Validate service configuration, operator selection, payment amount
| Name | Type | Description |
|---|---|---|
| requestId | uint64 | The request ID |
| requester | address | Who is requesting the service |
| operators | address[] | Requested operators |
| requestInputs | bytes | Service configuration (blueprint-specific encoding) |
| ttl | uint64 | Time-to-live for the service |
| paymentAsset | address | Payment token address (address(0) for native) |
| paymentAmount | uint256 | Payment amount |
function onApprove(address operator, uint64 requestId, uint8 stakingPercent) external payableCalled when an operator approves a service request
| Name | Type | Description |
|---|---|---|
| operator | address | The approving operator |
| requestId | uint64 | The request ID |
| stakingPercent | uint8 | Percentage of stake committed to this service (0-100) |
function onReject(address operator, uint64 requestId) externalCalled when an operator rejects a service request
| Name | Type | Description |
|---|---|---|
| operator | address | The rejecting operator |
| requestId | uint64 | The request ID |
function onServiceInitialized(uint64 blueprintId, uint64 requestId, uint64 serviceId, address owner, address[] permittedCallers, uint64 ttl) externalCalled when service becomes active (all operators approved)
| Name | Type | Description |
|---|---|---|
| blueprintId | uint64 | The blueprint ID |
| requestId | uint64 | The original request ID |
| serviceId | uint64 | The new service ID |
| owner | address | The service owner |
| permittedCallers | address[] | Addresses allowed to submit jobs |
| ttl | uint64 | Service time-to-live |
function onServiceTermination(uint64 serviceId, address owner) externalCalled when service is terminated
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| owner | address | The service owner |
function canJoin(uint64 serviceId, address operator) external view returns (bool allowed)Check if an operator can join a dynamic service
Called before operator joins - return false to reject
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator wanting to join |
| Name | Type | Description |
|---|---|---|
| allowed | bool | True if operator can join |
function onOperatorJoined(uint64 serviceId, address operator, uint16 exposureBps) externalCalled after an operator successfully joins a service
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator that joined |
| exposureBps | uint16 | The operator's stake exposure in basis points |
function canLeave(uint64 serviceId, address operator) external view returns (bool allowed)Check if an operator can leave a dynamic service
Called before operator leaves - return false to reject Note: This is called AFTER the exit queue check. Use getExitConfig to customize timing.
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator wanting to leave |
| Name | Type | Description |
|---|---|---|
| allowed | bool | True if operator can leave |
function onOperatorLeft(uint64 serviceId, address operator) externalCalled after an operator successfully leaves a service
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator that left |
function onExitScheduled(uint64 serviceId, address operator, uint64 executeAfter) externalCalled when an operator schedules their exit from a service
Allows manager to track pending exits, notify other parties, etc.
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator scheduling exit |
| executeAfter | uint64 | Timestamp when exit can be executed |
function onExitCanceled(uint64 serviceId, address operator) externalCalled when an operator cancels their scheduled exit
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| operator | address | The operator canceling exit |
function onJobCall(uint64 serviceId, uint8 job, uint64 jobCallId, bytes inputs) external payableCalled when a job is submitted
Validate job inputs, check caller permissions, etc.
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| job | uint8 | The job index in the blueprint |
| jobCallId | uint64 | Unique ID for this job call |
| inputs | bytes | Job inputs (blueprint-specific encoding) |
function onJobResult(uint64 serviceId, uint8 job, uint64 jobCallId, address operator, bytes inputs, bytes outputs) external payableCalled when an operator submits a job result
Validate result format, check operator eligibility, aggregate results
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| job | uint8 | The job index |
| jobCallId | uint64 | The job call ID |
| operator | address | The operator submitting |
| inputs | bytes | Original job inputs |
| outputs | bytes | Result outputs (blueprint-specific encoding) |
function onUnappliedSlash(uint64 serviceId, bytes offender, uint8 slashPercent) externalCalled when a slash is queued but not yet applied
This is the dispute window - gather evidence, notify parties
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| offender | bytes | The operator being slashed (encoded as bytes for flexibility) |
| slashPercent | uint8 | Percentage of stake to slash |
function onSlash(uint64 serviceId, bytes offender, uint8 slashPercent) externalCalled when a slash is finalized and applied
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| offender | bytes | The slashed operator |
| slashPercent | uint8 | Percentage slashed |
function querySlashingOrigin(uint64 serviceId) external view returns (address slashingOrigin)Query the account authorized to propose slashes for a service
Override to allow custom slashing authorities (dispute contracts, etc.)
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| slashingOrigin | address | Address that can slash (default: this contract) |
function queryDisputeOrigin(uint64 serviceId) external view returns (address disputeOrigin)Query the account authorized to dispute slashes
Override to allow custom dispute resolution
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| disputeOrigin | address | Address that can dispute (default: this contract) |
function queryDeveloperPaymentAddress(uint64 serviceId) external view returns (address payable developerPaymentAddress)Get the developer payment address for a service
Override to route payments to different addresses per service
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| Name | Type | Description |
|---|---|---|
| developerPaymentAddress | address payable | Address to receive developer share |
function queryIsPaymentAssetAllowed(uint64 serviceId, address asset) external view returns (bool isAllowed)Check if a payment asset is allowed for this blueprint
serviceId acts as the payment-policy context ID. In current core semantics, this check is strict/fail-closed: if a manager returns false for a context, the asset is denied for that context, and missing/reverting manager queries are treated as denied.
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| asset | address | The payment asset address (address(0) for native) |
| Name | Type | Description |
|---|---|---|
| isAllowed | bool | True if the asset can be used for payment |
function getRequiredResultCount(uint64 serviceId, uint8 jobIndex) external view returns (uint32 required)Get the number of results required to complete a job
Override for consensus requirements (e.g., 2/3 majority)
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| jobIndex | uint8 | The job index |
| Name | Type | Description |
|---|---|---|
| required | uint32 | Number of results needed (0 = service operator count) |
function requiresAggregation(uint64 serviceId, uint8 jobIndex) external view returns (bool required)Check if a job requires BLS aggregated results
When true, operators must submit individual signatures that are aggregated off-chain, then submitted via submitAggregatedResult instead of submitResult
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| jobIndex | uint8 | The job index |
| Name | Type | Description |
|---|---|---|
| required | bool | True if BLS aggregation is required for this job |
function getAggregationThreshold(uint64 serviceId, uint8 jobIndex) external view returns (uint16 thresholdBps, uint8 thresholdType)Get the aggregation threshold configuration for a job
Only relevant if requiresAggregation returns true
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| jobIndex | uint8 | The job index |
| Name | Type | Description |
|---|---|---|
| thresholdBps | uint16 | Threshold in basis points (6700 = 67%) |
| thresholdType | uint8 | 0 = CountBased (% of operators), 1 = StakeWeighted (% of total stake) |
function onAggregatedResult(uint64 serviceId, uint8 job, uint64 jobCallId, bytes output, uint256 signerBitmap, uint256[2] aggregatedSignature, uint256[4] aggregatedPubkey) externalCalled when an aggregated job result is submitted
Validate the aggregated result, verify BLS signature, check threshold
| Name | Type | Description |
|---|---|---|
| serviceId | uint64 | The service ID |
| job | uint8 | The job index |
| jobCallId | uint64 | The job call ID |
| output | bytes | The aggregated output |
| signerBitmap | uint256 | Bitmap of which operators signed |
| aggregatedSignature | uint256[2] | The aggregated BLS signature (G1 point x, y) |
| aggregatedPubkey | uint256[4] | The aggregated public key of signers (G2 point) |
function getMinOperatorStake() external view returns (bool useDefault, uint256 minStake)Get the minimum stake required for operators to register for this blueprint
Called during operator registration to validate stake requirements
| Name | Type | Description |
|---|---|---|
| useDefault | bool | True to use protocol default from staking module |
| minStake | uint256 | Custom minimum stake amount (only used if useDefault=false) |