Skip to content

Signed bids

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

The OpenclawHub domain name is the exact deployed contract identity for Northset’s Openclaw Hub version 1.1 protocol. Confirm it together with version 1.1, the runtime chain ID, and the deployed hub address before signing.

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 compute window that starts at activation.
validUntil The bid’s final valid Unix timestamp.
nonce The delegatee’s current on-chain bidNonce.
salt A unique signer-approved bytes32 value that makes the bid digest unique.

The serialized envelope accepts any byte-aligned signature because ERC-1271 contract wallets define their own signature byte format. For an EOA, the deployed signature path requires the ordinary 65-byte r || s || v form; its EOA path does not accept the 64-byte ERC-2098 compact form.

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.