Migration from 0.x
The 1.0 line (1.0.0) is a breaking migration to the current GalaChain DEX contract. Legacy names are removed; do not add compatibility fields to v2 DTOs.
From 1.2.x to 2.0.0: signing moved to @gala-chain/gala-core-sdk
The signing, transport, wallet-helper and base-error layer moved out of this
package into the peer package @gala-chain/gala-core-sdk. The DEX API, the write
protocol and the DTOs are unchanged. Install both packages
(npm install @gala-chain/gswap-sdk @gala-chain/gala-core-sdk); the peer range is ^1.0.0.
| 1.2.x | 2.0.0 |
|---|---|
import { PrivateKeySigner, GalaWalletSigner, BrowserWalletSigner, serialize, signNative, ... } from '@gala-chain/gswap-sdk' | The same names from @gala-chain/gala-core-sdk (no re-export from this package) |
@gala-chain/gswap-sdk/wallet | @gala-chain/gala-core-sdk/wallet |
isGSwapErrorLike, GSwapErrorShape, GSWAP_ERROR_PHASES, GSwapErrorPhase, GSwapErrorContext, renderGSwapErrorTemplate | isGalaErrorLike, GalaErrorShape, GALA_ERROR_PHASES, GalaErrorPhase, GalaErrorContext, renderGalaErrorTemplate |
Error brand Symbol.for('@gala-chain/gswap-sdk/error') | Symbol.for('@gala-chain/gala-core-sdk/error') |
error instanceof GSwapSDKError | isGSwapError(error) or core's isGalaError(error): a signer or transport error is a plain GalaSDKError |
gswapErrorTemplates held every code | DEX codes only; merge with core's galaErrorTemplates |
See core's Migrating from gswap-sdk 1.x for the full old-path to new-path table.
private key signer gala wallet browser sign native is swap error like shape gswap phases phase context render template sdk templates
From 1.1.x to 1.2.0 (release candidates on the rc tag)
The 1.2.0 line changes how errors reach your code. The write protocol and DTOs are unchanged.
| 1.1.x | 1.2.0-rc |
|---|---|
new GSwapSDKError(message, code, details), error.details, userMessage, chainMessage | new GSwapSDKError(code, params, context); error.params (flat primitives), typed status, url, uniqueKey, requestTransactionId, applyTransactionId, blockNumber, retryAfterMs, body, bodyText, cause. error.message is English for logs only; branch on code. |
A chain ErrorKey as error.code | CHAIN_REJECTED with params.errorKey and params.serverMessage |
VALIDATION_ERROR / INVALID_GATEWAY_RESPONSE with details.type | One code per fault (INVALID_FEE, NON_CANONICAL_PAIR, GATEWAY_DATA_MISSING, ...) |
| Retry and outcome rules kept in each app | classifyFailure(error), isNoMarket, mayHaveBeenQueued, pendingSwapFateFor |
Signing through @gala-chain/api | The SDK's own primitives on @noble/curves / @noble/hashes; @gala-chain/api is a devDependency only |
GalaWalletSigner fell back to personal-sign on a wallet that rejected native | No fallback; { scheme: 'personal-sign' } is explicit and needs a wallet build with the fix |
See Error Handling and Signing and Identity.
swap sdk error user message chain unique key request transaction id apply block number retry after ms body text rejected server validation invalid gateway response fee non canonical pair data missing classify failure is no market may have been queued pending fate for gala wallet signer
Changes between 1.0.0-rc.3 and 1.0.0-rc.4
A class key carries no symbol. Collection and symbol disagree for many tokens (GBNB's symbol is
BNB, every launchpad token shares the collection Token, and some real collections contain the
$ delimiter, e.g. $GMUSIC), so the SDK never derives one from the other.
createPoolfor a token with no registered trading symbol now needs one. Passtoken0Symbol/token1Symbol(ASCII letters and digits); without it the call throwsTOKEN_SYMBOL_NOT_REGISTEREDinstead of proposing the raw collection (which the bouncer rejects for any collection containing_or$, and always for launchpad tokens). A symbol that disagrees with the one already registered for that class is rejected. The CLI'screate_pooltakes the two optional symbol arguments.- Class keys parse from the right. The last three segments are category, type and
additionalKey; everything before them is the collection, so
$GMUSIC$Unit$none$noneresolves instead of failing as a five-part key. - Docs and examples no longer treat
collectionas the symbol (full_dexpasses full class keys and carries an explicitsymbolper token).
create pool token0 symbol token1 token not registered gmusic unit none full dex
Changes between 1.0.0-rc.2 and 1.0.0-rc.3
BrowserWalletSignerpersonal-sign now signs the bare serialized DTO and sends the EIP-191 header (\u0019Ethereum Signed Message:\n<byte length>) as the DTO'sprefix. The previous recipe embeddedprefixin the signed message, which the chain recovers to an address nobody holds, so a personal-signCreatePoolcould execute under a phantom creator; the swap backend now rejects that shape. No caller changes are needed; re-sign nothing.GalaWalletSigner's personal-sign scheme carries the same header value (the wallet prepends it before hashing).
browser wallet signer u0019 ethereum create pool gala
Changes between 1.0.0-rc.1 and 1.0.0-rc.2
Swaps are queued. The synchronous Trade method was removed from the contract
and from this SDK, with no fallback.
| rc.1 | rc.2 |
|---|---|
swaps.swap() signed and submitted Trade; the executed result came back inline | signs and submits RequestTrade; the gateway acknowledges with mode: 'queued' and result === undefined |
SubmittedTransaction.mode was always 'sync' | 'sync' for liquidity writes, 'queued' for swaps |
confirm() polled the indexed transaction and returned IndexedTransaction | reads apply-results and returns AppliedTrade (apply transactionId, blockNumber, requestTransactionId, executed result), or throws the chain's rejection (in 1.1.x its ErrorKey was error.code; since 1.2.0-rc.3 it is CHAIN_REJECTED with params.errorKey) |
| — | swaps.confirmSwap(uniqueKey) resolves a swap from the persisted key alone |
TradeDTO | RequestTradeDTO (same fields) |
ConfirmOptions had timeoutMs, pollIntervalMs | adds initialDelayMs (default 3 s for swaps, 0 for liquidity writes) |
CONFIRMATION_TIMEOUT meant "not indexed yet" | means the outcome is unknown: confirm the same key again, never resubmit |
gateway.submit('Trade', …) | refused locally with METHOD_NOT_SUPPORTED |
request trade submitted transaction indexed applied id block number error key chain rejected confirm swap unique dto options timeout ms poll interval initial delay confirmation method not supported
API replacements
| 0.x | v2 replacement |
|---|---|
Bundler | Chain Gateway writes through GSwap |
Events / EventSocketClient | No per-transaction event socket; call SubmittedTransaction.confirm(). Pool, balance and swap events: gSwap.stream (GdexStreamService) |
PendingTransaction | SubmittedTransaction |
TxWaiter | SubmittedTransaction.confirm() |
PendingTransaction.wait() | SubmittedTransaction.confirm() |
TransactionPendingResponse | AppliedTrade returned by confirm() for a queued swap |
stringsInstructions | Removed; the gateway derives chain references |
| bundle IDs | uniqueKey |
transactionId as the only correlation key | uniqueKey; request transactionId may be null |
GSwap.events.connectEventSocket() | Removed |
GSwap.swap(...) | gSwap.swaps.swap(tokenIn, tokenOut, fee, params) |
pools.getPoolData(...) | pools.getPool(...) |
positions.getPositionById(...) | positions.getPosition({ token0, token1, fee, owner, tickLower, tickUpper }) |
event socket client submitted transaction gdex stream service pending tx waiter response applied trade strings instructions unique key id connect token in out get pool data position by tick lower upper
DTO field replacements
| Removed field or shape | v2 shape |
|---|---|
Class-key object token0 / token1 in writes | Trading-symbol token0 / token1; SDK accepts a symbol or class key as input |
amount | One of sell0Qty, sell1Qty, buy0Qty, buy1Qty |
zeroForOne | Derived from token ordering and exact-in/exact-out side |
sqrtPriceLimit | Renamed priceLimit (optional, a sqrt-price limit on the swap amount argument); for slippage use amountOutMinimum / amountInMaximum |
positionId | Position identity: symbols, fee, owner, and tick range |
amount0Desired, amount1Desired | Exactly one depositQuantityToken0 or depositQuantityToken1 |
amount0Min, amount1Min | amountOutMinimum for trades, or estimate before a liquidity write |
| Partial collect amounts | Removed; collectPositionFees sweeps everything |
| Partial remove percentage | Optional withdrawalQuantityToken0 or withdrawalQuantityToken1; omit both to close |
CreatePool class-key token0 / token1 | token0Key / token1Key plus token0Symbol / token1Symbol |
FEE_TIER without zero | Fee tiers 0, 500, 3000, 10000 |
sell0 qty sell1 buy0 buy1 zero for one sqrt price limit amount out minimum in maximum position id amount0 desired amount1 deposit quantity token0 token1 min collect fees withdrawal key symbol fee tier
Transaction flow
Build a quote, choose the fee and slippage bound, submit through the SDK, then
persist uniqueKey and confirm. A queued swap acknowledgement has
mode: 'queued', no result, and a request transactionId when provided; the
applied outcome is returned by confirm().
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',
// pay at most 1% more than quoted
amountInMaximum: new BigNumber(quote.amountIn).multipliedBy('1.01').toFixed(),
});
await tx.confirm();
unique key transaction id
Signing migration
PrivateKeySigner remains native. GalaWalletSigner no longer signs EIP-712;
it uses native gala_signChainDto. The older-wallet personal-sign fallback was removed
(on released wallets it recovered a phantom signer); scheme: 'personal-sign' remains as an
explicit opt-in that requires a wallet build containing the fix.
Use BrowserWalletSigner for generic EIP-1193 wallets. See
Signing and Identity.
private key signer gala wallet sign chain dto browser