Documentation Index
Fetch the complete documentation index at: https://docs.context.markets/llms.txt
Use this file to discover all available pages before exploring further.
Overview
In April 2026, Context Markets deployed upgraded versions of the Holdings and Settlement contracts. These changes make market order execution and quoting significantly smoother by simplifying contract logic and removing unnecessary constraints.
Users are automatically migrated through a built-in flow in the app. This guide is for developers integrating the migration process into custom applications.
While migration is active, wallets that still need migration cannot continue normal trading through the API. Order create, bulk create, mixed bulk, and cancel-replace return 409 until the wallet finishes migration. Pure cancel flows remain available, and gasless operator approval defaults to Settlement V2.
Migration process
The SDK handles migrations via the migration module. Here’s the flow:
1. Check migration status
const status = await client.migration.getStatus({ address: walletAddress });
// Returns:
// - legacyBalances: Assets in old contracts
// - newBalances: Assets already in new contracts
// - fundsMigrationPlan: Chunked USDC migration plan
// - pendingRestorations: Legacy orders ready to restore
// - sponsoredFundsMigrationAvailable: Whether relayer will sponsor gas
2. Initiate migration
const result = await client.migration.start({
address: walletAddress,
authorization: signedAuth, // Optional: authorize on behalf of user
});
If sponsoredFundsMigrationAvailable is true, funds can be migrated gaslessly:
// Sign the migration
const signedMigration = await client.migration.signSponsoredMigrateFunds();
// Submit for relayer to execute
const result = await client.migration.migrateFunds(signedMigration);
Without sponsorship, use direct signatures:
// Manual batch withdraw to new Holdings and operator approval
const signed = await client.migration.signSponsoredMigrateFunds(status);
4. Restore legacy orders
Legacy limit orders can be restored as new Settlement V2 orders:
// Get pending restorations
const status = await client.migration.getStatus();
const pending = status.pendingRestorations;
// Sign and submit restorations
const result = await client.migration.restorePendingOrders(pending);
// Or restore specific orders
const filtered = pending.filter(r => selectedOrderIds.includes(r.legacyOrderId));
await client.migration.restorePendingOrders(filtered);
5. Dismiss orders (optional)
If a user wants to skip migrating specific legacy orders:
await client.migration.dismissOrders({
address: walletAddress,
legacyOrderIds: [1, 2, 3], // Specific orders to dismiss
authorization: signedAuth, // Optional
});
What changed
Holdings
Function signature updates:
| Function | V1 | V2 |
|---|
| deposit | (address to, address token, uint256 amount) | (address to, address token, uint256 amount) |
| depositWithPermit | (address from, address to, ...) | (address depositor, address token, uint256 amount, ...) |
| batchDeposit | (address to, ...) | (address to, ...) |
New functions added:
batchTransferFrom() — Execute batch transfers on behalf of users via EIP-712 signature
batchDepositMultipleRecipients() — Batch deposit to multiple recipients in one transaction
Settlement V2
Core semantic shift: Orders are explicitly typed instead of implicitly constrained. Buy orders are budget-native instead of price/size-native.
Inventory mode replaced with explicit order kinds:
| Constant | V1 | V2 |
|---|
| Mode/Kind | INVENTORY_MODE_ANY | ORDER_KIND_BUY |
| INVENTORY_MODE_REQUIRE_HAS_INVENTORY | ORDER_KIND_SELL_INVENTORY |
| INVENTORY_MODE_REQUIRE_NO_INVENTORY | ORDER_KIND_SELL_NO_INVENTORY |
Budget-native buys:
- V1: buys denominated in
price × size (shares), payable amount computed at fill time
- V2: buys denominated in
maxCollateralIn (budget) and minSharesOut (guaranteed output)
Single signed order type:
- V1: separate
SignedOrder and MarketOrderIntent structures
- V2: one
SignedOrder type for both limit and market orders
Consumption accounting is now per-order-kind:
- BUY orders:
consumed = buyerCollateralAmount + fees
- SELL orders:
consumed = shareAmount
Removed: mintAndDepositWithPermit()
- Use
Holdings.depositWithPermit() followed by Settlement.mintCompleteSetsFromHoldings() instead
New typehashes and constants:
BURN_FROM_HOLDINGS_TYPEHASH
MINT_FROM_HOLDINGS_TYPEHASH
ORDER_KIND_BUY
ORDER_KIND_SELL_INVENTORY
ORDER_KIND_SELL_NO_INVENTORY
SDK API reference
migration.getStatus(request?)
Get current migration state for a wallet.
Parameters:
address? — Wallet address (defaults to configured address)
Returns:
{
status: "not_started" | "in_progress" | "completed"
legacyBalances: { token: string; balance: string }[]
newBalances: { token: string; balance: string }[]
fundsMigrationPlan: {
totalAmount: string
tokens: { token: string; amount: string }[]
chunks: { tokens: { token: string; amount: string }[] }[]
}
pendingRestorations: {
legacyOrderId: number
draft: { /* order draft */ }
}[]
sponsoredFundsMigrationAvailable: boolean
sponsoredRelayerAddress?: string
newHoldingsOperatorNonce?: number
}
migration.start(request?)
Initiate the migration process.
Parameters:
address? — Target wallet address
authorization? — Signed authorization message (for third-party initiation)
migration.migrateFunds(request)
Submit signed fund migration to relayer or direct execution.
Parameters:
batchWithdraw — Single or array of signed batch withdrawals
setOperator — Signed operator approval for Settlement V2
address? — Target wallet address
migration.restoreOrders(request)
Restore legacy limit orders as new Settlement V2 orders.
Parameters:
restorations — Array of signed order restorations (legacyOrderId + signed order)
address? — Target wallet address
migration.dismissOrders(request?)
Mark legacy orders as dismissed (not to be migrated).
Parameters:
legacyOrderIds? — Specific orders to dismiss (omit to dismiss all)
address? — Target wallet address
authorization? — Signed authorization message
Sign fund migration for sponsored relayer execution.
Parameters:
status? — Migration status (fetched if omitted)
Returns:
batchWithdraw / chunks — Signed batch withdrawal(s)
setOperator — Signed operator approval
migration.signAddressAuthorization(request)
Create a signature authorizing a third party to act on your behalf.
Parameters:
action — Migration action (“start” | “migrate” | “restore” | “dismiss”)
address? — Target wallet address
legacyOrderIds? — Specific order IDs this auth covers
deadline? — Unix timestamp when auth expires
Contract addresses
Holdings
| Network | Version | Address |
|---|
| Mainnet | V2 | 0x0000000000CcA5bC44912C63d63e1673FeE923f6 |
| Beta | V2 | 0xBed9a1A6CB168D60aD2C7770Be6B62bD9244D6d3 |
| Dev | V2 | 0xAbB9B71453F85393020771Ddde3d4cA44F52B9A9 |
Settlement
| Network | Version | Address |
|---|
| Mainnet | V2 | 0x00000000008c286A2aaa99c6Be3b3D405A929500 |
| Beta | V2 | 0xa9b830f4496b88c2d3C103fB96Df8f413031eBDD |
| Dev | V2 | 0x2E74b22204589279CC61c0994D011bF628F3bE47 |
Implementation checklist
Common patterns
Check if wallet needs migration
const status = await client.migration.getStatus({ address });
const needsMigration =
status.legacyBalances.length > 0 ||
status.pendingRestorations.length > 0;
Sponsored migrations are gasless. For manual migration:
- Batch withdraw: ~200k gas per token batch
- Operator approval: ~50k gas
- Order restoration: ~150k gas per order
Handle migration errors
Common errors:
"Sponsored migrate-funds is not available" — Relayer unavailable; offer manual flow
"Migration status did not include a sponsored relayer address" — Relayer not configured
"No funds migration chunks are available" — All funds already migrated
"Legacy settlement trading is disabled during holdings migration; migrate holdings and orders first" — The wallet still has legacy balances, legacy open orders, or pending/failed restorations and must complete migration before placing new orders
Contact support if migration fails unexpectedly.