Skip to main content

Trading

Trading uses a queued RequestTrade DTO through the swap backend's chain-gateway route. The SDK resolves the input tokens, chooses the canonical symbols, creates a uniqueKey, signs the DTO, and submits the request. The HTTP 201 acknowledgement means the chain accepted the request; it does not mean the swap has executed.

The examples on this page continue from the gSwap client built in Getting started (with a signer) and run in an ES module (top-level await).

Exact input​

Sell exactly 100 GALA and protect the minimum output with amountOutMinimum:

import BigNumber from 'bignumber.js'; // a dependency of the SDK; install it in your own app too

const quote = await gSwap.quoting.quoteExactInput('GALA', 'GUSDC', '100');
const tx = await gSwap.swaps.swap('GALA', 'GUSDC', quote.feeTier, {
exactIn: '100',
// The least you accept: 1% under the quote. A bound equal to the quote is rejected whenever the
// price moves between the quote and the apply a few seconds later.
amountOutMinimum: new BigNumber(quote.amountOut).multipliedBy('0.99').toFixed(),
});
console.log(tx.mode, tx.uniqueKey, tx.transactionId, tx.result);
const applied = await tx.confirm();
console.log(applied.result);

Exact output​

Buy exactly 50 GUSDC and cap the amount of GALA spent:

import BigNumber from 'bignumber.js';

const quote = await gSwap.quoting.quoteExactOutput('GALA', 'GUSDC', '50');
const tx = await gSwap.swaps.swap('GALA', 'GUSDC', quote.feeTier, {
exactOut: '50',
amountInMaximum: new BigNumber(quote.amountIn).multipliedBy('1.01').toFixed(), // pay at most 1% more than quoted
});
const applied = await tx.confirm();
console.log(applied.result);

exactIn and exactOut are mutually exclusive. Their corresponding slippage fields are also directional: amountOutMinimum protects an exact-input trade, while amountInMaximum protects an exact-output trade. TypeScript refuses a trade that supplies both sides; plain JavaScript is not checked at runtime and the exact-input side wins, so supply exactly one.

An optional positive priceLimit (a sqrt-price limit) can be added to either form and is sent to the chain as the DTO's priceLimit.

Unique keys​

Every write carries a fresh uniqueKey of the form <prefix><uuid>. The default prefix is galaswap-operation-, what the Gala Wallet and the gSwap web app send. Set uniqueKeyPrefix on new GSwap({ uniqueKeyPrefix }) to change it; it must be at most 92 characters of A-Z a-z 0-9 . _ : - so the key remains readable by the apply-results endpoint.

What happens after submit​

The returned SubmittedTransaction has mode === 'queued', result === undefined, and a stable uniqueKey. Its transactionId is the request transaction when the gateway provides one. await tx.confirm() resolves an AppliedTrade with uniqueKey, the apply transactionId and blockNumber, the requestTransactionId, and a result containing token0, token1, fee, and applicable decimal-string quantities and fee fields.

For example, the applied fixture contains token0: 'GALA', token1: 'GUSDC', fee: 3000, sell0Qty: '0.99999996', and buy1Qty: '0.1202'. A Status: 0 apply result throws CHAIN_REJECTED, with the chain's ErrorKey as params.errorKey and its text as params.serverMessage; the rejected fixture has errorKey VALIDATION_FAILED and serverMessage Slippage limit: trade would return 0.120199 GUSDC, below the required minimum 999999999. Map params.errorKey to your own text; the server's English is data to relay or ignore. classifyFailure(error) tells you whether Retry is safe (see Error Handling).

There is no synchronous swap and no fallback to one. See Transaction Status.

The current backend route is method-specific and the body is the signed DTO itself.