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.Migration process
The SDK handles migrations via themigration module. Here’s the flow:
1. Check migration status
2. Initiate migration
3. Migrate funds (sponsored)
IfsponsoredFundsMigrationAvailable is true, funds can be migrated gaslessly:
4. Restore legacy orders
Legacy limit orders can be restored as new Settlement V2 orders:5. Dismiss orders (optional)
If a user wants to skip migrating specific legacy orders: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, ...) |
batchTransferFrom()— Execute batch transfers on behalf of users via EIP-712 signaturebatchDepositMultipleRecipients()— 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 |
- V1: buys denominated in
price × size(shares), payable amount computed at fill time - V2: buys denominated in
maxCollateralIn(budget) andminSharesOut(guaranteed output)
- V1: separate
SignedOrderandMarketOrderIntentstructures - V2: one
SignedOrdertype for both limit and market orders
- BUY orders:
consumed = buyerCollateralAmount + fees - SELL orders:
consumed = shareAmount
- Use
Holdings.depositWithPermit()followed bySettlement.mintCompleteSetsFromHoldings()instead
BURN_FROM_HOLDINGS_TYPEHASHMINT_FROM_HOLDINGS_TYPEHASHORDER_KIND_BUYORDER_KIND_SELL_INVENTORYORDER_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)
migration.start(request?)
Initiate the migration process.
Parameters:
address?— Target wallet addressauthorization?— 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 withdrawalssetOperator— Signed operator approval for Settlement V2address?— 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 addressauthorization?— Signed authorization message
migration.signSponsoredMigrateFunds(status?)
Sign fund migration for sponsored relayer execution.
Parameters:
status?— Migration status (fetched if omitted)
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 addresslegacyOrderIds?— Specific order IDs this auth coversdeadline?— 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
- Add
@contextwtf/sdkversion 0.7.0+ (includes migration module) - Call
client.migration.getStatus()to check if migration is needed - Present migration flow UI (status → approve → sign → confirm)
- Handle sponsored vs. manual migration based on
sponsoredFundsMigrationAvailable - For legacy orders, show
pendingRestorationsand let user select which to restore - Test with migration testnet (set chain config to testnet deployment)
- Monitor
OperatorSetevent on Holdings to confirm operator approval
Common patterns
Check if wallet needs migration
Estimate gas (unsponsored migration)
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