├── .npmrc ├── src ├── hooks │ ├── index.ts │ └── FlaunchPositionManagerHooks.ts ├── utils │ ├── index.ts │ └── parseSwap.ts ├── helpers │ ├── index.ts │ ├── chainIdToChain.ts │ ├── hex.ts │ └── permissions.ts ├── abi │ ├── index.ts │ ├── FLETH.ts │ ├── FastFlaunchZap.ts │ ├── TreasuryManager.ts │ ├── StateView.ts │ ├── FeeEscrow.ts │ ├── UniversalRouter.ts │ ├── ReferralEscrow.ts │ ├── InitialPrice.ts │ ├── FairLaunch.ts │ ├── TokenImporter.ts │ ├── Multicall.ts │ └── TreasuryManagerFactory.ts ├── clients │ ├── MulticallClient.ts │ ├── TrustedSignerFeeCalculatorClient.ts │ ├── InitialPriceClient.ts │ ├── FlaunchV1_1Client.ts │ ├── FlaunchV1_2Client.ts │ ├── BidWallClient.ts │ ├── AnyBidWall.ts │ ├── BidWallV1_1Client.ts │ ├── FlaunchClient.ts │ ├── AnyFlaunchClient.ts │ ├── FairLaunchClient.ts │ ├── FeeEscrowClient.ts │ ├── Permit2Client.ts │ ├── ReferralEscrowClient.ts │ ├── TreasuryManagerFactoryClient.ts │ ├── FairLaunchV1_1Client.ts │ ├── StateViewClient.ts │ ├── TreasuryManagerClient.ts │ ├── MemecoinClient.ts │ ├── FastFlaunchClient.ts │ ├── RevenueManagerClient.ts │ ├── PoolManagerClient.ts │ └── TokenImporter.ts ├── index.ts ├── sdk │ ├── drift.ts │ ├── factory.ts │ ├── FlaunchBackend.ts │ └── calldata.ts ├── types.ts └── addresses.ts ├── .gitignore ├── .github └── flaunch-header.png ├── tsconfig.json ├── LICENSE ├── scripts └── generate-llms-doc.js ├── rollup.config.js ├── package.json └── PUBLISHING.md /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="@flaunch/sdk@" 2 | message="@flaunch/sdk v%s" -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./FlaunchPositionManagerHooks"; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | *.log 4 | coverage 5 | .env 6 | docs 7 | .rollup.cache 8 | dist -------------------------------------------------------------------------------- /.github/flaunch-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flayerlabs/flaunch-sdk/HEAD/.github/flaunch-header.png -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./univ4"; 2 | export * from "./parseSwap"; 3 | export * from "./universalRouter"; 4 | -------------------------------------------------------------------------------- /src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./hex"; 2 | export * from "./ipfs"; 3 | export * from "./chainIdToChain"; 4 | export * from "./permissions"; 5 | -------------------------------------------------------------------------------- /src/helpers/chainIdToChain.ts: -------------------------------------------------------------------------------- 1 | import { Chain } from "viem"; 2 | import { base, baseSepolia } from "viem/chains"; 3 | 4 | export const chainIdToChain: { 5 | [key: number]: Chain; 6 | } = { 7 | [base.id]: base, 8 | [baseSepolia.id]: baseSepolia, 9 | }; 10 | -------------------------------------------------------------------------------- /src/helpers/hex.ts: -------------------------------------------------------------------------------- 1 | import { encodeAbiParameters, Hex, hexToBigInt, pad } from "viem"; 2 | 3 | export const bytes32ToUint256 = (value: Hex) => { 4 | return hexToBigInt(value); 5 | }; 6 | 7 | export const uint256ToBytes32 = (value: bigint) => { 8 | return pad( 9 | encodeAbiParameters([{ type: "uint256", name: "value" }], [value]), 10 | { size: 32, dir: "right" } 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "esnext", 5 | "moduleResolution": "bundler", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "outDir": "./dist", 10 | "rootDir": "./src", 11 | "esModuleInterop": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "skipLibCheck": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "strict": true, 19 | "baseUrl": "src", 20 | "paths": { 21 | "*": ["*"] 22 | } 23 | }, 24 | "include": ["src/**/*"], 25 | "exclude": ["node_modules", "dist", "**/*.test.ts"] 26 | } 27 | -------------------------------------------------------------------------------- /src/abi/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AnyPositionManager"; 2 | export * from "./BidWall"; 3 | export * from "./BidWallV1_1"; 4 | export * from "./FairLaunch"; 5 | export * from "./FairLaunchV1_1"; 6 | export * from "./FastFlaunchZap"; 7 | export * from "./FeeEscrow"; 8 | export * from "./Flaunch"; 9 | export * from "./FlaunchPositionManager"; 10 | export * from "./FlaunchPositionManagerV1_1"; 11 | export * from "./FlaunchV1_1"; 12 | export * from "./FlaunchZap"; 13 | export * from "./InitialPrice"; 14 | export * from "./Memecoin"; 15 | export * from "./Multicall"; 16 | export * from "./Permit2"; 17 | export * from "./PoolManager"; 18 | export * from "./Quoter"; 19 | export * from "./ReferralEscrow"; 20 | export * from "./RevenueManager"; 21 | export * from "./StateView"; 22 | export * from "./TreasuryManagerFactory"; 23 | export * from "./UniversalRouter"; 24 | -------------------------------------------------------------------------------- /src/helpers/permissions.ts: -------------------------------------------------------------------------------- 1 | import { Address, zeroAddress } from "viem"; 2 | import { Permissions } from "../types"; 3 | import { 4 | ClosedPermissionsAddress, 5 | WhitelistedPermissionsAddress, 6 | } from "../addresses"; 7 | 8 | /** 9 | * Maps a Permissions enum value to its corresponding contract address 10 | * @param permissions - The permissions enum value 11 | * @param chainId - The chain ID to get the address for 12 | * @returns The corresponding permissions contract address 13 | */ 14 | export function getPermissionsAddress( 15 | permissions: Permissions, 16 | chainId: number 17 | ): Address { 18 | switch (permissions) { 19 | case Permissions.CLOSED: 20 | return ClosedPermissionsAddress[chainId]; 21 | case Permissions.WHITELISTED: 22 | return WhitelistedPermissionsAddress[chainId]; 23 | case Permissions.OPEN: 24 | default: 25 | return zeroAddress; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/clients/MulticallClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { MulticallAbi } from "../abi/Multicall"; 12 | 13 | export type MulticallABI = typeof MulticallAbi; 14 | 15 | export class ReadMulticall { 16 | // same address across all chains 17 | public readonly address: Address = 18 | "0xcA11bde05977b3631167028862bE2a173976CA11"; 19 | 20 | public readonly contract: ReadContract; 21 | 22 | constructor(drift: Drift) { 23 | this.contract = drift.contract({ 24 | abi: MulticallAbi, 25 | address: this.address, 26 | }); 27 | } 28 | 29 | aggregate3(calls: { target: Address; callData: HexString }[]) { 30 | return this.contract.simulateWrite("aggregate3", { 31 | calls: calls.map((call) => ({ 32 | target: call.target, 33 | allowFailure: true, 34 | callData: call.callData, 35 | })), 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) https://flaunch.gg/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { ReadFlaunchSDK, ReadWriteFlaunchSDK } from "./sdk/FlaunchSDK"; 2 | 3 | export * from "./abi"; 4 | export * from "./addresses"; 5 | export * from "./helpers"; 6 | export * from "./utils/univ4"; 7 | export * from "./utils/parseSwap"; 8 | export * from "./utils/universalRouter"; 9 | export * from "./types"; 10 | 11 | export type { 12 | BuySwapLog, 13 | SellSwapLog, 14 | BaseSwapLog, 15 | PoolCreatedLogs, 16 | PoolSwapLog, 17 | } from "./clients/FlaunchPositionManagerClient"; 18 | 19 | export { ReadFlaunchSDK, ReadWriteFlaunchSDK }; 20 | export { createFlaunch } from "./sdk/factory"; 21 | export type { CreateFlaunchParams } from "./sdk/factory"; 22 | export { createDrift } from "./sdk/drift"; 23 | 24 | // Calldata generation exports 25 | export { 26 | createFlaunchCalldata, 27 | decodeCallData, 28 | parseCall, 29 | createCallDataWalletClient, 30 | encodedCallAbi, 31 | } from "./sdk/calldata"; 32 | export type { 33 | CreateFlaunchCalldataParams, 34 | CallData, 35 | CallDataMethod, 36 | CallDataResult, 37 | } from "./sdk/calldata"; 38 | 39 | export { FlaunchBackend } from "./sdk/FlaunchBackend"; 40 | 41 | export const FlaunchSDK = { 42 | ReadFlaunchSDK, 43 | ReadWriteFlaunchSDK, 44 | }; 45 | -------------------------------------------------------------------------------- /src/clients/TrustedSignerFeeCalculatorClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type ReadWriteContract, 6 | type ReadWriteAdapter, 7 | createDrift, 8 | HexString, 9 | } from "@delvtech/drift"; 10 | import { TrustedSignerFeeCalculatorAbi } from "../abi/TrustedSignerFeeCalculator"; 11 | 12 | export type TrustedSignerFeeCalculatorABI = 13 | typeof TrustedSignerFeeCalculatorAbi; 14 | 15 | export class ReadTrustedSignerFeeCalculator { 16 | public readonly contract: ReadContract; 17 | 18 | /** 19 | * Creates a new ReadTrustedSignerFeeCalculator instance 20 | * @param address - The address of the TrustedSignerFeeCalculator contract 21 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 22 | * @throws Error if address is not provided 23 | */ 24 | constructor(address: Address, drift: Drift = createDrift()) { 25 | if (!address) { 26 | throw new Error("Address is required"); 27 | } 28 | 29 | this.contract = drift.contract({ 30 | abi: TrustedSignerFeeCalculatorAbi, 31 | address, 32 | }); 33 | } 34 | 35 | trustedPoolKeySigner({ poolId }: { poolId: HexString }) { 36 | return this.contract.read("trustedPoolKeySigner", { 37 | _poolId: poolId, 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/abi/FLETH.ts: -------------------------------------------------------------------------------- 1 | export const FLETHAbi = [ 2 | { 3 | inputs: [{ internalType: "uint256", name: "wethAmount", type: "uint256" }], 4 | name: "deposit", 5 | outputs: [], 6 | stateMutability: "payable", 7 | type: "function", 8 | }, 9 | { 10 | inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], 11 | name: "withdraw", 12 | outputs: [], 13 | stateMutability: "nonpayable", 14 | type: "function", 15 | }, 16 | { 17 | inputs: [{ internalType: "address", name: "account", type: "address" }], 18 | name: "balanceOf", 19 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 20 | stateMutability: "view", 21 | type: "function", 22 | }, 23 | { 24 | inputs: [], 25 | name: "totalSupply", 26 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 27 | stateMutability: "view", 28 | type: "function", 29 | }, 30 | { 31 | inputs: [], 32 | name: "name", 33 | outputs: [{ internalType: "string", name: "", type: "string" }], 34 | stateMutability: "view", 35 | type: "function", 36 | }, 37 | { 38 | inputs: [], 39 | name: "symbol", 40 | outputs: [{ internalType: "string", name: "", type: "string" }], 41 | stateMutability: "view", 42 | type: "function", 43 | }, 44 | { 45 | inputs: [], 46 | name: "decimals", 47 | outputs: [{ internalType: "uint8", name: "", type: "uint8" }], 48 | stateMutability: "view", 49 | type: "function", 50 | }, 51 | ] as const; 52 | -------------------------------------------------------------------------------- /src/clients/InitialPriceClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { InitialPriceAbi } from "../abi/InitialPrice"; 12 | import { zeroAddress } from "viem"; 13 | 14 | export type InitialPriceABI = typeof InitialPriceAbi; 15 | 16 | export class ReadInitialPrice { 17 | public readonly contract: ReadContract; 18 | 19 | constructor(address: Address, drift: Drift = createDrift()) { 20 | if (!address) { 21 | throw new Error("Address is required"); 22 | } 23 | 24 | this.contract = drift.contract({ 25 | abi: InitialPriceAbi, 26 | address, 27 | }); 28 | } 29 | 30 | /** 31 | * Returns a flaunching fee of 0.1% of the initial market cap IF the market cap is greater than 10k & the sender is not fee exempt 32 | * @param params - The parameters for the flaunching fee calculation 33 | * @param params.sender - The address of the sender 34 | * @param params.initialPriceParams - The initial price parameters 35 | * @returns The flaunching fee 36 | */ 37 | getFlaunchingFee(params: { sender: Address; initialPriceParams: HexString }) { 38 | return this.contract.read("getFlaunchingFee", { 39 | _sender: params.sender, 40 | _initialPriceParams: params.initialPriceParams, 41 | }); 42 | } 43 | 44 | getSqrtPriceX96(params: { 45 | isFLETHZero: boolean; 46 | initialPriceParams: HexString; 47 | }) { 48 | return this.contract.read("getSqrtPriceX96", { 49 | _flipped: !params.isFLETHZero, 50 | _initialPriceParams: params.initialPriceParams, 51 | 0: zeroAddress, // sender 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/clients/FlaunchV1_1Client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { FlaunchV1_1Abi } from "../abi/FlaunchV1_1"; 12 | 13 | export type FlaunchV1_1ABI = typeof FlaunchV1_1Abi; 14 | 15 | /** 16 | * Client for interacting with the Flaunch V1.1 contract in read-only mode 17 | * Provides methods to query token IDs and metadata URIs 18 | * Enhanced version of the V1 contract with additional features 19 | */ 20 | export class ReadFlaunchV1_1 { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadFlaunchV1_1 instance 25 | * @param address - The address of the Flaunch V1.1 contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: FlaunchV1_1Abi, 36 | address, 37 | }); 38 | } 39 | 40 | /** 41 | * Gets the token ID associated with a memecoin 42 | * @param coinAddress - The address of the memecoin 43 | * @returns Promise - The token ID 44 | */ 45 | tokenId(coinAddress: Address) { 46 | return this.contract.read("tokenId", { 47 | _memecoin: coinAddress, 48 | }); 49 | } 50 | 51 | /** 52 | * Gets the metadata URI for a token 53 | * @param tokenId - The ID of the token 54 | * @returns Promise - The token's metadata URI 55 | */ 56 | tokenURI(tokenId: bigint) { 57 | return this.contract.read("tokenURI", { 58 | _tokenId: tokenId, 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/clients/FlaunchV1_2Client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { FlaunchV1_2Abi } from "../abi/FlaunchV1_2"; 12 | 13 | export type FlaunchV1_2ABI = typeof FlaunchV1_2Abi; 14 | 15 | /** 16 | * Client for interacting with the Flaunch V1.1 contract in read-only mode 17 | * Provides methods to query token IDs and metadata URIs 18 | * Enhanced version of the V1 contract with additional features 19 | */ 20 | export class ReadFlaunchV1_2 { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadFlaunchV1_1 instance 25 | * @param address - The address of the Flaunch V1.1 contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: FlaunchV1_2Abi, 36 | address, 37 | }); 38 | } 39 | 40 | /** 41 | * Gets the token ID associated with a memecoin 42 | * @param coinAddress - The address of the memecoin 43 | * @returns Promise - The token ID 44 | */ 45 | tokenId(coinAddress: Address) { 46 | return this.contract.read("tokenId", { 47 | _memecoin: coinAddress, 48 | }); 49 | } 50 | 51 | /** 52 | * Gets the metadata URI for a token 53 | * @param tokenId - The ID of the token 54 | * @returns Promise - The token's metadata URI 55 | */ 56 | tokenURI(tokenId: bigint) { 57 | return this.contract.read("tokenURI", { 58 | _tokenId: tokenId, 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/abi/FastFlaunchZap.ts: -------------------------------------------------------------------------------- 1 | export const FastFlaunchZapAbi = [ 2 | { 3 | inputs: [ 4 | { 5 | internalType: "contract PositionManager", 6 | name: "_positionManager", 7 | type: "address", 8 | }, 9 | ], 10 | stateMutability: "nonpayable", 11 | type: "constructor", 12 | }, 13 | { 14 | inputs: [], 15 | name: "CREATOR_FEE_ALLOCATION", 16 | outputs: [{ internalType: "uint24", name: "", type: "uint24" }], 17 | stateMutability: "view", 18 | type: "function", 19 | }, 20 | { 21 | inputs: [], 22 | name: "FAIR_LAUNCH_SUPPLY", 23 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 24 | stateMutability: "view", 25 | type: "function", 26 | }, 27 | { 28 | inputs: [], 29 | name: "USDC_MARKET_CAP", 30 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 31 | stateMutability: "view", 32 | type: "function", 33 | }, 34 | { 35 | inputs: [ 36 | { 37 | components: [ 38 | { internalType: "string", name: "name", type: "string" }, 39 | { internalType: "string", name: "symbol", type: "string" }, 40 | { internalType: "string", name: "tokenUri", type: "string" }, 41 | { internalType: "address", name: "creator", type: "address" }, 42 | ], 43 | internalType: "struct FastFlaunchZap.FastFlaunchParams", 44 | name: "_params", 45 | type: "tuple", 46 | }, 47 | ], 48 | name: "flaunch", 49 | outputs: [{ internalType: "address", name: "memecoin_", type: "address" }], 50 | stateMutability: "nonpayable", 51 | type: "function", 52 | }, 53 | { 54 | inputs: [], 55 | name: "positionManager", 56 | outputs: [ 57 | { internalType: "contract PositionManager", name: "", type: "address" }, 58 | ], 59 | stateMutability: "view", 60 | type: "function", 61 | }, 62 | ] as const; 63 | -------------------------------------------------------------------------------- /src/sdk/drift.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createDrift as createDriftOriginal, 3 | Drift, 4 | ReadWriteAdapter, 5 | } from "@delvtech/drift"; 6 | import { viemAdapter } from "@delvtech/drift-viem"; 7 | import type { PublicClient, WalletClient } from "viem"; 8 | 9 | export type CreateDriftParams = { 10 | publicClient: PublicClient; 11 | walletClient?: WalletClient; 12 | }; 13 | 14 | /** 15 | * Creates a read-only Drift instance with only public client 16 | * @param params - Parameters with only publicClient 17 | * @returns Drift instance for read-only operations 18 | * @throws Error if publicClient.chain is not configured 19 | */ 20 | export function createDrift( 21 | params: Omit 22 | ): Drift; 23 | /** 24 | * Creates a read-write Drift instance with both public and wallet clients 25 | * @param params - Parameters with both publicClient and walletClient 26 | * @returns Drift instance for read and write operations 27 | * @throws Error if publicClient.chain is not configured 28 | */ 29 | export function createDrift( 30 | params: Required 31 | ): Drift; 32 | 33 | /** 34 | * Creates a Drift instance with the provided clients 35 | * @param params - Parameters for creating the Drift instance 36 | * @returns Drift instance configured with the appropriate clients 37 | * @throws Error if publicClient.chain is not configured 38 | */ 39 | export function createDrift( 40 | params: CreateDriftParams 41 | ): Drift | Drift { 42 | const { publicClient, walletClient } = params; 43 | 44 | if (!publicClient.chain) { 45 | throw new Error("publicClient must be configured with a chain"); 46 | } 47 | 48 | return walletClient 49 | ? createDriftOriginal({ 50 | adapter: viemAdapter({ publicClient, walletClient }), 51 | }) 52 | : createDriftOriginal({ 53 | adapter: viemAdapter({ publicClient }), 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /src/clients/BidWallClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { BidwallAbi } from "../abi/BidWall"; 12 | 13 | export type BidwallABI = typeof BidwallAbi; 14 | 15 | /** 16 | * Client for interacting with the BidWall V1 contract in read-only mode 17 | * Provides methods to query bid wall positions and pool information 18 | */ 19 | export class ReadBidWall { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadBidWall instance 24 | * @param address - The address of the BidWall contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: BidwallAbi, 35 | address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets information about a bid wall position for a specific pool 41 | * @param poolId - The ID of the pool 42 | * @returns Promise<{amount0_: bigint, amount1_: bigint, pendingEth_: bigint}> - Position details including token amounts and pending ETH 43 | */ 44 | position({ poolId }: { poolId: HexString }) { 45 | return this.contract.read("position", { 46 | _poolId: poolId, 47 | }); 48 | } 49 | 50 | /** 51 | * Gets configuration information about a pool's bid wall 52 | * @param poolId - The ID of the pool 53 | * @returns Promise<{tickLower: number, tickUpper: number}> - Pool configuration including tick range 54 | */ 55 | poolInfo({ poolId }: { poolId: HexString }) { 56 | return this.contract.read("poolInfo", { 57 | _poolId: poolId, 58 | }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/clients/AnyBidWall.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { AnyBidWallAbi } from "../abi/AnyBidWall"; 12 | 13 | export type AnyBidWallABI = typeof AnyBidWallAbi; 14 | 15 | /** 16 | * Client for interacting with the AnyBidWall contract in read-only mode 17 | * Provides methods to query bid wall positions and pool information 18 | * Enhanced version of the V1 contract with additional features 19 | */ 20 | export class AnyBidWall { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadBidWallV1_1 instance 25 | * @param address - The address of the BidWall V1.1 contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: AnyBidWallAbi, 36 | address, 37 | }); 38 | } 39 | 40 | /** 41 | * Gets information about a bid wall position for a specific pool 42 | * @param poolId - The ID of the pool 43 | * @returns Promise<{amount0_: bigint, amount1_: bigint, pendingEth_: bigint}> - Position details including token amounts and pending ETH 44 | */ 45 | position({ poolId }: { poolId: HexString }) { 46 | return this.contract.read("position", { 47 | _poolId: poolId, 48 | }); 49 | } 50 | 51 | /** 52 | * Gets configuration information about a pool's bid wall 53 | * @param poolId - The ID of the pool 54 | * @returns Promise<{tickLower: number, tickUpper: number}> - Pool configuration including tick range 55 | */ 56 | poolInfo({ poolId }: { poolId: HexString }) { 57 | return this.contract.read("poolInfo", { 58 | _poolId: poolId, 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/sdk/factory.ts: -------------------------------------------------------------------------------- 1 | import { createDrift } from "./drift"; 2 | import { viemAdapter } from "@delvtech/drift-viem"; 3 | import type { PublicClient, WalletClient } from "viem"; 4 | import { ReadFlaunchSDK, ReadWriteFlaunchSDK } from "./FlaunchSDK"; 5 | 6 | export type CreateFlaunchParams = { 7 | publicClient: PublicClient; 8 | walletClient?: WalletClient; 9 | }; 10 | 11 | /** 12 | * Creates a read-only Flaunch SDK instance with only public client 13 | * @param params - Parameters with only publicClient 14 | * @returns ReadFlaunchSDK for read-only operations 15 | * @throws Error if publicClient.chain is not configured 16 | */ 17 | export function createFlaunch( 18 | params: Omit 19 | ): ReadFlaunchSDK; 20 | /** 21 | * Creates a read-write Flaunch SDK instance with both public and wallet clients 22 | * @param params - Parameters with both publicClient and walletClient 23 | * @returns ReadWriteFlaunchSDK for read and write operations 24 | * @throws Error if publicClient.chain is not configured 25 | */ 26 | export function createFlaunch( 27 | params: Required 28 | ): ReadWriteFlaunchSDK; 29 | 30 | /** 31 | * Creates a Flaunch SDK instance with the provided clients 32 | * @param params - Parameters for creating the SDK 33 | * @returns ReadFlaunchSDK if only publicClient is provided, ReadWriteFlaunchSDK if walletClient is also provided 34 | * @throws Error if publicClient.chain is not configured 35 | */ 36 | export function createFlaunch(params: CreateFlaunchParams) { 37 | const { publicClient, walletClient } = params; 38 | 39 | if (!publicClient.chain) { 40 | throw new Error("publicClient must be configured with a chain"); 41 | } 42 | 43 | const chainId = publicClient.chain.id; 44 | 45 | // Return appropriate SDK type based on whether walletClient is provided 46 | return walletClient 47 | ? new ReadWriteFlaunchSDK( 48 | chainId, 49 | createDrift({ publicClient, walletClient }), 50 | publicClient 51 | ) 52 | : new ReadFlaunchSDK(chainId, createDrift({ publicClient }), publicClient); 53 | } 54 | -------------------------------------------------------------------------------- /src/clients/BidWallV1_1Client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { BidWallV1_1Abi } from "../abi/BidWallV1_1"; 12 | 13 | export type BidwallV1_1ABI = typeof BidWallV1_1Abi; 14 | 15 | /** 16 | * Client for interacting with the BidWall V1.1 contract in read-only mode 17 | * Provides methods to query bid wall positions and pool information 18 | * Enhanced version of the V1 contract with additional features 19 | */ 20 | export class ReadBidWallV1_1 { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadBidWallV1_1 instance 25 | * @param address - The address of the BidWall V1.1 contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: BidWallV1_1Abi, 36 | address, 37 | }); 38 | } 39 | 40 | /** 41 | * Gets information about a bid wall position for a specific pool 42 | * @param poolId - The ID of the pool 43 | * @returns Promise<{amount0_: bigint, amount1_: bigint, pendingEth_: bigint}> - Position details including token amounts and pending ETH 44 | */ 45 | position({ poolId }: { poolId: HexString }) { 46 | return this.contract.read("position", { 47 | _poolId: poolId, 48 | }); 49 | } 50 | 51 | /** 52 | * Gets configuration information about a pool's bid wall 53 | * @param poolId - The ID of the pool 54 | * @returns Promise<{tickLower: number, tickUpper: number}> - Pool configuration including tick range 55 | */ 56 | poolInfo({ poolId }: { poolId: HexString }) { 57 | return this.contract.read("poolInfo", { 58 | _poolId: poolId, 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/clients/FlaunchClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { FlaunchAbi } from "../abi/Flaunch"; 12 | 13 | export type FlaunchABI = typeof FlaunchAbi; 14 | 15 | /** 16 | * Client for interacting with the Flaunch V1 contract in read-only mode 17 | * Provides methods to query token IDs and metadata URIs 18 | */ 19 | export class ReadFlaunch { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadFlaunch instance 24 | * @param address - The address of the Flaunch contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: FlaunchAbi, 35 | address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets the token ID associated with a memecoin 41 | * @param coinAddress - The address of the memecoin 42 | * @returns Promise - The token ID 43 | */ 44 | tokenId(coinAddress: Address) { 45 | return this.contract.read("tokenId", { 46 | _memecoin: coinAddress, 47 | }); 48 | } 49 | 50 | /** 51 | * Gets the metadata URI for a token 52 | * @param tokenId - The ID of the token 53 | * @returns Promise - The token's metadata URI 54 | */ 55 | tokenURI(tokenId: bigint) { 56 | return this.contract.read("tokenURI", { 57 | _tokenId: tokenId, 58 | }); 59 | } 60 | 61 | /** 62 | * Gets the memecoin address for a given token ID 63 | * @param tokenId - The ID of the token 64 | * @returns Promise
- The address of the memecoin 65 | */ 66 | memecoin(tokenId: bigint) { 67 | return this.contract.read("memecoin", { 68 | _tokenId: tokenId, 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/clients/AnyFlaunchClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { AnyFlaunchAbi } from "../abi/AnyFlaunch"; 12 | 13 | export type AnyFlaunchABI = typeof AnyFlaunchAbi; 14 | 15 | /** 16 | * Client for interacting with the AnyFlaunch contract in read-only mode 17 | * Provides methods to query token IDs and metadata URIs 18 | */ 19 | export class ReadAnyFlaunch { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadAnyFlaunch instance 24 | * @param address - The address of the AnyFlaunch contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: AnyFlaunchAbi, 35 | address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets the token ID associated with a memecoin 41 | * @param coinAddress - The address of the memecoin 42 | * @returns Promise - The token ID 43 | */ 44 | tokenId(coinAddress: Address) { 45 | return this.contract.read("tokenId", { 46 | _memecoin: coinAddress, 47 | }); 48 | } 49 | 50 | /** 51 | * Gets the metadata URI for a token 52 | * @param tokenId - The ID of the token 53 | * @returns Promise - The token's metadata URI 54 | */ 55 | tokenURI(tokenId: bigint) { 56 | return this.contract.read("tokenURI", { 57 | _tokenId: tokenId, 58 | }); 59 | } 60 | 61 | /** 62 | * Gets the memecoin address for a given token ID 63 | * @param tokenId - The ID of the token 64 | * @returns Promise
- The address of the memecoin 65 | */ 66 | memecoin(tokenId: bigint) { 67 | return this.contract.read("memecoin", { 68 | _tokenId: tokenId, 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/clients/FairLaunchClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { FairLaunchAbi } from "../abi/FairLaunch"; 12 | 13 | export type FairLaunchABI = typeof FairLaunchAbi; 14 | 15 | /** 16 | * Client for interacting with the FairLaunch V1 contract in read-only mode 17 | * Provides methods to query fair launch information and status 18 | */ 19 | export class ReadFairLaunch { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadFairLaunch instance 24 | * @param address - The address of the FairLaunch contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: FairLaunchAbi, 35 | address, 36 | }); 37 | } 38 | 39 | fairLaunchDuration({ poolId }: { poolId: HexString }) { 40 | return 30 * 60; // 30 minutes 41 | } 42 | 43 | /** 44 | * Gets information about a fair launch for a specific pool 45 | * @param poolId - The ID of the pool 46 | * @returns Promise<{initialTick: number, closed: boolean, endsAt: number}> - Fair launch details 47 | */ 48 | fairLaunchInfo({ poolId }: { poolId: HexString }) { 49 | return this.contract.read("fairLaunchInfo", { 50 | _poolId: poolId, 51 | }); 52 | } 53 | 54 | /** 55 | * Checks if a fair launch is currently active 56 | * @param poolId - The ID of the pool 57 | * @returns Promise - True if the fair launch is active (not closed and not expired), false otherwise 58 | */ 59 | async isFairLaunchActive({ poolId }: { poolId: HexString }) { 60 | const { closed, endsAt } = await this.fairLaunchInfo({ poolId }); 61 | if (closed) { 62 | return false; 63 | } 64 | 65 | if (new Date().getTime() / 1000 > endsAt) { 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/clients/FeeEscrowClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type ReadWriteContract, 6 | type ReadWriteAdapter, 7 | createDrift, 8 | } from "@delvtech/drift"; 9 | import { FeeEscrowAbi } from "../abi/FeeEscrow"; 10 | 11 | export type FeeEscrowABI = typeof FeeEscrowAbi; 12 | 13 | /** 14 | * Client for interacting with the FeeEscrow contract in read-only mode 15 | * Provides methods to query fee balances and withdraw fees 16 | */ 17 | export class ReadFeeEscrow { 18 | public readonly contract: ReadContract; 19 | 20 | /** 21 | * Creates a new ReadFeeEscrow instance 22 | * @param address - The address of the FeeEscrow contract 23 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 24 | * @throws Error if address is not provided 25 | */ 26 | constructor(address: Address, drift: Drift = createDrift()) { 27 | if (!address) { 28 | throw new Error("Address is required"); 29 | } 30 | 31 | this.contract = drift.contract({ 32 | abi: FeeEscrowAbi, 33 | address, 34 | }); 35 | } 36 | 37 | /** 38 | * Gets the claimable balance of fees for a creator 39 | * @param creator - The address of the creator to check 40 | * @returns Promise - The claimable balance of fees 41 | */ 42 | balances(creator: Address) { 43 | return this.contract.read("balances", { 44 | _recipient: creator, 45 | }); 46 | } 47 | } 48 | 49 | /** 50 | * Extended client for interacting with the FeeEscrow contract with write capabilities 51 | * Provides methods to withdraw fees 52 | */ 53 | export class ReadWriteFeeEscrow extends ReadFeeEscrow { 54 | declare contract: ReadWriteContract; 55 | 56 | constructor( 57 | address: Address, 58 | drift: Drift = createDrift() 59 | ) { 60 | super(address, drift); 61 | } 62 | 63 | /** 64 | * Withdraws fees as ETH to a recipient 65 | * @param recipient - The address to receive the fees 66 | * @param unwrap - Whether to unwrap the native token before sending 67 | * @returns Promise 68 | */ 69 | withdrawFees(recipient: Address) { 70 | return this.contract.write("withdrawFees", { 71 | _recipient: recipient, 72 | _unwrap: true, 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/clients/Permit2Client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { Permit2Abi } from "../abi/Permit2"; 12 | 13 | export type Permit2ABI = typeof Permit2Abi; 14 | 15 | /** 16 | * Client for interacting with Uniswap's Permit2 contract in read-only mode 17 | * Provides methods to query token approvals and allowances 18 | */ 19 | export class ReadPermit2 { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadPermit2 instance 24 | * @param address - The address of the Permit2 contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: Permit2Abi, 35 | address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets the allowance and nonce for a token approval 41 | * @param owner - The address of the token owner 42 | * @param coinAddress - The address of the token contract 43 | * @param spender - The address of the spender 44 | * @returns Promise<{amount: bigint, expiration: bigint, nonce: bigint}> - The allowance details 45 | */ 46 | async allowance(owner: Address, coinAddress: Address, spender: Address) { 47 | return this.contract.read("allowance", { 48 | 0: owner, 49 | 1: coinAddress, 50 | 2: spender, 51 | }); 52 | } 53 | } 54 | 55 | export class ReadWritePermit2 extends ReadPermit2 { 56 | declare contract: ReadWriteContract; 57 | 58 | constructor( 59 | address: Address, 60 | drift: Drift = createDrift() 61 | ) { 62 | super(address, drift); 63 | } 64 | 65 | /** 66 | * Approves a spender to spend a token via transaction 67 | * @param params - The parameters for the approval 68 | * @returns The transaction response 69 | */ 70 | approve(params: { 71 | token: Address; 72 | spender: Address; 73 | amount: bigint; 74 | expiration: number; 75 | }) { 76 | return this.contract.write("approve", params); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/clients/ReferralEscrowClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type ReadWriteContract, 6 | type ReadWriteAdapter, 7 | createDrift, 8 | } from "@delvtech/drift"; 9 | import { ReferralEscrowAbi } from "../abi/ReferralEscrow"; 10 | 11 | export type ReferralEscrowABI = typeof ReferralEscrowAbi; 12 | 13 | /** 14 | * Client for interacting with the ReferralEscrow contract in read-only mode 15 | * Provides methods to query token allocations 16 | */ 17 | export class ReadReferralEscrow { 18 | public readonly contract: ReadContract; 19 | 20 | /** 21 | * Creates a new ReadReferralEscrow instance 22 | * @param address - The address of the ReferralEscrow contract 23 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 24 | * @throws Error if address is not provided 25 | */ 26 | constructor(address: Address, drift: Drift = createDrift()) { 27 | if (!address) { 28 | throw new Error("Address is required"); 29 | } 30 | 31 | this.contract = drift.contract({ 32 | abi: ReferralEscrowAbi, 33 | address, 34 | }); 35 | } 36 | 37 | /** 38 | * Gets the token allocation for a specific user and token 39 | * @param user - The address of the user to check 40 | * @param token - The address of the token 41 | * @returns Promise - The allocated token amount 42 | */ 43 | allocations(user: Address, token: Address) { 44 | return this.contract.read("allocations", { 45 | _user: user, 46 | _token: token, 47 | }); 48 | } 49 | } 50 | 51 | /** 52 | * Extended client for interacting with the ReferralEscrow contract with write capabilities 53 | * Provides methods to claim tokens 54 | */ 55 | export class ReadWriteReferralEscrow extends ReadReferralEscrow { 56 | declare contract: ReadWriteContract; 57 | 58 | constructor( 59 | address: Address, 60 | drift: Drift = createDrift() 61 | ) { 62 | super(address, drift); 63 | } 64 | 65 | /** 66 | * Claims tokens for a recipient 67 | * @param tokens - Array of token addresses to claim 68 | * @param recipient - The address to receive the claimed tokens 69 | * @returns Promise 70 | */ 71 | claimTokens(tokens: Address[], recipient: Address) { 72 | return this.contract.write("claimTokens", { 73 | _tokens: tokens, 74 | _recipient: recipient, 75 | }); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/clients/TreasuryManagerFactoryClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { 12 | createPublicClient, 13 | type PublicClient, 14 | encodeAbiParameters, 15 | http, 16 | parseEventLogs, 17 | } from "viem"; 18 | import { TreasuryManagerFactoryAbi } from "../abi/TreasuryManagerFactory"; 19 | import { chainIdToChain } from "helpers/chainIdToChain"; 20 | 21 | export type TreasuryManagerFactoryABI = typeof TreasuryManagerFactoryAbi; 22 | 23 | export class ReadTreasuryManagerFactory { 24 | chainId: number; 25 | public readonly contract: ReadContract; 26 | public readonly publicClient: PublicClient | undefined; 27 | 28 | constructor( 29 | chainId: number, 30 | address: Address, 31 | drift: Drift = createDrift(), 32 | publicClient?: PublicClient 33 | ) { 34 | if (!address) { 35 | throw new Error("Address is required"); 36 | } 37 | this.contract = drift.contract({ 38 | abi: TreasuryManagerFactoryAbi, 39 | address, 40 | }); 41 | this.chainId = chainId; 42 | this.publicClient = publicClient; 43 | } 44 | 45 | async getManagerDeployedAddressFromTx(hash: HexString) { 46 | // Wait for transaction receipt 47 | if (!this.publicClient) { 48 | throw new Error("Public client is required"); 49 | } 50 | 51 | const receipt = await this.publicClient.waitForTransactionReceipt({ hash }); 52 | 53 | // Parse the ManagerDeployed event from receipt logs 54 | const parsedLogs = parseEventLogs({ 55 | abi: TreasuryManagerFactoryAbi, 56 | eventName: "ManagerDeployed", 57 | logs: receipt.logs, 58 | }); 59 | 60 | // Find the event from our transaction 61 | const event = parsedLogs.find( 62 | (log) => log.address.toLowerCase() === this.contract.address.toLowerCase() 63 | ); 64 | if (!event) { 65 | throw new Error("ManagerDeployed event not found in transaction logs"); 66 | } 67 | 68 | return event.args._manager as Address; 69 | } 70 | } 71 | 72 | export class ReadWriteTreasuryManagerFactory extends ReadTreasuryManagerFactory { 73 | declare contract: ReadWriteContract; 74 | 75 | constructor( 76 | chainId: number, 77 | address: Address, 78 | drift: Drift = createDrift(), 79 | publicClient?: PublicClient 80 | ) { 81 | super(chainId, address, drift, publicClient); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /scripts/generate-llms-doc.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | function combineDocumentation() { 5 | // Read README 6 | const readmePath = path.join(__dirname, "..", "README.md"); 7 | const readme = fs.readFileSync(readmePath, "utf8"); 8 | 9 | // Read TypeDoc generated files 10 | const docsPath = path.join(__dirname, "..", "docs"); 11 | let combinedDocs = [readme, "\n\n# API Documentation\n\n"]; 12 | 13 | function readDocsRecursively(dir) { 14 | const files = fs.readdirSync(dir); 15 | 16 | for (const file of files) { 17 | const fullPath = path.join(dir, file); 18 | const stat = fs.statSync(fullPath); 19 | 20 | if (stat.isDirectory()) { 21 | readDocsRecursively(fullPath); 22 | } else if (file.endsWith(".md") && file !== "README.md") { 23 | let content = fs.readFileSync(fullPath, "utf8"); 24 | 25 | // Remove "Defined in" lines and GitHub URLs 26 | content = content.replace(/#### Defined in[\s\S]*?(?=\n\n|$)/g, ""); 27 | 28 | // Remove file paths (e.g., "flaunch-sdk/src/helpers/hex.ts:7") 29 | content = content.replace(/flaunch-sdk\/src\/.*:\d+/g, ""); 30 | 31 | // Remove empty markdown links 32 | content = content.replace(/\[\]\([^)]+\)\n?/g, ""); 33 | 34 | // Remove markdown links while keeping the text 35 | content = content.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1"); 36 | 37 | // Remove GitHub specific URLs 38 | content = content.replace(/https:\/\/github\.com\/[^\s\n]+/g, ""); 39 | 40 | // Remove "#### " prefixes from headings as they're not needed 41 | content = content.replace(/#### /g, ""); 42 | 43 | // Remove empty lines after removals 44 | content = content.replace(/\n{3,}/g, "\n\n"); 45 | 46 | // Remove lines that only contain dashes (horizontal rules) 47 | content = content.replace(/^-+$/gm, ""); 48 | 49 | // Remove any remaining empty sections 50 | content = content.replace(/###\s*\w+\s*\n\n(?=###|$)/g, ""); 51 | 52 | combinedDocs.push(content); 53 | combinedDocs.push("\n\n---\n\n"); 54 | } 55 | } 56 | } 57 | 58 | // Generate TypeDoc documentation first 59 | require("child_process").execSync("npm run docs:generate", { 60 | stdio: "inherit", 61 | }); 62 | 63 | // Combine all documentation 64 | readDocsRecursively(docsPath); 65 | 66 | // Write combined documentation 67 | const outputPath = path.join(__dirname, "..", "llms-full.txt"); 68 | fs.writeFileSync(outputPath, combinedDocs.join("")); 69 | 70 | console.log("Generated llms-full.txt successfully!"); 71 | } 72 | 73 | combineDocumentation(); 74 | -------------------------------------------------------------------------------- /src/clients/FairLaunchV1_1Client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { FairLaunchV1_1Abi } from "../abi/FairLaunchV1_1"; 12 | 13 | export type FairLaunchV1_1ABI = typeof FairLaunchV1_1Abi; 14 | 15 | /** 16 | * Client for interacting with the FairLaunch V1.1 contract in read-only mode 17 | * Provides methods to query fair launch information and status 18 | * Enhanced version of the V1 contract with additional features like variable duration 19 | */ 20 | export class ReadFairLaunchV1_1 { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadFairLaunchV1_1 instance 25 | * @param address - The address of the FairLaunch V1.1 contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: FairLaunchV1_1Abi, 36 | address, 37 | }); 38 | } 39 | 40 | /** 41 | * Gets information about a fair launch for a specific pool 42 | * @param poolId - The ID of the pool 43 | * @returns Promise<{initialTick: number, closed: boolean, startsAt: number, endsAt: number}> - Fair launch details 44 | */ 45 | fairLaunchInfo({ poolId }: { poolId: HexString }) { 46 | return this.contract.read("fairLaunchInfo", { 47 | _poolId: poolId, 48 | }); 49 | } 50 | 51 | /** 52 | * Calculates the duration of a fair launch 53 | * @param poolId - The ID of the pool 54 | * @returns Promise - The duration in seconds between start and end time 55 | */ 56 | async fairLaunchDuration({ poolId }: { poolId: HexString }) { 57 | const { startsAt, endsAt } = await this.fairLaunchInfo({ poolId }); 58 | return endsAt - startsAt; 59 | } 60 | 61 | /** 62 | * Checks if a fair launch is currently active 63 | * @param poolId - The ID of the pool 64 | * @returns Promise - True if the fair launch is active (not closed and not expired), false otherwise 65 | */ 66 | async isFairLaunchActive({ poolId }: { poolId: HexString }) { 67 | const { closed, endsAt } = await this.fairLaunchInfo({ poolId }); 68 | if (closed) { 69 | return false; 70 | } 71 | 72 | if (new Date().getTime() / 1000 > endsAt) { 73 | return false; 74 | } 75 | 76 | return true; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/abi/TreasuryManager.ts: -------------------------------------------------------------------------------- 1 | export const TreasuryManagerAbi = [ 2 | { 3 | type: "function", 4 | name: "deposit", 5 | inputs: [ 6 | { 7 | name: "_flaunchToken", 8 | type: "tuple", 9 | internalType: "struct ITreasuryManager.FlaunchToken", 10 | components: [ 11 | { 12 | name: "flaunch", 13 | type: "address", 14 | internalType: "contract Flaunch", 15 | }, 16 | { name: "tokenId", type: "uint256", internalType: "uint256" }, 17 | ], 18 | }, 19 | { name: "_creator", type: "address", internalType: "address" }, 20 | { name: "_data", type: "bytes", internalType: "bytes" }, 21 | ], 22 | outputs: [], 23 | stateMutability: "nonpayable", 24 | }, 25 | { 26 | type: "function", 27 | name: "initialize", 28 | inputs: [ 29 | { name: "_owner", type: "address", internalType: "address" }, 30 | { name: "_data", type: "bytes", internalType: "bytes" }, 31 | ], 32 | outputs: [], 33 | stateMutability: "nonpayable", 34 | }, 35 | { 36 | type: "function", 37 | name: "managerOwner", 38 | inputs: [], 39 | outputs: [{ name: "", type: "address", internalType: "address" }], 40 | stateMutability: "view", 41 | }, 42 | { 43 | type: "function", 44 | name: "permissions", 45 | inputs: [], 46 | outputs: [ 47 | { 48 | name: "", 49 | type: "address", 50 | internalType: "contract IManagerPermissions", 51 | }, 52 | ], 53 | stateMutability: "view", 54 | }, 55 | { 56 | type: "function", 57 | name: "rescue", 58 | inputs: [ 59 | { 60 | name: "_flaunchToken", 61 | type: "tuple", 62 | internalType: "struct ITreasuryManager.FlaunchToken", 63 | components: [ 64 | { 65 | name: "flaunch", 66 | type: "address", 67 | internalType: "contract Flaunch", 68 | }, 69 | { name: "tokenId", type: "uint256", internalType: "uint256" }, 70 | ], 71 | }, 72 | { name: "_recipient", type: "address", internalType: "address" }, 73 | ], 74 | outputs: [], 75 | stateMutability: "nonpayable", 76 | }, 77 | { 78 | type: "function", 79 | name: "setPermissions", 80 | inputs: [ 81 | { name: "_permissions", type: "address", internalType: "address" }, 82 | ], 83 | outputs: [], 84 | stateMutability: "nonpayable", 85 | }, 86 | { 87 | type: "function", 88 | name: "transferManagerOwnership", 89 | inputs: [ 90 | { 91 | name: "_newManagerOwner", 92 | type: "address", 93 | internalType: "address", 94 | }, 95 | ], 96 | outputs: [], 97 | stateMutability: "nonpayable", 98 | }, 99 | ] as const; 100 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "@rollup/plugin-typescript"; 2 | import resolve from "@rollup/plugin-node-resolve"; 3 | import commonjs from "@rollup/plugin-commonjs"; 4 | import json from "@rollup/plugin-json"; 5 | import terser from "@rollup/plugin-terser"; 6 | import pkg from "./package.json"; 7 | 8 | const external = [ 9 | ...Object.keys(pkg.dependencies || {}), 10 | ...Object.keys(pkg.peerDependencies || {}), 11 | ]; 12 | 13 | // Custom onwarn function to ignore circular dependency warnings from viem 14 | const onwarn = (warning, warn) => { 15 | // Ignore circular dependency warnings from viem 16 | if ( 17 | warning.code === "CIRCULAR_DEPENDENCY" && 18 | warning.message.includes("viem") 19 | ) { 20 | return; 21 | } 22 | // Use default warning for everything else 23 | warn(warning); 24 | }; 25 | 26 | const createConfig = (input, output, format, plugins = []) => ({ 27 | input, 28 | output: { 29 | ...output, 30 | sourcemap: true, 31 | exports: "named", 32 | }, 33 | plugins: [ 34 | typescript({ 35 | tsconfig: "./tsconfig.json", 36 | outDir: output.dir || "./dist", 37 | declaration: false, 38 | }), 39 | resolve(), 40 | commonjs(), 41 | json(), 42 | ...plugins, 43 | ], 44 | external, 45 | onwarn, 46 | }); 47 | 48 | // Main entry point configs 49 | const mainConfigs = [ 50 | // ESM 51 | createConfig("src/index.ts", { 52 | file: pkg.module, 53 | format: "esm", 54 | }), 55 | // CJS 56 | createConfig("src/index.ts", { 57 | file: pkg.main, 58 | format: "cjs", 59 | }), 60 | // UMD (minified) 61 | createConfig( 62 | "src/index.ts", 63 | { 64 | name: pkg.name.replace(/-/g, "").replace(/\//g, "_"), 65 | file: pkg.unpkg, 66 | format: "umd", 67 | globals: { 68 | "@delvtech/drift": "drift", 69 | viem: "viem", 70 | "@uniswap/v3-sdk": "v3Sdk", 71 | axios: "axios", 72 | react: "React", 73 | }, 74 | }, 75 | "umd", 76 | [terser()] 77 | ), 78 | ]; 79 | 80 | // Create configs for directory-based subpaths 81 | const directorySubpaths = ["abi", "helpers", "hooks"].map((subpath) => ({ 82 | name: subpath, 83 | input: `src/${subpath}/index.ts`, 84 | })); 85 | 86 | // Create configs for file-based subpaths 87 | const fileSubpaths = [{ name: "addresses", input: "src/addresses.ts" }]; 88 | 89 | // Create all subpath configs 90 | const subpathConfigs = [...directorySubpaths, ...fileSubpaths].flatMap( 91 | ({ name, input }) => [ 92 | // ESM for subpath 93 | createConfig(input, { 94 | dir: `dist/${name}`, 95 | format: "esm", 96 | entryFileNames: "index.js", 97 | }), 98 | // CJS for subpath 99 | createConfig(input, { 100 | dir: `dist/${name}`, 101 | format: "cjs", 102 | entryFileNames: "index.cjs", 103 | }), 104 | ] 105 | ); 106 | 107 | export default [...mainConfigs, ...subpathConfigs]; 108 | -------------------------------------------------------------------------------- /src/clients/StateViewClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { StateViewAbi } from "../abi/StateView"; 12 | import { PositionInfoParams } from "./PoolManagerClient"; 13 | import { stringToHex } from "viem"; 14 | import { pad } from "viem"; 15 | 16 | export type StateViewABI = typeof StateViewAbi; 17 | 18 | /** 19 | * Client for reading state information from Uniswap V4 pools 20 | * Provides methods to query pool states, positions, and tick liquidity 21 | */ 22 | export class ReadStateView { 23 | public readonly contract: ReadContract; 24 | 25 | /** 26 | * Creates a new ReadStateView instance 27 | * @param address - The address of the StateView contract 28 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 29 | * @throws Error if address is not provided 30 | */ 31 | constructor(address: Address, drift: Drift = createDrift()) { 32 | if (!address) { 33 | throw new Error("Address is required"); 34 | } 35 | 36 | this.contract = drift.contract({ 37 | abi: StateViewAbi, 38 | address, 39 | }); 40 | } 41 | 42 | /** 43 | * Gets the Slot0 data for a pool 44 | * @param poolId - The ID of the pool to query 45 | * @returns Promise<{tick: number, sqrtPriceX96: bigint, protocolFees: bigint}> - Current pool state 46 | */ 47 | poolSlot0({ poolId }: { poolId: HexString }) { 48 | return this.contract.read("getSlot0", { 49 | poolId, 50 | }); 51 | } 52 | 53 | /** 54 | * Gets information about a liquidity position 55 | * @param poolId - The ID of the pool 56 | * @param owner - The address of the position owner 57 | * @param tickLower - The lower tick of the position 58 | * @param tickUpper - The upper tick of the position 59 | * @param salt - The salt used to identify the position 60 | * @returns Promise<{liquidity: bigint, feeGrowthInside0LastX128: bigint, feeGrowthInside1LastX128: bigint, tokensOwed0: bigint, tokensOwed1: bigint}> - Position details 61 | */ 62 | positionInfo({ 63 | poolId, 64 | owner, 65 | tickLower, 66 | tickUpper, 67 | salt, 68 | }: PositionInfoParams) { 69 | const saltBytes32 = pad(stringToHex(salt), { size: 32, dir: "right" }); 70 | 71 | return this.contract.read("getPositionInfo", { 72 | poolId, 73 | owner, 74 | tickLower, 75 | tickUpper, 76 | salt: saltBytes32, 77 | }); 78 | } 79 | 80 | /** 81 | * Gets the liquidity at a specific tick 82 | * @param poolId - The ID of the pool 83 | * @param tick - The tick to query 84 | * @returns Promise<{liquidityGross: bigint, liquidityNet: bigint, feeGrowthOutside0X128: bigint, feeGrowthOutside1X128: bigint}> - Tick liquidity information 85 | */ 86 | getTickLiquidity({ poolId, tick }: { poolId: HexString; tick: number }) { 87 | return this.contract.read("getTickLiquidity", { 88 | poolId, 89 | tick, 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@flaunch/sdk", 3 | "version": "0.9.15", 4 | "description": "Flaunch SDK to easily interact with the Flaunch protocol", 5 | "license": "MIT", 6 | "author": "Apoorv Lathey ", 7 | "homepage": "https://github.com/flayerlabs/flaunch-sdk#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/flayerlabs/flaunch-sdk.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/flayerlabs/flaunch-sdk/issues" 14 | }, 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "keywords": [ 19 | "flaunch", 20 | "memecoin", 21 | "launchpad", 22 | "uniswap", 23 | "uniswap v4", 24 | "sdk" 25 | ], 26 | "main": "dist/index.cjs.js", 27 | "module": "dist/index.esm.js", 28 | "unpkg": "dist/index.umd.js", 29 | "types": "dist/index.d.ts", 30 | "exports": { 31 | ".": { 32 | "types": "./dist/index.d.ts", 33 | "import": "./dist/index.esm.js", 34 | "require": "./dist/index.cjs.js" 35 | }, 36 | "./abi": { 37 | "types": "./dist/abi/index.d.ts", 38 | "import": "./dist/abi/index.js", 39 | "require": "./dist/abi/index.cjs" 40 | }, 41 | "./addresses": { 42 | "types": "./dist/addresses.d.ts", 43 | "import": "./dist/addresses.js", 44 | "require": "./dist/addresses.cjs" 45 | }, 46 | "./helpers": { 47 | "types": "./dist/helpers/index.d.ts", 48 | "import": "./dist/helpers/index.js", 49 | "require": "./dist/helpers/index.cjs" 50 | }, 51 | "./hooks": { 52 | "types": "./dist/hooks/index.d.ts", 53 | "import": "./dist/hooks/index.js", 54 | "require": "./dist/hooks/index.cjs" 55 | }, 56 | "./utils": { 57 | "types": "./dist/utils/index.d.ts", 58 | "import": "./dist/utils/index.js", 59 | "require": "./dist/utils/index.cjs" 60 | } 61 | }, 62 | "files": [ 63 | "dist" 64 | ], 65 | "scripts": { 66 | "build": "tsc --emitDeclarationOnly && rollup -c", 67 | "dev": "rollup -c -w", 68 | "clean": "rimraf dist", 69 | "prebuild": "npm run clean", 70 | "prepublishOnly": "npm run build", 71 | "typecheck": "tsc --noEmit", 72 | "docs:generate": "typedoc --plugin typedoc-plugin-markdown --out docs src/index.ts --excludeExternals --exclude '**/abi/**' --includeVersion", 73 | "docs:llms": "node scripts/generate-llms-doc.js" 74 | }, 75 | "packageManager": "pnpm@8.15.4", 76 | "devDependencies": { 77 | "@rollup/plugin-commonjs": "^22.0.0", 78 | "@rollup/plugin-json": "^4.1.0", 79 | "@rollup/plugin-node-resolve": "^13.3.0", 80 | "@rollup/plugin-terser": "^0.4.4", 81 | "@rollup/plugin-typescript": "^8.3.2", 82 | "@types/react": "^19.0.10", 83 | "rimraf": "^6.0.1", 84 | "rollup": "^2.75.6", 85 | "tslib": "^2.4.0", 86 | "typedoc": "^0.25.12", 87 | "typedoc-plugin-markdown": "^3.17.1", 88 | "typescript": "^5.3.3" 89 | }, 90 | "dependencies": { 91 | "@delvtech/drift": "^0.11.0", 92 | "@delvtech/drift-viem": "^0.11.0", 93 | "@uniswap/v3-sdk": "^3.24.1", 94 | "axios": "^1.8.1", 95 | "react": "^19.0.0", 96 | "viem": "^2.29.2" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/clients/TreasuryManagerClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type ReadWriteContract, 6 | type ReadWriteAdapter, 7 | createDrift, 8 | } from "@delvtech/drift"; 9 | import { TreasuryManagerAbi } from "../abi/TreasuryManager"; 10 | 11 | export type TreasuryManagerABI = typeof TreasuryManagerAbi; 12 | 13 | export type FlaunchToken = { 14 | flaunch: Address; 15 | tokenId: bigint; 16 | }; 17 | 18 | /** 19 | * Client for interacting with the TreasuryManager contract in read-only mode 20 | * Provides methods to query permissions and manager owner 21 | */ 22 | export class ReadTreasuryManager { 23 | public readonly contract: ReadContract; 24 | 25 | /** 26 | * Creates a new ReadTreasuryManager instance 27 | * @param address - The address of the TreasuryManager contract 28 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 29 | * @throws Error if address is not provided 30 | */ 31 | constructor(address: Address, drift: Drift = createDrift()) { 32 | if (!address) { 33 | throw new Error("Address is required"); 34 | } 35 | 36 | this.contract = drift.contract({ 37 | abi: TreasuryManagerAbi, 38 | address, 39 | }); 40 | } 41 | 42 | /** 43 | * Gets the permissions contract address 44 | * @returns Promise
- The address of the permissions contract 45 | */ 46 | permissions() { 47 | return this.contract.read("permissions"); 48 | } 49 | 50 | /** 51 | * Gets the manager owner address 52 | * @returns Promise
- The address of the manager owner 53 | */ 54 | managerOwner() { 55 | return this.contract.read("managerOwner"); 56 | } 57 | } 58 | 59 | /** 60 | * Extended client for interacting with the TreasuryManager contract with write capabilities 61 | * Provides methods to deposit tokens, set permissions, and transfer ownership 62 | */ 63 | export class ReadWriteTreasuryManager extends ReadTreasuryManager { 64 | declare contract: ReadWriteContract; 65 | 66 | constructor( 67 | address: Address, 68 | drift: Drift = createDrift() 69 | ) { 70 | super(address, drift); 71 | } 72 | 73 | /** 74 | * Deposits a flaunch token to the treasury 75 | * @param flaunchToken - The flaunch token to deposit 76 | * @param creator - The address of the creator 77 | * @param data - Additional data for the deposit 78 | * @returns Promise 79 | */ 80 | deposit(flaunchToken: FlaunchToken, creator: Address, data: `0x${string}`) { 81 | return this.contract.write("deposit", { 82 | _flaunchToken: flaunchToken, 83 | _creator: creator, 84 | _data: data, 85 | }); 86 | } 87 | 88 | /** 89 | * Sets the permissions contract address 90 | * @param permissions - The address of the new permissions contract 91 | * @returns Promise 92 | */ 93 | setPermissions(permissions: Address) { 94 | return this.contract.write("setPermissions", { 95 | _permissions: permissions, 96 | }); 97 | } 98 | 99 | /** 100 | * Transfers the manager ownership to a new address 101 | * @param newManagerOwner - The address of the new manager owner 102 | * @returns Promise 103 | */ 104 | transferManagerOwnership(newManagerOwner: Address) { 105 | return this.contract.write("transferManagerOwnership", { 106 | _newManagerOwner: newManagerOwner, 107 | }); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/clients/MemecoinClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { MemecoinAbi } from "../abi/Memecoin"; 12 | 13 | export type MemecoinABI = typeof MemecoinAbi; 14 | 15 | /** 16 | * Client for interacting with Memecoin (ERC20) contracts in read-only mode 17 | * Provides methods to query basic token information and balances 18 | */ 19 | export class ReadMemecoin { 20 | public readonly contract: ReadContract; 21 | 22 | /** 23 | * Creates a new ReadMemecoin instance 24 | * @param address - The address of the Memecoin contract 25 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 26 | * @throws Error if address is not provided 27 | */ 28 | constructor(address: Address, drift: Drift = createDrift()) { 29 | if (!address) { 30 | throw new Error("Address is required"); 31 | } 32 | 33 | this.contract = drift.contract({ 34 | abi: MemecoinAbi, 35 | address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets the name of the token 41 | * @returns Promise - The name of the token 42 | */ 43 | name() { 44 | return this.contract.read("name", {}); 45 | } 46 | 47 | /** 48 | * Gets the symbol of the token 49 | * @returns Promise - The symbol of the token 50 | */ 51 | symbol() { 52 | return this.contract.read("symbol"); 53 | } 54 | 55 | /** 56 | * Gets the token URI containing metadata 57 | * @returns Promise - The token URI 58 | */ 59 | tokenURI() { 60 | return this.contract.read("tokenURI"); 61 | } 62 | 63 | /** 64 | * Gets the decimals of the token 65 | * @returns Promise - The decimals of the token 66 | */ 67 | decimals() { 68 | return this.contract.read("decimals"); 69 | } 70 | 71 | /** 72 | * Gets the total supply of the token 73 | * @returns Promise - The total supply 74 | */ 75 | totalSupply() { 76 | return this.contract.read("totalSupply"); 77 | } 78 | 79 | /** 80 | * Gets the token balance of a specific user 81 | * @param user - The address of the user to check 82 | * @returns Promise - The token balance 83 | */ 84 | balanceOf(user: Address) { 85 | return this.contract.read("balanceOf", { 86 | account: user, 87 | }); 88 | } 89 | 90 | /** 91 | * Gets the allowance of an ERC20 token to a spender 92 | * @param owner - The address of the owner to check 93 | * @param spender - The address of the spender to check 94 | * @returns Promise - The allowance of the coin to the spender 95 | */ 96 | allowance(owner: Address, spender: Address) { 97 | return this.contract.read("allowance", { 98 | owner, 99 | spender, 100 | }); 101 | } 102 | } 103 | 104 | export class ReadWriteMemecoin extends ReadMemecoin { 105 | declare contract: ReadWriteContract; 106 | 107 | constructor(address: Address, drift: Drift = createDrift()) { 108 | super(address, drift); 109 | } 110 | 111 | /** 112 | * Approves an amount of the token to be spent by another address 113 | * @param spender - The address of the spender to approve 114 | * @param amount - The amount of the token to approve 115 | * @returns Promise - The transaction receipt 116 | */ 117 | approve(spender: Address, amount: bigint) { 118 | return this.contract.write("approve", { 119 | spender, 120 | amount, 121 | }); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/utils/parseSwap.ts: -------------------------------------------------------------------------------- 1 | export interface SwapLogArgs { 2 | flAmount0: bigint; 3 | flAmount1: bigint; 4 | flFee0: bigint; 5 | flFee1: bigint; 6 | ispAmount0: bigint; 7 | ispAmount1: bigint; 8 | ispFee0: bigint; 9 | ispFee1: bigint; 10 | uniAmount0: bigint; 11 | uniAmount1: bigint; 12 | uniFee0: bigint; 13 | uniFee1: bigint; 14 | } 15 | 16 | export interface SwapFees { 17 | isInFLETH: boolean; 18 | amount: bigint; 19 | } 20 | 21 | export interface BuySwapData { 22 | type: "BUY"; 23 | delta: { 24 | coinsBought: bigint; 25 | flETHSold: bigint; 26 | fees: SwapFees; 27 | }; 28 | } 29 | 30 | export interface SellSwapData { 31 | type: "SELL"; 32 | delta: { 33 | coinsSold: bigint; 34 | flETHBought: bigint; 35 | fees: SwapFees; 36 | }; 37 | } 38 | 39 | export type ParsedSwapData = BuySwapData | SellSwapData; 40 | 41 | /** 42 | * Parses raw swap log arguments into structured swap data 43 | * @param args - The swap log arguments 44 | * @param flETHIsCurrencyZero - Whether flETH is currency 0 in the pool 45 | * @returns Parsed swap data with type and delta information 46 | */ 47 | export function parseSwapData( 48 | args: SwapLogArgs, 49 | flETHIsCurrencyZero: boolean 50 | ): ParsedSwapData { 51 | const { 52 | flAmount0, 53 | flAmount1, 54 | flFee0, 55 | flFee1, 56 | ispAmount0, 57 | ispAmount1, 58 | ispFee0, 59 | ispFee1, 60 | uniAmount0, 61 | uniAmount1, 62 | uniFee0, 63 | uniFee1, 64 | } = args; 65 | 66 | const currency0Delta = flAmount0 + ispAmount0 + uniAmount0; 67 | const currency1Delta = flAmount1 + ispAmount1 + uniAmount1; 68 | const currency0Fees = flFee0 + ispFee0 + uniFee0; 69 | const currency1Fees = flFee1 + ispFee1 + uniFee1; 70 | 71 | let feesIsInFLETH: boolean; 72 | let swapType: "BUY" | "SELL"; 73 | 74 | if (flETHIsCurrencyZero) { 75 | swapType = currency0Delta < 0 ? "BUY" : "SELL"; 76 | feesIsInFLETH = currency0Fees < 0; 77 | } else { 78 | swapType = currency1Delta < 0 ? "BUY" : "SELL"; 79 | feesIsInFLETH = currency1Fees < 0; 80 | } 81 | 82 | const absCurrency0Delta = 83 | currency0Delta < 0 ? -currency0Delta : currency0Delta; 84 | const absCurrency1Delta = 85 | currency1Delta < 0 ? -currency1Delta : currency1Delta; 86 | const absCurrency0Fees = currency0Fees < 0 ? -currency0Fees : currency0Fees; 87 | const absCurrency1Fees = currency1Fees < 0 ? -currency1Fees : currency1Fees; 88 | 89 | const fees: SwapFees = { 90 | isInFLETH: feesIsInFLETH, 91 | amount: flETHIsCurrencyZero 92 | ? feesIsInFLETH 93 | ? absCurrency0Fees 94 | : absCurrency1Fees 95 | : feesIsInFLETH 96 | ? absCurrency1Fees 97 | : absCurrency0Fees, 98 | }; 99 | 100 | if (swapType === "BUY") { 101 | return { 102 | type: swapType, 103 | delta: { 104 | coinsBought: flETHIsCurrencyZero 105 | ? absCurrency1Delta - (!fees.isInFLETH ? fees.amount : 0n) 106 | : absCurrency0Delta - (!fees.isInFLETH ? fees.amount : 0n), 107 | flETHSold: flETHIsCurrencyZero 108 | ? absCurrency0Delta - (fees.isInFLETH ? fees.amount : 0n) 109 | : absCurrency1Delta - (fees.isInFLETH ? fees.amount : 0n), 110 | fees, 111 | }, 112 | }; 113 | } else { 114 | return { 115 | type: swapType, 116 | delta: { 117 | coinsSold: flETHIsCurrencyZero 118 | ? absCurrency1Delta - (!fees.isInFLETH ? fees.amount : 0n) 119 | : absCurrency0Delta - (!fees.isInFLETH ? fees.amount : 0n), 120 | flETHBought: flETHIsCurrencyZero 121 | ? absCurrency0Delta - (fees.isInFLETH ? fees.amount : 0n) 122 | : absCurrency1Delta - (fees.isInFLETH ? fees.amount : 0n), 123 | fees, 124 | }, 125 | }; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/clients/FastFlaunchClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | createDrift, 9 | } from "@delvtech/drift"; 10 | import { FastFlaunchZapAbi } from "../abi/FastFlaunchZap"; 11 | import { generateTokenUri } from "../helpers/ipfs"; 12 | import { IPFSParams } from "../types"; 13 | 14 | export type FastFlaunchZapABI = typeof FastFlaunchZapAbi; 15 | 16 | /** 17 | * Base client for interacting with the FastFlaunchZap contract in read-only mode 18 | * Provides basic contract initialization 19 | */ 20 | export class ReadFastFlaunchZap { 21 | public readonly contract: ReadContract; 22 | 23 | /** 24 | * Creates a new ReadFastFlaunchZap instance 25 | * @param address - The address of the FastFlaunchZap contract 26 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 27 | * @throws Error if address is not provided 28 | */ 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | this.contract = drift.contract({ 34 | abi: FastFlaunchZapAbi, 35 | address, 36 | }); 37 | } 38 | } 39 | 40 | /** 41 | * Parameters for creating a new fast flaunch with direct token URI 42 | */ 43 | export interface FastFlaunchParams { 44 | /** The name of the token */ 45 | name: string; 46 | /** The symbol of the token */ 47 | symbol: string; 48 | /** The URI containing the token metadata */ 49 | tokenUri: string; 50 | /** The address of the token creator */ 51 | creator: Address; 52 | } 53 | 54 | /** 55 | * Parameters for creating a new fast flaunch with IPFS metadata 56 | * Extends FastFlaunchParams (without tokenUri) and IPFSParams 57 | */ 58 | export interface FastFlaunchIPFSParams 59 | extends Omit, 60 | IPFSParams {} 61 | 62 | /** 63 | * Extended client for interacting with the FastFlaunchZap contract with write capabilities 64 | * Provides methods to create new fast flaunches with direct URI or IPFS metadata 65 | */ 66 | export class ReadWriteFastFlaunchZap extends ReadFastFlaunchZap { 67 | declare contract: ReadWriteContract; 68 | 69 | /** 70 | * Creates a new ReadWriteFastFlaunchZap instance 71 | * @param address - The address of the FastFlaunchZap contract 72 | * @param drift - Optional drift instance for contract interactions (creates new instance if not provided) 73 | */ 74 | constructor( 75 | address: Address, 76 | drift: Drift = createDrift() 77 | ) { 78 | super(address, drift); 79 | } 80 | 81 | /** 82 | * Creates a new fast flaunch with direct token URI 83 | * @param params - Parameters for the fast flaunch including name, symbol, tokenUri, and creator 84 | * @returns Transaction response for the flaunch creation 85 | */ 86 | fastFlaunch({ name, symbol, tokenUri, creator }: FastFlaunchParams) { 87 | return this.contract.write("flaunch", { 88 | _params: { 89 | name, 90 | symbol, 91 | tokenUri, 92 | creator, 93 | }, 94 | }); 95 | } 96 | 97 | /** 98 | * Creates a new fast flaunch with metadata stored on IPFS 99 | * @param params - Parameters for the fast flaunch including name, symbol, creator, metadata, and Pinata config 100 | * @returns Promise resolving to the transaction response for the flaunch creation 101 | */ 102 | async fastFlaunchIPFS({ 103 | name, 104 | symbol, 105 | creator, 106 | metadata, 107 | pinataConfig, 108 | }: FastFlaunchIPFSParams) { 109 | const tokenUri = await generateTokenUri(name, symbol, { 110 | metadata, 111 | pinataConfig, 112 | }); 113 | 114 | return this.fastFlaunch({ 115 | name, 116 | symbol, 117 | tokenUri, 118 | creator, 119 | }); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/clients/RevenueManagerClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { RevenueManagerAbi } from "../abi/RevenueManager"; 12 | import { ReadMulticall } from "./MulticallClient"; 13 | 14 | export type RevenueManagerABI = typeof RevenueManagerAbi; 15 | 16 | export class ReadRevenueManager { 17 | drift: Drift; 18 | public readonly contract: ReadContract; 19 | 20 | constructor(address: Address, drift: Drift = createDrift()) { 21 | this.drift = drift; 22 | this.contract = drift.contract({ 23 | abi: RevenueManagerAbi, 24 | address, 25 | }); 26 | } 27 | 28 | /** 29 | * Gets the claimable balance of ETH for the recipient 30 | * @param recipient - The address of the recipient to check 31 | * @returns Promise - The claimable balance of ETH 32 | */ 33 | balances(address: Address) { 34 | return this.contract.read("balances", { 35 | _recipient: address, 36 | }); 37 | } 38 | 39 | /** 40 | * Gets the protocol recipient address 41 | * @returns Promise
- The protocol recipient address 42 | */ 43 | protocolRecipient() { 44 | return this.contract.read("protocolRecipient"); 45 | } 46 | 47 | /** 48 | * Gets the total number of tokens managed by the revenue manager 49 | * @returns Promise - The total count of tokens 50 | */ 51 | async tokensCount() { 52 | const nextInternalId = await this.contract.read("nextInternalId"); 53 | return nextInternalId - 1n; 54 | } 55 | 56 | /** 57 | * Gets all tokens created by a specific creator address 58 | * @param creator - The address of the creator to query tokens for 59 | * @param sortByDesc - Optional boolean to sort tokens in descending order (default: false) 60 | * @returns Promise> - Array of token objects containing flaunch address and token ID 61 | */ 62 | async allTokensByCreator(creator: Address, sortByDesc: boolean = false) { 63 | const tokens = await this.contract.read("tokens", { 64 | _creator: creator, 65 | }); 66 | 67 | if (sortByDesc) { 68 | return [...tokens].reverse(); 69 | } 70 | 71 | return tokens; 72 | } 73 | 74 | /** 75 | * Gets all tokens currently managed by the revenue manager contract 76 | * @dev Uses multicall to batch requests for better performance 77 | * @param sortByDesc - Optional boolean to sort tokens in descending order (default: false) 78 | * @returns Promise> - Array of token objects containing flaunch address and token ID 79 | */ 80 | async allTokensInManager(sortByDesc: boolean = false) { 81 | const count = await this.tokensCount(); 82 | const multicall = new ReadMulticall(this.drift); 83 | 84 | let calldatas = Array.from({ length: Number(count) }, (_, i) => 85 | this.contract.encodeFunctionData("internalIds", { 86 | _internalId: BigInt(i + 1), 87 | }) 88 | ); 89 | 90 | // Reverse the array if sortByDesc is true 91 | if (sortByDesc) { 92 | calldatas = calldatas.reverse(); 93 | } 94 | 95 | const result = await multicall.aggregate3( 96 | calldatas.map((calldata) => ({ 97 | target: this.contract.address, 98 | callData: calldata, 99 | })) 100 | ); 101 | 102 | return result.map((r) => 103 | this.contract.decodeFunctionReturn("internalIds", r.returnData) 104 | ); 105 | } 106 | } 107 | 108 | export class ReadWriteRevenueManager extends ReadRevenueManager { 109 | declare contract: ReadWriteContract; 110 | 111 | constructor( 112 | address: Address, 113 | drift: Drift = createDrift() 114 | ) { 115 | super(address, drift); 116 | } 117 | 118 | /** 119 | * Allows the protocol recipient to claim the protocol's share of the revenue 120 | * @returns Promise - The transaction response 121 | */ 122 | protocolClaim() { 123 | return this.contract.write("claim", {}); 124 | } 125 | 126 | /** 127 | * Allows the creator to claim their total share of the revenue from a revenue manager 128 | * @returns Promise - The transaction response 129 | */ 130 | creatorClaim() { 131 | return this.contract.write("claim", {}); 132 | } 133 | 134 | /** 135 | * Allows the creator to claim their share of the revenue from specific flaunch tokens 136 | * @param flaunchTokens - The flaunch token ids to claim the revenue for 137 | * @returns Promise - The transaction response 138 | */ 139 | creatorClaimForTokens( 140 | flaunchTokens: { flaunch: Address; tokenId: bigint }[] 141 | ) { 142 | return this.contract.write("claim", { 143 | _flaunchToken: flaunchTokens, 144 | }); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/clients/PoolManagerClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type Contract, 3 | type ReadContract, 4 | type Address, 5 | type Drift, 6 | type EventLog, 7 | type ReadWriteContract, 8 | type ReadWriteAdapter, 9 | type HexString, 10 | createDrift, 11 | } from "@delvtech/drift"; 12 | import { keccak256, encodePacked, stringToHex, pad, hexToBigInt } from "viem"; 13 | import { bytes32ToUint256, uint256ToBytes32 } from "../helpers/hex"; 14 | import { PoolManagerAbi } from "../abi/PoolManager"; 15 | 16 | export type PoolManagerABI = typeof PoolManagerAbi; 17 | 18 | export interface PositionInfoParams { 19 | poolId: HexString; 20 | owner: Address; 21 | tickLower: number; 22 | tickUpper: number; 23 | salt: string; 24 | } 25 | 26 | export class ReadPoolManager { 27 | public readonly contract: ReadContract; 28 | 29 | constructor(address: Address, drift: Drift = createDrift()) { 30 | if (!address) { 31 | throw new Error("Address is required"); 32 | } 33 | 34 | this.contract = drift.contract({ 35 | abi: PoolManagerAbi, 36 | address, 37 | }); 38 | } 39 | 40 | poolStateSlot({ poolId }: { poolId: HexString }) { 41 | const POOLS_SLOT = uint256ToBytes32(6n); 42 | 43 | return keccak256( 44 | encodePacked(["bytes32", "bytes32"], [poolId, POOLS_SLOT]) 45 | ); 46 | } 47 | 48 | async poolSlot0({ poolId }: { poolId: HexString }) { 49 | const stateSlot = this.poolStateSlot({ poolId }); 50 | 51 | let res = { sqrtPriceX96: 0n, tick: 0, protocolFee: 0, lpFee: 0 }; 52 | 53 | try { 54 | const result = await this.contract.read("extsload", { 55 | slot: stateSlot, 56 | }); 57 | 58 | const data = (Array.isArray(result) ? result[0] : result) as HexString; 59 | 60 | // Convert the input hex to a BigInt for bitwise operations 61 | const dataAsBigInt = BigInt(data); 62 | 63 | // Extract sqrtPriceX96 (bottom 160 bits) 64 | const sqrtPriceX96Mask = BigInt( 65 | "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 66 | ); 67 | const sqrtPriceX96 = dataAsBigInt & sqrtPriceX96Mask; 68 | 69 | // Extract tick (next 24 bits after sqrtPriceX96) 70 | // First, shift right by 160 bits to get the tick bits at the bottom 71 | const tickShifted = dataAsBigInt >> 160n; 72 | // Then mask to get only the 24 bits we want 73 | const tickMask = BigInt("0xFFFFFF"); 74 | const tickRaw = Number(tickShifted & tickMask); 75 | // Sign extend the 24-bit number if needed 76 | const tick = tickRaw > 0x7fffff ? tickRaw - 0x1000000 : tickRaw; 77 | 78 | // Extract protocolFee (next 24 bits) 79 | const protocolFeeShifted = dataAsBigInt >> 184n; 80 | const protocolFeeMask = BigInt("0xFFFFFF"); 81 | const protocolFee = Number(protocolFeeShifted & protocolFeeMask); 82 | 83 | // Extract lpFee (last 24 bits) 84 | const lpFeeShifted = dataAsBigInt >> 208n; 85 | const lpFeeMask = BigInt("0xFFFFFF"); 86 | const lpFee = Number(lpFeeShifted & lpFeeMask); 87 | 88 | res = { sqrtPriceX96, tick, protocolFee, lpFee }; 89 | } catch (error) { 90 | console.error(error); 91 | } 92 | 93 | return res; 94 | } 95 | 96 | async positionInfo({ 97 | poolId, 98 | owner, 99 | tickLower, 100 | tickUpper, 101 | salt, 102 | }: PositionInfoParams): Promise<{ 103 | liquidity: bigint; 104 | feeGrowthInside0LastX128: bigint; 105 | feeGrowthInside1LastX128: bigint; 106 | }> { 107 | const saltBytes32 = pad(stringToHex(salt), { size: 32, dir: "right" }); 108 | 109 | const positionKey = keccak256( 110 | encodePacked( 111 | ["address", "int24", "int24", "bytes32"], 112 | [owner, tickLower, tickUpper, saltBytes32] 113 | ) 114 | ); 115 | 116 | const stateSlot = this.poolStateSlot({ poolId }); 117 | 118 | const POSITIONS_OFFSET = 6n; 119 | const positionMapping = uint256ToBytes32( 120 | bytes32ToUint256(stateSlot) + POSITIONS_OFFSET 121 | ); 122 | 123 | const positionInfoSlot = keccak256( 124 | encodePacked(["bytes32", "bytes32"], [positionKey, positionMapping]) 125 | ); 126 | 127 | const data = (await this.contract.read("extsload", { 128 | startSlot: positionInfoSlot, 129 | nSlots: 3n, 130 | })) as HexString[]; 131 | 132 | // FIXME: data returned is not an array 133 | console.log({ data }); 134 | 135 | const liquidity = hexToBigInt(data[0]); 136 | const feeGrowthInside0LastX128 = hexToBigInt(data[1]); 137 | const feeGrowthInside1LastX128 = hexToBigInt(data[2]); 138 | 139 | return { 140 | liquidity, 141 | feeGrowthInside0LastX128, 142 | feeGrowthInside1LastX128, 143 | }; 144 | } 145 | 146 | async getStateSlot(stateSlot: HexString): Promise { 147 | const result = await this.contract.read("extsload", { 148 | slot: stateSlot, 149 | }); 150 | // Cast through unknown first to avoid type checking issues 151 | const firstResult = Array.isArray(result) ? result[0] : result; 152 | return firstResult as unknown as HexString; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/clients/TokenImporter.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ReadContract, 3 | type Address, 4 | type Drift, 5 | type EventLog, 6 | type ReadWriteContract, 7 | type ReadWriteAdapter, 8 | type HexString, 9 | createDrift, 10 | } from "@delvtech/drift"; 11 | import { TokenImporterAbi } from "../abi/TokenImporter"; 12 | import { zeroAddress, parseUnits, formatUnits } from "viem"; 13 | import { Verifier } from "../types"; 14 | import { 15 | ClankerWorldVerifierAddress, 16 | DopplerVerifierAddress, 17 | SolanaVerifierAddress, 18 | VirtualsVerifierAddress, 19 | WhitelistVerifierAddress, 20 | ZoraVerifierAddress, 21 | } from "addresses"; 22 | import { ReadMemecoin } from "./MemecoinClient"; 23 | 24 | export type TokenImporterABI = typeof TokenImporterAbi; 25 | 26 | /** 27 | * Base client for interacting with the TokenImporter contract in read-only mode 28 | * Provides basic contract initialization 29 | */ 30 | export class ReadTokenImporter { 31 | drift: Drift; 32 | chainId: number; 33 | public readonly contract: ReadContract; 34 | 35 | constructor(chainId: number, address: Address, drift: Drift = createDrift()) { 36 | this.chainId = chainId; 37 | this.drift = drift; 38 | this.contract = drift.contract({ 39 | abi: TokenImporterAbi, 40 | address, 41 | }); 42 | } 43 | 44 | /** 45 | * Verifies if a memecoin is valid for importing 46 | * @param memecoin - The address of the memecoin to import 47 | * @returns Promise<{ isValid: boolean; verifier: Address }> - The result of the verification 48 | */ 49 | async verifyMemecoin(memecoin: Address): Promise<{ 50 | isValid: boolean; 51 | verifier: Address; 52 | }> { 53 | const verifier = await this.contract.read("verifyMemecoin", { 54 | _memecoin: memecoin, 55 | }); 56 | 57 | return { 58 | isValid: verifier !== zeroAddress, 59 | verifier, 60 | }; 61 | } 62 | 63 | /** 64 | * Returns the address of a verifier 65 | */ 66 | verifierAddress(verifier: Verifier) { 67 | switch (verifier) { 68 | case Verifier.CLANKER: 69 | return ClankerWorldVerifierAddress[this.chainId]; 70 | case Verifier.DOPPLER: 71 | return DopplerVerifierAddress[this.chainId]; 72 | case Verifier.SOLANA: 73 | return SolanaVerifierAddress[this.chainId]; 74 | case Verifier.VIRTUALS: 75 | return VirtualsVerifierAddress[this.chainId]; 76 | case Verifier.WHITELIST: 77 | return WhitelistVerifierAddress[this.chainId]; 78 | case Verifier.ZORA: 79 | return ZoraVerifierAddress[this.chainId]; 80 | default: 81 | throw new Error(`Unknown verifier: ${verifier}`); 82 | } 83 | } 84 | } 85 | 86 | /** 87 | * Extended client for interacting with the TokenImporter contract with write capabilities 88 | */ 89 | export class ReadWriteTokenImporter extends ReadTokenImporter { 90 | declare contract: ReadWriteContract; 91 | 92 | constructor( 93 | chainId: number, 94 | address: Address, 95 | drift: Drift = createDrift() 96 | ) { 97 | super(chainId, address, drift); 98 | } 99 | 100 | async initialize( 101 | params: 102 | | { 103 | coinAddress: Address; 104 | creatorFeeAllocationPercent: number; 105 | initialMarketCapUSD: number; 106 | verifier?: Verifier; 107 | tokenSupply?: bigint; 108 | } 109 | | { 110 | coinAddress: Address; 111 | creatorFeeAllocationPercent: number; 112 | initialPriceUSD: number; 113 | verifier?: Verifier; 114 | tokenSupply?: bigint; 115 | } 116 | ) { 117 | return this.contract.write( 118 | "initialize", 119 | await this.getInitializeParams(params) 120 | ); 121 | } 122 | 123 | async getInitializeParams( 124 | params: 125 | | { 126 | coinAddress: Address; 127 | creatorFeeAllocationPercent: number; 128 | initialMarketCapUSD: number; 129 | verifier?: Verifier; 130 | tokenSupply?: bigint; 131 | } 132 | | { 133 | coinAddress: Address; 134 | creatorFeeAllocationPercent: number; 135 | initialPriceUSD: number; 136 | verifier?: Verifier; 137 | tokenSupply?: bigint; 138 | } 139 | ) { 140 | let initialMarketCapUSD: number; 141 | if ("initialMarketCapUSD" in params) { 142 | initialMarketCapUSD = params.initialMarketCapUSD; 143 | } else { 144 | const memecoin = new ReadMemecoin(params.coinAddress, this.drift); 145 | const totalSupply = await memecoin.totalSupply(); 146 | const decimals = await memecoin.decimals(); 147 | const formattedTotalSupply = parseFloat( 148 | formatUnits(totalSupply, decimals) 149 | ); 150 | 151 | initialMarketCapUSD = params.initialPriceUSD * formattedTotalSupply; 152 | } 153 | 154 | const initialMCapInUSDCWei = parseUnits(initialMarketCapUSD.toString(), 6); 155 | const creatorFeeAllocationInBps = params.creatorFeeAllocationPercent * 100; 156 | 157 | // Passing in the verifier here, as drift doesn't recognize the other initialize function without the verifier param 158 | let _verifier = params.verifier 159 | ? this.verifierAddress(params.verifier) 160 | : await this.contract.read("verifyMemecoin", { 161 | _memecoin: params.coinAddress, 162 | }); 163 | 164 | const baseParams = { 165 | _memecoin: params.coinAddress, 166 | _creatorFeeAllocation: creatorFeeAllocationInBps, 167 | _initialMarketCap: initialMCapInUSDCWei, 168 | _verifier, 169 | }; 170 | 171 | // If tokenSupply is provided (even if 0n), include it to use the 5-parameter initialize overload 172 | if (params.tokenSupply !== undefined) { 173 | return { 174 | ...baseParams, 175 | _totalSupply: params.tokenSupply, 176 | }; 177 | } 178 | 179 | return baseParams; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/sdk/FlaunchBackend.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Address, 3 | Hex, 4 | keccak256, 5 | encodePacked, 6 | zeroAddress, 7 | encodeAbiParameters, 8 | } from "viem"; 9 | import { privateKeyToAccount } from "viem/accounts"; 10 | import { TICK_SPACING, orderPoolKey, getPoolId } from "../utils/univ4"; 11 | import { FlaunchVersion } from "../types"; 12 | import { 13 | FLETHAddress, 14 | FlaunchPositionManagerAddress, 15 | FlaunchPositionManagerV1_1Address, 16 | FlaunchPositionManagerV1_2Address, 17 | } from "addresses"; 18 | 19 | /** 20 | * Backend class for interacting with Flaunch protocol for generating hookData with signature for swaps. 21 | * Doesn't require any publicClient or walletClient to be initialized. 22 | */ 23 | export class FlaunchBackend { 24 | signerPrivateKey: Hex; 25 | public readonly chainId: number; 26 | 27 | constructor(signerPrivateKey: Hex, chainId: number) { 28 | this.signerPrivateKey = signerPrivateKey; 29 | this.chainId = chainId; 30 | } 31 | 32 | /** 33 | * Generates the hookData for swaps when TrustedSigner is enabled for a coin during fair launch 34 | * 35 | * @param userWallet - The wallet address to generate a signature for 36 | * @param coinAddress - The address of the coin to generate a signature for 37 | * @param deadlineFromNowInSeconds - The deadline from now in seconds 38 | * @param version - The version to get the position manager address for, defaults to the latest version if undefined 39 | * @param referrer - (optional) The referrer address for the swap 40 | * @return The hookData, deadline and signature 41 | */ 42 | async generateHookDataWithSignature({ 43 | userWallet, 44 | coinAddress, 45 | deadlineFromNowInSeconds, 46 | version, 47 | referrer, 48 | }: { 49 | userWallet: Address; 50 | coinAddress: Address; 51 | deadlineFromNowInSeconds: number; 52 | version?: FlaunchVersion; 53 | referrer?: Address; 54 | }): Promise<{ 55 | hookData: Hex; 56 | deadline: number; 57 | signature: Hex; 58 | }> { 59 | const poolId = getPoolId( 60 | orderPoolKey({ 61 | currency0: FLETHAddress[this.chainId], 62 | currency1: coinAddress, 63 | fee: 0, 64 | tickSpacing: TICK_SPACING, 65 | hooks: this.getPositionManagerAddress(version), 66 | }) 67 | ); 68 | 69 | const nowInSeconds = Math.floor(Date.now() / 1000); 70 | const deadline = BigInt(nowInSeconds + deadlineFromNowInSeconds); 71 | 72 | const signature = await generateSignatureRaw({ 73 | userWallet, 74 | poolId, 75 | deadline, 76 | privateKey: this.signerPrivateKey, 77 | }); 78 | 79 | if (!referrer) { 80 | referrer = zeroAddress; 81 | } 82 | 83 | // Encode hookData equivalent to Solidity's abi.encode(referrer, SignedMessage) 84 | const hookData = encodeAbiParameters( 85 | [ 86 | { name: "referrer", type: "address" }, 87 | { 88 | name: "signedMessage", 89 | type: "tuple", 90 | components: [ 91 | { name: "poolId", type: "bytes32" }, 92 | { name: "deadline", type: "uint256" }, 93 | { name: "signature", type: "bytes" }, 94 | ], 95 | }, 96 | ], 97 | [ 98 | referrer, 99 | { 100 | poolId, 101 | deadline, 102 | signature, 103 | }, 104 | ] 105 | ); 106 | 107 | return { 108 | hookData, 109 | deadline: Number(deadline), 110 | signature, 111 | }; 112 | } 113 | 114 | /** 115 | * Gets the position manager address for a given version 116 | * @param version - The version to get the position manager address for, defaults to the latest version if undefined 117 | */ 118 | getPositionManagerAddress(version?: FlaunchVersion) { 119 | const latestVersionAddress = 120 | FlaunchPositionManagerV1_2Address[this.chainId]; 121 | 122 | if (!version) { 123 | return latestVersionAddress; 124 | } 125 | 126 | switch (version) { 127 | case FlaunchVersion.V1: 128 | return FlaunchPositionManagerAddress[this.chainId]; 129 | case FlaunchVersion.V1_1: 130 | return FlaunchPositionManagerV1_1Address[this.chainId]; 131 | case FlaunchVersion.V1_2: 132 | return FlaunchPositionManagerV1_2Address[this.chainId]; 133 | case FlaunchVersion.ANY: 134 | throw Error("AnyPositionManager is not supported for TrustedSigner"); 135 | default: 136 | return latestVersionAddress; 137 | } 138 | } 139 | } 140 | 141 | /** 142 | * Generates a signature for a given wallet, poolId, deadline and private key. 143 | * 144 | * @param userWallet The wallet address to generate a signature for 145 | * @param poolId The pool id that this signature is valid for (as hex string) 146 | * @param deadline The deadline for the signature 147 | * @param privateKey The private key to use to generate the signature (as hex string) 148 | * @return The encoded signature as hex string 149 | */ 150 | export const generateSignatureRaw = async ({ 151 | userWallet, 152 | poolId, 153 | deadline, 154 | privateKey, 155 | }: { 156 | userWallet: Address; 157 | poolId: Hex; 158 | deadline: bigint; 159 | privateKey: Hex; 160 | }): Promise => { 161 | // Equivalent to: keccak256(abi.encodePacked(_wallet, _poolId, _deadline)) 162 | const hash = keccak256( 163 | encodePacked( 164 | ["address", "bytes32", "uint256"], 165 | [userWallet, poolId, deadline] 166 | ) 167 | ); 168 | 169 | // Equivalent to: keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)) 170 | const ethSignedMessagePrefix = "\x19Ethereum Signed Message:\n32"; 171 | const message = keccak256( 172 | encodePacked(["string", "bytes32"], [ethSignedMessagePrefix, hash]) 173 | ); 174 | 175 | // Create account from private key and sign the prefixed hash 176 | const account = privateKeyToAccount(privateKey); 177 | const signature = await account.sign({ hash: message }); 178 | 179 | return signature; 180 | }; 181 | -------------------------------------------------------------------------------- /src/abi/StateView.ts: -------------------------------------------------------------------------------- 1 | export const StateViewAbi = [ 2 | { 3 | inputs: [ 4 | { 5 | internalType: "contract IPoolManager", 6 | name: "_poolManager", 7 | type: "address", 8 | }, 9 | ], 10 | stateMutability: "nonpayable", 11 | type: "constructor", 12 | }, 13 | { 14 | inputs: [{ internalType: "PoolId", name: "poolId", type: "bytes32" }], 15 | name: "getFeeGrowthGlobals", 16 | outputs: [ 17 | { internalType: "uint256", name: "feeGrowthGlobal0", type: "uint256" }, 18 | { internalType: "uint256", name: "feeGrowthGlobal1", type: "uint256" }, 19 | ], 20 | stateMutability: "view", 21 | type: "function", 22 | }, 23 | { 24 | inputs: [ 25 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 26 | { internalType: "int24", name: "tickLower", type: "int24" }, 27 | { internalType: "int24", name: "tickUpper", type: "int24" }, 28 | ], 29 | name: "getFeeGrowthInside", 30 | outputs: [ 31 | { 32 | internalType: "uint256", 33 | name: "feeGrowthInside0X128", 34 | type: "uint256", 35 | }, 36 | { 37 | internalType: "uint256", 38 | name: "feeGrowthInside1X128", 39 | type: "uint256", 40 | }, 41 | ], 42 | stateMutability: "view", 43 | type: "function", 44 | }, 45 | { 46 | inputs: [{ internalType: "PoolId", name: "poolId", type: "bytes32" }], 47 | name: "getLiquidity", 48 | outputs: [{ internalType: "uint128", name: "liquidity", type: "uint128" }], 49 | stateMutability: "view", 50 | type: "function", 51 | }, 52 | { 53 | inputs: [ 54 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 55 | { internalType: "bytes32", name: "positionId", type: "bytes32" }, 56 | ], 57 | name: "getPositionInfo", 58 | outputs: [ 59 | { internalType: "uint128", name: "liquidity", type: "uint128" }, 60 | { 61 | internalType: "uint256", 62 | name: "feeGrowthInside0LastX128", 63 | type: "uint256", 64 | }, 65 | { 66 | internalType: "uint256", 67 | name: "feeGrowthInside1LastX128", 68 | type: "uint256", 69 | }, 70 | ], 71 | stateMutability: "view", 72 | type: "function", 73 | }, 74 | { 75 | inputs: [ 76 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 77 | { internalType: "address", name: "owner", type: "address" }, 78 | { internalType: "int24", name: "tickLower", type: "int24" }, 79 | { internalType: "int24", name: "tickUpper", type: "int24" }, 80 | { internalType: "bytes32", name: "salt", type: "bytes32" }, 81 | ], 82 | name: "getPositionInfo", 83 | outputs: [ 84 | { internalType: "uint128", name: "liquidity", type: "uint128" }, 85 | { 86 | internalType: "uint256", 87 | name: "feeGrowthInside0LastX128", 88 | type: "uint256", 89 | }, 90 | { 91 | internalType: "uint256", 92 | name: "feeGrowthInside1LastX128", 93 | type: "uint256", 94 | }, 95 | ], 96 | stateMutability: "view", 97 | type: "function", 98 | }, 99 | { 100 | inputs: [ 101 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 102 | { internalType: "bytes32", name: "positionId", type: "bytes32" }, 103 | ], 104 | name: "getPositionLiquidity", 105 | outputs: [{ internalType: "uint128", name: "liquidity", type: "uint128" }], 106 | stateMutability: "view", 107 | type: "function", 108 | }, 109 | { 110 | inputs: [{ internalType: "PoolId", name: "poolId", type: "bytes32" }], 111 | name: "getSlot0", 112 | outputs: [ 113 | { internalType: "uint160", name: "sqrtPriceX96", type: "uint160" }, 114 | { internalType: "int24", name: "tick", type: "int24" }, 115 | { internalType: "uint24", name: "protocolFee", type: "uint24" }, 116 | { internalType: "uint24", name: "lpFee", type: "uint24" }, 117 | ], 118 | stateMutability: "view", 119 | type: "function", 120 | }, 121 | { 122 | inputs: [ 123 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 124 | { internalType: "int16", name: "tick", type: "int16" }, 125 | ], 126 | name: "getTickBitmap", 127 | outputs: [{ internalType: "uint256", name: "tickBitmap", type: "uint256" }], 128 | stateMutability: "view", 129 | type: "function", 130 | }, 131 | { 132 | inputs: [ 133 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 134 | { internalType: "int24", name: "tick", type: "int24" }, 135 | ], 136 | name: "getTickFeeGrowthOutside", 137 | outputs: [ 138 | { 139 | internalType: "uint256", 140 | name: "feeGrowthOutside0X128", 141 | type: "uint256", 142 | }, 143 | { 144 | internalType: "uint256", 145 | name: "feeGrowthOutside1X128", 146 | type: "uint256", 147 | }, 148 | ], 149 | stateMutability: "view", 150 | type: "function", 151 | }, 152 | { 153 | inputs: [ 154 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 155 | { internalType: "int24", name: "tick", type: "int24" }, 156 | ], 157 | name: "getTickInfo", 158 | outputs: [ 159 | { internalType: "uint128", name: "liquidityGross", type: "uint128" }, 160 | { internalType: "int128", name: "liquidityNet", type: "int128" }, 161 | { 162 | internalType: "uint256", 163 | name: "feeGrowthOutside0X128", 164 | type: "uint256", 165 | }, 166 | { 167 | internalType: "uint256", 168 | name: "feeGrowthOutside1X128", 169 | type: "uint256", 170 | }, 171 | ], 172 | stateMutability: "view", 173 | type: "function", 174 | }, 175 | { 176 | inputs: [ 177 | { internalType: "PoolId", name: "poolId", type: "bytes32" }, 178 | { internalType: "int24", name: "tick", type: "int24" }, 179 | ], 180 | name: "getTickLiquidity", 181 | outputs: [ 182 | { internalType: "uint128", name: "liquidityGross", type: "uint128" }, 183 | { internalType: "int128", name: "liquidityNet", type: "int128" }, 184 | ], 185 | stateMutability: "view", 186 | type: "function", 187 | }, 188 | { 189 | inputs: [], 190 | name: "poolManager", 191 | outputs: [ 192 | { internalType: "contract IPoolManager", name: "", type: "address" }, 193 | ], 194 | stateMutability: "view", 195 | type: "function", 196 | }, 197 | ] as const; 198 | -------------------------------------------------------------------------------- /src/abi/FeeEscrow.ts: -------------------------------------------------------------------------------- 1 | export const FeeEscrowAbi = [ 2 | { 3 | inputs: [ 4 | { internalType: "address", name: "_nativeToken", type: "address" }, 5 | { internalType: "address", name: "_indexer", type: "address" }, 6 | ], 7 | stateMutability: "nonpayable", 8 | type: "constructor", 9 | }, 10 | { inputs: [], name: "AlreadyInitialized", type: "error" }, 11 | { inputs: [], name: "InvalidRecipient", type: "error" }, 12 | { inputs: [], name: "NewOwnerIsZeroAddress", type: "error" }, 13 | { inputs: [], name: "NoHandoverRequest", type: "error" }, 14 | { inputs: [], name: "PoolIdNotIndexed", type: "error" }, 15 | { inputs: [], name: "RecipientZeroAddress", type: "error" }, 16 | { inputs: [], name: "Unauthorized", type: "error" }, 17 | { 18 | anonymous: false, 19 | inputs: [ 20 | { 21 | indexed: true, 22 | internalType: "PoolId", 23 | name: "_poolId", 24 | type: "bytes32", 25 | }, 26 | { 27 | indexed: false, 28 | internalType: "address", 29 | name: "_payee", 30 | type: "address", 31 | }, 32 | { 33 | indexed: false, 34 | internalType: "address", 35 | name: "_token", 36 | type: "address", 37 | }, 38 | { 39 | indexed: false, 40 | internalType: "uint256", 41 | name: "_amount", 42 | type: "uint256", 43 | }, 44 | ], 45 | name: "Deposit", 46 | type: "event", 47 | }, 48 | { 49 | anonymous: false, 50 | inputs: [ 51 | { 52 | indexed: true, 53 | internalType: "address", 54 | name: "pendingOwner", 55 | type: "address", 56 | }, 57 | ], 58 | name: "OwnershipHandoverCanceled", 59 | type: "event", 60 | }, 61 | { 62 | anonymous: false, 63 | inputs: [ 64 | { 65 | indexed: true, 66 | internalType: "address", 67 | name: "pendingOwner", 68 | type: "address", 69 | }, 70 | ], 71 | name: "OwnershipHandoverRequested", 72 | type: "event", 73 | }, 74 | { 75 | anonymous: false, 76 | inputs: [ 77 | { 78 | indexed: true, 79 | internalType: "address", 80 | name: "oldOwner", 81 | type: "address", 82 | }, 83 | { 84 | indexed: true, 85 | internalType: "address", 86 | name: "newOwner", 87 | type: "address", 88 | }, 89 | ], 90 | name: "OwnershipTransferred", 91 | type: "event", 92 | }, 93 | { 94 | anonymous: false, 95 | inputs: [ 96 | { 97 | indexed: false, 98 | internalType: "address", 99 | name: "_sender", 100 | type: "address", 101 | }, 102 | { 103 | indexed: false, 104 | internalType: "address", 105 | name: "_recipient", 106 | type: "address", 107 | }, 108 | { 109 | indexed: false, 110 | internalType: "address", 111 | name: "_token", 112 | type: "address", 113 | }, 114 | { 115 | indexed: false, 116 | internalType: "uint256", 117 | name: "_amount", 118 | type: "uint256", 119 | }, 120 | ], 121 | name: "Withdrawal", 122 | type: "event", 123 | }, 124 | { 125 | inputs: [ 126 | { internalType: "PoolId", name: "_poolId", type: "bytes32" }, 127 | { internalType: "address", name: "_recipient", type: "address" }, 128 | { internalType: "uint256", name: "_amount", type: "uint256" }, 129 | ], 130 | name: "allocateFees", 131 | outputs: [], 132 | stateMutability: "nonpayable", 133 | type: "function", 134 | }, 135 | { 136 | inputs: [{ internalType: "address", name: "_recipient", type: "address" }], 137 | name: "balances", 138 | outputs: [{ internalType: "uint256", name: "_amount", type: "uint256" }], 139 | stateMutability: "view", 140 | type: "function", 141 | }, 142 | { 143 | inputs: [], 144 | name: "cancelOwnershipHandover", 145 | outputs: [], 146 | stateMutability: "payable", 147 | type: "function", 148 | }, 149 | { 150 | inputs: [ 151 | { internalType: "address", name: "pendingOwner", type: "address" }, 152 | ], 153 | name: "completeOwnershipHandover", 154 | outputs: [], 155 | stateMutability: "payable", 156 | type: "function", 157 | }, 158 | { 159 | inputs: [], 160 | name: "indexer", 161 | outputs: [ 162 | { internalType: "contract IndexerSubscriber", name: "", type: "address" }, 163 | ], 164 | stateMutability: "view", 165 | type: "function", 166 | }, 167 | { 168 | inputs: [], 169 | name: "nativeToken", 170 | outputs: [{ internalType: "address", name: "", type: "address" }], 171 | stateMutability: "view", 172 | type: "function", 173 | }, 174 | { 175 | inputs: [], 176 | name: "owner", 177 | outputs: [{ internalType: "address", name: "result", type: "address" }], 178 | stateMutability: "view", 179 | type: "function", 180 | }, 181 | { 182 | inputs: [ 183 | { internalType: "address", name: "pendingOwner", type: "address" }, 184 | ], 185 | name: "ownershipHandoverExpiresAt", 186 | outputs: [{ internalType: "uint256", name: "result", type: "uint256" }], 187 | stateMutability: "view", 188 | type: "function", 189 | }, 190 | { 191 | inputs: [], 192 | name: "renounceOwnership", 193 | outputs: [], 194 | stateMutability: "payable", 195 | type: "function", 196 | }, 197 | { 198 | inputs: [], 199 | name: "requestOwnershipHandover", 200 | outputs: [], 201 | stateMutability: "payable", 202 | type: "function", 203 | }, 204 | { 205 | inputs: [{ internalType: "address", name: "_indexer", type: "address" }], 206 | name: "setIndexer", 207 | outputs: [], 208 | stateMutability: "nonpayable", 209 | type: "function", 210 | }, 211 | { 212 | inputs: [{ internalType: "PoolId", name: "_poolId", type: "bytes32" }], 213 | name: "totalFeesAllocated", 214 | outputs: [{ internalType: "uint256", name: "_amount", type: "uint256" }], 215 | stateMutability: "view", 216 | type: "function", 217 | }, 218 | { 219 | inputs: [{ internalType: "address", name: "newOwner", type: "address" }], 220 | name: "transferOwnership", 221 | outputs: [], 222 | stateMutability: "payable", 223 | type: "function", 224 | }, 225 | { 226 | inputs: [ 227 | { internalType: "address", name: "_recipient", type: "address" }, 228 | { internalType: "bool", name: "_unwrap", type: "bool" }, 229 | ], 230 | name: "withdrawFees", 231 | outputs: [], 232 | stateMutability: "nonpayable", 233 | type: "function", 234 | }, 235 | { stateMutability: "payable", type: "receive" }, 236 | ] as const; 237 | -------------------------------------------------------------------------------- /src/abi/UniversalRouter.ts: -------------------------------------------------------------------------------- 1 | export const UniversalRouterAbi = [ 2 | { 3 | inputs: [ 4 | { 5 | components: [ 6 | { internalType: "address", name: "permit2", type: "address" }, 7 | { internalType: "address", name: "weth9", type: "address" }, 8 | { internalType: "address", name: "v2Factory", type: "address" }, 9 | { internalType: "address", name: "v3Factory", type: "address" }, 10 | { 11 | internalType: "bytes32", 12 | name: "pairInitCodeHash", 13 | type: "bytes32", 14 | }, 15 | { 16 | internalType: "bytes32", 17 | name: "poolInitCodeHash", 18 | type: "bytes32", 19 | }, 20 | { internalType: "address", name: "v4PoolManager", type: "address" }, 21 | { 22 | internalType: "address", 23 | name: "v3NFTPositionManager", 24 | type: "address", 25 | }, 26 | { 27 | internalType: "address", 28 | name: "v4PositionManager", 29 | type: "address", 30 | }, 31 | ], 32 | internalType: "struct RouterParameters", 33 | name: "params", 34 | type: "tuple", 35 | }, 36 | ], 37 | stateMutability: "nonpayable", 38 | type: "constructor", 39 | }, 40 | { inputs: [], name: "BalanceTooLow", type: "error" }, 41 | { inputs: [], name: "ContractLocked", type: "error" }, 42 | { 43 | inputs: [{ internalType: "Currency", name: "currency", type: "address" }], 44 | name: "DeltaNotNegative", 45 | type: "error", 46 | }, 47 | { 48 | inputs: [{ internalType: "Currency", name: "currency", type: "address" }], 49 | name: "DeltaNotPositive", 50 | type: "error", 51 | }, 52 | { inputs: [], name: "ETHNotAccepted", type: "error" }, 53 | { 54 | inputs: [ 55 | { internalType: "uint256", name: "commandIndex", type: "uint256" }, 56 | { internalType: "bytes", name: "message", type: "bytes" }, 57 | ], 58 | name: "ExecutionFailed", 59 | type: "error", 60 | }, 61 | { inputs: [], name: "FromAddressIsNotOwner", type: "error" }, 62 | { inputs: [], name: "InputLengthMismatch", type: "error" }, 63 | { inputs: [], name: "InsufficientBalance", type: "error" }, 64 | { inputs: [], name: "InsufficientETH", type: "error" }, 65 | { inputs: [], name: "InsufficientToken", type: "error" }, 66 | { 67 | inputs: [{ internalType: "bytes4", name: "action", type: "bytes4" }], 68 | name: "InvalidAction", 69 | type: "error", 70 | }, 71 | { inputs: [], name: "InvalidBips", type: "error" }, 72 | { 73 | inputs: [{ internalType: "uint256", name: "commandType", type: "uint256" }], 74 | name: "InvalidCommandType", 75 | type: "error", 76 | }, 77 | { inputs: [], name: "InvalidEthSender", type: "error" }, 78 | { inputs: [], name: "InvalidPath", type: "error" }, 79 | { inputs: [], name: "InvalidReserves", type: "error" }, 80 | { inputs: [], name: "LengthMismatch", type: "error" }, 81 | { 82 | inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], 83 | name: "NotAuthorizedForToken", 84 | type: "error", 85 | }, 86 | { inputs: [], name: "NotPoolManager", type: "error" }, 87 | { inputs: [], name: "OnlyMintAllowed", type: "error" }, 88 | { inputs: [], name: "SliceOutOfBounds", type: "error" }, 89 | { inputs: [], name: "TransactionDeadlinePassed", type: "error" }, 90 | { inputs: [], name: "UnsafeCast", type: "error" }, 91 | { 92 | inputs: [{ internalType: "uint256", name: "action", type: "uint256" }], 93 | name: "UnsupportedAction", 94 | type: "error", 95 | }, 96 | { inputs: [], name: "V2InvalidPath", type: "error" }, 97 | { inputs: [], name: "V2TooLittleReceived", type: "error" }, 98 | { inputs: [], name: "V2TooMuchRequested", type: "error" }, 99 | { inputs: [], name: "V3InvalidAmountOut", type: "error" }, 100 | { inputs: [], name: "V3InvalidCaller", type: "error" }, 101 | { inputs: [], name: "V3InvalidSwap", type: "error" }, 102 | { inputs: [], name: "V3TooLittleReceived", type: "error" }, 103 | { inputs: [], name: "V3TooMuchRequested", type: "error" }, 104 | { 105 | inputs: [ 106 | { 107 | internalType: "uint256", 108 | name: "minAmountOutReceived", 109 | type: "uint256", 110 | }, 111 | { internalType: "uint256", name: "amountReceived", type: "uint256" }, 112 | ], 113 | name: "V4TooLittleReceived", 114 | type: "error", 115 | }, 116 | { 117 | inputs: [ 118 | { 119 | internalType: "uint256", 120 | name: "maxAmountInRequested", 121 | type: "uint256", 122 | }, 123 | { internalType: "uint256", name: "amountRequested", type: "uint256" }, 124 | ], 125 | name: "V4TooMuchRequested", 126 | type: "error", 127 | }, 128 | { 129 | inputs: [], 130 | name: "V3_POSITION_MANAGER", 131 | outputs: [ 132 | { 133 | internalType: "contract INonfungiblePositionManager", 134 | name: "", 135 | type: "address", 136 | }, 137 | ], 138 | stateMutability: "view", 139 | type: "function", 140 | }, 141 | { 142 | inputs: [], 143 | name: "V4_POSITION_MANAGER", 144 | outputs: [ 145 | { internalType: "contract IPositionManager", name: "", type: "address" }, 146 | ], 147 | stateMutability: "view", 148 | type: "function", 149 | }, 150 | { 151 | inputs: [ 152 | { internalType: "bytes", name: "commands", type: "bytes" }, 153 | { internalType: "bytes[]", name: "inputs", type: "bytes[]" }, 154 | ], 155 | name: "execute", 156 | outputs: [], 157 | stateMutability: "payable", 158 | type: "function", 159 | }, 160 | { 161 | inputs: [ 162 | { internalType: "bytes", name: "commands", type: "bytes" }, 163 | { internalType: "bytes[]", name: "inputs", type: "bytes[]" }, 164 | { internalType: "uint256", name: "deadline", type: "uint256" }, 165 | ], 166 | name: "execute", 167 | outputs: [], 168 | stateMutability: "payable", 169 | type: "function", 170 | }, 171 | { 172 | inputs: [], 173 | name: "msgSender", 174 | outputs: [{ internalType: "address", name: "", type: "address" }], 175 | stateMutability: "view", 176 | type: "function", 177 | }, 178 | { 179 | inputs: [], 180 | name: "poolManager", 181 | outputs: [ 182 | { internalType: "contract IPoolManager", name: "", type: "address" }, 183 | ], 184 | stateMutability: "view", 185 | type: "function", 186 | }, 187 | { 188 | inputs: [ 189 | { internalType: "int256", name: "amount0Delta", type: "int256" }, 190 | { internalType: "int256", name: "amount1Delta", type: "int256" }, 191 | { internalType: "bytes", name: "data", type: "bytes" }, 192 | ], 193 | name: "uniswapV3SwapCallback", 194 | outputs: [], 195 | stateMutability: "nonpayable", 196 | type: "function", 197 | }, 198 | { 199 | inputs: [{ internalType: "bytes", name: "data", type: "bytes" }], 200 | name: "unlockCallback", 201 | outputs: [{ internalType: "bytes", name: "", type: "bytes" }], 202 | stateMutability: "nonpayable", 203 | type: "function", 204 | }, 205 | { stateMutability: "payable", type: "receive" }, 206 | ] as const; 207 | -------------------------------------------------------------------------------- /src/sdk/calldata.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createWalletClient, 3 | http, 4 | encodeFunctionData, 5 | decodeFunctionData, 6 | parseAbi, 7 | type PublicClient, 8 | type WalletClient, 9 | type Address, 10 | type Hex, 11 | } from "viem"; 12 | import { createDrift } from "./drift"; 13 | import { ReadFlaunchSDK, ReadWriteFlaunchSDK } from "./FlaunchSDK"; 14 | 15 | // ABI for encoding the call data 16 | export const encodedCallAbi = parseAbi([ 17 | "function call(address to, uint256 value, bytes data)", 18 | ]); 19 | 20 | export interface CallData { 21 | to: Address; 22 | value: bigint; 23 | data: Hex; 24 | } 25 | 26 | export type CreateFlaunchCalldataParams = { 27 | publicClient: PublicClient; 28 | walletAddress?: Address; 29 | }; 30 | 31 | /** 32 | * Creates a custom wallet client that returns encoded calldata instead of broadcasting transactions 33 | */ 34 | export function createCallDataWalletClient( 35 | publicClient: PublicClient, 36 | walletAddress: Address 37 | ): WalletClient { 38 | if (!publicClient.chain) { 39 | throw new Error("publicClient must be configured with a chain"); 40 | } 41 | 42 | // Create a base wallet client with the chain configuration 43 | const baseWalletClient = createWalletClient({ 44 | chain: publicClient.chain, 45 | transport: http(), 46 | }); 47 | 48 | // Override the wallet client methods to return encoded calldata 49 | const callDataWalletClient = baseWalletClient.extend((client) => ({ 50 | // Override the account-related methods to return the provided walletAddress 51 | get account() { 52 | return { 53 | address: walletAddress, 54 | type: "json-rpc" as const, 55 | } as any; 56 | }, 57 | 58 | async getAddresses() { 59 | return [walletAddress]; 60 | }, 61 | 62 | async requestAddresses() { 63 | return [walletAddress]; 64 | }, 65 | 66 | // Override writeContract to return encoded calldata instead of broadcasting 67 | async writeContract(args: any) { 68 | const to = args.address as Address; 69 | const value = (args.value ?? 0n) as bigint; 70 | 71 | // Encode the function call data 72 | const calldata = encodeFunctionData({ 73 | abi: args.abi, 74 | functionName: args.functionName, 75 | args: args.args, 76 | }) as Hex; 77 | 78 | // Encode the call using the standard call format 79 | const encodedCall = encodeFunctionData({ 80 | abi: encodedCallAbi, 81 | functionName: "call", 82 | args: [to, value, calldata], 83 | }) as Hex; 84 | 85 | return encodedCall; 86 | }, 87 | 88 | // Override sendTransaction to return encoded calldata instead of broadcasting 89 | async sendTransaction(args: any) { 90 | const to = args.to as Address; 91 | const value = (args.value ?? 0n) as bigint; 92 | const data = (args.data ?? "0x") as Hex; 93 | 94 | // Encode the call using the standard call format 95 | const encodedCall = encodeFunctionData({ 96 | abi: encodedCallAbi, 97 | functionName: "call", 98 | args: [to, value, data], 99 | }) as Hex; 100 | 101 | return encodedCall; 102 | }, 103 | 104 | // Override signTransaction to return encoded calldata (for consistency) 105 | async signTransaction(args: any) { 106 | const to = args.to as Address; 107 | const value = (args.value ?? 0n) as bigint; 108 | const data = (args.data ?? "0x") as Hex; 109 | 110 | const encodedCall = encodeFunctionData({ 111 | abi: encodedCallAbi, 112 | functionName: "call", 113 | args: [to, value, data], 114 | }) as Hex; 115 | 116 | return encodedCall; 117 | }, 118 | })); 119 | 120 | return callDataWalletClient; 121 | } 122 | 123 | /** 124 | * Creates a read-only Flaunch SDK instance with only public client 125 | * @param params - Parameters with only publicClient 126 | * @returns ReadFlaunchSDK for read-only operations 127 | * @throws Error if publicClient.chain is not configured 128 | */ 129 | export function createFlaunchCalldata( 130 | params: Omit 131 | ): ReadFlaunchSDK; 132 | /** 133 | * Creates a read-write Flaunch SDK instance that returns encoded calldata instead of broadcasting transactions 134 | * @param params - Parameters containing publicClient and walletAddress 135 | * @returns ReadWriteFlaunchSDK instance configured for calldata generation 136 | * @throws Error if publicClient.chain is not configured 137 | */ 138 | export function createFlaunchCalldata( 139 | params: Required 140 | ): ReadWriteFlaunchSDK; 141 | 142 | /** 143 | * Creates a Flaunch SDK instance that returns encoded calldata instead of broadcasting transactions 144 | * @param params - Parameters containing publicClient and optionally walletAddress 145 | * @returns ReadFlaunchSDK if only publicClient is provided, ReadWriteFlaunchSDK if walletAddress is also provided 146 | * @throws Error if publicClient.chain is not configured 147 | */ 148 | export function createFlaunchCalldata(params: CreateFlaunchCalldataParams) { 149 | const { publicClient, walletAddress } = params; 150 | 151 | if (!publicClient.chain) { 152 | throw new Error("publicClient must be configured with a chain"); 153 | } 154 | 155 | const chainId = publicClient.chain.id; 156 | 157 | // Return appropriate SDK type based on whether walletAddress is provided 158 | if (walletAddress) { 159 | // Create custom wallet client that returns calldata 160 | const callDataWalletClient = createCallDataWalletClient( 161 | publicClient, 162 | walletAddress 163 | ); 164 | 165 | // Create Drift with the custom wallet client 166 | const drift = createDrift({ 167 | publicClient, 168 | walletClient: callDataWalletClient, 169 | }); 170 | 171 | return new ReadWriteFlaunchSDK(chainId, drift); 172 | } else { 173 | // Create read-only SDK with only public client 174 | const drift = createDrift({ publicClient }); 175 | return new ReadFlaunchSDK(chainId, drift); 176 | } 177 | } 178 | 179 | /** 180 | * Decodes the result from SDK methods into transaction object 181 | * @param encodedCall - The result returned by SDK methods 182 | * @returns Call data containing to, value, and data 183 | */ 184 | export function decodeCallData(encodedCall: Hex): CallData { 185 | const decodedCall = decodeFunctionData({ 186 | abi: encodedCallAbi, 187 | data: encodedCall, 188 | }); 189 | 190 | return { 191 | to: decodedCall.args[0] as Address, 192 | value: decodedCall.args[1] as bigint, 193 | data: decodedCall.args[2] as Hex, 194 | }; 195 | } 196 | 197 | /** 198 | * Convenience function to call an SDK method and automatically parse the result as transaction object 199 | * @param sdkMethod - A function that returns a Promise (encoded calldata) 200 | * @returns Promise with decoded transaction parameters 201 | */ 202 | export async function parseCall Promise>( 203 | sdkMethod: T 204 | ): Promise { 205 | const encodedCall = await sdkMethod(); 206 | return decodeCallData(encodedCall); 207 | } 208 | 209 | /** 210 | * Type helper for SDK methods that return encoded calldata 211 | */ 212 | export type CallDataMethod = ( 213 | ...args: T 214 | ) => Promise; 215 | 216 | /** 217 | * Type helper for the result of a calldata operation 218 | */ 219 | export type CallDataResult = Promise; 220 | -------------------------------------------------------------------------------- /src/hooks/FlaunchPositionManagerHooks.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { 3 | BuySwapLog, 4 | PoolCreatedLogs, 5 | SellSwapLog, 6 | } from "../clients/FlaunchPositionManagerClient"; 7 | import { ReadFlaunchSDK } from "../sdk/FlaunchSDK"; 8 | import { Address } from "viem"; 9 | 10 | /** 11 | * Hook to watch and track pool creation events from the Flaunch V1.1 contract 12 | * @param flaunch - Instance of ReadFlaunchSDK to interact with the contract 13 | * @param startBlockNumber - Optional block number to start watching events from 14 | * @returns Object containing: 15 | * - logs: Array of pool creation events in reverse chronological order 16 | * - isFetchingFromStart: Boolean indicating if initial historical events are being fetched 17 | */ 18 | export function usePoolCreatedEvents( 19 | flaunch: ReadFlaunchSDK, 20 | startBlockNumber?: bigint 21 | ) { 22 | const [logs, setLogs] = useState([]); 23 | const [isFetchingFromStart, setIsFetchingFromStart] = useState(false); 24 | 25 | useEffect(() => { 26 | const setupWatcher = async () => { 27 | const cleanup = await flaunch.watchPoolCreated({ 28 | onPoolCreated: ({ logs: newLogs, isFetchingFromStart }) => { 29 | setIsFetchingFromStart(isFetchingFromStart); 30 | setLogs((prevLogs) => [...newLogs, ...prevLogs]); 31 | }, 32 | startBlockNumber, 33 | }); 34 | return cleanup; 35 | }; 36 | 37 | const cleanupPromise = setupWatcher(); 38 | 39 | return () => { 40 | cleanupPromise.then(({ cleanup }) => cleanup()); 41 | }; 42 | }, [flaunch.chainId, startBlockNumber]); 43 | 44 | // Add effect to update times 45 | useEffect(() => { 46 | const timer = setInterval(() => { 47 | // Force re-render to update relative times 48 | setLogs((prev) => [...prev]); 49 | }, 1000); 50 | 51 | return () => clearInterval(timer); 52 | }, []); 53 | 54 | return { logs, isFetchingFromStart }; 55 | } 56 | 57 | /** 58 | * Hook to watch and track swap events (buys/sells) for a specific coin from the Flaunch V1.1 contract 59 | * @param flaunch - Instance of ReadFlaunchSDK to interact with the contract 60 | * @param coinAddress - Address of the coin to watch swaps for 61 | * @param startBlockNumber - Optional block number to start watching events from 62 | * @returns Object containing: 63 | * - logs: Array of swap events (both buys and sells) in reverse chronological order 64 | * - isFetchingFromStart: Boolean indicating if initial historical events are being fetched 65 | */ 66 | export function usePoolSwapEvents( 67 | flaunch: ReadFlaunchSDK, 68 | coinAddress: Address, 69 | startBlockNumber?: bigint 70 | ) { 71 | const [logs, setLogs] = useState<(BuySwapLog | SellSwapLog)[]>([]); 72 | const [isFetchingFromStart, setIsFetchingFromStart] = useState(false); 73 | 74 | useEffect(() => { 75 | const setupWatcher = async () => { 76 | const cleanup = await flaunch.watchPoolSwap({ 77 | onPoolSwap: ({ logs: newLogs, isFetchingFromStart }) => { 78 | setIsFetchingFromStart(isFetchingFromStart); 79 | setLogs((prevLogs) => [...newLogs, ...prevLogs]); 80 | }, 81 | filterByCoin: coinAddress, 82 | startBlockNumber, 83 | }); 84 | return cleanup; 85 | }; 86 | 87 | const cleanupPromise = setupWatcher(); 88 | 89 | return () => { 90 | cleanupPromise.then(({ cleanup }) => cleanup()); 91 | }; 92 | }, [flaunch.chainId, coinAddress, startBlockNumber]); 93 | 94 | // Add effect to update times 95 | useEffect(() => { 96 | const timer = setInterval(() => { 97 | // Force re-render to update relative times 98 | setLogs((prev) => [...prev]); 99 | }, 1000); 100 | 101 | return () => clearInterval(timer); 102 | }, []); 103 | 104 | return { logs, isFetchingFromStart }; 105 | } 106 | 107 | /** 108 | * Hook to watch and track pool creation events from the Flaunch V1 contract 109 | * @param flaunch - Instance of ReadFlaunchSDK to interact with the contract 110 | * @param startBlockNumber - Optional block number to start watching events from 111 | * @returns Object containing: 112 | * - logs: Array of pool creation events in reverse chronological order 113 | * - isFetchingFromStart: Boolean indicating if initial historical events are being fetched 114 | */ 115 | export function usePoolCreatedEventsV1( 116 | flaunch: ReadFlaunchSDK, 117 | startBlockNumber?: bigint 118 | ) { 119 | const [logs, setLogs] = useState([]); 120 | const [isFetchingFromStart, setIsFetchingFromStart] = useState(false); 121 | 122 | useEffect(() => { 123 | const setupWatcher = async () => { 124 | const cleanup = await flaunch.watchPoolCreated({ 125 | onPoolCreated: ({ logs: newLogs, isFetchingFromStart }) => { 126 | setIsFetchingFromStart(isFetchingFromStart); 127 | setLogs((prevLogs) => [...newLogs, ...prevLogs]); 128 | }, 129 | startBlockNumber, 130 | }); 131 | return cleanup; 132 | }; 133 | 134 | const cleanupPromise = setupWatcher(); 135 | 136 | return () => { 137 | cleanupPromise.then(({ cleanup }) => cleanup()); 138 | }; 139 | }, [flaunch.chainId, startBlockNumber]); 140 | 141 | // Add effect to update times 142 | useEffect(() => { 143 | const timer = setInterval(() => { 144 | // Force re-render to update relative times 145 | setLogs((prev) => [...prev]); 146 | }, 1000); 147 | 148 | return () => clearInterval(timer); 149 | }, []); 150 | 151 | return { logs, isFetchingFromStart }; 152 | } 153 | 154 | /** 155 | * Hook to watch and track swap events (buys/sells) for a specific coin from the Flaunch V1 contract 156 | * @param flaunch - Instance of ReadFlaunchSDK to interact with the contract 157 | * @param coinAddress - Address of the coin to watch swaps for 158 | * @param startBlockNumber - Optional block number to start watching events from 159 | * @returns Object containing: 160 | * - logs: Array of swap events (both buys and sells) in reverse chronological order 161 | * - isFetchingFromStart: Boolean indicating if initial historical events are being fetched 162 | */ 163 | export function usePoolSwapEventsV1( 164 | flaunch: ReadFlaunchSDK, 165 | coinAddress: Address, 166 | startBlockNumber?: bigint 167 | ) { 168 | const [logs, setLogs] = useState<(BuySwapLog | SellSwapLog)[]>([]); 169 | const [isFetchingFromStart, setIsFetchingFromStart] = useState(false); 170 | 171 | useEffect(() => { 172 | const setupWatcher = async () => { 173 | const cleanup = await flaunch.watchPoolSwap({ 174 | onPoolSwap: ({ logs: newLogs, isFetchingFromStart }) => { 175 | setIsFetchingFromStart(isFetchingFromStart); 176 | setLogs((prevLogs) => [...newLogs, ...prevLogs]); 177 | }, 178 | filterByCoin: coinAddress, 179 | startBlockNumber, 180 | }); 181 | return cleanup; 182 | }; 183 | 184 | const cleanupPromise = setupWatcher(); 185 | 186 | return () => { 187 | cleanupPromise.then(({ cleanup }) => cleanup()); 188 | }; 189 | }, [flaunch.chainId, coinAddress, startBlockNumber]); 190 | 191 | // Add effect to update times 192 | useEffect(() => { 193 | const timer = setInterval(() => { 194 | // Force re-render to update relative times 195 | setLogs((prev) => [...prev]); 196 | }, 1000); 197 | 198 | return () => clearInterval(timer); 199 | }, []); 200 | 201 | return { logs, isFetchingFromStart }; 202 | } 203 | -------------------------------------------------------------------------------- /src/abi/ReferralEscrow.ts: -------------------------------------------------------------------------------- 1 | export const ReferralEscrowAbi = [ 2 | { 3 | inputs: [ 4 | { internalType: "address", name: "_nativeToken", type: "address" }, 5 | { internalType: "address", name: "_positionManager", type: "address" }, 6 | ], 7 | stateMutability: "nonpayable", 8 | type: "constructor", 9 | }, 10 | { inputs: [], name: "AlreadyInitialized", type: "error" }, 11 | { inputs: [], name: "MismatchedTokensAndLimits", type: "error" }, 12 | { inputs: [], name: "NewOwnerIsZeroAddress", type: "error" }, 13 | { inputs: [], name: "NoHandoverRequest", type: "error" }, 14 | { inputs: [], name: "Unauthorized", type: "error" }, 15 | { 16 | anonymous: false, 17 | inputs: [ 18 | { 19 | indexed: true, 20 | internalType: "address", 21 | name: "pendingOwner", 22 | type: "address", 23 | }, 24 | ], 25 | name: "OwnershipHandoverCanceled", 26 | type: "event", 27 | }, 28 | { 29 | anonymous: false, 30 | inputs: [ 31 | { 32 | indexed: true, 33 | internalType: "address", 34 | name: "pendingOwner", 35 | type: "address", 36 | }, 37 | ], 38 | name: "OwnershipHandoverRequested", 39 | type: "event", 40 | }, 41 | { 42 | anonymous: false, 43 | inputs: [ 44 | { 45 | indexed: true, 46 | internalType: "address", 47 | name: "oldOwner", 48 | type: "address", 49 | }, 50 | { 51 | indexed: true, 52 | internalType: "address", 53 | name: "newOwner", 54 | type: "address", 55 | }, 56 | ], 57 | name: "OwnershipTransferred", 58 | type: "event", 59 | }, 60 | { 61 | anonymous: false, 62 | inputs: [ 63 | { 64 | indexed: true, 65 | internalType: "PoolId", 66 | name: "_poolId", 67 | type: "bytes32", 68 | }, 69 | { 70 | indexed: true, 71 | internalType: "address", 72 | name: "_user", 73 | type: "address", 74 | }, 75 | { 76 | indexed: true, 77 | internalType: "address", 78 | name: "_token", 79 | type: "address", 80 | }, 81 | { 82 | indexed: false, 83 | internalType: "uint256", 84 | name: "_amount", 85 | type: "uint256", 86 | }, 87 | ], 88 | name: "TokensAssigned", 89 | type: "event", 90 | }, 91 | { 92 | anonymous: false, 93 | inputs: [ 94 | { 95 | indexed: true, 96 | internalType: "address", 97 | name: "_user", 98 | type: "address", 99 | }, 100 | { 101 | indexed: false, 102 | internalType: "address", 103 | name: "_recipient", 104 | type: "address", 105 | }, 106 | { 107 | indexed: true, 108 | internalType: "address", 109 | name: "_token", 110 | type: "address", 111 | }, 112 | { 113 | indexed: false, 114 | internalType: "uint256", 115 | name: "_amount", 116 | type: "uint256", 117 | }, 118 | ], 119 | name: "TokensClaimed", 120 | type: "event", 121 | }, 122 | { 123 | anonymous: false, 124 | inputs: [ 125 | { 126 | indexed: true, 127 | internalType: "address", 128 | name: "_user", 129 | type: "address", 130 | }, 131 | { 132 | indexed: true, 133 | internalType: "address", 134 | name: "_token", 135 | type: "address", 136 | }, 137 | { 138 | indexed: false, 139 | internalType: "uint256", 140 | name: "_tokenIn", 141 | type: "uint256", 142 | }, 143 | { 144 | indexed: false, 145 | internalType: "uint256", 146 | name: "_ethOut", 147 | type: "uint256", 148 | }, 149 | ], 150 | name: "TokensSwapped", 151 | type: "event", 152 | }, 153 | { 154 | inputs: [ 155 | { internalType: "address", name: "_user", type: "address" }, 156 | { internalType: "address", name: "_token", type: "address" }, 157 | ], 158 | name: "allocations", 159 | outputs: [{ internalType: "uint256", name: "_amount", type: "uint256" }], 160 | stateMutability: "view", 161 | type: "function", 162 | }, 163 | { 164 | inputs: [ 165 | { internalType: "PoolId", name: "_poolId", type: "bytes32" }, 166 | { internalType: "address", name: "_user", type: "address" }, 167 | { internalType: "address", name: "_token", type: "address" }, 168 | { internalType: "uint256", name: "_amount", type: "uint256" }, 169 | ], 170 | name: "assignTokens", 171 | outputs: [], 172 | stateMutability: "nonpayable", 173 | type: "function", 174 | }, 175 | { 176 | inputs: [], 177 | name: "cancelOwnershipHandover", 178 | outputs: [], 179 | stateMutability: "payable", 180 | type: "function", 181 | }, 182 | { 183 | inputs: [ 184 | { internalType: "address[]", name: "_tokens", type: "address[]" }, 185 | { 186 | internalType: "uint160[]", 187 | name: "_sqrtPriceX96Limits", 188 | type: "uint160[]", 189 | }, 190 | { internalType: "address payable", name: "_recipient", type: "address" }, 191 | ], 192 | name: "claimAndSwap", 193 | outputs: [], 194 | stateMutability: "nonpayable", 195 | type: "function", 196 | }, 197 | { 198 | inputs: [ 199 | { internalType: "address[]", name: "_tokens", type: "address[]" }, 200 | { internalType: "address payable", name: "_recipient", type: "address" }, 201 | ], 202 | name: "claimTokens", 203 | outputs: [], 204 | stateMutability: "nonpayable", 205 | type: "function", 206 | }, 207 | { 208 | inputs: [ 209 | { internalType: "address", name: "pendingOwner", type: "address" }, 210 | ], 211 | name: "completeOwnershipHandover", 212 | outputs: [], 213 | stateMutability: "payable", 214 | type: "function", 215 | }, 216 | { 217 | inputs: [], 218 | name: "nativeToken", 219 | outputs: [{ internalType: "address", name: "", type: "address" }], 220 | stateMutability: "view", 221 | type: "function", 222 | }, 223 | { 224 | inputs: [], 225 | name: "owner", 226 | outputs: [{ internalType: "address", name: "result", type: "address" }], 227 | stateMutability: "view", 228 | type: "function", 229 | }, 230 | { 231 | inputs: [ 232 | { internalType: "address", name: "pendingOwner", type: "address" }, 233 | ], 234 | name: "ownershipHandoverExpiresAt", 235 | outputs: [{ internalType: "uint256", name: "result", type: "uint256" }], 236 | stateMutability: "view", 237 | type: "function", 238 | }, 239 | { 240 | inputs: [], 241 | name: "poolSwap", 242 | outputs: [{ internalType: "contract PoolSwap", name: "", type: "address" }], 243 | stateMutability: "view", 244 | type: "function", 245 | }, 246 | { 247 | inputs: [], 248 | name: "positionManager", 249 | outputs: [{ internalType: "address", name: "", type: "address" }], 250 | stateMutability: "view", 251 | type: "function", 252 | }, 253 | { 254 | inputs: [], 255 | name: "renounceOwnership", 256 | outputs: [], 257 | stateMutability: "payable", 258 | type: "function", 259 | }, 260 | { 261 | inputs: [], 262 | name: "requestOwnershipHandover", 263 | outputs: [], 264 | stateMutability: "payable", 265 | type: "function", 266 | }, 267 | { 268 | inputs: [{ internalType: "address", name: "_poolSwap", type: "address" }], 269 | name: "setPoolSwap", 270 | outputs: [], 271 | stateMutability: "nonpayable", 272 | type: "function", 273 | }, 274 | { 275 | inputs: [{ internalType: "address", name: "newOwner", type: "address" }], 276 | name: "transferOwnership", 277 | outputs: [], 278 | stateMutability: "payable", 279 | type: "function", 280 | }, 281 | { stateMutability: "payable", type: "receive" }, 282 | ] as const; 283 | -------------------------------------------------------------------------------- /src/abi/InitialPrice.ts: -------------------------------------------------------------------------------- 1 | export const InitialPriceAbi = [ 2 | { 3 | inputs: [ 4 | { internalType: "address", name: "_protocolOwner", type: "address" }, 5 | { internalType: "address", name: "_poolManager", type: "address" }, 6 | { internalType: "address", name: "_ethToken", type: "address" }, 7 | { internalType: "address", name: "_usdcToken", type: "address" }, 8 | { 9 | internalType: "address", 10 | name: "_flaunchFeeExemption", 11 | type: "address", 12 | }, 13 | ], 14 | stateMutability: "nonpayable", 15 | type: "constructor", 16 | }, 17 | { inputs: [], name: "AlreadyInitialized", type: "error" }, 18 | { 19 | inputs: [ 20 | { internalType: "uint256", name: "_usdcMarketCap", type: "uint256" }, 21 | { 22 | internalType: "uint256", 23 | name: "_usdcMarketCapMinimum", 24 | type: "uint256", 25 | }, 26 | ], 27 | name: "MarketCapTooSmall", 28 | type: "error", 29 | }, 30 | { inputs: [], name: "NewOwnerIsZeroAddress", type: "error" }, 31 | { inputs: [], name: "NoHandoverRequest", type: "error" }, 32 | { inputs: [], name: "Unauthorized", type: "error" }, 33 | { 34 | anonymous: false, 35 | inputs: [ 36 | { 37 | indexed: false, 38 | internalType: "uint256", 39 | name: "_flaunchFeeThreshold", 40 | type: "uint256", 41 | }, 42 | ], 43 | name: "FlaunchFeeThresholdUpdated", 44 | type: "event", 45 | }, 46 | { 47 | anonymous: false, 48 | inputs: [ 49 | { 50 | indexed: true, 51 | internalType: "address", 52 | name: "pendingOwner", 53 | type: "address", 54 | }, 55 | ], 56 | name: "OwnershipHandoverCanceled", 57 | type: "event", 58 | }, 59 | { 60 | anonymous: false, 61 | inputs: [ 62 | { 63 | indexed: true, 64 | internalType: "address", 65 | name: "pendingOwner", 66 | type: "address", 67 | }, 68 | ], 69 | name: "OwnershipHandoverRequested", 70 | type: "event", 71 | }, 72 | { 73 | anonymous: false, 74 | inputs: [ 75 | { 76 | indexed: true, 77 | internalType: "address", 78 | name: "oldOwner", 79 | type: "address", 80 | }, 81 | { 82 | indexed: true, 83 | internalType: "address", 84 | name: "newOwner", 85 | type: "address", 86 | }, 87 | ], 88 | name: "OwnershipTransferred", 89 | type: "event", 90 | }, 91 | { 92 | inputs: [], 93 | name: "MINIMUM_USDC_MARKET_CAP", 94 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 95 | stateMutability: "view", 96 | type: "function", 97 | }, 98 | { 99 | inputs: [], 100 | name: "cancelOwnershipHandover", 101 | outputs: [], 102 | stateMutability: "payable", 103 | type: "function", 104 | }, 105 | { 106 | inputs: [ 107 | { internalType: "address", name: "pendingOwner", type: "address" }, 108 | ], 109 | name: "completeOwnershipHandover", 110 | outputs: [], 111 | stateMutability: "payable", 112 | type: "function", 113 | }, 114 | { 115 | inputs: [], 116 | name: "ethToken", 117 | outputs: [{ internalType: "Currency", name: "", type: "address" }], 118 | stateMutability: "view", 119 | type: "function", 120 | }, 121 | { 122 | inputs: [], 123 | name: "flaunchFeeExemption", 124 | outputs: [ 125 | { 126 | internalType: "contract FlaunchFeeExemption", 127 | name: "", 128 | type: "address", 129 | }, 130 | ], 131 | stateMutability: "view", 132 | type: "function", 133 | }, 134 | { 135 | inputs: [], 136 | name: "flaunchFeeThreshold", 137 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 138 | stateMutability: "view", 139 | type: "function", 140 | }, 141 | { 142 | inputs: [ 143 | { internalType: "address", name: "_sender", type: "address" }, 144 | { internalType: "bytes", name: "_initialPriceParams", type: "bytes" }, 145 | ], 146 | name: "getFlaunchingFee", 147 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 148 | stateMutability: "view", 149 | type: "function", 150 | }, 151 | { 152 | inputs: [ 153 | { internalType: "bytes", name: "_initialPriceParams", type: "bytes" }, 154 | ], 155 | name: "getMarketCap", 156 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 157 | stateMutability: "view", 158 | type: "function", 159 | }, 160 | { 161 | inputs: [ 162 | { internalType: "address", name: "", type: "address" }, 163 | { internalType: "bool", name: "_flipped", type: "bool" }, 164 | { internalType: "bytes", name: "_initialPriceParams", type: "bytes" }, 165 | ], 166 | name: "getSqrtPriceX96", 167 | outputs: [ 168 | { internalType: "uint160", name: "sqrtPriceX96_", type: "uint160" }, 169 | ], 170 | stateMutability: "view", 171 | type: "function", 172 | }, 173 | { 174 | inputs: [], 175 | name: "owner", 176 | outputs: [{ internalType: "address", name: "result", type: "address" }], 177 | stateMutability: "view", 178 | type: "function", 179 | }, 180 | { 181 | inputs: [ 182 | { internalType: "address", name: "pendingOwner", type: "address" }, 183 | ], 184 | name: "ownershipHandoverExpiresAt", 185 | outputs: [{ internalType: "uint256", name: "result", type: "uint256" }], 186 | stateMutability: "view", 187 | type: "function", 188 | }, 189 | { 190 | inputs: [], 191 | name: "poolId", 192 | outputs: [{ internalType: "PoolId", name: "", type: "bytes32" }], 193 | stateMutability: "view", 194 | type: "function", 195 | }, 196 | { 197 | inputs: [], 198 | name: "poolManager", 199 | outputs: [ 200 | { internalType: "contract IPoolManager", name: "", type: "address" }, 201 | ], 202 | stateMutability: "view", 203 | type: "function", 204 | }, 205 | { 206 | inputs: [], 207 | name: "renounceOwnership", 208 | outputs: [], 209 | stateMutability: "payable", 210 | type: "function", 211 | }, 212 | { 213 | inputs: [], 214 | name: "requestOwnershipHandover", 215 | outputs: [], 216 | stateMutability: "payable", 217 | type: "function", 218 | }, 219 | { 220 | inputs: [ 221 | { 222 | internalType: "uint256", 223 | name: "_flaunchFeeThreshold", 224 | type: "uint256", 225 | }, 226 | ], 227 | name: "setFlaunchFeeThreshold", 228 | outputs: [], 229 | stateMutability: "nonpayable", 230 | type: "function", 231 | }, 232 | { 233 | inputs: [ 234 | { 235 | components: [ 236 | { internalType: "Currency", name: "currency0", type: "address" }, 237 | { internalType: "Currency", name: "currency1", type: "address" }, 238 | { internalType: "uint24", name: "fee", type: "uint24" }, 239 | { internalType: "int24", name: "tickSpacing", type: "int24" }, 240 | { internalType: "contract IHooks", name: "hooks", type: "address" }, 241 | ], 242 | internalType: "struct PoolKey", 243 | name: "_poolKey", 244 | type: "tuple", 245 | }, 246 | ], 247 | name: "setPool", 248 | outputs: [], 249 | stateMutability: "nonpayable", 250 | type: "function", 251 | }, 252 | { 253 | inputs: [{ internalType: "address", name: "newOwner", type: "address" }], 254 | name: "transferOwnership", 255 | outputs: [], 256 | stateMutability: "payable", 257 | type: "function", 258 | }, 259 | { 260 | inputs: [], 261 | name: "usdcToken", 262 | outputs: [{ internalType: "Currency", name: "", type: "address" }], 263 | stateMutability: "view", 264 | type: "function", 265 | }, 266 | { 267 | inputs: [], 268 | name: "usdcToken0", 269 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 270 | stateMutability: "view", 271 | type: "function", 272 | }, 273 | ] as const; 274 | -------------------------------------------------------------------------------- /src/abi/FairLaunch.ts: -------------------------------------------------------------------------------- 1 | export const FairLaunchAbi = [ 2 | { 3 | inputs: [ 4 | { 5 | internalType: "contract IPoolManager", 6 | name: "_poolManager", 7 | type: "address", 8 | }, 9 | ], 10 | stateMutability: "nonpayable", 11 | type: "constructor", 12 | }, 13 | { inputs: [], name: "CannotModifyLiquidityDuringFairLaunch", type: "error" }, 14 | { inputs: [], name: "CannotSellTokenDuringFairLaunch", type: "error" }, 15 | { inputs: [], name: "NotPositionManager", type: "error" }, 16 | { 17 | anonymous: false, 18 | inputs: [ 19 | { 20 | indexed: true, 21 | internalType: "PoolId", 22 | name: "_poolId", 23 | type: "bytes32", 24 | }, 25 | { 26 | indexed: false, 27 | internalType: "uint256", 28 | name: "_tokens", 29 | type: "uint256", 30 | }, 31 | { 32 | indexed: false, 33 | internalType: "uint256", 34 | name: "_startsAt", 35 | type: "uint256", 36 | }, 37 | { 38 | indexed: false, 39 | internalType: "uint256", 40 | name: "_endsAt", 41 | type: "uint256", 42 | }, 43 | ], 44 | name: "FairLaunchCreated", 45 | type: "event", 46 | }, 47 | { 48 | anonymous: false, 49 | inputs: [ 50 | { 51 | indexed: true, 52 | internalType: "PoolId", 53 | name: "_poolId", 54 | type: "bytes32", 55 | }, 56 | { 57 | indexed: false, 58 | internalType: "uint256", 59 | name: "_revenue", 60 | type: "uint256", 61 | }, 62 | { 63 | indexed: false, 64 | internalType: "uint256", 65 | name: "_supply", 66 | type: "uint256", 67 | }, 68 | { 69 | indexed: false, 70 | internalType: "uint256", 71 | name: "_endedAt", 72 | type: "uint256", 73 | }, 74 | ], 75 | name: "FairLaunchEnded", 76 | type: "event", 77 | }, 78 | { 79 | inputs: [], 80 | name: "FAIR_LAUNCH_WINDOW", 81 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 82 | stateMutability: "view", 83 | type: "function", 84 | }, 85 | { 86 | inputs: [ 87 | { 88 | components: [ 89 | { internalType: "Currency", name: "currency0", type: "address" }, 90 | { internalType: "Currency", name: "currency1", type: "address" }, 91 | { internalType: "uint24", name: "fee", type: "uint24" }, 92 | { internalType: "int24", name: "tickSpacing", type: "int24" }, 93 | { internalType: "contract IHooks", name: "hooks", type: "address" }, 94 | ], 95 | internalType: "struct PoolKey", 96 | name: "_poolKey", 97 | type: "tuple", 98 | }, 99 | { internalType: "uint256", name: "_tokenFees", type: "uint256" }, 100 | { internalType: "bool", name: "_nativeIsZero", type: "bool" }, 101 | ], 102 | name: "closePosition", 103 | outputs: [ 104 | { 105 | components: [ 106 | { internalType: "uint256", name: "startsAt", type: "uint256" }, 107 | { internalType: "uint256", name: "endsAt", type: "uint256" }, 108 | { internalType: "int24", name: "initialTick", type: "int24" }, 109 | { internalType: "uint256", name: "revenue", type: "uint256" }, 110 | { internalType: "uint256", name: "supply", type: "uint256" }, 111 | { internalType: "bool", name: "closed", type: "bool" }, 112 | ], 113 | internalType: "struct FairLaunch.FairLaunchInfo", 114 | name: "", 115 | type: "tuple", 116 | }, 117 | ], 118 | stateMutability: "nonpayable", 119 | type: "function", 120 | }, 121 | { 122 | inputs: [ 123 | { internalType: "PoolId", name: "_poolId", type: "bytes32" }, 124 | { internalType: "int24", name: "_initialTick", type: "int24" }, 125 | { internalType: "uint256", name: "_flaunchesAt", type: "uint256" }, 126 | { 127 | internalType: "uint256", 128 | name: "_initialTokenFairLaunch", 129 | type: "uint256", 130 | }, 131 | ], 132 | name: "createPosition", 133 | outputs: [ 134 | { 135 | components: [ 136 | { internalType: "uint256", name: "startsAt", type: "uint256" }, 137 | { internalType: "uint256", name: "endsAt", type: "uint256" }, 138 | { internalType: "int24", name: "initialTick", type: "int24" }, 139 | { internalType: "uint256", name: "revenue", type: "uint256" }, 140 | { internalType: "uint256", name: "supply", type: "uint256" }, 141 | { internalType: "bool", name: "closed", type: "bool" }, 142 | ], 143 | internalType: "struct FairLaunch.FairLaunchInfo", 144 | name: "", 145 | type: "tuple", 146 | }, 147 | ], 148 | stateMutability: "nonpayable", 149 | type: "function", 150 | }, 151 | { 152 | inputs: [{ internalType: "PoolId", name: "_poolId", type: "bytes32" }], 153 | name: "fairLaunchInfo", 154 | outputs: [ 155 | { 156 | components: [ 157 | { internalType: "uint256", name: "startsAt", type: "uint256" }, 158 | { internalType: "uint256", name: "endsAt", type: "uint256" }, 159 | { internalType: "int24", name: "initialTick", type: "int24" }, 160 | { internalType: "uint256", name: "revenue", type: "uint256" }, 161 | { internalType: "uint256", name: "supply", type: "uint256" }, 162 | { internalType: "bool", name: "closed", type: "bool" }, 163 | ], 164 | internalType: "struct FairLaunch.FairLaunchInfo", 165 | name: "", 166 | type: "tuple", 167 | }, 168 | ], 169 | stateMutability: "view", 170 | type: "function", 171 | }, 172 | { 173 | inputs: [ 174 | { 175 | components: [ 176 | { internalType: "Currency", name: "currency0", type: "address" }, 177 | { internalType: "Currency", name: "currency1", type: "address" }, 178 | { internalType: "uint24", name: "fee", type: "uint24" }, 179 | { internalType: "int24", name: "tickSpacing", type: "int24" }, 180 | { internalType: "contract IHooks", name: "hooks", type: "address" }, 181 | ], 182 | internalType: "struct PoolKey", 183 | name: "_poolKey", 184 | type: "tuple", 185 | }, 186 | { internalType: "int256", name: "_amountSpecified", type: "int256" }, 187 | { internalType: "bool", name: "_nativeIsZero", type: "bool" }, 188 | ], 189 | name: "fillFromPosition", 190 | outputs: [ 191 | { 192 | internalType: "BeforeSwapDelta", 193 | name: "beforeSwapDelta_", 194 | type: "int256", 195 | }, 196 | { internalType: "BalanceDelta", name: "balanceDelta_", type: "int256" }, 197 | { 198 | components: [ 199 | { internalType: "uint256", name: "startsAt", type: "uint256" }, 200 | { internalType: "uint256", name: "endsAt", type: "uint256" }, 201 | { internalType: "int24", name: "initialTick", type: "int24" }, 202 | { internalType: "uint256", name: "revenue", type: "uint256" }, 203 | { internalType: "uint256", name: "supply", type: "uint256" }, 204 | { internalType: "bool", name: "closed", type: "bool" }, 205 | ], 206 | internalType: "struct FairLaunch.FairLaunchInfo", 207 | name: "fairLaunchInfo_", 208 | type: "tuple", 209 | }, 210 | ], 211 | stateMutability: "nonpayable", 212 | type: "function", 213 | }, 214 | { 215 | inputs: [{ internalType: "PoolId", name: "_poolId", type: "bytes32" }], 216 | name: "inFairLaunchWindow", 217 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 218 | stateMutability: "view", 219 | type: "function", 220 | }, 221 | { 222 | inputs: [ 223 | { internalType: "PoolId", name: "_poolId", type: "bytes32" }, 224 | { internalType: "int256", name: "_revenue", type: "int256" }, 225 | ], 226 | name: "modifyRevenue", 227 | outputs: [], 228 | stateMutability: "nonpayable", 229 | type: "function", 230 | }, 231 | { 232 | inputs: [], 233 | name: "poolManager", 234 | outputs: [ 235 | { internalType: "contract IPoolManager", name: "", type: "address" }, 236 | ], 237 | stateMutability: "view", 238 | type: "function", 239 | }, 240 | { 241 | inputs: [], 242 | name: "positionManager", 243 | outputs: [{ internalType: "address", name: "", type: "address" }], 244 | stateMutability: "view", 245 | type: "function", 246 | }, 247 | ] as const; 248 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { Address, Call, Hex } from "viem"; 2 | import { PinataConfig } from "helpers/ipfs"; 3 | 4 | // Utility type to flatten complex intersections for better IntelliSense 5 | type Flatten = { 6 | [K in keyof T]: T[K]; 7 | } & {}; 8 | 9 | export interface Addresses { 10 | [chainId: number]: Address; 11 | } 12 | 13 | export interface PoolKey { 14 | currency0: Address; 15 | currency1: Address; 16 | fee: number; 17 | tickSpacing: number; 18 | hooks: Address; 19 | } 20 | 21 | export interface PoolWithHookData extends PoolKey { 22 | hookData: Hex; 23 | } 24 | 25 | export interface CoinMetadata { 26 | name: string; 27 | description: string; 28 | image: string; 29 | external_link: string; 30 | collaborators: string[]; 31 | discordUrl: string; 32 | twitterUrl: string; 33 | telegramUrl: string; 34 | } 35 | 36 | export interface IPFSParams { 37 | metadata: { 38 | base64Image: string; 39 | description: string; 40 | websiteUrl?: string; 41 | discordUrl?: string; 42 | twitterUrl?: string; 43 | telegramUrl?: string; 44 | }; 45 | pinataConfig?: PinataConfig; 46 | } 47 | 48 | /** 49 | * Enumeration of Flaunch contract versions 50 | */ 51 | export enum FlaunchVersion { 52 | V1 = "V1", 53 | V1_1 = "V1_1", 54 | V1_2 = "V1_2", 55 | ANY = "ANY", 56 | } 57 | 58 | /** 59 | * Enumeration of Verifiers for TokenImporter 60 | */ 61 | export enum Verifier { 62 | CLANKER = "clanker", 63 | DOPPLER = "doppler", 64 | SOLANA = "solana", 65 | VIRTUALS = "virtuals", 66 | WHITELIST = "whitelist", 67 | ZORA = "zora", 68 | } 69 | 70 | export enum LiquidityMode { 71 | FULL_RANGE = "full-range", 72 | CONCENTRATED = "concentrated", 73 | } 74 | 75 | export type CallWithDescription = Call & { 76 | description?: string; 77 | }; 78 | /** 79 | * Enumeration of Permissions for TreasuryManagers. Defaults to OPEN. 80 | */ 81 | export enum Permissions { 82 | OPEN = "open", 83 | CLOSED = "closed", 84 | WHITELISTED = "whitelisted", 85 | } 86 | 87 | // either initialMarketCapUSD or initialPriceUSD must be provided 88 | export type ImportMemecoinParams = 89 | | { 90 | coinAddress: Address; 91 | verifier?: Verifier; 92 | creatorFeeAllocationPercent: number; 93 | initialMarketCapUSD: number; 94 | } 95 | | { 96 | coinAddress: Address; 97 | verifier?: Verifier; 98 | creatorFeeAllocationPercent: number; 99 | initialPriceUSD: number; 100 | }; 101 | 102 | export type CalculateAddLiquidityAmountsParams = 103 | | { 104 | coinAddress: Address; 105 | liquidityMode: LiquidityMode; 106 | coinOrEthInputAmount: bigint; 107 | inputToken: "coin" | "eth"; 108 | minMarketCap: string; 109 | maxMarketCap: string; 110 | currentMarketCap?: string; 111 | version?: FlaunchVersion; 112 | } 113 | | { 114 | coinAddress: Address; 115 | liquidityMode: LiquidityMode; 116 | coinOrEthInputAmount: bigint; 117 | inputToken: "coin" | "eth"; 118 | minPriceUSD: string; 119 | maxPriceUSD: string; 120 | currentPriceUSD?: number; 121 | version?: FlaunchVersion; 122 | }; 123 | 124 | export type GetAddLiquidityCallsParams = 125 | | { 126 | coinAddress: Address; 127 | liquidityMode: LiquidityMode; 128 | coinOrEthInputAmount: bigint; 129 | inputToken: "coin" | "eth"; 130 | minMarketCap: string; 131 | maxMarketCap: string; 132 | initialMarketCapUSD?: number; 133 | version?: FlaunchVersion; 134 | slippagePercent?: number; 135 | } 136 | | { 137 | coinAddress: Address; 138 | liquidityMode: LiquidityMode; 139 | coinOrEthInputAmount: bigint; 140 | inputToken: "coin" | "eth"; 141 | minPriceUSD: string; 142 | maxPriceUSD: string; 143 | initialPriceUSD?: number; 144 | version?: FlaunchVersion; 145 | slippagePercent?: number; 146 | } 147 | | { 148 | coinAddress: Address; 149 | coinAmount: bigint; 150 | flethAmount: bigint; 151 | tickLower: number; 152 | tickUpper: number; 153 | currentTick?: number; 154 | version?: FlaunchVersion; 155 | slippagePercent?: number; 156 | }; 157 | 158 | export type GetSingleSidedCoinAddLiquidityCallsParams = 159 | | { 160 | coinAddress: Address; 161 | coinAmount: bigint; 162 | initialMarketCapUSD?: number; 163 | version?: FlaunchVersion; 164 | tokenSupply?: bigint; 165 | slippagePercent?: number; 166 | } 167 | | { 168 | coinAddress: Address; 169 | coinAmount: bigint; 170 | initialPriceUSD?: number; 171 | version?: FlaunchVersion; 172 | tokenSupply?: bigint; 173 | slippagePercent?: number; 174 | }; 175 | 176 | export type CheckSingleSidedAddLiquidityParams = 177 | | { 178 | coinAddress: Address; 179 | liquidityMode: LiquidityMode; 180 | minMarketCap: string; 181 | maxMarketCap: string; 182 | currentMarketCap?: string; 183 | version?: FlaunchVersion; 184 | } 185 | | { 186 | coinAddress: Address; 187 | liquidityMode: LiquidityMode; 188 | minPriceUSD: string; 189 | maxPriceUSD: string; 190 | currentPriceUSD?: number; 191 | version?: FlaunchVersion; 192 | }; 193 | 194 | export interface SingleSidedLiquidityInfo { 195 | isSingleSided: boolean; 196 | shouldHideCoinInput: boolean; 197 | shouldHideETHInput: boolean; 198 | } 199 | 200 | // Flattened parameter types for better SDK integrator experience 201 | export type ImportAndAddLiquidityWithMarketCap = Flatten<{ 202 | coinAddress: Address; 203 | verifier?: Verifier; 204 | creatorFeeAllocationPercent: number; 205 | liquidityMode: LiquidityMode; 206 | coinOrEthInputAmount: bigint; 207 | inputToken: "coin" | "eth"; 208 | minMarketCap: string; 209 | maxMarketCap: string; 210 | initialMarketCapUSD: number; 211 | version?: FlaunchVersion; 212 | slippagePercent?: number; 213 | }>; 214 | 215 | export type ImportAndAddLiquidityWithPrice = Flatten<{ 216 | coinAddress: Address; 217 | verifier?: Verifier; 218 | creatorFeeAllocationPercent: number; 219 | liquidityMode: LiquidityMode; 220 | coinOrEthInputAmount: bigint; 221 | inputToken: "coin" | "eth"; 222 | minPriceUSD: string; 223 | maxPriceUSD: string; 224 | initialPriceUSD: number; 225 | version?: FlaunchVersion; 226 | slippagePercent?: number; 227 | }>; 228 | 229 | export type ImportAndAddLiquidityWithExactAmounts = Flatten<{ 230 | coinAddress: Address; 231 | verifier?: Verifier; 232 | creatorFeeAllocationPercent: number; 233 | coinAmount: bigint; 234 | flethAmount: bigint; 235 | tickLower: number; 236 | tickUpper: number; 237 | currentTick?: number; 238 | version?: FlaunchVersion; 239 | slippagePercent?: number; 240 | }>; 241 | 242 | // Union type for backward compatibility (still used internally) 243 | export type ImportAndAddLiquidityParams = 244 | | ImportAndAddLiquidityWithMarketCap 245 | | ImportAndAddLiquidityWithPrice 246 | | ImportAndAddLiquidityWithExactAmounts; 247 | 248 | // Union type for getImportAndSingleSidedCoinAddLiquidityCalls to ensure consistent price/market cap params 249 | 250 | // Resolved, flattened parameter types for better SDK integrator experience 251 | export type ImportAndSingleSidedCoinAddLiquidityWithMarketCap = Flatten<{ 252 | coinAddress: Address; 253 | verifier?: Verifier; 254 | creatorFeeAllocationPercent: number; 255 | coinAmount: bigint; 256 | initialMarketCapUSD: number; 257 | version?: FlaunchVersion; 258 | }>; 259 | 260 | export type ImportAndSingleSidedCoinAddLiquidityWithPrice = Flatten<{ 261 | coinAddress: Address; 262 | verifier?: Verifier; 263 | creatorFeeAllocationPercent: number; 264 | coinAmount: bigint; 265 | initialPriceUSD: number; 266 | version?: FlaunchVersion; 267 | }>; 268 | 269 | // Union type for backward compatibility (still used internally) 270 | export type ImportAndSingleSidedCoinAddLiquidityParams = 271 | | ImportAndSingleSidedCoinAddLiquidityWithMarketCap 272 | | ImportAndSingleSidedCoinAddLiquidityWithPrice; 273 | 274 | /** 275 | * Parsed data from a PoolCreated event 276 | */ 277 | export type PoolCreatedEventData = { 278 | poolId: Hex; 279 | memecoin: Address; 280 | memecoinTreasury: Address; 281 | tokenId: bigint; 282 | currencyFlipped: boolean; 283 | flaunchFee: bigint; 284 | params: { 285 | name: string; 286 | symbol: string; 287 | tokenUri: string; 288 | initialTokenFairLaunch: bigint; 289 | fairLaunchDuration?: bigint; // Optional as V1/V1_1 don't have this field 290 | premineAmount: bigint; 291 | creator: Address; 292 | creatorFeeAllocation: number; 293 | flaunchAt: bigint; 294 | initialPriceParams: Hex; 295 | feeCalculatorParams: Hex; 296 | }; 297 | }; 298 | -------------------------------------------------------------------------------- /src/addresses.ts: -------------------------------------------------------------------------------- 1 | import { base, baseSepolia } from "viem/chains"; 2 | import { Addresses, PoolKey } from "./types"; 3 | import { zeroAddress } from "viem"; 4 | 5 | export const FlaunchZapAddress: Addresses = { 6 | [base.id]: "0xe52dE1801C10cF709cc8e62d43D783AFe984b510", 7 | [baseSepolia.id]: "0xf0Fd8Bb98c050607d999D6fFF9C617edD6673b75", 8 | }; 9 | 10 | // only old V1.0: doesn't use FeeEscrow 11 | export const FlaunchPositionManagerAddress: Addresses = { 12 | [base.id]: "0x51Bba15255406Cfe7099a42183302640ba7dAFDC", 13 | [baseSepolia.id]: "0x9A7059cA00dA92843906Cb4bCa1D005cE848AFdC", 14 | }; 15 | 16 | export const FlaunchPositionManagerV1_1Address: Addresses = { 17 | [base.id]: "0xf785bb58059fab6fb19bdda2cb9078d9e546efdc", 18 | [baseSepolia.id]: "0x24347e0dd16357059abfc1b321df354873552fdc", 19 | }; 20 | 21 | export const FlaunchPositionManagerV1_2Address: Addresses = { 22 | [base.id]: "0x23321f11a6d44fd1ab790044fdfde5758c902fdc", // "1.3" from github releases 23 | [baseSepolia.id]: "0x4e7cb1e6800a7b297b38bddcecaf9ca5b6616fdc", 24 | }; 25 | 26 | export const AnyPositionManagerAddress: Addresses = { 27 | [base.id]: "0x8DC3b85e1dc1C846ebf3971179a751896842e5dC", 28 | [baseSepolia.id]: "0xB4A535B9D35851972736495CC52FBfDaCF32e5dc", 29 | }; 30 | 31 | export const FlaunchAddress: Addresses = { 32 | [base.id]: "0xCc7A4A00072ccbeEEbd999edc812C0ce498Fb63B", 33 | [baseSepolia.id]: "0x7D375C9133721083DF7b7e5Cb0Ed8Fc78862dfe3", 34 | }; 35 | 36 | export const FlaunchV1_1Address: Addresses = { 37 | [base.id]: "0xb4512bf57d50fbcb64a3adf8b17a79b2a204c18c", 38 | [baseSepolia.id]: "0x96be8ff5e244294a34bfa507a39190dc7a839baa", 39 | }; 40 | 41 | export const FlaunchV1_2Address: Addresses = { 42 | [base.id]: "0x516af52d0c629b5e378da4dc64ecb0744ce10109", // "1.3" from github releases 43 | [baseSepolia.id]: "0xe2ef58a54ee79dac0D4A130ea58b340124DF9438", 44 | }; 45 | 46 | export const AnyFlaunchAddress: Addresses = { 47 | [base.id]: "0xc5B2E8F197407263F4B62a35C71bFc394ecF95D5", 48 | [baseSepolia.id]: "0x67Ee6C83956a75f67bD3Fc8Ca4080D95a145c7C9", 49 | }; 50 | 51 | export const FairLaunchAddress: Addresses = { 52 | [base.id]: "0xCc7A4A00072ccbeEEbd999edc812C0ce498Fb63B", 53 | [baseSepolia.id]: "0x227Fc288aC56E169f2BfEA82e07F8635054d4136", 54 | }; 55 | 56 | // also supports AnyPositionManager & PositionManagerV1_2 (sepolia) 57 | export const FairLaunchV1_1Address: Addresses = { 58 | [base.id]: "0x4dc442403e8c758425b93C59Dc737da522f32640", 59 | [baseSepolia.id]: "0x7922c1ead7c5825fb52ed6b14f397d064508acbe", 60 | }; 61 | 62 | export const BidWallAddress: Addresses = { 63 | [base.id]: "0x66681f10BA90496241A25e33380004f30Dfd8aa8", 64 | [baseSepolia.id]: "0xa2107050ACEf4809c88Ab744F8e667605db5ACDB", 65 | }; 66 | 67 | // also supports AnyPositionManager & PositionManagerV1_2 (sepolia) 68 | export const BidWallV1_1Address: Addresses = { 69 | [base.id]: "0x7f22353d1634223a802D1c1Ea5308Ddf5DD0ef9c", 70 | [baseSepolia.id]: "0x6f2fa01a05ff8b6efbfefd91a3b85aaf19265a00", 71 | }; 72 | 73 | export const AnyBidWallAddress: Addresses = { 74 | [base.id]: "0x2154c604df568A5285284D1c4918DC98C39240df", 75 | [baseSepolia.id]: "0xcfF222eA42E43F46A98755db237E4c9C2CA9B772", 76 | }; 77 | 78 | export const TreasuryManagerFactoryAddress: Addresses = { 79 | [base.id]: "0x48af8b28DDC5e5A86c4906212fc35Fa808CA8763", 80 | [baseSepolia.id]: "0xD2F3C6185e06925dCBE794C6574315b2202E9CcD", 81 | }; 82 | 83 | export const RevenueManagerAddress: Addresses = { 84 | [base.id]: "0xc8d4B2Ca8eD6868eE768beAb1f932d7eecCc1b50", 85 | [baseSepolia.id]: "0xA8153b14c8CfdDfb02627807D84AB02D12A85477", 86 | }; 87 | 88 | export const AddressFeeSplitManagerAddress: Addresses = { 89 | [base.id]: "0xfAB4BA48a322Efc8b25815448BE6018D211e89f3", 90 | [baseSepolia.id]: "0x0A3AF63cd86E68a852A1D4923FEfC4e855D8499d", 91 | }; 92 | 93 | export const StakingManagerAddress: Addresses = { 94 | [base.id]: "0xec0069F8DBbbC94058dc895000dd38ef40b3125d", 95 | [baseSepolia.id]: "0xB8f1cb6B4Ff8f07149276bbfA617aed7bd32d20D", 96 | }; 97 | 98 | export const BuyBackManagerAddress: Addresses = { 99 | [base.id]: "0x3AAF3b1D8cD5b61C77f99bA7cdf41E9eC0Ba8a3f", 100 | [baseSepolia.id]: "0xc3947EC9d687053bBA72b36Fd6b2567e775E82C7", 101 | }; 102 | 103 | /** Verifiers */ 104 | export const TokenImporterAddress: Addresses = { 105 | [base.id]: "0x6fb66f4fc262dc86e12136c481ba7c411e668197", 106 | [baseSepolia.id]: "0x7981369D21975F39773f289F759F7d7CE1097139", 107 | }; 108 | 109 | export const ClankerWorldVerifierAddress: Addresses = { 110 | [base.id]: "0xFe55dFf581b665479ABe9Fc0A0578FB222cB4Dda", 111 | [baseSepolia.id]: "0x2874F9A30348aCAaaD55D74B0BEc9C18f04b471a", 112 | }; 113 | 114 | export const DopplerVerifierAddress: Addresses = { 115 | [base.id]: "0xedd66b080b8e9425c39d349a3fb69f480580f993", 116 | [baseSepolia.id]: "0x6428b5C4da36ecB070aBdcB5E1939244A3cC7fb5", 117 | }; 118 | 119 | export const SolanaVerifierAddress: Addresses = { 120 | [base.id]: "0xba28ac1540893a34476c24b2c4fa32e0506c9055", 121 | [baseSepolia.id]: "0x47226918e518f205584bd75bf81e0b532b0b3ea7", 122 | }; 123 | 124 | export const VirtualsVerifierAddress: Addresses = { 125 | [base.id]: "0x06a089fa231aca48d2aa77365123ad9aca43d3a4", 126 | [baseSepolia.id]: "0x6582d2bc6a7eba3b40bdf46b3868fc7ec2ff96ec", 127 | }; 128 | 129 | export const WhitelistVerifierAddress: Addresses = { 130 | [base.id]: "0x7a04367563a65db574d6b7d084fdbcf4a570c5a6", 131 | [baseSepolia.id]: "0xfde5b79e3e2814edd5f91e8694ae400954d9cfaa", 132 | }; 133 | 134 | export const ZoraVerifierAddress: Addresses = { 135 | [base.id]: "0x656047fd43d2c3a121f2ef859d7171d7dd59f8b9", 136 | [baseSepolia.id]: "0x05a5763e9199b88bb591c6b112d0424b2cd7a99e", 137 | }; 138 | 139 | /** ======== */ 140 | 141 | /** Permissions */ 142 | export const ClosedPermissionsAddress: Addresses = { 143 | [base.id]: "0x4dfc76A31A2a0110739611683a8b6C5201480fa1", 144 | [baseSepolia.id]: "0x551aeD820CAfaca2f9cD1C637AAc076D05a03AC2", 145 | }; 146 | 147 | export const WhitelistedPermissionsAddress: Addresses = { 148 | [base.id]: "0x828B58B2B2df8ff3221Fbe2b07e75a56a84493Cc", 149 | [baseSepolia.id]: "0xe8691E8f576A98c41EBB5E984207d4F51386621f", 150 | }; 151 | /** =========== */ 152 | 153 | export const FeeEscrowAddress: Addresses = { 154 | [base.id]: "0x72e6f7948b1B1A343B477F39aAbd2E35E6D27dde", 155 | [baseSepolia.id]: "0x73E27908b7d35A9251a54799A8ef4C17e4ED9FF9", 156 | }; 157 | 158 | export const ReferralEscrowAddress: Addresses = { 159 | [base.id]: "0xBD39c7Be6D98BD1a3e4Ad482baF99d738947fE55", 160 | [baseSepolia.id]: "0xd3d9047CaBE3346C70b510435866565176e8CE12", 161 | }; 162 | 163 | export const FLETHAddress: Addresses = { 164 | [base.id]: "0x000000000D564D5be76f7f0d28fE52605afC7Cf8", 165 | [baseSepolia.id]: "0x79FC52701cD4BE6f9Ba9aDC94c207DE37e3314eb", 166 | }; 167 | 168 | export const FLETHHooksAddress: Addresses = { 169 | [base.id]: "0x9E433F32bb5481a9CA7DFF5b3af74A7ed041a888", 170 | [baseSepolia.id]: "0x4bd2ca15286c96e4e731337de8b375da6841e888", 171 | }; 172 | 173 | // @deprecated: FlaunchZap used instead 174 | export const FastFlaunchZapAddress: Addresses = { 175 | [base.id]: "0x68d967d25806fef4aa134db031cdcc55d3e20f92", 176 | [baseSepolia.id]: "0x821d9f6075e7971cc71c379081de9d532f5f9957", 177 | }; 178 | 179 | export const PoolManagerAddress: Addresses = { 180 | [base.id]: "0x498581fF718922c3f8e6A244956aF099B2652b2b", 181 | [baseSepolia.id]: "0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408", 182 | }; 183 | 184 | export const UniversalRouterAddress: Addresses = { 185 | [base.id]: "0x6fF5693b99212Da76ad316178A184AB56D299b43", 186 | [baseSepolia.id]: "0x492E6456D9528771018DeB9E87ef7750EF184104", 187 | }; 188 | 189 | export const QuoterAddress: Addresses = { 190 | [base.id]: "0x0d5e0f971ed27fbff6c2837bf31316121532048d", 191 | [baseSepolia.id]: "0x4a6513c898fe1b2d0e78d3b0e0a4a151589b1cba", 192 | }; 193 | 194 | export const StateViewAddress: Addresses = { 195 | [base.id]: "0xA3c0c9b65baD0b08107Aa264b0f3dB444b867A71", 196 | [baseSepolia.id]: "0x571291b572ed32ce6751a2Cb2486EbEe8DEfB9B4", 197 | }; 198 | 199 | export const Permit2Address: Addresses = { 200 | [base.id]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", 201 | [baseSepolia.id]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", 202 | }; 203 | 204 | export const UniV4PositionManagerAddress: Addresses = { 205 | [base.id]: "0x7C5f5A4bBd8fD63184577525326123B519429bDc", 206 | [baseSepolia.id]: "0x4B2C77d209D3405F41a037Ec6c77F7F5b8e2ca80", 207 | }; 208 | 209 | export const USDCETHPoolKeys: { 210 | [chainId: number]: PoolKey; 211 | } = { 212 | [base.id]: { 213 | currency0: zeroAddress, 214 | currency1: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", 215 | fee: 500, 216 | tickSpacing: 10, 217 | hooks: zeroAddress, 218 | }, 219 | [baseSepolia.id]: { 220 | currency0: zeroAddress, 221 | currency1: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", 222 | fee: 0, 223 | tickSpacing: 30, 224 | hooks: zeroAddress, 225 | }, 226 | }; 227 | -------------------------------------------------------------------------------- /PUBLISHING.md: -------------------------------------------------------------------------------- 1 | # Publishing Process for @flaunch/sdk 2 | 3 | This document outlines the process for versioning and publishing updates to the `@flaunch/sdk` package. 4 | 5 | ## Versioning Guidelines 6 | 7 | We follow [Semantic Versioning](https://semver.org/) (SemVer) with the following guidelines: 8 | 9 | - **MAJOR version (1.0.0 → 2.0.0)**: Incompatible API changes 10 | - **MINOR version (0.1.0 → 0.2.0)**: 11 | - For versions < 1.0.0: Breaking changes (as pre-1.0 is considered development phase) 12 | - For versions ≥ 1.0.0: Backward-compatible new features 13 | - **PATCH version (0.1.0 → 0.1.1)**: Backward-compatible bug fixes 14 | 15 | ## When to Update Versions 16 | 17 | - **Breaking Changes**: If you remove or rename parameters, change function signatures, or make any other changes that would break existing code using the SDK, increment the appropriate version (MAJOR for ≥1.0.0, MINOR for <1.0.0). 18 | - **New Features**: When adding new functionality without breaking existing code, increment the MINOR version. 19 | - **Bug Fixes**: When fixing bugs without changing the API, increment the PATCH version. 20 | 21 | ## Publishing Process 22 | 23 | ### 1. 24 | 25 | Update CHANGELOG.md by running this prompt: 26 | 27 | ```` 28 | You are tasked with creating a detailed and accurate changelog entry for a new software version by analyzing git changes. Follow this systematic approach: 29 | 30 | ## Step 1: Gather Git Information 31 | 1. Get the commit history since the last version: 32 | ``` 33 | git log --oneline --since="YYYY-MM-DD" --until="now" 34 | git log --since="YYYY-MM-DD" --until="now" --pretty=format:"%h - %s (%an, %ad)" --date=short 35 | ``` 36 | 37 | 2. Get the actual code differences: 38 | ``` 39 | git diff PREVIOUS_VERSION..CURRENT_VERSION 40 | ``` 41 | 42 | ## Step 2: Analyze the Changes 43 | 44 | **Important**: Don't rely solely on commit messages. Examine the actual code diffs to understand: 45 | 46 | - **New files added** - What functionality do they provide? 47 | - **Modified files** - What specific changes were made? 48 | - **Function/method additions** - What new capabilities were added? 49 | - **API changes** - What interfaces changed? 50 | - **Configuration changes** - Address mappings, constants, etc. 51 | - **Refactoring** - Code organization improvements 52 | - **Bug fixes** - What issues were resolved? 53 | 54 | ## Step 3: Categorize Changes 55 | 56 | Organize findings into these categories: 57 | 58 | ### Added 59 | 60 | - New features, functions, methods, or capabilities 61 | - New files, modules, or components 62 | - New configuration options or addresses 63 | - New utility functions or helpers 64 | 65 | ### Changed 66 | 67 | - Modified existing functionality 68 | - Updated dependencies or versions 69 | - Refactored code (improved organization) 70 | - Updated documentation or comments 71 | - Address or configuration updates 72 | 73 | ### Fixed 74 | 75 | - Bug fixes and error corrections 76 | - Performance improvements 77 | - Security patches 78 | - Documentation corrections 79 | 80 | ### Deprecated (if applicable) 81 | 82 | - Features marked for removal 83 | - Methods or APIs being phased out 84 | 85 | ## Step 4: Write the Changelog Entry 86 | 87 | Format: `## [VERSION] - YYYY-MM-DD` 88 | 89 | **Guidelines:** 90 | 91 | - Use **bold** for major feature categories 92 | - Use `code blocks` for function/method names, file names, and technical terms 93 | - Provide context - don't just list what changed, but explain what it enables 94 | - Group related changes under logical headings 95 | - Be specific but concise 96 | - Include technical details developers would find useful 97 | - Mention both the "what" and "why" when relevant 98 | 99 | **Example Structure:** 100 | 101 | ``` 102 | ## [X.Y.Z] - YYYY-MM-DD 103 | 104 | ### Added 105 | 106 | - **Major Feature Name** description of what it enables 107 | - `specificMethod()` and `anotherMethod()` for doing X 108 | - New `FileName.ts` utility with functionality for Y 109 | - Support for Z with configurable options 110 | 111 | ### Changed 112 | 113 | - **Improved functionality** description 114 | - Refactored duplicate logic into reusable utilities 115 | - Updated address mappings for network support 116 | 117 | ### Fixed 118 | 119 | - **Issue description** - specific fix details 120 | ``` 121 | 122 | ## Step 5: Verification 123 | 124 | - Ensure every significant change in the diff is reflected 125 | - Check that technical terms and method names are accurate 126 | - Verify that the impact and benefits are clearly explained 127 | - Confirm the changelog helps users understand what changed and why it matters 128 | 129 | ## Key Principles: 130 | 131 | 1. **Accuracy over speed** - Take time to understand the actual changes 132 | 2. **Developer-focused** - Write for people who will use or maintain the code 133 | 3. **Context matters** - Explain not just what changed, but what it enables 134 | 4. **Be specific** - Use exact function names, file names, and technical terms 135 | 5. **Logical grouping** - Group related changes together under clear headings 136 | 137 | This approach ensures the changelog accurately reflects the actual code changes rather than just commit message summaries. 138 | 139 | ```` 140 | 141 | ### 2. 142 | 143 | Update the llm docs: 144 | 145 | ```bash 146 | pnpm docs:llms 147 | ``` 148 | 149 | ### 3. Update the Version 150 | 151 | Use the pnpm version command to update the version in package.json: 152 | 153 | ```bash 154 | # For bug fixes 155 | pnpm version patch 156 | 157 | # For breaking changes in pre-1.0 or new features in post-1.0 158 | pnpm version minor 159 | 160 | # For breaking changes in post-1.0 161 | pnpm version major 162 | ``` 163 | 164 | This command will: 165 | 166 | - Update the version in package.json 167 | - Create a git commit with the message "@flaunch/sdk v{version}" 168 | - Create a git tag with the name "@flaunch/sdk@{version}" 169 | 170 | ### 4. Push Changes to GitHub 171 | 172 | Push both the commit and the tag to GitHub: 173 | 174 | ```bash 175 | git push && git push --tags 176 | ``` 177 | 178 | ### 5. Build and Publish the Package 179 | 180 | Build the package and publish it to npm: 181 | 182 | ```bash 183 | pnpm publish 184 | ``` 185 | 186 | The `pnpm publish` command will automatically run the build script (via prepublishOnly) before publishing. 187 | 188 | ## Beta Version Publishing 189 | 190 | Beta versions allow you to publish pre-release versions for testing without affecting the stable release channel. Users who don't specify a version will continue to get the latest stable version, while those who explicitly want the beta can install it. 191 | 192 | ### 1. Creating a Beta Version 193 | 194 | Update your version to include a beta suffix: 195 | 196 | ```bash 197 | # Option 1: Increment patch version with beta suffix 198 | pnpm version 0.8.3-beta.0 199 | 200 | # Option 2: Increment minor version with beta suffix 201 | pnpm version 0.9.0-beta.0 202 | 203 | # Option 3: Use npm version command with prerelease 204 | pnpm version prerelease --preid=beta 205 | ``` 206 | 207 | ### 2. Publishing the Beta Version 208 | 209 | Publish with the `beta` tag instead of `latest`: 210 | 211 | ```bash 212 | pnpm publish --tag beta 213 | ``` 214 | 215 | ### 3. How Users Install Different Versions 216 | 217 | After publishing, users can install versions as follows: 218 | 219 | ```bash 220 | # Latest stable version (current latest) 221 | npm install @flaunch/sdk 222 | 223 | # Beta version explicitly by tag 224 | npm install @flaunch/sdk@beta 225 | 226 | # Beta version explicitly by version number 227 | npm install @flaunch/sdk@0.8.3-beta.0 228 | ``` 229 | 230 | ### 4. Verifying Beta Publication 231 | 232 | Check that your beta version was published correctly: 233 | 234 | ```bash 235 | # View all versions and their tags 236 | npm view @flaunch/sdk versions --json 237 | npm view @flaunch/sdk dist-tags 238 | ``` 239 | 240 | ### 5. Publishing Additional Beta Versions 241 | 242 | If you need to publish more beta versions, increment the beta number: 243 | 244 | ```bash 245 | pnpm version 0.8.3-beta.1 246 | pnpm publish --tag beta 247 | ``` 248 | 249 | ### 6. Promoting Beta to Stable 250 | 251 | When ready to make the beta version stable: 252 | 253 | ```bash 254 | # Remove the beta suffix 255 | pnpm version 0.8.3 256 | 257 | # Publish as latest (default tag) 258 | pnpm publish 259 | ``` 260 | 261 | ### Important Notes for Beta Versions 262 | 263 | - Your `prepublishOnly` script will automatically build the package before publishing 264 | - The `latest` tag will remain on the previous stable version until you publish a new stable version 265 | - Users who don't specify a version will continue to get the current stable version 266 | - Beta versions are discoverable but won't be installed by default 267 | - Beta versions should still follow semantic versioning principles 268 | - Consider updating documentation to mention beta availability when appropriate 269 | 270 | ## Configuration 271 | 272 | The versioning and commit message format is configured in the `.npmrc` file: 273 | 274 | ``` 275 | 276 | tag-version-prefix="@flaunch/sdk@" 277 | message="@flaunch/sdk v%s" 278 | 279 | ``` 280 | 281 | This ensures consistent tagging and commit messages across all releases. 282 | -------------------------------------------------------------------------------- /src/abi/TokenImporter.ts: -------------------------------------------------------------------------------- 1 | export const TokenImporterAbi = [ 2 | { 3 | "type": "constructor", 4 | "inputs": [ 5 | { 6 | "name": "_anyPositionManager", 7 | "type": "address", 8 | "internalType": "address payable" 9 | } 10 | ], 11 | "stateMutability": "nonpayable" 12 | }, 13 | { 14 | "type": "function", 15 | "name": "addVerifier", 16 | "inputs": [ 17 | { 18 | "name": "_verifier", 19 | "type": "address", 20 | "internalType": "address" 21 | } 22 | ], 23 | "outputs": [], 24 | "stateMutability": "nonpayable" 25 | }, 26 | { 27 | "type": "function", 28 | "name": "anyPositionManager", 29 | "inputs": [], 30 | "outputs": [ 31 | { 32 | "name": "", 33 | "type": "address", 34 | "internalType": "contract AnyPositionManager" 35 | } 36 | ], 37 | "stateMutability": "view" 38 | }, 39 | { 40 | "type": "function", 41 | "name": "cancelOwnershipHandover", 42 | "inputs": [], 43 | "outputs": [], 44 | "stateMutability": "payable" 45 | }, 46 | { 47 | "type": "function", 48 | "name": "completeOwnershipHandover", 49 | "inputs": [ 50 | { 51 | "name": "pendingOwner", 52 | "type": "address", 53 | "internalType": "address" 54 | } 55 | ], 56 | "outputs": [], 57 | "stateMutability": "payable" 58 | }, 59 | { 60 | "type": "function", 61 | "name": "getAllVerifiers", 62 | "inputs": [], 63 | "outputs": [ 64 | { 65 | "name": "verifiers_", 66 | "type": "address[]", 67 | "internalType": "address[]" 68 | } 69 | ], 70 | "stateMutability": "view" 71 | }, 72 | { 73 | "type": "function", 74 | "name": "initialize", 75 | "inputs": [ 76 | { 77 | "name": "_memecoin", 78 | "type": "address", 79 | "internalType": "address" 80 | }, 81 | { 82 | "name": "_creatorFeeAllocation", 83 | "type": "uint24", 84 | "internalType": "uint24" 85 | }, 86 | { 87 | "name": "_initialMarketCap", 88 | "type": "uint256", 89 | "internalType": "uint256" 90 | }, 91 | { 92 | "name": "_verifier", 93 | "type": "address", 94 | "internalType": "address" 95 | } 96 | ], 97 | "outputs": [], 98 | "stateMutability": "nonpayable" 99 | }, 100 | { 101 | "type": "function", 102 | "name": "initialize", 103 | "inputs": [ 104 | { 105 | "name": "_memecoin", 106 | "type": "address", 107 | "internalType": "address" 108 | }, 109 | { 110 | "name": "_creatorFeeAllocation", 111 | "type": "uint24", 112 | "internalType": "uint24" 113 | }, 114 | { 115 | "name": "_initialMarketCap", 116 | "type": "uint256", 117 | "internalType": "uint256" 118 | }, 119 | { 120 | "name": "_totalSupply", 121 | "type": "uint256", 122 | "internalType": "uint256" 123 | }, 124 | { 125 | "name": "_verifier", 126 | "type": "address", 127 | "internalType": "address" 128 | } 129 | ], 130 | "outputs": [], 131 | "stateMutability": "nonpayable" 132 | }, 133 | { 134 | "type": "function", 135 | "name": "initialize", 136 | "inputs": [ 137 | { 138 | "name": "_memecoin", 139 | "type": "address", 140 | "internalType": "address" 141 | }, 142 | { 143 | "name": "_creatorFeeAllocation", 144 | "type": "uint24", 145 | "internalType": "uint24" 146 | }, 147 | { 148 | "name": "_initialMarketCap", 149 | "type": "uint256", 150 | "internalType": "uint256" 151 | } 152 | ], 153 | "outputs": [], 154 | "stateMutability": "nonpayable" 155 | }, 156 | { 157 | "type": "function", 158 | "name": "owner", 159 | "inputs": [], 160 | "outputs": [ 161 | { 162 | "name": "result", 163 | "type": "address", 164 | "internalType": "address" 165 | } 166 | ], 167 | "stateMutability": "view" 168 | }, 169 | { 170 | "type": "function", 171 | "name": "ownershipHandoverExpiresAt", 172 | "inputs": [ 173 | { 174 | "name": "pendingOwner", 175 | "type": "address", 176 | "internalType": "address" 177 | } 178 | ], 179 | "outputs": [ 180 | { 181 | "name": "result", 182 | "type": "uint256", 183 | "internalType": "uint256" 184 | } 185 | ], 186 | "stateMutability": "view" 187 | }, 188 | { 189 | "type": "function", 190 | "name": "removeVerifier", 191 | "inputs": [ 192 | { 193 | "name": "_verifier", 194 | "type": "address", 195 | "internalType": "address" 196 | } 197 | ], 198 | "outputs": [], 199 | "stateMutability": "nonpayable" 200 | }, 201 | { 202 | "type": "function", 203 | "name": "renounceOwnership", 204 | "inputs": [], 205 | "outputs": [], 206 | "stateMutability": "payable" 207 | }, 208 | { 209 | "type": "function", 210 | "name": "requestOwnershipHandover", 211 | "inputs": [], 212 | "outputs": [], 213 | "stateMutability": "payable" 214 | }, 215 | { 216 | "type": "function", 217 | "name": "setAnyPositionManager", 218 | "inputs": [ 219 | { 220 | "name": "_anyPositionManager", 221 | "type": "address", 222 | "internalType": "address payable" 223 | } 224 | ], 225 | "outputs": [], 226 | "stateMutability": "nonpayable" 227 | }, 228 | { 229 | "type": "function", 230 | "name": "transferOwnership", 231 | "inputs": [ 232 | { 233 | "name": "newOwner", 234 | "type": "address", 235 | "internalType": "address" 236 | } 237 | ], 238 | "outputs": [], 239 | "stateMutability": "payable" 240 | }, 241 | { 242 | "type": "function", 243 | "name": "verifyMemecoin", 244 | "inputs": [ 245 | { 246 | "name": "_memecoin", 247 | "type": "address", 248 | "internalType": "address" 249 | } 250 | ], 251 | "outputs": [ 252 | { 253 | "name": "verifier_", 254 | "type": "address", 255 | "internalType": "address" 256 | } 257 | ], 258 | "stateMutability": "view" 259 | }, 260 | { 261 | "type": "event", 262 | "name": "AnyPositionManagerSet", 263 | "inputs": [ 264 | { 265 | "name": "_anyPositionManager", 266 | "type": "address", 267 | "indexed": true, 268 | "internalType": "address" 269 | } 270 | ], 271 | "anonymous": false 272 | }, 273 | { 274 | "type": "event", 275 | "name": "OwnershipHandoverCanceled", 276 | "inputs": [ 277 | { 278 | "name": "pendingOwner", 279 | "type": "address", 280 | "indexed": true, 281 | "internalType": "address" 282 | } 283 | ], 284 | "anonymous": false 285 | }, 286 | { 287 | "type": "event", 288 | "name": "OwnershipHandoverRequested", 289 | "inputs": [ 290 | { 291 | "name": "pendingOwner", 292 | "type": "address", 293 | "indexed": true, 294 | "internalType": "address" 295 | } 296 | ], 297 | "anonymous": false 298 | }, 299 | { 300 | "type": "event", 301 | "name": "OwnershipTransferred", 302 | "inputs": [ 303 | { 304 | "name": "oldOwner", 305 | "type": "address", 306 | "indexed": true, 307 | "internalType": "address" 308 | }, 309 | { 310 | "name": "newOwner", 311 | "type": "address", 312 | "indexed": true, 313 | "internalType": "address" 314 | } 315 | ], 316 | "anonymous": false 317 | }, 318 | { 319 | "type": "event", 320 | "name": "TokenImported", 321 | "inputs": [ 322 | { 323 | "name": "_memecoin", 324 | "type": "address", 325 | "indexed": true, 326 | "internalType": "address" 327 | }, 328 | { 329 | "name": "_verifier", 330 | "type": "address", 331 | "indexed": true, 332 | "internalType": "address" 333 | } 334 | ], 335 | "anonymous": false 336 | }, 337 | { 338 | "type": "event", 339 | "name": "VerifierAdded", 340 | "inputs": [ 341 | { 342 | "name": "_verifier", 343 | "type": "address", 344 | "indexed": true, 345 | "internalType": "address" 346 | } 347 | ], 348 | "anonymous": false 349 | }, 350 | { 351 | "type": "event", 352 | "name": "VerifierRemoved", 353 | "inputs": [ 354 | { 355 | "name": "_verifier", 356 | "type": "address", 357 | "indexed": true, 358 | "internalType": "address" 359 | } 360 | ], 361 | "anonymous": false 362 | }, 363 | { 364 | "type": "error", 365 | "name": "AlreadyInitialized", 366 | "inputs": [] 367 | }, 368 | { 369 | "type": "error", 370 | "name": "InvalidMemecoin", 371 | "inputs": [] 372 | }, 373 | { 374 | "type": "error", 375 | "name": "NewOwnerIsZeroAddress", 376 | "inputs": [] 377 | }, 378 | { 379 | "type": "error", 380 | "name": "NoHandoverRequest", 381 | "inputs": [] 382 | }, 383 | { 384 | "type": "error", 385 | "name": "Unauthorized", 386 | "inputs": [] 387 | }, 388 | { 389 | "type": "error", 390 | "name": "VerifierAlreadyAdded", 391 | "inputs": [] 392 | }, 393 | { 394 | "type": "error", 395 | "name": "VerifierNotAdded", 396 | "inputs": [] 397 | }, 398 | { 399 | "type": "error", 400 | "name": "ZeroAddress", 401 | "inputs": [] 402 | } 403 | ] as const; 404 | -------------------------------------------------------------------------------- /src/abi/Multicall.ts: -------------------------------------------------------------------------------- 1 | export const MulticallAbi = [ 2 | { 3 | inputs: [ 4 | { 5 | components: [ 6 | { 7 | internalType: "address", 8 | name: "target", 9 | type: "address", 10 | }, 11 | { 12 | internalType: "bytes", 13 | name: "callData", 14 | type: "bytes", 15 | }, 16 | ], 17 | internalType: "struct Multicall3.Call[]", 18 | name: "calls", 19 | type: "tuple[]", 20 | }, 21 | ], 22 | name: "aggregate", 23 | outputs: [ 24 | { 25 | internalType: "uint256", 26 | name: "blockNumber", 27 | type: "uint256", 28 | }, 29 | { 30 | internalType: "bytes[]", 31 | name: "returnData", 32 | type: "bytes[]", 33 | }, 34 | ], 35 | stateMutability: "payable", 36 | type: "function", 37 | }, 38 | { 39 | inputs: [ 40 | { 41 | components: [ 42 | { 43 | internalType: "address", 44 | name: "target", 45 | type: "address", 46 | }, 47 | { 48 | internalType: "bool", 49 | name: "allowFailure", 50 | type: "bool", 51 | }, 52 | { 53 | internalType: "bytes", 54 | name: "callData", 55 | type: "bytes", 56 | }, 57 | ], 58 | internalType: "struct Multicall3.Call3[]", 59 | name: "calls", 60 | type: "tuple[]", 61 | }, 62 | ], 63 | name: "aggregate3", 64 | outputs: [ 65 | { 66 | components: [ 67 | { 68 | internalType: "bool", 69 | name: "success", 70 | type: "bool", 71 | }, 72 | { 73 | internalType: "bytes", 74 | name: "returnData", 75 | type: "bytes", 76 | }, 77 | ], 78 | internalType: "struct Multicall3.Result[]", 79 | name: "returnData", 80 | type: "tuple[]", 81 | }, 82 | ], 83 | stateMutability: "payable", 84 | type: "function", 85 | }, 86 | { 87 | inputs: [ 88 | { 89 | components: [ 90 | { 91 | internalType: "address", 92 | name: "target", 93 | type: "address", 94 | }, 95 | { 96 | internalType: "bool", 97 | name: "allowFailure", 98 | type: "bool", 99 | }, 100 | { 101 | internalType: "uint256", 102 | name: "value", 103 | type: "uint256", 104 | }, 105 | { 106 | internalType: "bytes", 107 | name: "callData", 108 | type: "bytes", 109 | }, 110 | ], 111 | internalType: "struct Multicall3.Call3Value[]", 112 | name: "calls", 113 | type: "tuple[]", 114 | }, 115 | ], 116 | name: "aggregate3Value", 117 | outputs: [ 118 | { 119 | components: [ 120 | { 121 | internalType: "bool", 122 | name: "success", 123 | type: "bool", 124 | }, 125 | { 126 | internalType: "bytes", 127 | name: "returnData", 128 | type: "bytes", 129 | }, 130 | ], 131 | internalType: "struct Multicall3.Result[]", 132 | name: "returnData", 133 | type: "tuple[]", 134 | }, 135 | ], 136 | stateMutability: "payable", 137 | type: "function", 138 | }, 139 | { 140 | inputs: [ 141 | { 142 | components: [ 143 | { 144 | internalType: "address", 145 | name: "target", 146 | type: "address", 147 | }, 148 | { 149 | internalType: "bytes", 150 | name: "callData", 151 | type: "bytes", 152 | }, 153 | ], 154 | internalType: "struct Multicall3.Call[]", 155 | name: "calls", 156 | type: "tuple[]", 157 | }, 158 | ], 159 | name: "blockAndAggregate", 160 | outputs: [ 161 | { 162 | internalType: "uint256", 163 | name: "blockNumber", 164 | type: "uint256", 165 | }, 166 | { 167 | internalType: "bytes32", 168 | name: "blockHash", 169 | type: "bytes32", 170 | }, 171 | { 172 | components: [ 173 | { 174 | internalType: "bool", 175 | name: "success", 176 | type: "bool", 177 | }, 178 | { 179 | internalType: "bytes", 180 | name: "returnData", 181 | type: "bytes", 182 | }, 183 | ], 184 | internalType: "struct Multicall3.Result[]", 185 | name: "returnData", 186 | type: "tuple[]", 187 | }, 188 | ], 189 | stateMutability: "payable", 190 | type: "function", 191 | }, 192 | { 193 | inputs: [], 194 | name: "getBasefee", 195 | outputs: [ 196 | { 197 | internalType: "uint256", 198 | name: "basefee", 199 | type: "uint256", 200 | }, 201 | ], 202 | stateMutability: "view", 203 | type: "function", 204 | }, 205 | { 206 | inputs: [ 207 | { 208 | internalType: "uint256", 209 | name: "blockNumber", 210 | type: "uint256", 211 | }, 212 | ], 213 | name: "getBlockHash", 214 | outputs: [ 215 | { 216 | internalType: "bytes32", 217 | name: "blockHash", 218 | type: "bytes32", 219 | }, 220 | ], 221 | stateMutability: "view", 222 | type: "function", 223 | }, 224 | { 225 | inputs: [], 226 | name: "getBlockNumber", 227 | outputs: [ 228 | { 229 | internalType: "uint256", 230 | name: "blockNumber", 231 | type: "uint256", 232 | }, 233 | ], 234 | stateMutability: "view", 235 | type: "function", 236 | }, 237 | { 238 | inputs: [], 239 | name: "getChainId", 240 | outputs: [ 241 | { 242 | internalType: "uint256", 243 | name: "chainid", 244 | type: "uint256", 245 | }, 246 | ], 247 | stateMutability: "view", 248 | type: "function", 249 | }, 250 | { 251 | inputs: [], 252 | name: "getCurrentBlockCoinbase", 253 | outputs: [ 254 | { 255 | internalType: "address", 256 | name: "coinbase", 257 | type: "address", 258 | }, 259 | ], 260 | stateMutability: "view", 261 | type: "function", 262 | }, 263 | { 264 | inputs: [], 265 | name: "getCurrentBlockDifficulty", 266 | outputs: [ 267 | { 268 | internalType: "uint256", 269 | name: "difficulty", 270 | type: "uint256", 271 | }, 272 | ], 273 | stateMutability: "view", 274 | type: "function", 275 | }, 276 | { 277 | inputs: [], 278 | name: "getCurrentBlockGasLimit", 279 | outputs: [ 280 | { 281 | internalType: "uint256", 282 | name: "gaslimit", 283 | type: "uint256", 284 | }, 285 | ], 286 | stateMutability: "view", 287 | type: "function", 288 | }, 289 | { 290 | inputs: [], 291 | name: "getCurrentBlockTimestamp", 292 | outputs: [ 293 | { 294 | internalType: "uint256", 295 | name: "timestamp", 296 | type: "uint256", 297 | }, 298 | ], 299 | stateMutability: "view", 300 | type: "function", 301 | }, 302 | { 303 | inputs: [ 304 | { 305 | internalType: "address", 306 | name: "addr", 307 | type: "address", 308 | }, 309 | ], 310 | name: "getEthBalance", 311 | outputs: [ 312 | { 313 | internalType: "uint256", 314 | name: "balance", 315 | type: "uint256", 316 | }, 317 | ], 318 | stateMutability: "view", 319 | type: "function", 320 | }, 321 | { 322 | inputs: [], 323 | name: "getLastBlockHash", 324 | outputs: [ 325 | { 326 | internalType: "bytes32", 327 | name: "blockHash", 328 | type: "bytes32", 329 | }, 330 | ], 331 | stateMutability: "view", 332 | type: "function", 333 | }, 334 | { 335 | inputs: [ 336 | { 337 | internalType: "bool", 338 | name: "requireSuccess", 339 | type: "bool", 340 | }, 341 | { 342 | components: [ 343 | { 344 | internalType: "address", 345 | name: "target", 346 | type: "address", 347 | }, 348 | { 349 | internalType: "bytes", 350 | name: "callData", 351 | type: "bytes", 352 | }, 353 | ], 354 | internalType: "struct Multicall3.Call[]", 355 | name: "calls", 356 | type: "tuple[]", 357 | }, 358 | ], 359 | name: "tryAggregate", 360 | outputs: [ 361 | { 362 | components: [ 363 | { 364 | internalType: "bool", 365 | name: "success", 366 | type: "bool", 367 | }, 368 | { 369 | internalType: "bytes", 370 | name: "returnData", 371 | type: "bytes", 372 | }, 373 | ], 374 | internalType: "struct Multicall3.Result[]", 375 | name: "returnData", 376 | type: "tuple[]", 377 | }, 378 | ], 379 | stateMutability: "payable", 380 | type: "function", 381 | }, 382 | { 383 | inputs: [ 384 | { 385 | internalType: "bool", 386 | name: "requireSuccess", 387 | type: "bool", 388 | }, 389 | { 390 | components: [ 391 | { 392 | internalType: "address", 393 | name: "target", 394 | type: "address", 395 | }, 396 | { 397 | internalType: "bytes", 398 | name: "callData", 399 | type: "bytes", 400 | }, 401 | ], 402 | internalType: "struct Multicall3.Call[]", 403 | name: "calls", 404 | type: "tuple[]", 405 | }, 406 | ], 407 | name: "tryBlockAndAggregate", 408 | outputs: [ 409 | { 410 | internalType: "uint256", 411 | name: "blockNumber", 412 | type: "uint256", 413 | }, 414 | { 415 | internalType: "bytes32", 416 | name: "blockHash", 417 | type: "bytes32", 418 | }, 419 | { 420 | components: [ 421 | { 422 | internalType: "bool", 423 | name: "success", 424 | type: "bool", 425 | }, 426 | { 427 | internalType: "bytes", 428 | name: "returnData", 429 | type: "bytes", 430 | }, 431 | ], 432 | internalType: "struct Multicall3.Result[]", 433 | name: "returnData", 434 | type: "tuple[]", 435 | }, 436 | ], 437 | stateMutability: "payable", 438 | type: "function", 439 | }, 440 | ] as const; 441 | -------------------------------------------------------------------------------- /src/abi/TreasuryManagerFactory.ts: -------------------------------------------------------------------------------- 1 | export const TreasuryManagerFactoryAbi = [ 2 | { 3 | type: "constructor", 4 | inputs: [ 5 | { 6 | name: "_protocolOwner", 7 | type: "address", 8 | internalType: "address", 9 | }, 10 | { name: "_feeEscrow", type: "address", internalType: "address" }, 11 | ], 12 | stateMutability: "nonpayable", 13 | }, 14 | { 15 | type: "function", 16 | name: "DEFAULT_ADMIN_ROLE", 17 | inputs: [], 18 | outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], 19 | stateMutability: "view", 20 | }, 21 | { 22 | type: "function", 23 | name: "approveManager", 24 | inputs: [ 25 | { 26 | name: "_managerImplementation", 27 | type: "address", 28 | internalType: "address", 29 | }, 30 | ], 31 | outputs: [], 32 | stateMutability: "nonpayable", 33 | }, 34 | { 35 | type: "function", 36 | name: "approvedManagerImplementation", 37 | inputs: [ 38 | { 39 | name: "_managerImplementation", 40 | type: "address", 41 | internalType: "address", 42 | }, 43 | ], 44 | outputs: [{ name: "_approved", type: "bool", internalType: "bool" }], 45 | stateMutability: "view", 46 | }, 47 | { 48 | type: "function", 49 | name: "cancelOwnershipHandover", 50 | inputs: [], 51 | outputs: [], 52 | stateMutability: "payable", 53 | }, 54 | { 55 | type: "function", 56 | name: "completeOwnershipHandover", 57 | inputs: [ 58 | { name: "pendingOwner", type: "address", internalType: "address" }, 59 | ], 60 | outputs: [], 61 | stateMutability: "payable", 62 | }, 63 | { 64 | type: "function", 65 | name: "deployAndInitializeManager", 66 | inputs: [ 67 | { 68 | name: "_managerImplementation", 69 | type: "address", 70 | internalType: "address", 71 | }, 72 | { name: "_owner", type: "address", internalType: "address" }, 73 | { name: "_data", type: "bytes", internalType: "bytes" }, 74 | ], 75 | outputs: [ 76 | { 77 | name: "manager_", 78 | type: "address", 79 | internalType: "address payable", 80 | }, 81 | ], 82 | stateMutability: "nonpayable", 83 | }, 84 | { 85 | type: "function", 86 | name: "deployManager", 87 | inputs: [ 88 | { 89 | name: "_managerImplementation", 90 | type: "address", 91 | internalType: "address", 92 | }, 93 | ], 94 | outputs: [ 95 | { 96 | name: "manager_", 97 | type: "address", 98 | internalType: "address payable", 99 | }, 100 | ], 101 | stateMutability: "nonpayable", 102 | }, 103 | { 104 | type: "function", 105 | name: "feeEscrow", 106 | inputs: [], 107 | outputs: [ 108 | { name: "", type: "address", internalType: "contract IFeeEscrow" }, 109 | ], 110 | stateMutability: "view", 111 | }, 112 | { 113 | type: "function", 114 | name: "getRoleAdmin", 115 | inputs: [{ name: "role", type: "bytes32", internalType: "bytes32" }], 116 | outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], 117 | stateMutability: "view", 118 | }, 119 | { 120 | type: "function", 121 | name: "grantRole", 122 | inputs: [ 123 | { name: "role", type: "bytes32", internalType: "bytes32" }, 124 | { name: "account", type: "address", internalType: "address" }, 125 | ], 126 | outputs: [], 127 | stateMutability: "nonpayable", 128 | }, 129 | { 130 | type: "function", 131 | name: "hasRole", 132 | inputs: [ 133 | { name: "role", type: "bytes32", internalType: "bytes32" }, 134 | { name: "account", type: "address", internalType: "address" }, 135 | ], 136 | outputs: [{ name: "", type: "bool", internalType: "bool" }], 137 | stateMutability: "view", 138 | }, 139 | { 140 | type: "function", 141 | name: "managerImplementation", 142 | inputs: [{ name: "_manager", type: "address", internalType: "address" }], 143 | outputs: [ 144 | { 145 | name: "_managerImplementation", 146 | type: "address", 147 | internalType: "address", 148 | }, 149 | ], 150 | stateMutability: "view", 151 | }, 152 | { 153 | type: "function", 154 | name: "owner", 155 | inputs: [], 156 | outputs: [{ name: "result", type: "address", internalType: "address" }], 157 | stateMutability: "view", 158 | }, 159 | { 160 | type: "function", 161 | name: "ownershipHandoverExpiresAt", 162 | inputs: [ 163 | { name: "pendingOwner", type: "address", internalType: "address" }, 164 | ], 165 | outputs: [{ name: "result", type: "uint256", internalType: "uint256" }], 166 | stateMutability: "view", 167 | }, 168 | { 169 | type: "function", 170 | name: "renounceOwnership", 171 | inputs: [], 172 | outputs: [], 173 | stateMutability: "payable", 174 | }, 175 | { 176 | type: "function", 177 | name: "renounceRole", 178 | inputs: [ 179 | { name: "role", type: "bytes32", internalType: "bytes32" }, 180 | { 181 | name: "callerConfirmation", 182 | type: "address", 183 | internalType: "address", 184 | }, 185 | ], 186 | outputs: [], 187 | stateMutability: "nonpayable", 188 | }, 189 | { 190 | type: "function", 191 | name: "requestOwnershipHandover", 192 | inputs: [], 193 | outputs: [], 194 | stateMutability: "payable", 195 | }, 196 | { 197 | type: "function", 198 | name: "revokeRole", 199 | inputs: [ 200 | { name: "role", type: "bytes32", internalType: "bytes32" }, 201 | { name: "account", type: "address", internalType: "address" }, 202 | ], 203 | outputs: [], 204 | stateMutability: "nonpayable", 205 | }, 206 | { 207 | type: "function", 208 | name: "supportsInterface", 209 | inputs: [{ name: "interfaceId", type: "bytes4", internalType: "bytes4" }], 210 | outputs: [{ name: "", type: "bool", internalType: "bool" }], 211 | stateMutability: "view", 212 | }, 213 | { 214 | type: "function", 215 | name: "transferOwnership", 216 | inputs: [{ name: "newOwner", type: "address", internalType: "address" }], 217 | outputs: [], 218 | stateMutability: "payable", 219 | }, 220 | { 221 | type: "function", 222 | name: "unapproveManager", 223 | inputs: [ 224 | { 225 | name: "_managerImplementation", 226 | type: "address", 227 | internalType: "address", 228 | }, 229 | ], 230 | outputs: [], 231 | stateMutability: "nonpayable", 232 | }, 233 | { 234 | type: "event", 235 | name: "ManagerDeployed", 236 | inputs: [ 237 | { 238 | name: "_manager", 239 | type: "address", 240 | indexed: true, 241 | internalType: "address", 242 | }, 243 | { 244 | name: "_managerImplementation", 245 | type: "address", 246 | indexed: true, 247 | internalType: "address", 248 | }, 249 | ], 250 | anonymous: false, 251 | }, 252 | { 253 | type: "event", 254 | name: "ManagerImplementationApproved", 255 | inputs: [ 256 | { 257 | name: "_managerImplementation", 258 | type: "address", 259 | indexed: true, 260 | internalType: "address", 261 | }, 262 | ], 263 | anonymous: false, 264 | }, 265 | { 266 | type: "event", 267 | name: "ManagerImplementationUnapproved", 268 | inputs: [ 269 | { 270 | name: "_managerImplementation", 271 | type: "address", 272 | indexed: true, 273 | internalType: "address", 274 | }, 275 | ], 276 | anonymous: false, 277 | }, 278 | { 279 | type: "event", 280 | name: "OwnershipHandoverCanceled", 281 | inputs: [ 282 | { 283 | name: "pendingOwner", 284 | type: "address", 285 | indexed: true, 286 | internalType: "address", 287 | }, 288 | ], 289 | anonymous: false, 290 | }, 291 | { 292 | type: "event", 293 | name: "OwnershipHandoverRequested", 294 | inputs: [ 295 | { 296 | name: "pendingOwner", 297 | type: "address", 298 | indexed: true, 299 | internalType: "address", 300 | }, 301 | ], 302 | anonymous: false, 303 | }, 304 | { 305 | type: "event", 306 | name: "OwnershipTransferred", 307 | inputs: [ 308 | { 309 | name: "oldOwner", 310 | type: "address", 311 | indexed: true, 312 | internalType: "address", 313 | }, 314 | { 315 | name: "newOwner", 316 | type: "address", 317 | indexed: true, 318 | internalType: "address", 319 | }, 320 | ], 321 | anonymous: false, 322 | }, 323 | { 324 | type: "event", 325 | name: "RoleAdminChanged", 326 | inputs: [ 327 | { 328 | name: "role", 329 | type: "bytes32", 330 | indexed: true, 331 | internalType: "bytes32", 332 | }, 333 | { 334 | name: "previousAdminRole", 335 | type: "bytes32", 336 | indexed: true, 337 | internalType: "bytes32", 338 | }, 339 | { 340 | name: "newAdminRole", 341 | type: "bytes32", 342 | indexed: true, 343 | internalType: "bytes32", 344 | }, 345 | ], 346 | anonymous: false, 347 | }, 348 | { 349 | type: "event", 350 | name: "RoleGranted", 351 | inputs: [ 352 | { 353 | name: "role", 354 | type: "bytes32", 355 | indexed: true, 356 | internalType: "bytes32", 357 | }, 358 | { 359 | name: "account", 360 | type: "address", 361 | indexed: true, 362 | internalType: "address", 363 | }, 364 | { 365 | name: "sender", 366 | type: "address", 367 | indexed: true, 368 | internalType: "address", 369 | }, 370 | ], 371 | anonymous: false, 372 | }, 373 | { 374 | type: "event", 375 | name: "RoleRevoked", 376 | inputs: [ 377 | { 378 | name: "role", 379 | type: "bytes32", 380 | indexed: true, 381 | internalType: "bytes32", 382 | }, 383 | { 384 | name: "account", 385 | type: "address", 386 | indexed: true, 387 | internalType: "address", 388 | }, 389 | { 390 | name: "sender", 391 | type: "address", 392 | indexed: true, 393 | internalType: "address", 394 | }, 395 | ], 396 | anonymous: false, 397 | }, 398 | { type: "error", name: "AccessControlBadConfirmation", inputs: [] }, 399 | { 400 | type: "error", 401 | name: "AccessControlUnauthorizedAccount", 402 | inputs: [ 403 | { name: "account", type: "address", internalType: "address" }, 404 | { name: "neededRole", type: "bytes32", internalType: "bytes32" }, 405 | ], 406 | }, 407 | { type: "error", name: "AlreadyInitialized", inputs: [] }, 408 | { type: "error", name: "NewOwnerIsZeroAddress", inputs: [] }, 409 | { type: "error", name: "NoHandoverRequest", inputs: [] }, 410 | { type: "error", name: "Unauthorized", inputs: [] }, 411 | { type: "error", name: "UnknownManagerImplemention", inputs: [] }, 412 | ] as const; 413 | --------------------------------------------------------------------------------