POST /api/v1/operations/prepare_revnet_deploy/plans
Parameters
| Name | Location | Details |
|---|---|---|
X-Juicebox-Account | header / required | Enrolled account identity, including authority chain and lowercase owner address. Enrollment derives this identity before the account exists. |
X-Juicebox-Signer | header / required | Owner wallet or authorized bot address that signed this request. |
X-Juicebox-Issued-At | header / required | Unix seconds, sent as 1–13 decimal digits without leading zeros; at most 30 seconds ahead of server time. |
X-Juicebox-Expires-At | header / required | Unix seconds, sent as 1–13 decimal digits without leading zeros; in the future and within 300 seconds of issuedAt. |
X-Juicebox-Nonce | header / required | Fresh random 32-byte lowercase nonce. A consumed nonce cannot be retried. |
X-Juicebox-Signature | header / required | EIP-712 CenterRequest signature over every signed field. Contract-owner signatures may vary in length. This is a computed request proof, not a reusable API key. |
X-Juicebox-Grant | header / optional | Authorized bot grant ID. Required for a bot; omit for the owner, signing grantId as the empty string. |
Idempotency-Key | header / required | Signed retry identity. Required on plan creation and transaction submission. Preserve exact method, target, Content-Type, and body bytes; use a fresh request nonce and signature. |
Request body
| Field | Type | Details | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
chainId | one of required | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
account | string required | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
config | object required | Fields
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
accountingContexts | array required | Fields
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainIds | array optional | Every chain the revnet launches on, including chainId. Instead of suckerConfig: the sucker registry fills the bridges to the other chains, salted with config.description.salt, mapping native ETH and USDC when accepted. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bridge | string optional | With chainIds. Default ccip. ccip links any chain pair. native links Ethereum with one L2 and maps native ETH only. both adds a native sucker where one exists. Values: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
suckerConfig | object optional | Explicit bridges, instead of chainIds. Use { salt, deployerConfigurations: [] } for one chain.Fields
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tiered721Config | object optional | Fields
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
allowedPosts | array optional | Fields
|
JSON schema
{
"type": "object",
"properties": {
"chainId": {
"anyOf": [
{
"type": "number",
"const": 1
},
{
"type": "number",
"const": 10
},
{
"type": "number",
"const": 8453
},
{
"type": "number",
"const": 42161
},
{
"type": "number",
"const": 11155111
},
{
"type": "number",
"const": 11155420
},
{
"type": "number",
"const": 84532
},
{
"type": "number",
"const": 421614
}
]
},
"account": {
"type": "string"
},
"config": {
"type": "object",
"properties": {
"description": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"ticker": {
"type": "string",
"minLength": 1,
"maxLength": 32
},
"uri": {
"type": "string",
"maxLength": 4096
},
"salt": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
}
},
"required": [
"name",
"ticker",
"uri",
"salt"
],
"additionalProperties": false
},
"baseCurrency": {
"description": "Currency that issuance is priced in: 1 = ETH, 2 = USD. Use 1 for ETH, not 61166 (native ETH's accounting currency). A token's own currency, uint32(uint160(token)), applies only when payments come in that token or JBPrices has a feed for it.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"operator": {
"type": "string"
},
"scopeCashOutsToLocalBalances": {
"type": "boolean",
"description": "false: cash outs count every chain's supply and surplus (through the suckers). true: only this chain's. Recommended: false, which is what revnet.money sends."
},
"stageConfigurations": {
"minItems": 1,
"maxItems": 16,
"type": "array",
"items": {
"type": "object",
"properties": {
"startsAtOrAfter": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"autoIssuances": {
"maxItems": 32,
"type": "array",
"items": {
"type": "object",
"properties": {
"chainId": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"count": {
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"beneficiary": {
"type": "string"
}
},
"required": [
"chainId",
"count",
"beneficiary"
],
"additionalProperties": false
}
},
"splitPercent": {
"description": "Share of new tokens sent to this stage's splits, out of 10,000. 2000 = 20%.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"splits": {
"maxItems": 32,
"type": "array",
"items": {
"type": "object",
"properties": {
"percent": {
"description": "Share of the split group, out of 1,000,000,000. 500,000,000 = 50%.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"projectId": {
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"beneficiary": {
"type": "string"
},
"preferAddToBalance": {
"type": "boolean"
},
"lockedUntil": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"hook": {
"type": "string"
}
},
"required": [
"percent",
"projectId",
"beneficiary",
"preferAddToBalance",
"lockedUntil",
"hook"
],
"additionalProperties": false
}
},
"initialIssuance": {
"description": "Tokens issued per one unit of baseCurrency at stage start, with 18 decimals: 1000000000000000000000 = 1,000 tokens.",
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"issuanceCutFrequency": {
"description": "Seconds between issuance cuts.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"issuanceCutPercent": {
"description": "Issuance cut applied every issuanceCutFrequency, out of 1,000,000,000. 0 = no cut.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"cashOutTaxRate": {
"description": "Cash-out tax out of 10,000, at most 9,999. 0 = no tax.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"extraMetadata": {
"description": "Ruleset metadata bits for hooks (uint16, lower 14 bits kept, at most 16,383). Bit 2 (value 4): while this stage is active the operator may add or retry suckers with REVDeployer.deploySuckersFor; the launch suckers deploy without it. A cross-chain revnet must set it on every stage, because the SDK refuses to encode one that does not. Bits 0 (1) and 1 (2): the NFT hook pauses transfers of pausable tiers, and pending reserve mints. Recommended: include 4 on every stage, even for one chain, so chains can be added later. revnet.money also sets bit 0, so pausable NFT tiers cannot be transferred, and sends 5.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
}
},
"required": [
"startsAtOrAfter",
"autoIssuances",
"splitPercent",
"splits",
"initialIssuance",
"issuanceCutFrequency",
"issuanceCutPercent",
"cashOutTaxRate",
"extraMetadata"
],
"additionalProperties": false
}
}
},
"required": [
"description",
"baseCurrency",
"operator",
"scopeCashOutsToLocalBalances",
"stageConfigurations"
],
"additionalProperties": false
},
"accountingContexts": {
"minItems": 1,
"maxItems": 16,
"type": "array",
"items": {
"type": "object",
"properties": {
"token": {
"description": "Token address; native ETH is 0x000000000000000000000000000000000000EEEe.",
"type": "string"
},
"decimals": {
"description": "Token decimals. Native ETH uses 18.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"currency": {
"description": "Usually uint32(uint160(token)); native ETH is 0x000000000000000000000000000000000000EEEe, currency 61166.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
}
},
"required": [
"token",
"decimals",
"currency"
],
"additionalProperties": false
}
},
"chainIds": {
"description": "Every chain the revnet launches on, including chainId. Instead of suckerConfig: the sucker registry fills the bridges to the other chains, salted with config.description.salt, mapping native ETH and USDC when accepted.",
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"anyOf": [
{
"type": "number",
"const": 1
},
{
"type": "number",
"const": 10
},
{
"type": "number",
"const": 8453
},
{
"type": "number",
"const": 42161
},
{
"type": "number",
"const": 11155111
},
{
"type": "number",
"const": 11155420
},
{
"type": "number",
"const": 84532
},
{
"type": "number",
"const": 421614
}
]
}
},
"bridge": {
"description": "With chainIds. Default ccip. ccip links any chain pair. native links Ethereum with one L2 and maps native ETH only. both adds a native sucker where one exists.",
"type": "string",
"enum": [
"ccip",
"native",
"both"
]
},
"suckerConfig": {
"description": "Explicit bridges, instead of chainIds. Use { salt, deployerConfigurations: [] } for one chain.",
"type": "object",
"properties": {
"salt": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
},
"deployerConfigurations": {
"maxItems": 16,
"type": "array",
"items": {
"type": "object",
"properties": {
"deployer": {
"type": "string"
},
"peer": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
},
"mappings": {
"minItems": 1,
"maxItems": 16,
"type": "array",
"items": {
"type": "object",
"properties": {
"localToken": {
"type": "string"
},
"minGas": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"remoteToken": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
}
},
"required": [
"localToken",
"minGas",
"remoteToken"
],
"additionalProperties": false
}
}
},
"required": [
"deployer",
"peer",
"mappings"
],
"additionalProperties": false
}
}
},
"required": [
"salt",
"deployerConfigurations"
],
"additionalProperties": false
},
"tiered721Config": {
"type": "object",
"properties": {
"baseline721HookConfiguration": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"symbol": {
"type": "string",
"minLength": 1,
"maxLength": 32
},
"baseUri": {
"type": "string",
"maxLength": 4096
},
"tokenUriResolver": {
"type": "string"
},
"contractUri": {
"type": "string",
"maxLength": 4096
},
"tiersConfig": {
"type": "object",
"properties": {
"tiers": {
"maxItems": 32,
"type": "array",
"items": {
"type": "object",
"properties": {
"price": {
"description": "Tier price in the tiers currency, with the tiers decimals.",
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"initialSupply": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"votingUnits": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"reserveFrequency": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"reserveBeneficiary": {
"type": "string"
},
"encodedIpfsUri": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
},
"category": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"discountPercent": {
"description": "Tier price discount, out of 200. 200 = free.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"flags": {
"type": "object",
"properties": {
"allowOwnerMint": {
"type": "boolean"
},
"useReserveBeneficiaryAsDefault": {
"type": "boolean"
},
"transfersPausable": {
"type": "boolean"
},
"useVotingUnits": {
"type": "boolean"
},
"cantBeRemoved": {
"type": "boolean"
},
"cantIncreaseDiscountPercent": {
"type": "boolean"
},
"cantBuyWithCredits": {
"type": "boolean"
}
},
"required": [
"allowOwnerMint",
"useReserveBeneficiaryAsDefault",
"transfersPausable",
"useVotingUnits",
"cantBeRemoved",
"cantIncreaseDiscountPercent",
"cantBuyWithCredits"
],
"additionalProperties": false
},
"splitPercent": {
"description": "Share of the tier price sent to the tier's splits, out of 1,000,000,000.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"splits": {
"maxItems": 32,
"type": "array",
"items": {
"type": "object",
"properties": {
"percent": {
"description": "Share of the split group, out of 1,000,000,000. 500,000,000 = 50%.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"projectId": {
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"beneficiary": {
"type": "string"
},
"preferAddToBalance": {
"type": "boolean"
},
"lockedUntil": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"hook": {
"type": "string"
}
},
"required": [
"percent",
"projectId",
"beneficiary",
"preferAddToBalance",
"lockedUntil",
"hook"
],
"additionalProperties": false
}
}
},
"required": [
"price",
"initialSupply",
"votingUnits",
"reserveFrequency",
"reserveBeneficiary",
"encodedIpfsUri",
"category",
"discountPercent",
"flags",
"splitPercent",
"splits"
],
"additionalProperties": false
}
},
"currency": {
"description": "JB currency ID: uint32(uint160(token)) for a token (native ETH is 0x000000000000000000000000000000000000EEEe, currency 61166), or 1 = ETH and 2 = USD.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"decimals": {
"description": "Decimals of tier prices.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
}
},
"required": [
"tiers",
"currency",
"decimals"
],
"additionalProperties": false
},
"flags": {
"type": "object",
"properties": {
"noNewTiersWithReserves": {
"type": "boolean"
},
"noNewTiersWithVotes": {
"type": "boolean"
},
"noNewTiersWithOwnerMinting": {
"type": "boolean"
},
"preventOverspending": {
"type": "boolean"
}
},
"required": [
"noNewTiersWithReserves",
"noNewTiersWithVotes",
"noNewTiersWithOwnerMinting",
"preventOverspending"
],
"additionalProperties": false
}
},
"required": [
"name",
"symbol",
"baseUri",
"tokenUriResolver",
"contractUri",
"tiersConfig",
"flags"
],
"additionalProperties": false
},
"salt": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{64}$"
},
"preventOperatorAdjustingTiers": {
"type": "boolean"
},
"preventOperatorUpdatingMetadata": {
"type": "boolean"
},
"preventOperatorMinting": {
"type": "boolean"
},
"preventOperatorIncreasingDiscountPercent": {
"type": "boolean"
}
},
"required": [
"baseline721HookConfiguration",
"salt",
"preventOperatorAdjustingTiers",
"preventOperatorUpdatingMetadata",
"preventOperatorMinting",
"preventOperatorIncreasingDiscountPercent"
],
"additionalProperties": false
},
"allowedPosts": {
"maxItems": 16,
"type": "array",
"items": {
"type": "object",
"properties": {
"category": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"minimumPrice": {
"type": "string",
"maxLength": 78,
"pattern": "^(0|[1-9][0-9]*)$"
},
"minimumTotalSupply": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"maximumTotalSupply": {
"description": "0 means unlimited; actual minted NFT tiers remain subject to the store supply cap.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"maximumSplitPercent": {
"description": "Largest tier split a poster may set, out of 1,000,000,000.",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(0|[1-9][0-9]*)$",
"maxLength": 78
}
]
},
"allowedAddresses": {
"maxItems": 32,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"category",
"minimumPrice",
"minimumTotalSupply",
"maximumTotalSupply",
"maximumSplitPercent",
"allowedAddresses"
],
"additionalProperties": false
}
}
},
"required": [
"chainId",
"account",
"config",
"accountingContexts"
],
"additionalProperties": false
}Response 201
| Field | Type | Details | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | string (uuid) required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
account | string required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
operation | string required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
draft | object required | Fields
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
commitment | string required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
createdAt | integer required | Unix timestamp in milliseconds. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expiresAt | integer required | Unix timestamp in milliseconds. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
revision | integer required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
smartAccount | object optional | Fields
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status | string required | Values: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
steps | array required | Fields
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
confirmationScope | string required |
JSON schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"account": {
"$ref": "#/components/schemas/Address"
},
"operation": {
"type": "string"
},
"draft": {
"$ref": "#/components/schemas/PlanDraft"
},
"commitment": {
"$ref": "#/components/schemas/Hash"
},
"createdAt": {
"$ref": "#/components/schemas/UnixMilliseconds"
},
"expiresAt": {
"$ref": "#/components/schemas/UnixMilliseconds"
},
"revision": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"smartAccount": {
"type": "object",
"properties": {
"bindingId": {
"$ref": "#/components/schemas/Hash"
},
"stateHash": {
"$ref": "#/components/schemas/Hash"
},
"chainId": {
"$ref": "#/components/schemas/ChainId"
},
"address": {
"$ref": "#/components/schemas/Address"
},
"manifestRevision": {
"$ref": "#/components/schemas/Hash"
}
},
"required": [
"bindingId",
"stateHash",
"chainId",
"address",
"manifestRevision"
],
"additionalProperties": false
},
"status": {
"type": "string",
"enum": [
"prepared",
"pending",
"partial",
"blocked",
"reorged",
"expired",
"transactions_confirmed"
]
},
"steps": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PlanStep"
},
"minItems": 1,
"maxItems": 32
},
"confirmationScope": {
"type": "string"
}
},
"required": [
"id",
"account",
"operation",
"draft",
"commitment",
"createdAt",
"expiresAt",
"revision",
"status",
"steps",
"confirmationScope"
],
"additionalProperties": false
}