GrantCovenant on-chain, the creator funds it once, and the contract releases one tranche per confirmed milestone. The covenant has two authority slots: the creator wallet (admin paths, cancel refund) and a backend-held claim authority (co-signs milestone releases). Grants support BCH and CashTokens, and optionally allow the recipient to transfer their right to a new address.
All routes live under /api. Mutating routes require Bearer wallet auth and the x-user-address header.
Grant statuses
PENDING- contract deployed, awaiting fundingACTIVE- funded, releasing milestonesPAUSED- creator paused; releases blockedCANCELLED- creator cancelled; remaining balance refunded to authority addressCOMPLETED- all milestones released
List grants
creator, newest first. Deprecated grants are hidden unless showDeprecated=true.
Query parameters
| Param | Required | Meaning |
|---|---|---|
creator | yes | Creator wallet address |
showDeprecated | no | Include deprecated grants when true. Default false. |
Response
Get grant
Response
Create grant
GrantCovenant on chipnet, generates a backend-held claim authority keypair (encrypted at rest), and returns funding instructions. Status is PENDING until funding confirms.
Body
Body fields
| Field | Required | Notes |
|---|---|---|
title | yes | Human label |
description | no | |
vaultId | no | Link the grant to an existing vault |
recipient | yes | CashAddress that receives every milestone payout |
milestonesTotal | yes | Integer in [1, 255] |
amountPerMilestone | yes | Display amount per tranche, greater than 0 |
totalAmount | yes | Display total amount the contract holds |
tokenType | yes | BCH or FUNGIBLE_TOKEN (CASHTOKENS is normalized to FUNGIBLE_TOKEN) |
tokenCategory | cond. | Required when tokenType is FUNGIBLE_TOKEN |
cancelable | no | Default true |
transferable | no | Default false. When true, recipient may transfer the right |
milestones | yes | Non-empty array; each entry may carry title and description |
Response
Funding info
wcTransaction the creator wallet signs to fund the deployed contract with the required state NFT.
If the wallet needs a consolidation transaction first (genesis UTXO at outpoint index 0), the response shape switches:
Standard response
Confirm funding
- the tx is indexed on chipnet
- one input belongs to the caller’s wallet (audit H-07)
- the contract output carries the expected satoshi/token amount and a mutable NFT with a 32+ byte commitment
ACTIVE.
Error responses
| HTTP | errorCode | Meaning |
|---|---|---|
| 409 | TX_NOT_FOUND | Tx not yet indexed on chipnet. Retryable. |
| 403 | TX_INPUT_NOT_FROM_FUNDER | Caller wallet did not contribute an input. |
| 400 | - | Funding tx is missing the expected contract output. |
| 500 | CONFIRM_FAILED | Server error during confirmation. |
Release a milestone
Release is a two-call flow: build, then confirm.Build release transaction
ACTIVE and have remaining milestones.
Confirm release
milestones_completed, adds to total_released, marks the milestone RELEASED, and flips the grant to COMPLETED when the last milestone lands.
Error responses
| HTTP | errorCode | Meaning |
|---|---|---|
| 400 | - | Missing amount, milestoneNumber, or txHash. |
| 409 | TX_NOT_FOUND | Tx not yet indexed on chipnet. Retryable. |
| 400 | - | Release tx is missing the expected recipient output. |
| 500 | CONFIRM_FAILED | Server error during confirmation. |
Pause
PAUSED, blocking further releases until cancellation (the on-chain covenant does not currently expose resume).
Pause response
Confirm pause body
PAUSED.
Cancel
ACTIVE or PAUSED. The cancel transaction refunds the remaining balance to the authority address encoded in the contract constructor.
Cancel response
warning field. The refund still goes to the contract-encoded authority address regardless.
Confirm cancel body
CANCELLED.
Transfer recipient rights
transferable: true and is currently ACTIVE.
Transfer body
Transfer response
Confirm transfer body
Common error shape
All confirm endpoints return a consistent shape on retryable and terminal failures:| Field | Values |
|---|---|
state | pending, confirmed, failed |
retryable | true when the client should retry |
errorCode | TX_NOT_FOUND, TX_INPUT_NOT_FROM_FUNDER, CONFIRM_FAILED |

