Signing Direct Requests
The recommended way to submit signed exchange actions is through ExchangeClient.
Use direct signing only when implementing a custom HTTP client or integrating the Exchange API without the SDK client wrapper.
Direct signing requires exact agreement on:
Action type
Field names
Field order
Solidity integer widths
Addresses
Numeric conversion
Chain ID
Verifying contract
EIP-712 domain
Changing any signed field after calculating the digest invalidates the signature.
EIP-712 domain
Signed exchange actions use this domain:
name: GammaSwap Exchange
version: 2
chainId: request chain ID
verifyingContract: exchange verifying contractThe domain prevents a signature from being reused against another chain or exchange deployment.
Signed request wrapper
Most signed HTTP endpoints use this outer structure:
The action field depends on the endpoint:
POST /orders
order
POST /cancels
cancel
POST /cancel-replace
cancelReplace
POST /withdrawals
withdrawal
POST /claim
claim
POST /agents/approve
approval
POST /agents/revoke
revocation
The field name orderHash is historical.
It contains the EIP-712 digest of the signed action, even when the action is a cancel, withdrawal, claim, approval, or revocation.
It is not a hash of the outer HTTP request body and does not include signature.
Signature types
0
EOA
The sender signs directly
4
Agent
An approved agent signs for a master account
Signing process
A direct client signs an action in this order:
Construct the complete action object.
Convert human inputs into exact protocol integers.
Construct the EIP-712 domain.
Calculate the action-specific struct hash.
Calculate the final EIP-712 digest.
Sign the digest.
Serialize bigint fields as decimal strings.
Send the action, chain ID, digest, and signature.
The final digest is constructed as:
Hash helpers
The SDK exports helpers for each action type.
Order
POST /orders
hashFillOrderJS
Cancel
POST /cancels
hashCancelOrderJS
Cancel-replace
POST /cancel-replace
hashCancelReplaceOrderJS
Replacement order
POST /cancel-replace
hashFillOrderJS
Withdrawal
POST /withdrawals
hashWithdrawalOrderJS
Claim
POST /claim
hashClaimOrderJS
Agent approval
POST /agents/approve
hashApproveAgentOrderJS
Inner agent approval
POST /agents/approve
hashAgentApprovalJS
Agent revocation
POST /agents/revoke
hashRevokeAgentOrderJS
Sign an order
Serialize the request
Bigint values must be serialized as decimal strings before JSON encoding.
Serialized request body:
Submit the request
Successful response:
Cancel-and-replace signing
Cancel-and-replace contains two separately signed actions:
The replacement order
The cancel-replace action
Sign the replacement order first:
The cancel-replace action includes replacementOrderHash.
Calculate and sign the cancel-replace digest:
The HTTP body includes both signatures:
Agent approval signing
Agent approval contains two signatures:
An inner signature over the agent approval.
An outer signature over the approve-agent action.
Use:
for the inner agent approval and:
for the outer approval action.
Address handling
Normalize relevant address fields consistently before hashing and sending requests.
The API normalizes signed address fields to lowercase when validating hashes and signatures.
A difference in address representation can produce a different digest if the direct signing implementation does not follow the same normalization rules.
Numeric handling
Do not use floating-point JavaScript numbers when building signed actions.
Use exact integer values:
Do not sign:
Human decimal inputs must be converted before hashing.
Common signature failures
A request can fail authentication if:
The wrong chain ID is used.
The wrong verifying contract is used.
A signed field changes before submission.
Human decimal values are signed instead of protocol integers.
Fields are encoded in the wrong order.
An incorrect Solidity integer width is used.
The submitted digest does not match the action.
The recovered signer does not match the action’s
signer.An agent approval is missing, inactive, or expired.
The wrong approval nonce is used.
The signature type does not match the signing flow.
Common API errors include:
For most integrations, use ExchangeClient instead of constructing direct signatures manually.
Last updated