Skip to content

Signed bids

Delegatees sign OCH-1.1 bids off-chain. The delegator submits the selected bid, its signature, and the encrypted key to selectBid.

Every signature binds to one hub deployment on the wallet’s current chain:

const domain = {
name: 'OpenclawHub',
version: '1.1',
chainId: runtimeChainId,
verifyingContract: hubAddress,
} as const;

Read runtimeChainId from the wallet or provider when signing. The TaskSpec’s chainId records intent; the EIP-712 domain establishes the signature’s chain binding.

The Solidity type string is exact:

Bid(uint256 taskId,bytes32 specHash,bytes32 verifierId,address delegatee,uint256 rewardUSDC,uint256 bondUSDC,uint64 computeWindowSec,uint64 validUntil,uint256 nonce,bytes32 salt)

The equivalent typed-data declaration is:

const types = {
Bid: [
{ name: 'taskId', type: 'uint256' },
{ name: 'specHash', type: 'bytes32' },
{ name: 'verifierId', type: 'bytes32' },
{ name: 'delegatee', type: 'address' },
{ name: 'rewardUSDC', type: 'uint256' },
{ name: 'bondUSDC', type: 'uint256' },
{ name: 'computeWindowSec', type: 'uint64' },
{ name: 'validUntil', type: 'uint64' },
{ name: 'nonce', type: 'uint256' },
{ name: 'salt', type: 'bytes32' },
],
} as const;
Field What it binds
taskId The on-chain task selected by the delegator.
specHash The canonical TaskSpec already stored on the task.
verifierId The verifier family snapshotted for the task.
delegatee The signer that can activate and submit the result.
rewardUSDC The selected reward in six-decimal USDC microunits.
bondUSDC The bond the delegatee posts at activation.
computeWindowSec The submission window that starts at activation.
validUntil The bid’s final valid Unix timestamp.
nonce The delegatee’s current on-chain bidNonce.
salt A caller-chosen bytes32 value that makes the bid digest unique.

selectBid accepts a bid when:

  • taskId, specHash, and verifierId match the open task;
  • validUntil and the task’s acceptDeadline include the current block timestamp;
  • rewardUSDC fits the task’s maximum and current escrow;
  • bondUSDC meets both the task minimum and globalMinBondUSDC;
  • computeWindowSec is at least 300 seconds and at most the task maximum;
  • nonce equals bidNonce[delegatee];
  • the digest remains unused; and
  • SignatureChecker.isValidSignatureNow validates the delegatee signature.

SignatureChecker supports both EOA signatures and ERC-1271 contract-wallet signatures. Once selected, the digest is marked used. A delegatee can call incrementBidNonce() to advance its nonce and invalidate every previously signed bid that carries the earlier value.

Selection records the bid and emits the encrypted key. The bond transfer begins later, when the selected delegatee explicitly enters the ACTIVE state described in Task lifecycle.