POST /api/v1/smart-accounts/binding-challenges
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 / optional | 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 |
|---|---|---|
manifestId | string required | |
address | string required | |
nonce | value required | |
expiresAt | integer required | Future Unix seconds no more than 900 seconds after server time. |
JSON schema
{
"type": "object",
"properties": {
"manifestId": {
"type": "string"
},
"address": {
"$ref": "#/components/schemas/Address"
},
"nonce": {
"allOf": [
{
"$ref": "#/components/schemas/Hash"
},
{
"not": {
"const": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
}
]
},
"expiresAt": {
"$ref": "#/components/schemas/UnixSeconds",
"description": "Future Unix seconds no more than 900 seconds after server time."
}
},
"required": [
"manifestId",
"address",
"nonce",
"expiresAt"
],
"additionalProperties": false,
"description": "Select a server-published reviewed manifest and an existing Safe distinct from the API owner EOA. The API owner must be a current Safe owner. Nonce must be nonzero."
}Response 200
| Field | Type | Details | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
state | object required | Fields
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
digest | string required | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
typedData | object required | Fields
|
JSON schema
{
"type": "object",
"properties": {
"state": {
"$ref": "#/components/schemas/SmartAccountState"
},
"digest": {
"$ref": "#/components/schemas/Hash"
},
"typedData": {
"type": "object",
"properties": {
"domain": {
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Juicebox Center Smart Account"
},
"version": {
"type": "string",
"const": "1"
},
"chainId": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"verifyingContract": {
"$ref": "#/components/schemas/Address"
},
"salt": {
"$ref": "#/components/schemas/Hash"
}
},
"required": [
"name",
"version",
"chainId",
"verifyingContract",
"salt"
],
"additionalProperties": false
},
"primaryType": {
"type": "string",
"const": "BindSmartAccount"
},
"types": {
"type": "object",
"const": {
"BindSmartAccount": [
{
"name": "accountId",
"type": "string"
},
{
"name": "owner",
"type": "address"
},
{
"name": "stateHash",
"type": "bytes32"
},
{
"name": "nonce",
"type": "bytes32"
},
{
"name": "expiresAt",
"type": "uint64"
}
]
}
},
"message": {
"type": "object",
"properties": {
"accountId": {
"$ref": "#/components/schemas/AccountId"
},
"owner": {
"$ref": "#/components/schemas/Address"
},
"stateHash": {
"$ref": "#/components/schemas/Hash"
},
"nonce": {
"allOf": [
{
"$ref": "#/components/schemas/Hash"
},
{
"not": {
"const": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
}
]
},
"expiresAt": {
"type": "string",
"pattern": "^(?:0|9007199254740991|[1-9][0-9]{0,14}|[1-8][0-9]{15}|900[0-6][0-9]{12}|90070[0-9]{11}|90071[0-8][0-9]{10}|900719[0-8][0-9]{9}|9007199[0-1][0-9]{8}|90071992[0-4][0-9]{7}|900719925[0-3][0-9]{6}|9007199254[0-6][0-9]{5}|90071992547[0-3][0-9]{4}|9007199254740[0-8][0-9]{2}|90071992547409[0-8][0-9]{1}|9007199254740990[0-9]{0})$",
"description": "Uint64 typed-data value serialized as a decimal string. Challenge request `expiresAt` uses a JSON integer in Unix seconds."
}
},
"required": [
"accountId",
"owner",
"stateHash",
"nonce",
"expiresAt"
],
"additionalProperties": false
}
},
"required": [
"domain",
"primaryType",
"types",
"message"
],
"additionalProperties": false
}
},
"required": [
"state",
"digest",
"typedData"
],
"additionalProperties": false
}