From fb492944aa7ffe02b5ccfafa0f75e46e552d3f7f Mon Sep 17 00:00:00 2001 From: brianshattuck Date: Thu, 17 Sep 2026 00:53:54 +0900 Subject: [PATCH 1/4] feat(sdk): add anubis chain --- packages/sdk/src/constants.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/sdk/src/constants.ts b/packages/sdk/src/constants.ts index 76a2cfb..5806ebe 100755 --- a/packages/sdk/src/constants.ts +++ b/packages/sdk/src/constants.ts @@ -25,7 +25,8 @@ export enum ChainId { SOMNIA_TESTNET = 50312, BASE = 8453, SOMNIA = 5031, - MANTRA = 5888 + MANTRA = 5888, + ANUBIS = 6714, } export enum TradeType { @@ -61,7 +62,8 @@ export const FACTORY_ADDRESS = { [ChainId.SOMNIA_TESTNET]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32', //DUMMY [ChainId.BASE]: '0xEC6540261aaaE13F236A032d454dc9287E52e56A', [ChainId.SOMNIA]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32', //DUMMY - [ChainId.MANTRA]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32' //DUMMY + [ChainId.MANTRA]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32', //DUMMY + [ChainId.ANUBIS]: '0x10253594A832f967994b44f33411940533302ACb' } export const INIT_CODE_HASH = '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' From c02acaa86612b81fcdf26dcd29444db4f266d00c Mon Sep 17 00:00:00 2001 From: brianshattuck Date: Thu, 17 Sep 2026 00:54:11 +0900 Subject: [PATCH 2/4] feat(sdk): bump up version --- packages/sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 8840057..0fa5d9e 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,7 +1,7 @@ { "name": "@quickswap-defi/sdk", "license": "MIT", - "version": "1.0.1", + "version": "1.0.2", "description": "🛠 An SDK for building applications on top of Quickswap.", "main": "dist/index.js", "typings": "dist/index.d.ts", From a687f73a7ebc7da35b02ca39c99a0f7990feab08 Mon Sep 17 00:00:00 2001 From: brianshattuck Date: Fri, 18 Sep 2026 01:32:28 +0900 Subject: [PATCH 3/4] feat(sdk): add native currency DAI and a wrapped dummy currency --- packages/sdk/src/entities/currency.ts | 3 ++- packages/sdk/src/entities/token.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/sdk/src/entities/currency.ts b/packages/sdk/src/entities/currency.ts index a9e392b..f03424e 100755 --- a/packages/sdk/src/entities/currency.ts +++ b/packages/sdk/src/entities/currency.ts @@ -39,7 +39,8 @@ export class Currency { [ChainId.SOMNIA_TESTNET]: new Currency(18, 'STT', 'Somnia Testnet Tokens'), [ChainId.BASE]: new Currency(18, 'ETH', 'Ether'), [ChainId.SOMNIA]: new Currency(18, 'SOMI', 'Somnia Tokens'), - [ChainId.MANTRA]: new Currency(18, 'MANTRA', 'Mantra Token') + [ChainId.MANTRA]: new Currency(18, 'MANTRA', 'Mantra Token'), + [ChainId.ANUBIS]: new Currency(18, 'DAI', 'DAI'), } /** diff --git a/packages/sdk/src/entities/token.ts b/packages/sdk/src/entities/token.ts index 18ce637..6db3253 100755 --- a/packages/sdk/src/entities/token.ts +++ b/packages/sdk/src/entities/token.ts @@ -156,5 +156,12 @@ export const WETH = { 18, 'WMANTRA', 'Wrapped MANTRA' - ) + ), + [ChainId.ANUBIS]: new Token( + ChainId.ANUBIS, + '0x4200000000000000000000000000000000000006', + 18, + 'WDAI', + 'Wrapped DAI' + ), } From 2ab664aaabb4b614d099d5c9817b668ce3ae87e5 Mon Sep 17 00:00:00 2001 From: Henry Palacios <4270166+henrypalacios@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:56:42 -0300 Subject: [PATCH 4/4] fix(sdk): model chains without a wrapped native token Anubis pays gas with the ERC-20 DAI and has no wrapped-native contract, so the WETH map cannot have an entry for it. Adding the chain id without one broke the DTS build because the map was inferred as exhaustive. - Type WETH as a partial record and resolve it through wrappedNative(), which fails fast instead of yielding a phantom token - Register DAI as the chain's native currency - Keep the V2 factory entry as a placeholder like other V4-only chains --- packages/sdk/src/constants.ts | 2 +- packages/sdk/src/entities/currency.ts | 2 +- packages/sdk/src/entities/route.ts | 8 +++---- packages/sdk/src/entities/token.ts | 18 +++++++------- packages/sdk/src/entities/trade.ts | 6 ++--- packages/sdk/test/native-currency.test.ts | 29 +++++++++++++++++++++++ 6 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 packages/sdk/test/native-currency.test.ts diff --git a/packages/sdk/src/constants.ts b/packages/sdk/src/constants.ts index 5806ebe..4f41e15 100755 --- a/packages/sdk/src/constants.ts +++ b/packages/sdk/src/constants.ts @@ -63,7 +63,7 @@ export const FACTORY_ADDRESS = { [ChainId.BASE]: '0xEC6540261aaaE13F236A032d454dc9287E52e56A', [ChainId.SOMNIA]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32', //DUMMY [ChainId.MANTRA]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32', //DUMMY - [ChainId.ANUBIS]: '0x10253594A832f967994b44f33411940533302ACb' + [ChainId.ANUBIS]: '0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32' //DUMMY } export const INIT_CODE_HASH = '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' diff --git a/packages/sdk/src/entities/currency.ts b/packages/sdk/src/entities/currency.ts index f03424e..7358044 100755 --- a/packages/sdk/src/entities/currency.ts +++ b/packages/sdk/src/entities/currency.ts @@ -40,7 +40,7 @@ export class Currency { [ChainId.BASE]: new Currency(18, 'ETH', 'Ether'), [ChainId.SOMNIA]: new Currency(18, 'SOMI', 'Somnia Tokens'), [ChainId.MANTRA]: new Currency(18, 'MANTRA', 'Mantra Token'), - [ChainId.ANUBIS]: new Currency(18, 'DAI', 'DAI'), + [ChainId.ANUBIS]: new Currency(18, 'DAI', 'Dai Stablecoin') } /** diff --git a/packages/sdk/src/entities/route.ts b/packages/sdk/src/entities/route.ts index 816cde9..33ca5ff 100755 --- a/packages/sdk/src/entities/route.ts +++ b/packages/sdk/src/entities/route.ts @@ -2,7 +2,7 @@ import { ChainId } from '../constants' import invariant from 'tiny-invariant' import { Currency, ETHER } from './currency' -import { Token, WETH } from './token' +import { Token, wrappedNative } from './token' import { Pair } from './pair' import { Price } from './fractions/price' @@ -21,17 +21,17 @@ export class Route { ) invariant( (input instanceof Token && pairs[0].involvesToken(input)) || - (input === ETHER[pairs[0].chainId] && pairs[0].involvesToken(WETH[pairs[0].chainId])), + (input === ETHER[pairs[0].chainId] && pairs[0].involvesToken(wrappedNative(pairs[0].chainId))), 'INPUT' ) invariant( typeof output === 'undefined' || (output instanceof Token && pairs[pairs.length - 1].involvesToken(output)) || - (output === ETHER[pairs[0].chainId] && pairs[pairs.length - 1].involvesToken(WETH[pairs[0].chainId])), + (output === ETHER[pairs[0].chainId] && pairs[pairs.length - 1].involvesToken(wrappedNative(pairs[0].chainId))), 'OUTPUT' ) - const path: Token[] = [input instanceof Token ? input : WETH[pairs[0].chainId]] + const path: Token[] = [input instanceof Token ? input : wrappedNative(pairs[0].chainId)] for (const [i, pair] of pairs.entries()) { const currentInput = path[i] invariant(currentInput.equals(pair.token0) || currentInput.equals(pair.token1), 'PATH') diff --git a/packages/sdk/src/entities/token.ts b/packages/sdk/src/entities/token.ts index 6db3253..cdb7773 100755 --- a/packages/sdk/src/entities/token.ts +++ b/packages/sdk/src/entities/token.ts @@ -56,7 +56,7 @@ export function currencyEquals(currencyA: Currency, currencyB: Currency): boolea } } -export const WETH = { +export const WETH: Partial> = { [ChainId.MUMBAI]: new Token( ChainId.MUMBAI, '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889', @@ -156,12 +156,12 @@ export const WETH = { 18, 'WMANTRA', 'Wrapped MANTRA' - ), - [ChainId.ANUBIS]: new Token( - ChainId.ANUBIS, - '0x4200000000000000000000000000000000000006', - 18, - 'WDAI', - 'Wrapped DAI' - ), + ) + // ChainId.ANUBIS has no entry: its gas token is the ERC-20 DAI and there is no wrapped-native contract. +} + +export function wrappedNative(chainId: ChainId): Token { + const token = WETH[chainId] + invariant(token, 'WRAPPED_NATIVE') + return token } diff --git a/packages/sdk/src/entities/trade.ts b/packages/sdk/src/entities/trade.ts index f13c89e..36ba5ef 100755 --- a/packages/sdk/src/entities/trade.ts +++ b/packages/sdk/src/entities/trade.ts @@ -11,7 +11,7 @@ import { Price } from './fractions/price' import { TokenAmount } from './fractions/tokenAmount' import { Pair } from './pair' import { Route } from './route' -import { currencyEquals, Token, WETH } from './token' +import { currencyEquals, Token, wrappedNative } from './token' /** * Returns the percent difference between the mid price and the execution price, i.e. price impact. @@ -90,13 +90,13 @@ export interface BestTradeOptions { */ function wrappedAmount(currencyAmount: CurrencyAmount, chainId: ChainId): TokenAmount { if (currencyAmount instanceof TokenAmount) return currencyAmount - if (currencyAmount.currency === ETHER[chainId]) return new TokenAmount(WETH[chainId], currencyAmount.raw) + if (currencyAmount.currency === ETHER[chainId]) return new TokenAmount(wrappedNative(chainId), currencyAmount.raw) invariant(false, 'CURRENCY') } function wrappedCurrency(currency: Currency, chainId: ChainId): Token { if (currency instanceof Token) return currency - if (currency === ETHER[chainId]) return WETH[chainId] + if (currency === ETHER[chainId]) return wrappedNative(chainId) invariant(false, 'CURRENCY') } diff --git a/packages/sdk/test/native-currency.test.ts b/packages/sdk/test/native-currency.test.ts new file mode 100644 index 0000000..c98f0b5 --- /dev/null +++ b/packages/sdk/test/native-currency.test.ts @@ -0,0 +1,29 @@ +import { ChainId, Currency, WETH, wrappedNative } from '../src' + +describe('The native currency', () => { + describe('on a chain whose gas token is an ERC-20 with no wrapped contract', () => { + it('describes the gas token so wallets can display balances', () => { + const native = Currency.ETHER[ChainId.ANUBIS] + + expect(native.symbol).toBe('DAI') + expect(native.decimals).toBe(18) + }) + + it('exposes no wrapped token', () => { + expect(WETH[ChainId.ANUBIS]).toBeUndefined() + }) + + it('rejects wrapping instead of returning a phantom token', () => { + expect(() => wrappedNative(ChainId.ANUBIS)).toThrow('WRAPPED_NATIVE') + }) + }) + + describe('on a chain with a wrapped native token', () => { + it('resolves the wrapped token for routing', () => { + const wrapped = wrappedNative(ChainId.ETHEREUM) + + expect(wrapped.chainId).toBe(ChainId.ETHEREUM) + expect(wrapped.symbol).toBe('WETH') + }) + }) +})