@mania-labs/mania-sdk 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/abi.ts CHANGED
@@ -199,6 +199,141 @@ export const MANIA_FACTORY_ABI = [
199
199
  },
200
200
  ] as const;
201
201
 
202
+ export const QUOTER_V2_ABI = [
203
+ {
204
+ inputs: [
205
+ { internalType: "address", name: "_factory", type: "address" },
206
+ { internalType: "address", name: "_WETH9", type: "address" },
207
+ ],
208
+ stateMutability: "nonpayable",
209
+ type: "constructor",
210
+ },
211
+ {
212
+ inputs: [],
213
+ name: "WETH9",
214
+ outputs: [{ internalType: "address", name: "", type: "address" }],
215
+ stateMutability: "view",
216
+ type: "function",
217
+ },
218
+ {
219
+ inputs: [],
220
+ name: "factory",
221
+ outputs: [{ internalType: "address", name: "", type: "address" }],
222
+ stateMutability: "view",
223
+ type: "function",
224
+ },
225
+ {
226
+ inputs: [
227
+ { internalType: "bytes", name: "path", type: "bytes" },
228
+ { internalType: "uint256", name: "amountIn", type: "uint256" },
229
+ ],
230
+ name: "quoteExactInput",
231
+ outputs: [
232
+ { internalType: "uint256", name: "amountOut", type: "uint256" },
233
+ { internalType: "uint160[]", name: "sqrtPriceX96AfterList", type: "uint160[]" },
234
+ { internalType: "uint32[]", name: "initializedTicksCrossedList", type: "uint32[]" },
235
+ { internalType: "uint256", name: "gasEstimate", type: "uint256" },
236
+ ],
237
+ stateMutability: "nonpayable",
238
+ type: "function",
239
+ },
240
+ {
241
+ inputs: [
242
+ {
243
+ components: [
244
+ { internalType: "address", name: "tokenIn", type: "address" },
245
+ { internalType: "address", name: "tokenOut", type: "address" },
246
+ { internalType: "uint256", name: "amountIn", type: "uint256" },
247
+ { internalType: "uint24", name: "fee", type: "uint24" },
248
+ { internalType: "uint160", name: "sqrtPriceLimitX96", type: "uint160" },
249
+ ],
250
+ internalType: "struct IQuoterV2.QuoteExactInputSingleParams",
251
+ name: "params",
252
+ type: "tuple",
253
+ },
254
+ ],
255
+ name: "quoteExactInputSingle",
256
+ outputs: [
257
+ { internalType: "uint256", name: "amountOut", type: "uint256" },
258
+ { internalType: "uint160", name: "sqrtPriceX96After", type: "uint160" },
259
+ { internalType: "uint32", name: "initializedTicksCrossed", type: "uint32" },
260
+ { internalType: "uint256", name: "gasEstimate", type: "uint256" },
261
+ ],
262
+ stateMutability: "nonpayable",
263
+ type: "function",
264
+ },
265
+ {
266
+ inputs: [
267
+ { internalType: "bytes", name: "path", type: "bytes" },
268
+ { internalType: "uint256", name: "amountOut", type: "uint256" },
269
+ ],
270
+ name: "quoteExactOutput",
271
+ outputs: [
272
+ { internalType: "uint256", name: "amountIn", type: "uint256" },
273
+ { internalType: "uint160[]", name: "sqrtPriceX96AfterList", type: "uint160[]" },
274
+ { internalType: "uint32[]", name: "initializedTicksCrossedList", type: "uint32[]" },
275
+ { internalType: "uint256", name: "gasEstimate", type: "uint256" },
276
+ ],
277
+ stateMutability: "nonpayable",
278
+ type: "function",
279
+ },
280
+ {
281
+ inputs: [
282
+ {
283
+ components: [
284
+ { internalType: "address", name: "tokenIn", type: "address" },
285
+ { internalType: "address", name: "tokenOut", type: "address" },
286
+ { internalType: "uint256", name: "amount", type: "uint256" },
287
+ { internalType: "uint24", name: "fee", type: "uint24" },
288
+ { internalType: "uint160", name: "sqrtPriceLimitX96", type: "uint160" },
289
+ ],
290
+ internalType: "struct IQuoterV2.QuoteExactOutputSingleParams",
291
+ name: "params",
292
+ type: "tuple",
293
+ },
294
+ ],
295
+ name: "quoteExactOutputSingle",
296
+ outputs: [
297
+ { internalType: "uint256", name: "amountIn", type: "uint256" },
298
+ { internalType: "uint160", name: "sqrtPriceX96After", type: "uint160" },
299
+ { internalType: "uint32", name: "initializedTicksCrossed", type: "uint32" },
300
+ { internalType: "uint256", name: "gasEstimate", type: "uint256" },
301
+ ],
302
+ stateMutability: "nonpayable",
303
+ type: "function",
304
+ },
305
+ {
306
+ inputs: [
307
+ { internalType: "int256", name: "amount0Delta", type: "int256" },
308
+ { internalType: "int256", name: "amount1Delta", type: "int256" },
309
+ { internalType: "bytes", name: "path", type: "bytes" },
310
+ ],
311
+ name: "uniswapV3SwapCallback",
312
+ outputs: [],
313
+ stateMutability: "view",
314
+ type: "function",
315
+ },
316
+ ] as const;
317
+
318
+ export const UNISWAP_V3_FACTORY_ABI = [
319
+ {
320
+ inputs: [],
321
+ stateMutability: "nonpayable",
322
+ type: "constructor",
323
+ },
324
+ {
325
+ inputs: [
326
+ { internalType: "address", name: "tokenA", type: "address" },
327
+ { internalType: "address", name: "tokenB", type: "address" },
328
+ { internalType: "uint24", name: "fee", type: "uint24" },
329
+ ],
330
+ name: "getPool",
331
+ outputs: [{ internalType: "address", name: "", type: "address" }],
332
+ stateMutability: "view",
333
+ type: "function",
334
+ },
335
+ ] as const;
336
+
202
337
  export const ERC20_ABI = [
203
338
  {
204
339
  type: "function",
package/src/constants.ts CHANGED
@@ -43,6 +43,7 @@ export interface ChainConfig {
43
43
  wethAddress: Address;
44
44
  nonfungiblePositionManager: Address;
45
45
  uniswapV3Factory: Address;
46
+ quoterV2: Address;
46
47
  blockExplorer: string;
47
48
  }
48
49
 
@@ -60,8 +61,21 @@ export const CHAIN_CONFIGS: Record<number, ChainConfig> = {
60
61
  nonfungiblePositionManager:
61
62
  "0xa204A97EF8Bd2E3198f19EB5a804680467BD85f5" as Address,
62
63
  uniswapV3Factory: "0x619fb6C12c36b57a8bAb05e98F42C43745DCf69f" as Address,
64
+ quoterV2: "0xfb230b93803F90238cB03f254452bA3a3b0Ec38d" as Address,
63
65
  blockExplorer: "https://megaeth-testnet-v2.blockscout.com",
64
66
  },
67
+ // Mega Eth Mainnet
68
+ 4326: {
69
+ chainId: 4326,
70
+ name: "Mega Eth Mainnet",
71
+ factoryAddress: "0xb2f6344Cb0Ee13e027759166770198f4d8B3106d" as Address,
72
+ wethAddress: "0x4200000000000000000000000000000000000006" as Address,
73
+ nonfungiblePositionManager:
74
+ "0x2b781C57e6358f64864Ff8EC464a03Fdaf9974bA" as Address,
75
+ uniswapV3Factory: "0x68b34591f662508076927803c567Cc8006988a09" as Address,
76
+ quoterV2: "0x1F1a8dC7E138C34b503Ca080962aC10B75384a27" as Address,
77
+ blockExplorer: "https://megaeth.blockscout.com/",
78
+ },
65
79
  };
66
80
 
67
81
  /**
package/src/index.ts CHANGED
@@ -68,4 +68,4 @@ export {
68
68
  } from "./utils.js";
69
69
 
70
70
  // ABIs
71
- export { MANIA_FACTORY_ABI, ERC20_ABI } from "./abi.js";
71
+ export { MANIA_FACTORY_ABI, ERC20_ABI, QUOTER_V2_ABI, UNISWAP_V3_FACTORY_ABI } from "./abi.js";
package/src/mania.ts CHANGED
@@ -28,9 +28,11 @@ import type {
28
28
  import { BondingCurve } from "./bondingCurve.js";
29
29
  import {
30
30
  DEFAULT_SLIPPAGE_BPS,
31
+ UNISWAP_FEE_TIER,
31
32
  getChainConfig,
33
+ type ChainConfig,
32
34
  } from "./constants.js";
33
- import { MANIA_FACTORY_ABI } from "./abi.js";
35
+ import { MANIA_FACTORY_ABI, QUOTER_V2_ABI, UNISWAP_V3_FACTORY_ABI, ERC20_ABI } from "./abi.js";
34
36
 
35
37
  /**
36
38
  * ManiaSDK - Official SDK for interacting with the Mania Protocol
@@ -216,7 +218,7 @@ export class ManiaSDK {
216
218
 
217
219
  /**
218
220
  * Get comprehensive token information
219
- *
221
+ *
220
222
  * @param token - Token address
221
223
  */
222
224
  async getTokenInfo(token: Address): Promise<TokenInfo> {
@@ -232,6 +234,19 @@ export class ManiaSDK {
232
234
  };
233
235
  }
234
236
 
237
+ /**
238
+ * Get token name and symbol
239
+ *
240
+ * @param token - Token address
241
+ */
242
+ async getTokenMetadata(token: Address): Promise<{ name: string; symbol: string }> {
243
+ const [name, symbol] = await Promise.all([
244
+ this.publicClient.readContract({ address: token, abi: ERC20_ABI, functionName: "name" }),
245
+ this.publicClient.readContract({ address: token, abi: ERC20_ABI, functionName: "symbol" }),
246
+ ]);
247
+ return { name: name as string, symbol: symbol as string };
248
+ }
249
+
235
250
  /**
236
251
  * Get buy quote from contract
237
252
  *
@@ -654,4 +669,95 @@ export class ManiaSDK {
654
669
  getWalletClient(): WalletClient | null {
655
670
  return this.walletClient;
656
671
  }
672
+
673
+ // ========== MIGRATED TOKEN METHODS ==========
674
+
675
+ /**
676
+ * Get chain config or throw if not found
677
+ */
678
+ private getChainConfigOrThrow(): ChainConfig {
679
+ const config = getChainConfig(this.chainId);
680
+ if (!config) {
681
+ throw new Error(`Chain config not found for chain ID: ${this.chainId}`);
682
+ }
683
+ return config;
684
+ }
685
+
686
+ /**
687
+ * Get quote for buying tokens with ETH on Kumbaya DEX (Uniswap V3)
688
+ * Use this for tokens that have migrated from the bonding curve
689
+ *
690
+ * @param token - Token address
691
+ * @param ethAmount - ETH amount in wei
692
+ * @returns Token amount out
693
+ */
694
+ async getMigratedBuyQuote(token: Address, ethAmount: bigint): Promise<bigint> {
695
+ const chainConfig = this.getChainConfigOrThrow();
696
+
697
+ const { result } = await this.publicClient.simulateContract({
698
+ address: chainConfig.quoterV2,
699
+ abi: QUOTER_V2_ABI,
700
+ functionName: "quoteExactInputSingle",
701
+ args: [{
702
+ tokenIn: chainConfig.wethAddress,
703
+ tokenOut: token,
704
+ amountIn: ethAmount,
705
+ fee: UNISWAP_FEE_TIER,
706
+ sqrtPriceLimitX96: 0n,
707
+ }],
708
+ });
709
+
710
+ return result[0];
711
+ }
712
+
713
+ /**
714
+ * Get quote for selling tokens for ETH on Kumbaya DEX (Uniswap V3)
715
+ * Use this for tokens that have migrated from the bonding curve
716
+ *
717
+ * @param token - Token address
718
+ * @param tokenAmount - Token amount to sell
719
+ * @returns ETH amount out in wei
720
+ */
721
+ async getMigratedSellQuote(token: Address, tokenAmount: bigint): Promise<bigint> {
722
+ const chainConfig = this.getChainConfigOrThrow();
723
+
724
+ const { result } = await this.publicClient.simulateContract({
725
+ address: chainConfig.quoterV2,
726
+ abi: QUOTER_V2_ABI,
727
+ functionName: "quoteExactInputSingle",
728
+ args: [{
729
+ tokenIn: token,
730
+ tokenOut: chainConfig.wethAddress,
731
+ amountIn: tokenAmount,
732
+ fee: UNISWAP_FEE_TIER,
733
+ sqrtPriceLimitX96: 0n,
734
+ }],
735
+ });
736
+
737
+ return result[0];
738
+ }
739
+
740
+ /**
741
+ * Get the Uniswap V3 pool address for a token/WETH pair
742
+ *
743
+ * @param token - Token address
744
+ * @returns Pool address
745
+ * @throws Error if pool not found
746
+ */
747
+ async getPoolAddress(token: Address): Promise<Address> {
748
+ const chainConfig = this.getChainConfigOrThrow();
749
+
750
+ const poolAddress = await this.publicClient.readContract({
751
+ address: chainConfig.uniswapV3Factory,
752
+ abi: UNISWAP_V3_FACTORY_ABI,
753
+ functionName: "getPool",
754
+ args: [token, chainConfig.wethAddress, UNISWAP_FEE_TIER],
755
+ });
756
+
757
+ if (poolAddress === "0x0000000000000000000000000000000000000000") {
758
+ throw new Error(`Pool not found for token ${token}`);
759
+ }
760
+
761
+ return poolAddress as Address;
762
+ }
657
763
  }