POST /v0/agreements/deploy-with-permit or POST /v0/agreements/{id}/input.
For normal TypeScript integrations, prefer the TypeScript client reference: deployAgreementWithPermit(...) signs and submits deployment permits, and submitAgreementInputWithPermit(...) signs and submits input permits. Use this reference when you are constructing typed data directly, verifying SDK helper behavior, or debugging a signing mismatch.
Deploy signing reference
The deployment permit is signed over derived on-chain parameters, not over the raw deployment request body. If you usedeployAgreementWithPermit(...), the SDK performs this derivation and signing for you. For raw API deployment, use the same supported chainId in deployment preflight, EIP-712 domain construction, and the deploy-with-permit request body.
Deploy typed data
Deploy permit nonce
Setmessage.nonce to the current value of AgreementFactory.nonces(signer) on the target chain before signing. Read it through a live publicClient/RPC connected to the same chain as domain.chainId and factoryAddress; do not hardcode 0.
A successful deploy permit consumes that factory nonce, so deploy signatures are single-use. If the signer nonce changes for any reason, including a previous successful deploy permit, the signature becomes stale and must be regenerated.
Exact derivation rules
| Array | Source | Derivation |
|---|---|---|
inputDefs | agreement.execution.inputs | Each input ID becomes keccak256(stringToHex(inputId)); each field ID becomes keccak256(stringToHex(fieldName)); issuer constraints become on-chain conditions. |
transitions | agreement.execution.transitions | fromState = keccak256(stringToHex(from)); toState = keccak256(stringToHex(to)); inputId = keccak256(stringToHex(transition.conditions[0].input)). |
initVars | Variables referenced by agreement.execution.initialize.data | Each variable ID becomes keccak256(stringToHex(variableName)); each variable value is ABI-encoded according to its field type. |
verifiers | Verifier registrations supplied for deployment | Each verifier registration binds a verifier key to the verifier contract address installed during agreement initialization. |
actions | agreement.execution.actions | fromState and inputId are hashed to bytes32; target, value, and data come from the resolved action call. |
- Do not sign against raw caller input when participant mappings change any value that is hashed or encoded into the signed message.
- Sign against the effective post-mapping values instead.
- For deploy, the safe source of truth is the normalized
variablesobject returned byPOST /v0/agreements/validatefor the exact deployment payload you plan to submit.
agreement.execution.initialize.data references participant-backed variables such as partyAEthAddress or partyBEthAddress, and those addresses are supplied through participants, the final mapped wallet addresses still need to be reflected in the initVars used for signing.
Field type encoding for initVars follows these rules:
string,dateTime,signature→abi.encode(string)address→abi.encode(address)uint256→abi.encode(uint256)bool→abi.encode(bool)bytes32,txHash→abi.encode(bytes32)
Factory address source
The TypeScript helpers resolve the correct factory for the selected chain through the protocol SDK registry. When constructing typed data manually, use the factory address for the samechainId that you pass in the EIP-712 domain.
Current factory addresses from the protocol SDK registry:
- Base Mainnet (
chainId = 8453):0x76dAA59C02d902e7063E6328D2E64ACee6CC121e - Linea Sepolia (
chainId = 59141):0x26Ff3AdEC23fC5778f190371B1CcCadDa74e26c8 - Linea Mainnet (
chainId = 59144):0xB772Ea12546fd7153Bf1F5ED7266B8faB0dAD6C9 - Base Sepolia (
chainId = 84532):0x76dAA59C02d902e7063E6328D2E64ACee6CC121e - Ethereum Sepolia (
chainId = 11155111):0x76dAA59C02d902e7063E6328D2E64ACee6CC121e
Signing call
signatureHex into:
r = 0x...s = 0x...v = 27or28
initValues, docUri, chain, factory address, signer nonce, or deadline changes, the signature must be regenerated.
The TypeScript client uses a one-hour default permit lifetime through computeDefaultDeadlineSeconds(). Low-level signing calls still require you to pass an explicit deadline.
Input signing reference
The input permit is signed over the hashed input ID and an ABI-encoded payload. If you usesubmitAgreementInputWithPermit(...), the SDK performs this derivation and signing for you. For raw input submission, read the deployed agreement record first and use its chainId and contract address in the EIP-712 domain.
Input typed data
Exact derivation rules
dataFields has this contract shape:
| Step | Derivation |
|---|---|
| Look up the input schema | Read agreement.execution.inputs[inputId].data. |
| Encode each submitted field | id = keccak256(stringToHex(fieldName)); fType = the on-chain field type mapped from the authored variable type; data = ABI-encoded field value. |
| Encode the array | ABI-encode the whole array as (bytes32 id, uint8 fType, bytes data)[]. |
Field type mapping
uint256→UINT256string→STRINGaddress→ADDRESSbool→BOOLbytes32→BYTES32signature→STRINGdateTime→STRINGtxHash→BYTES32
Field value encoding rules
STRING→abi.encode(string)ADDRESS→abi.encode(address)UINT256→abi.encode(uint256)BOOL→abi.encode(bool)BYTES32→abi.encode(bytes32)
Effective signing pipeline
Signing call
signatureHex into:
r = 0x...s = 0x...v = 27or28
inputId, values, agreement schema, agreement address, signer nonce, chain, or deadline changes, the signature must be regenerated.