Skip to main content
Closing follows the same client-signed prepare → sign → submit → poll flow as opening, with two differences:
  • No amount — close always sells the wallet’s full holding of the basket’s tokens. It is balance-driven: whatever of the basket the wallet holds gets closed, exactly what positions.getPosition reports. There is no partial close.
  • The prepare call is close.prepare / the one-call helper is close.execute.
Like opening, closing requires a write-scoped API key and the user’s wallet pays its own gas — it must hold some SOL.

One-call flow (you hold the keypair)

See Open a Position for a full signTransactions implementation with @solana/web3.js.

Split flow (browser wallet signs)

1

Backend: prepare

Send prepared.transactions to the browser immediately — the set expires ~60 seconds after prepare.
2

Browser: the user signs

Sign the transactions as-is — any modified byte is rejected at submit. Same signing code as the open flow.
3

Backend: submit and wait

Method reference

close.prepare(params)

user
string
required
Solana address of the wallet closing the position.
slug
string
required
Basket to close, by slug (a product id also works).
Returns { executionId, transactions, expiresAt }. positions.submit, getExecution, and waitForExecution are shared with the open flow — see the method reference there.

Results, errors, and security

Terminal statuses (COMPLETED, PARTIALLY_COMPLETED, FAILED), partial-completion semantics, the common-error table, and the security model are identical to opening — see Open a Position. Two close-specific notes:
  • A wallet with no holdings of the basket has nothing to sell — check positions.getPosition(...).hasPosition before preparing a close.
  • A PARTIALLY_COMPLETED close means some legs sold and some didn’t; the remaining holdings are still in the wallet and a fresh close.prepare will target exactly what’s left.