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).
request trade unique key
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);
amount out minimum
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.
exact in out amount minimum maximum price limit
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.
unique key prefix
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.
submitted transaction unique key id applied trade block number request sell0 qty buy1 chain rejected error server message validation failed classify failure