diff --git a/examples/admin/init-secondary-market.ts b/examples/admin/init-secondary-market.ts index e10d496..ab471bf 100644 --- a/examples/admin/init-secondary-market.ts +++ b/examples/admin/init-secondary-market.ts @@ -40,6 +40,7 @@ export const initSecondaryMarketExample = async ({ transaction }: { transaction? ...initSecondaryMarketData, lpCoinTreasureCapId: lpCoinData.lpCoin.treasureCapId, lpCoinType: lpCoinData.lpCoin.coinType, + lpMeta: lpCoinData.lpCoin.metadataObjectId, }; console.debug("initSecondaryParams: ", initSecondaryParams); diff --git a/examples/bonding-curve/create/create-coins-and-create-bonding-curve-granural-version.ts b/examples/bonding-curve/create/create-coins-and-create-bonding-curve-granural-version.ts deleted file mode 100644 index beb8ed2..0000000 --- a/examples/bonding-curve/create/create-coins-and-create-bonding-curve-granural-version.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable max-len */ -import { CreateCoinTransactionParams } from "../../../src"; -import { BondingPoolSingleton } from "../../../src/bonding-pool/BondingPool"; -import { getTicketDataFromCoinParams } from "../../../src/bonding-pool/utils/getTicketDataFromCoinParams"; -import { parseTransactionDataCoinAndTicketCreation } from "../../../src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation"; -import { CoinManagerSingleton } from "../../../src/coin/CoinManager"; -import { LONG_SUI_COIN_TYPE } from "../../../src/common/sui"; -import { keypair, provider, user } from "../../common"; -import { sleep } from "../../utils/sleep"; - -// yarn tsx examples/bonding-curve/create/create-coins-and-create-bonding-curve-granural-version.ts -export const createCoinsForBondingCurve = async (params: CreateCoinTransactionParams) => { - // Create Coin - const coinTx = await CoinManagerSingleton.getCreateCoinTransaction(params); - // Create Ticket for Coin - const ticketFromParams = getTicketDataFromCoinParams(params); - const ticketCoinTx = await CoinManagerSingleton.getCreateCoinTransaction({ - ...ticketFromParams, - transaction: coinTx, - }); - - const res = await provider.signAndExecuteTransactionBlock({ - transactionBlock: ticketCoinTx, - signer: keypair, - requestType: "WaitForLocalExecution", - options: { - showBalanceChanges: true, - showEffects: true, - showEvents: true, - showObjectChanges: true, - showInput: true, - }, - }); - - const { memeCoin, ticketCoin } = parseTransactionDataCoinAndTicketCreation(res.objectChanges); - - const createBondingCurvePoolTx = BondingPoolSingleton.createBondingCurvePoolWithDefaultParams( - { - registry: BondingPoolSingleton.REGISTRY_OBJECT_ID, - memeCoinCap: memeCoin.treasureCapId, - memeCoinMetadata: memeCoin.metadataObjectId, - ticketCoinCap: ticketCoin.treasureCapId, - ticketCoinMetadata: ticketCoin.metadataObjectId, - }, - [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], - ); - - await sleep(7000); - - const res2 = await provider.signAndExecuteTransactionBlock({ - transactionBlock: createBondingCurvePoolTx.tx, - signer: keypair, - requestType: "WaitForLocalExecution", - options: { - showBalanceChanges: true, - showEffects: true, - showEvents: true, - showObjectChanges: true, - showInput: true, - }, - }); - - console.debug("res2: ", res2); -}; - -createCoinsForBondingCurve({ - decimals: "6", - description: "testtoken4am description", - fixedSupply: false, - mintAmount: "0", - name: "testtoken4am", - signerAddress: user, - symbol: "TEST_TOKEN_4am", - url: "", -}); diff --git a/examples/bonding-curve/create/create-coins-and-create-bonding-curve.ts b/examples/bonding-curve/create/create-coins-and-create-bonding-curve.ts deleted file mode 100644 index d26458b..0000000 --- a/examples/bonding-curve/create/create-coins-and-create-bonding-curve.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable max-len */ -import { BondingPoolSingleton } from "../../../src/bonding-pool/BondingPool"; -import { CreateCoinTransactionParamsWithoutCertainProps } from "../../../src/bonding-pool/types"; -import { parseTransactionDataCoinAndTicketCreation } from "../../../src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation"; -import { keypair, provider, user } from "../../common"; -import { sleep } from "../../utils/sleep"; - -// yarn tsx examples/bonding-curve/create/create-coins-and-create-bonding-curve.ts -export const createCoinsForBondingCurve = async (params: CreateCoinTransactionParamsWithoutCertainProps) => { - const memeAndTicketCoinTx = await BondingPoolSingleton.createMemeAndTicketCoins(params); - - const res = await provider.signAndExecuteTransactionBlock({ - transactionBlock: memeAndTicketCoinTx, - signer: keypair, - requestType: "WaitForLocalExecution", - options: { - showBalanceChanges: true, - showEffects: true, - showEvents: true, - showObjectChanges: true, - showInput: true, - }, - }); - - console.debug("tx coin res: ", res); - const { memeCoin, ticketCoin } = parseTransactionDataCoinAndTicketCreation(res.objectChanges); - const createBondingCurvePoolTx = BondingPoolSingleton.createBondingCurvePool({ memeCoin, ticketCoin }); - await sleep(7000); - - const res2 = await provider.signAndExecuteTransactionBlock({ - transactionBlock: createBondingCurvePoolTx.tx, - signer: keypair, - requestType: "WaitForLocalExecution", - options: { - showBalanceChanges: true, - showEffects: true, - showEvents: true, - showObjectChanges: true, - showInput: true, - }, - }); - - console.debug("res2: ", res2); - return res; -}; - -createCoinsForBondingCurve({ - description: "testtoken4am description", - name: "testtoken4am", - signerAddress: user, - symbol: "TEST_TOKEN_4am", - url: "", -}); diff --git a/examples/bonding-curve/create/create-coins-and-create-custom-params-bonding-curve.ts b/examples/bonding-curve/create/create-coins-and-create-custom-params-bonding-curve.ts index 14b0f88..88697d9 100644 --- a/examples/bonding-curve/create/create-coins-and-create-custom-params-bonding-curve.ts +++ b/examples/bonding-curve/create/create-coins-and-create-custom-params-bonding-curve.ts @@ -7,7 +7,7 @@ import { sleep } from "../../utils/sleep"; // yarn tsx examples/bonding-curve/create/create-coins-and-create-custom-params-bonding-curve.ts export const createCustomBondingCurveAndCoins = async (params: CreateCoinTransactionParamsWithoutCertainProps) => { - const memeAndTicketCoinTx = await BondingPoolSingleton.createMemeAndTicketCoins(params); + const memeAndTicketCoinTx = await BondingPoolSingleton.createMemeCoin(params); const res = await provider.signAndExecuteTransactionBlock({ transactionBlock: memeAndTicketCoinTx, @@ -23,7 +23,10 @@ export const createCustomBondingCurveAndCoins = async (params: CreateCoinTransac }); console.debug("create coin tx res: ", res); - const { memeCoin, ticketCoin } = parseTransactionDataCoinAndTicketCreation(res.objectChanges); + const { memeCoin } = parseTransactionDataCoinAndTicketCreation(res.objectChanges); + + console.debug("memeCoin: ", memeCoin); + // 10 sui const THRESHOLD_FOR_GOING_LIVE_IN_SUI = BigInt(10); // 5 minutes @@ -37,7 +40,6 @@ export const createCustomBondingCurveAndCoins = async (params: CreateCoinTransac const createBondingCurvePoolTx = BondingPoolSingleton.createBondingCurvePool({ memeCoin, - ticketCoin, bondingCurveCustomParams: bondingCurveCustomParams, }); @@ -65,9 +67,9 @@ export const createCustomBondingCurveAndCoins = async (params: CreateCoinTransac }; createCustomBondingCurveAndCoins({ - description: "26 April 2024", - name: "meme262024", + description: "01 May 2024", + name: "meme01052024", signerAddress: user, - symbol: "MEME_26_2024", + symbol: "MEME_01_05_2024", url: "", }); diff --git a/examples/bonding-curve/create/create-meme-and-ticket-coins-tx.ts b/examples/bonding-curve/create/create-meme-and-ticket-coins-tx.ts deleted file mode 100644 index 51838d6..0000000 --- a/examples/bonding-curve/create/create-meme-and-ticket-coins-tx.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable max-len */ -import { CreateCoinTransactionParams } from "../../../src"; -import { BondingPoolSingleton } from "../../../src/bonding-pool/BondingPool"; -import { getTicketDataFromCoinParams } from "../../../src/bonding-pool/utils/getTicketDataFromCoinParams"; -import { parseTransactionDataCoinAndTicketCreation } from "../../../src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation"; -import { CoinManagerSingleton } from "../../../src/coin/CoinManager"; -import { LONG_SUI_COIN_TYPE } from "../../../src/common/sui"; -import { keypair, provider, user } from "../../common"; -import { sleep } from "../../utils/sleep"; - -// yarn tsx examples/bonding-curve/create/create-meme-and-ticket-coins-tx.ts -export const createMemeAndTicketCoinsTxExample = async (params: CreateCoinTransactionParams) => { - // Create Coin - const coinTx = await CoinManagerSingleton.getCreateCoinTransaction(params); - // Create Ticket for Coin - const ticketFromParams = getTicketDataFromCoinParams(params); - const ticketCoinTx = await CoinManagerSingleton.getCreateCoinTransaction({ - ...ticketFromParams, - transaction: coinTx, - }); - - const res = await provider.devInspectTransactionBlock({ - transactionBlock: ticketCoinTx, - sender: user, - }); - - // const res = await provider.signAndExecuteTransactionBlock({ - // transactionBlock: ticketCoinTx, - // signer: keypair, - // requestType: "WaitForLocalExecution", - // options: { - // showBalanceChanges: true, - // showEffects: true, - // showEvents: true, - // showObjectChanges: true, - // showInput: true, - // }, - // }); - - console.debug("res: ", res); -}; - -createMemeAndTicketCoinsTxExample({ - decimals: "6", - description: "super awesome description", - fixedSupply: false, - mintAmount: "0", - name: "superawesome", - signerAddress: user, - symbol: "SUPER_AWESOME", - url: "", -}); diff --git a/examples/bonding-curve/extract-registry-key-data.ts b/examples/bonding-curve/extract-registry-key-data.ts index 074bc0b..89ae3f5 100644 --- a/examples/bonding-curve/extract-registry-key-data.ts +++ b/examples/bonding-curve/extract-registry-key-data.ts @@ -4,7 +4,7 @@ import { extractRegistryKeyData } from "../../src/bonding-pool/utils/extractRegi export const extractRegistryKeyDataExample = () => { const registryKeyTypenameData = // eslint-disable-next-line max-len - "9e1701ec8d7942a79874a40d4d5c9d94c45ffd141c9cd2cff4f4fc3820329b61::index::RegistryKey"; + "a06a92a380b04366b5bf54587b89c0d04772e48170ea3c3d0647dac85be038d9::index::RegistryKey<0000000000000000000000000000000000000000000000000000000000000002::sui::SUI,6b98a3246b0e269466f36e7f22dc3a5e856afade41c00a0be7046c762aaf8787::meme_01_05_2024::MEME_01_05_2024>"; const data = extractRegistryKeyData(registryKeyTypenameData); diff --git a/examples/bonding-curve/get-pool-detailed-info.ts b/examples/bonding-curve/get-pool-detailed-info.ts new file mode 100644 index 0000000..7d1f9c5 --- /dev/null +++ b/examples/bonding-curve/get-pool-detailed-info.ts @@ -0,0 +1,14 @@ +import { suiProviderUrl } from "../common"; +import { BondingPoolSingleton } from "../../src"; + +// yarn tsx examples/bonding-curve/get-pool-detailed-info.ts +export const getPoolDetailedInfo = async () => { + const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); + const allPools = await bondingCurveInstance.getAllPools(); + const pool = allPools.pools[0]; + + const res = await bondingCurveInstance.getPoolDetailedInfo({ poolId: pool.objectId }); + console.debug("res: ", res); +}; + +getPoolDetailedInfo(); diff --git a/examples/bonding-curve/get-token-policy-cap-by-pool-id.ts b/examples/bonding-curve/get-token-policy-cap-by-pool-id.ts deleted file mode 100644 index b91d692..0000000 --- a/examples/bonding-curve/get-token-policy-cap-by-pool-id.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { suiProviderUrl } from "../common"; -import { BondingPoolSingleton } from "../../src"; - -// yarn tsx examples/bonding-curve/get-token-policy-cap-by-pool-id.ts -export const getTokenPolicyCapByPoolIdExample = async () => { - const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); - - const { poolIds } = await bondingCurveInstance.getAllPools(); - const [poolId] = poolIds; - - console.debug("poolId: ", poolId); - - const res = await bondingCurveInstance.getTokenPolicyCapByPoolId({ poolId }); - console.debug("res: ", res); -}; - -getTokenPolicyCapByPoolIdExample(); diff --git a/examples/bonding-curve/is-memecoin-ready-to-live-phase.ts b/examples/bonding-curve/is-memecoin-ready-to-live-phase.ts index 4daad63..24744ec 100644 --- a/examples/bonding-curve/is-memecoin-ready-to-live-phase.ts +++ b/examples/bonding-curve/is-memecoin-ready-to-live-phase.ts @@ -8,11 +8,12 @@ export const isMemecoinReadyToLivePhase = async () => { const { pools } = await bondingCurveInstance.getAllPools(); const [pool] = pools; + console.debug("allPools: ", pools); console.debug("poolId: ", pool.objectId); + console.debug("pool: ", pool); const res = await bondingCurveInstance.isMemeCoinReadyToLivePhase({ memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, poolId: pool.objectId, }); console.debug("res: ", res); diff --git a/examples/bonding-curve/trading/get-swap-output-amount-for-sui-input.ts b/examples/bonding-curve/trading/get-swap-output-amount-for-sui-input.ts index cdaacc6..8fa104e 100644 --- a/examples/bonding-curve/trading/get-swap-output-amount-for-sui-input.ts +++ b/examples/bonding-curve/trading/get-swap-output-amount-for-sui-input.ts @@ -5,18 +5,17 @@ import { BondingPoolSingleton } from "../../../src"; export const getSwapOutputAmountByPoolExample = async () => { const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); const { pools } = await bondingCurveInstance.getAllPools(); - const pool = pools[1]; + const pool = pools[0]; console.debug("pool: ", pool); - const inputAmount = "950"; + const inputAmount = "951"; // const inputAmount = "30000"; const res = await bondingCurveInstance.getSwapOutputAmountForSuiInput({ bondingCurvePoolObjectId: pool.objectId, inputAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, // slippagePercentage: 1, }); console.debug("res: ", res); diff --git a/examples/bonding-curve/trading/get-swap-output-amount-for-ticket-input.ts b/examples/bonding-curve/trading/get-swap-output-amount-for-ticket-input.ts index 9413f6a..eee5f7d 100644 --- a/examples/bonding-curve/trading/get-swap-output-amount-for-ticket-input.ts +++ b/examples/bonding-curve/trading/get-swap-output-amount-for-ticket-input.ts @@ -5,7 +5,7 @@ import { BondingPoolSingleton } from "../../../src"; export const getSwapOutputAmountByPoolExample = async () => { const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); const { pools } = await bondingCurveInstance.getAllPools(); - const pool = pools[1]; + const pool = pools[0]; console.debug("pool: ", pool); @@ -15,7 +15,6 @@ export const getSwapOutputAmountByPoolExample = async () => { bondingCurvePoolObjectId: pool.objectId, inputTicketAmount: inputAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, // slippagePercentage: 1, }); console.debug("res: ", res); diff --git a/examples/bonding-curve/trading/swap-sui-for-ticket.ts b/examples/bonding-curve/trading/swap-sui-for-ticket.ts index 1482187..c5bcf84 100644 --- a/examples/bonding-curve/trading/swap-sui-for-ticket.ts +++ b/examples/bonding-curve/trading/swap-sui-for-ticket.ts @@ -6,18 +6,17 @@ export const swapSuiForTicketExample = async () => { const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); // get all pools - const { pools, poolsByMemeCoinTypeMap, poolsByTicketCoinTypeMap } = await bondingCurveInstance.getAllPools(); + const { pools, poolsByMemeCoinTypeMap } = await bondingCurveInstance.getAllPools(); // get random pool - const pool = pools[1]; - const inputAmount = "0.077"; + const pool = pools[0]; + const inputAmount = "0.2"; // const inputAmount = "30000"; const outputAmount = await bondingCurveInstance.getSwapOutputAmountForSuiInput({ bondingCurvePoolObjectId: pool.objectId, inputAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, slippagePercentage: 0, }); @@ -27,9 +26,9 @@ export const swapSuiForTicketExample = async () => { bondingCurvePoolObjectId: pool.objectId, inputAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, minOutputTicketAmount: outputAmount, signerAddress: user, + slippagePercentage: 0, }); console.debug("swapTxData.tx: ", swapTxData.tx); diff --git a/examples/bonding-curve/trading/swap-ticket-for-sui.ts b/examples/bonding-curve/trading/swap-ticket-for-sui.ts index 1c37766..22a94f5 100644 --- a/examples/bonding-curve/trading/swap-ticket-for-sui.ts +++ b/examples/bonding-curve/trading/swap-ticket-for-sui.ts @@ -6,13 +6,13 @@ export const swapTicketForSuiExample = async () => { const bondingCurveInstance = BondingPoolSingleton.getInstance(suiProviderUrl); // get all pools - const { pools, poolsByMemeCoinTypeMap, poolsByTicketCoinTypeMap } = await bondingCurveInstance.getAllPools(); + const { pools, poolsByMemeCoinTypeMap } = await bondingCurveInstance.getAllPools(); // get random pool - const ticketCoinType = - "0xbab599a35e42232bb8af53d7c2dc747d186fe5720b7c06306c22055d44da3dce::ticket_meme_26_2024::TICKET_MEME_26_2024"; - const pool = poolsByTicketCoinTypeMap[ticketCoinType]; - const inputTicketAmount = "10672466"; + const memeCoinType = + "0x6b98a3246b0e269466f36e7f22dc3a5e856afade41c00a0be7046c762aaf8787::meme_01_05_2024::MEME_01_05_2024"; + const pool = poolsByMemeCoinTypeMap[memeCoinType]; + const inputTicketAmount = "9551313"; console.debug("pool: ", pool); @@ -20,8 +20,7 @@ export const swapTicketForSuiExample = async () => { bondingCurvePoolObjectId: pool.objectId, inputTicketAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, - slippagePercentage: 10, + slippagePercentage: 0, }); console.debug("outputAmount: ", outputAmount); @@ -30,10 +29,9 @@ export const swapTicketForSuiExample = async () => { bondingCurvePoolObjectId: pool.objectId, inputTicketAmount, memeCoin: { coinType: pool.memeCoinType }, - ticketCoin: { coinType: pool.ticketCoinType }, minOutputSuiAmount: outputAmount, signerAddress: user, - slippagePercentage: 10, + slippagePercentage: 0, }); // console.debug("swapTxData.tx: ", swapTxData.tx); diff --git a/examples/create-coin/create-coin-and-ticket.ts b/examples/create-coin/create-coin-and-ticket.ts index 9768106..847f01b 100644 --- a/examples/create-coin/create-coin-and-ticket.ts +++ b/examples/create-coin/create-coin-and-ticket.ts @@ -2,7 +2,7 @@ import { BondingPoolSingleton, CreateCoinTransactionParams } from "../../src"; import { keypair, provider } from "../common"; export const createCoinAndTicket = async (params: CreateCoinTransactionParams) => { - const memeAndTicketCoinTx = await BondingPoolSingleton.createMemeAndTicketCoins(params); + const memeAndTicketCoinTx = await BondingPoolSingleton.createMemeCoin(params); const res = await provider.signAndExecuteTransactionBlock({ transactionBlock: memeAndTicketCoinTx, diff --git a/package.json b/package.json index 9f4fe84..cef7772 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@avernikoz/memechan-ts-sdk", - "version": "1.1.5", + "version": "1.1.6", "description": "Typescript SDK for Memechan.gg", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -34,7 +34,7 @@ "registry": "https://registry.npmjs.org" }, "dependencies": { - "@avernikoz/memechan-ts-interface": "^1.0.17", + "@avernikoz/memechan-ts-interface": "^1.0.18", "@aws-crypto/sha256-browser": "^5.2.0", "@interest-protocol/clamm-sdk": "3.2.0-alpha", "@mysten/sui.js": "^0.51.2", diff --git a/src/bonding-pool/BondingPool.ts b/src/bonding-pool/BondingPool.ts index d784a4d..4760191 100644 --- a/src/bonding-pool/BondingPool.ts +++ b/src/bonding-pool/BondingPool.ts @@ -6,16 +6,16 @@ import { isReadyToLaunch, newDefault, new_, + quoteBuyMeme, quoteSellMeme, sellMeme, } from "@avernikoz/memechan-ts-interface/dist/memechan/seed-pool/functions"; -import { split, join, intoToken } from "@avernikoz/memechan-ts-interface/dist/memechan/staked-lp/functions"; +import { intoToken, join, split } from "@avernikoz/memechan-ts-interface/dist/memechan/staked-lp/functions"; import { SuiClient } from "@mysten/sui.js/client"; import { TransactionArgument, TransactionBlock } from "@mysten/sui.js/transactions"; import { seedPools } from "@avernikoz/memechan-ts-interface/dist/memechan/index/functions"; -import { StakedLP } from "@avernikoz/memechan-ts-interface/dist/memechan/staked-lp/structs"; import { goLiveDefault } from "@avernikoz/memechan-ts-interface/dist/memechan/go-live/functions"; import { bcs } from "@mysten/sui.js/bcs"; @@ -28,6 +28,7 @@ import { BondingCurveCustomParams, CreateBondingCurvePoolParams, CreateCoinTransactionParamsWithoutCertainProps, + DetailedPoolInfo, ExtractedRegistryKeyData, GetBondingCurveCustomParams, StakedLpObject, @@ -42,10 +43,9 @@ import { extractRegistryKeyData } from "./utils/extractRegistryKeyData"; import { getAllDynamicFields } from "./utils/getAllDynamicFields"; import { getAllObjects } from "./utils/getAllObjects"; import { getAllOwnedObjects } from "./utils/getAllOwnedObjects"; -import { getTicketDataFromCoinParams } from "./utils/getTicketDataFromCoinParams"; +import { isPoolDetailedInfo } from "./utils/isPoolDetailedInfo"; import { isPoolObjectData } from "./utils/isPoolObjectData"; import { isStakedLpObjectDataList } from "./utils/isStakedLpObjectData"; -import { isTokenPolicyCapObjectData } from "./utils/isTokenPolicyCapObjectData"; import { normalizeInputCoinAmount } from "./utils/normalizeInputCoinAmount"; import { isRegistryTableTypenameDynamicFields } from "./utils/registryTableTypenameUtils"; @@ -57,16 +57,14 @@ import { isRegistryTableTypenameDynamicFields } from "./utils/registryTableTypen export class BondingPoolSingleton { private static _instance: BondingPoolSingleton; public static TX_OF_CONTRACT_DEPLOY = - "https://suivision.xyz/txblock/7vwqjLH2QZXiDyUYBT8haL1YT5k5PtCiWfpsBiLjw4C9?tab=Changes"; + "https://suivision.xyz/txblock/4exX4n9sNeTWwCcb9yFzd415E1Zf21CfKRr2eqQRrNgv?tab=Changes"; - public static TX_OF_TICKET_BUY = - "https://suivision.xyz/txblock/Gz6vfDgeE9tErU2iUJ9Yh1NitDkKZC2CzM17sgu9PkT7?tab=Changes"; public static SUI_METADATA_OBJECT_ID = "0x9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3"; - public static PACKAGE_OBJECT_ID = "0x1a0c65c5850f32caf3b8bc1973837c830e1159b566b3684ace43e37c59868974"; - public static UPGRADE_CAP_OBJECT_ID = "0x80cad8ae4b6ecf68bb6d699f7710b43b941a7fb0f1ac7c476e2087d188b1448b"; - public static REGISTRY_OBJECT_ID = "0xdce76690fe5d10fa91c8ad1fa37896c7cdc370c71d27620cb48bc315f4a255af"; - public static ADMIN_OBJECT_ID = "0xf5399ac8c3ce69f423e841c6b14e3f3c4bcab45405151b1614721e189fda527d"; + public static PACKAGE_OBJECT_ID = "0xa06a92a380b04366b5bf54587b89c0d04772e48170ea3c3d0647dac85be038d9"; + public static UPGRADE_CAP_OBJECT_ID = "0xf5c67bd71a1d71e14505860407a8ce9e4bbbe5b879c05c16693c301aae9595c3"; + public static REGISTRY_OBJECT_ID = "0x71cf42c722f75314c7e9649c89b1a11e9e557242b713a0b619bdda13dfb5ac6b"; + public static ADMIN_OBJECT_ID = "0x6bb56f9b2d15eb26f1ada8b40136bbef755dc735cbb5b994b566e96db2ec3596"; // TODO: Move that to StakingPool public static STAKING_MODULE_NAME = "staked_lp"; public static STAKING_LP_STRUCT_TYPE = "StakedLP"; @@ -134,7 +132,7 @@ export class BondingPoolSingleton { public static createBondingCurvePoolWithDefaultParams( args: NewDefaultArgs, - typeArgs: [string, string, string], + typeArgs: [string, string], transaction?: TransactionBlock, ) { const tx = new TransactionBlock() ?? transaction; @@ -145,7 +143,7 @@ export class BondingPoolSingleton { public static createBondingCurvePoolWithCustomParams( args: NewArgs, - typeArgs: [string, string, string], + typeArgs: [string, string], transaction?: TransactionBlock, ) { const tx = new TransactionBlock() ?? transaction; @@ -175,7 +173,7 @@ export class BondingPoolSingleton { } public static createBondingCurvePool(params: CreateBondingCurvePoolParams) { - const { memeCoin, ticketCoin, transaction, bondingCurveCustomParams } = params; + const { memeCoin, transaction, bondingCurveCustomParams } = params; const tx = transaction ?? new TransactionBlock(); if (bondingCurveCustomParams) { @@ -183,12 +181,9 @@ export class BondingPoolSingleton { { registry: BondingPoolSingleton.REGISTRY_OBJECT_ID, memeCoinCap: memeCoin.treasureCapId, - memeCoinMetadata: memeCoin.metadataObjectId, - ticketCoinCap: ticketCoin.treasureCapId, - ticketCoinMetadata: ticketCoin.metadataObjectId, ...bondingCurveCustomParams, }, - [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], + [LONG_SUI_COIN_TYPE, memeCoin.coinType], tx, ); @@ -198,18 +193,15 @@ export class BondingPoolSingleton { { registry: BondingPoolSingleton.REGISTRY_OBJECT_ID, memeCoinCap: memeCoin.treasureCapId, - memeCoinMetadata: memeCoin.metadataObjectId, - ticketCoinCap: ticketCoin.treasureCapId, - ticketCoinMetadata: ticketCoin.metadataObjectId, }, - [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], + [LONG_SUI_COIN_TYPE, memeCoin.coinType], tx, ); return createBondingCurvePoolTx; } } - public static async createMemeAndTicketCoins(params: CreateCoinTransactionParamsWithoutCertainProps) { + public static async createMemeCoin(params: CreateCoinTransactionParamsWithoutCertainProps) { const tx = params.transaction ?? new TransactionBlock(); const coinCreationParams: CreateCoinTransactionParams = { @@ -223,15 +215,8 @@ export class BondingPoolSingleton { // Create Coin TransactionBlock const coinTx = await CoinManagerSingleton.getCreateCoinTransaction(coinCreationParams); - // Transform data for Ticket Coin - const ticketFromParams = getTicketDataFromCoinParams(coinCreationParams); - // Create Ticket Coin TransactionBlock - const memeAndTicketCoinTx = await CoinManagerSingleton.getCreateCoinTransaction({ - ...ticketFromParams, - transaction: coinTx, - }); - return memeAndTicketCoinTx; + return coinTx; } public async getAllStakedLPObjectsByOwner({ owner }: { owner: string }) { @@ -262,15 +247,15 @@ export class BondingPoolSingleton { .dividedBy(10 ** +BondingPoolSingleton.LP_COIN_DECIMALS) .toString(), untilTimestamp: +el.data.content.fields.until_timestamp, - ticketCoinType: extractCoinType(el.data.type), + memeCoinType: extractCoinType(el.data.type), })); - const stakedLpObjectsByTicketCoinTypeMap = stakedLpObjectList.reduce( + const stakedLpObjectsByMemeCoinTypeMap = stakedLpObjectList.reduce( (acc: { [ticketCoinType: string]: StakedLpObject[] }, el) => { - if (acc[el.ticketCoinType]) { - acc[el.ticketCoinType] = [...acc[el.ticketCoinType], el]; + if (acc[el.memeCoinType]) { + acc[el.memeCoinType] = [...acc[el.memeCoinType], el]; } else { - acc[el.ticketCoinType] = [el]; + acc[el.memeCoinType] = [el]; } return acc; @@ -278,7 +263,7 @@ export class BondingPoolSingleton { {}, ); - return { stakedLpObjectList, stakedLpObjectsByTicketCoinTypeMap }; + return { stakedLpObjectList, stakedLpObjectsByMemeCoinTypeMap }; } public async getAvailableStakedLpByOwner({ owner }: { owner: string }) { @@ -288,12 +273,12 @@ export class BondingPoolSingleton { (el) => currentTimestampMs > el.untilTimestamp, ); - const availableStakedLpObjectsByTicketCoinTypeMap = availableStakedLps.reduce( - (acc: { [ticketCoinType: string]: StakedLpObject[] }, el) => { - if (acc[el.ticketCoinType]) { - acc[el.ticketCoinType] = [...acc[el.ticketCoinType], el]; + const availableStakedLpObjectsByMemeCoinTypeMap = availableStakedLps.reduce( + (acc: { [memeCoinType: string]: StakedLpObject[] }, el) => { + if (acc[el.memeCoinType]) { + acc[el.memeCoinType] = [...acc[el.memeCoinType], el]; } else { - acc[el.ticketCoinType] = [el]; + acc[el.memeCoinType] = [el]; } return acc; @@ -301,20 +286,20 @@ export class BondingPoolSingleton { {}, ); - return { availableStakedLps, availableStakedLpObjectsByTicketCoinTypeMap }; + return { availableStakedLps, availableStakedLpObjectsByMemeCoinTypeMap }; } public async getAvailableAmountOfTicketsToSell({ owner, - ticketCoin, + memeCoin, }: { owner: string; - ticketCoin: { coinType: string }; + memeCoin: { coinType: string }; }) { - const { availableStakedLpObjectsByTicketCoinTypeMap } = await this.getAvailableStakedLpByOwner({ + const { availableStakedLpObjectsByMemeCoinTypeMap } = await this.getAvailableStakedLpByOwner({ owner, }); - const availableTickets = availableStakedLpObjectsByTicketCoinTypeMap[ticketCoin.coinType] ?? []; + const availableTickets = availableStakedLpObjectsByMemeCoinTypeMap[memeCoin.coinType] ?? []; const aggregatedAmount = availableTickets.reduce( (acc: BigNumber, el) => acc.plus(new BigNumber(el.balance)), @@ -328,20 +313,16 @@ export class BondingPoolSingleton { }; } - // TODO ASAP IMPORTANT: Issue? with 950 SUI Magic Number on simulation public async getSwapOutputAmountForSuiInput(params: SwapParamsForSuiInput) { - const { memeCoin, ticketCoin, transaction, bondingCurvePoolObjectId, inputAmount, slippagePercentage = 0 } = params; + const { memeCoin, transaction, bondingCurvePoolObjectId, inputAmount, slippagePercentage = 0 } = params; const tx = transaction ?? new TransactionBlock(); const inputAmountWithDecimals = normalizeInputCoinAmount(inputAmount, SUI_DECIMALS); - const suiCoinObject = tx.splitCoins(tx.gas, [inputAmountWithDecimals]); // Please note, mutation of `tx` happening below - buyMeme(tx, [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], { + quoteBuyMeme(tx, [LONG_SUI_COIN_TYPE, memeCoin.coinType], { + coinS: inputAmountWithDecimals, pool: bondingCurvePoolObjectId, - coinMMinValue: BigInt(1), - coinS: suiCoinObject, - clock: SUI_CLOCK_OBJECT_ID, }); const res = await this.provider.devInspectTransactionBlock({ @@ -353,16 +334,14 @@ export class BondingPoolSingleton { throw new Error("No results found for simulation of swap"); } - const returnValues = res.results[1].returnValues; + const returnValues = res.results[0].returnValues; if (!returnValues) { throw new Error("Return values are undefined"); } - // console.debug("returnValues"); - // console.dir(returnValues, { depth: null }); const rawAmountBytes = returnValues[0][0]; - const decoded = StakedLP.bcs.parse(new Uint8Array(rawAmountBytes)); - const outputRaw = decoded.balance.value; + const decoded = bcs.de("u64", new Uint8Array(rawAmountBytes)); + const outputRaw = decoded; const outputAmount = new BigNumber(outputRaw).div(10 ** parseInt(BondingPoolSingleton.MEMECOIN_DECIMALS)); const outputAmountRespectingSlippage = deductSlippage(outputAmount, slippagePercentage); @@ -378,14 +357,7 @@ export class BondingPoolSingleton { * That case should be handled on the client-side */ public async getSwapOutputAmountForTicketInput(params: SwapParamsForTicketInput) { - const { - bondingCurvePoolObjectId, - inputTicketAmount, - slippagePercentage = 0, - transaction, - memeCoin, - ticketCoin, - } = params; + const { bondingCurvePoolObjectId, inputTicketAmount, slippagePercentage = 0, transaction, memeCoin } = params; const tx = transaction ?? new TransactionBlock(); const inputAmountWithDecimals = normalizeInputCoinAmount( @@ -394,7 +366,7 @@ export class BondingPoolSingleton { ); // Please note, mutation of `tx` happening below - quoteSellMeme(tx, [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], { + quoteSellMeme(tx, [LONG_SUI_COIN_TYPE, memeCoin.coinType], { coinM: inputAmountWithDecimals, pool: bondingCurvePoolObjectId, }); @@ -429,7 +401,6 @@ export class BondingPoolSingleton { public static async swapSuiForTicket(params: SwapParamsForSuiInputAndTicketOutput) { const { memeCoin, - ticketCoin, transaction, bondingCurvePoolObjectId, minOutputTicketAmount, @@ -452,7 +423,7 @@ export class BondingPoolSingleton { ); const minOutputBigInt = BigInt(minOutputNormalized); - const txResult = buyMeme(tx, [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], { + const txResult = buyMeme(tx, [LONG_SUI_COIN_TYPE, memeCoin.coinType], { pool: bondingCurvePoolObjectId, coinMMinValue: minOutputBigInt, coinS: suiCoinObject, @@ -486,13 +457,13 @@ export class BondingPoolSingleton { remainingAmountBN, availableTickets, tokenPolicyObjectId, - ticketCoinType, + memeCoinType, transaction, }: { remainingAmountBN: BigNumber; availableTickets: StakedLpObject[]; tokenPolicyObjectId: string; - ticketCoinType: string; + memeCoinType: string; transaction?: TransactionBlock; }) { const tx = transaction ?? new TransactionBlock(); @@ -507,7 +478,7 @@ export class BondingPoolSingleton { } else if (firstTicketAmountBN.isGreaterThan(remainingAmountBN)) { // if first ticket object can fulfill all remaining amount with split const splitAmountBigInt = BigInt(remainingAmountBN.toString()); - const splitTxResult = split(tx, firstTicket.ticketCoinType, { + const splitTxResult = split(tx, firstTicket.memeCoinType, { self: firstTicket.objectId, splitAmount: splitAmountBigInt, }); @@ -533,31 +504,31 @@ export class BondingPoolSingleton { if (ticketBalanceBN.isEqualTo(remainingAmountBN)) { // if current ticket is equal to remainingAmount - join(tx, ticket.ticketCoinType, { self: ticketObject, c: ticket.objectId }); + join(tx, ticket.memeCoinType, { self: ticketObject, c: ticket.objectId }); break; } else if (ticketBalanceBN.isGreaterThan(remainingAmountBN)) { // if current ticket amount is bigger than the remainingAmount, we need to split, and then exit from the loop const splitAmountBigInt = BigInt(remainingAmountBN.toString()); - const splitTxResult = split(tx, ticket.ticketCoinType, { + const splitTxResult = split(tx, ticket.memeCoinType, { self: ticket.objectId, splitAmount: splitAmountBigInt, }); const [ticketSplittedObject] = splitTxResult; - join(tx, ticket.ticketCoinType, { self: ticketObject, c: ticketSplittedObject }); + join(tx, ticket.memeCoinType, { self: ticketObject, c: ticketSplittedObject }); break; } else if (ticketBalanceBN.isLessThan(remainingAmountBN)) { // if current ticket amount is less than the remainingAmount, we need to join with existing tickets // and continue iterating over cycle - join(tx, ticket.ticketCoinType, { self: ticketObject, c: ticket.objectId }); + join(tx, ticket.memeCoinType, { self: ticketObject, c: ticket.objectId }); } remainingAmountBN = remainingAmountBN.minus(ticketBalanceBN); } // converting ticket into token object - const ticketTokenObjectTxResult = intoToken(tx, ticketCoinType, { + const ticketTokenObjectTxResult = intoToken(tx, memeCoinType, { clock: SUI_CLOCK_OBJECT_ID, policy: tokenPolicyObjectId, stakedLp: ticketObject, @@ -570,7 +541,6 @@ export class BondingPoolSingleton { public async swapTicketForSui(params: SwapParamsForTicketInputAndSuiOutput) { const { memeCoin, - ticketCoin, transaction, bondingCurvePoolObjectId, inputTicketAmount, @@ -580,9 +550,11 @@ export class BondingPoolSingleton { } = params; const tx = transaction ?? new TransactionBlock(); + // TODO ASAP IMPORTANT: Replace `ticketCoin` in the params with something else (maybe `memeCoin` would work) const { amountWithDecimals, tickets: availableTickets } = await this.getAvailableAmountOfTicketsToSell({ owner, - ticketCoin, + // TODO ASAP IMPORTANT: Replace `ticketCoin` in the params with something else (maybe `memeCoin` would work) + memeCoin, }); const isInputTicketAmountIsLargerThanAvailable = new BigNumber(inputTicketAmount).isGreaterThan( @@ -603,11 +575,13 @@ export class BondingPoolSingleton { ); const remainingAmountBN = new BigNumber(inputAmountWithDecimals.toString()); + // TODO ASAP IMPORTANT: Replace `ticketCoin` in the params with something else (maybe `memeCoin` would work) const ticketObject = await this.getMergedTicketObjectForSwap({ remainingAmountBN, availableTickets, tokenPolicyObjectId, - ticketCoinType: ticketCoin.coinType, + // TODO ASAP IMPORTANT: Replace `ticketCoin` in the params with something else (maybe `memeCoin` would work) + memeCoinType: memeCoin.coinType, transaction: tx, }); @@ -617,7 +591,7 @@ export class BondingPoolSingleton { const minOutputWithSlippage = deductSlippage(new BigNumber(minOutputSuiAmount), slippagePercentage); const minOutputNormalized = normalizeInputCoinAmount(minOutputWithSlippage.toString(), SUI_DECIMALS); - const txResult = sellMeme(tx, [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], { + const txResult = sellMeme(tx, [LONG_SUI_COIN_TYPE, memeCoin.coinType], { pool: bondingCurvePoolObjectId, coinSMinValue: minOutputNormalized, policy: tokenPolicyObjectId, @@ -654,6 +628,19 @@ export class BondingPoolSingleton { return decodedTableAddress; } + public async getPoolDetailedInfo({ poolId }: { poolId: string }): Promise { + const poolObject = await this.provider.getObject({ + id: poolId, + options: { showContent: true, showOwner: true, showType: true }, + }); + + if (!isPoolDetailedInfo(poolObject)) { + throw new Error("Wrong shape of detailed pool object info"); + } + + return poolObject; + } + public async getAllPools({ transaction }: { transaction?: TransactionBlock } = {}) { const registryTableId = await this.getRegistryTableAddress({ transaction }); @@ -686,6 +673,7 @@ export class BondingPoolSingleton { if (!isPoolObjectData(objectDataList)) { throw new Error("Wrong shape of seed pools of bonding curve pools"); } + // TODO: Might be good to get detailed info for all pools data here as well const pools = objectDataList.map((el) => ({ objectId: el.data.content.fields.value, @@ -694,14 +682,6 @@ export class BondingPoolSingleton { })); const poolIds = pools.map((el) => el.objectId); - const poolsByTicketCoinTypeMap = pools.reduce( - (acc: { [ticketCoinType: string]: ExtractedRegistryKeyData & { objectId: string; typename: string } }, el) => { - acc[el.ticketCoinType] = { ...el }; - - return acc; - }, - {}, - ); const poolsByMemeCoinTypeMap = pools.reduce( (acc: { [memeCoinType: string]: ExtractedRegistryKeyData & { objectId: string; typename: string } }, el) => { @@ -721,18 +701,7 @@ export class BondingPoolSingleton { {}, ); - return { poolIds, pools, poolsByTicketCoinTypeMap, poolsByMemeCoinTypeMap, poolsByPoolId }; - } - - public async getPoolByTicket({ ticketCoin }: { ticketCoin: { coinType: string } }) { - const allPools = await this.getAllPools(); - const pool = allPools.poolsByTicketCoinTypeMap[ticketCoin.coinType]; - - if (!pool) { - throw new Error(`No such pool found for provided ticketCoin coinType ${ticketCoin.coinType}`); - } - - return pool; + return { poolIds, pools, poolsByMemeCoinTypeMap, poolsByPoolId }; } public async getPoolByMeme({ memeCoin }: { memeCoin: { coinType: string } }) { @@ -749,18 +718,16 @@ export class BondingPoolSingleton { public async isMemeCoinReadyToLivePhase({ transaction, memeCoin, - ticketCoin, poolId, }: { memeCoin: { coinType: string }; - ticketCoin: { coinType: string }; poolId: string; transaction?: TransactionBlock; }): Promise { const tx = transaction ?? new TransactionBlock(); // Please note, mutation of `tx` happening below - isReadyToLaunch(tx, [ticketCoin.coinType, LONG_SUI_COIN_TYPE, memeCoin.coinType], poolId); + isReadyToLaunch(tx, [LONG_SUI_COIN_TYPE, memeCoin.coinType], poolId); const res = await this.provider.devInspectTransactionBlock({ sender: BondingPoolSingleton.SIMULATION_ACCOUNT_ADDRESS, @@ -781,42 +748,14 @@ export class BondingPoolSingleton { return decodedIsReadyToLivePhase; } - public async getTokenPolicyCapByPoolId({ poolId }: { poolId: string }) { - const poolDynamicFields = await getAllDynamicFields({ parentObjectId: poolId, provider: this.provider }); - const tokenPolicyCapList = poolDynamicFields.filter((el) => el.objectType.includes("0x2::token::TokenPolicyCap")); - - if (tokenPolicyCapList.length === 0) { - throw new Error(`[getTokenPolicyCapByPoolId] No token policy cap found for the pool ${poolId}`); - } - - if (tokenPolicyCapList.length > 1) { - console.warn( - `[getTokenPolicyCapByPoolId] Warning: multiple tokenPolicyCaps found for pool ${poolId}, - ignoring the rest except first`, - tokenPolicyCapList, - ); - } - - const [tokenPolicyCapObject] = tokenPolicyCapList; - const tokenPolicyCapObjectId = tokenPolicyCapObject.objectId; - - return tokenPolicyCapObjectId; - } - public async getTokenPolicyByPoolId({ poolId }: { poolId: string }) { - const tokenPolicyCap = await this.getTokenPolicyCapByPoolId({ poolId }); - - const tokenPolicyCapObjectData = await this.provider.getObject({ - id: tokenPolicyCap, - options: { showContent: true, showOwner: true, showType: true }, - }); + const poolDetailedInfo = await this.getPoolDetailedInfo({ poolId }); + const tokenPolicyObjectId = poolDetailedInfo.data.content.fields.policy_cap.fields.for; - if (!isTokenPolicyCapObjectData(tokenPolicyCapObjectData)) { - throw new Error(`[getTokenPolicyByPoolId] No token policy cap found for the pool ${poolId}`); + if (!tokenPolicyObjectId) { + throw new Error(`[getTokenPolicyByPoolId] No token policy found for ${poolId}`); } - const tokenPolicyObjectId = tokenPolicyCapObjectData.data?.content.fields.value.fields.for; - return tokenPolicyObjectId; } @@ -843,17 +782,18 @@ export class BondingPoolSingleton { memeCoinType: string; lpCoinType: string; lpCoinTreasureCapId: string; + lpMeta: string; suiMetadataObject: string; - coinTicketType: string; }) { const tx = params.transaction ?? new TransactionBlock(); - const txResult = goLiveDefault(tx, [params.coinTicketType, params.memeCoinType, params.lpCoinType], { + const txResult = goLiveDefault(tx, [params.memeCoinType, params.lpCoinType], { adminCap: params.adminCap, - clock: SUI_CLOCK_OBJECT_ID, - memeMeta: params.memeMeta, - suiMeta: params.suiMetadataObject, seedPool: params.seedPool, + suiMeta: params.suiMetadataObject, + memeMeta: params.memeMeta, + lpMeta: params.lpMeta, + clock: SUI_CLOCK_OBJECT_ID, treasuryCap: params.lpCoinTreasureCapId, }); @@ -867,36 +807,25 @@ export class BondingPoolSingleton { const instance = CoinManagerSingleton.getInstance(this.suiProviderUrl); const memeMetaDataPromise = instance.fetchCoinMetadata(pool.memeCoinType); - const ticketMetaDataPromise = instance.fetchCoinMetadata(pool.ticketCoinType); - const [memeMetaData, ticketMetaData] = await Promise.all([memeMetaDataPromise, ticketMetaDataPromise]); + const [memeMetaData] = await Promise.all([memeMetaDataPromise]); if (!memeMetaData) { throw new Error("Meme metadata is null"); } - if (!ticketMetaData) { - throw new Error("Ticket metadata is null"); - } - const memeMetaDataObjectId = memeMetaData.id; - const ticketMetaDataObjectId = ticketMetaData.id; if (!memeMetaDataObjectId) { throw new Error("Meme id is empty"); } - if (!ticketMetaDataObjectId) { - throw new Error("Ticket id is empty"); - } - return { adminCap: BondingPoolSingleton.ADMIN_OBJECT_ID, seedPool: pool.objectId, memeMeta: memeMetaDataObjectId, memeCoinType: pool.memeCoinType, suiMetadataObject: BondingPoolSingleton.SUI_METADATA_OBJECT_ID, - coinTicketType: pool.ticketCoinType, }; } } diff --git a/src/bonding-pool/types.ts b/src/bonding-pool/types.ts index 84a152d..e1a9d1b 100644 --- a/src/bonding-pool/types.ts +++ b/src/bonding-pool/types.ts @@ -16,14 +16,6 @@ export type ExtractedCoinDataFromTransaction = { packageId: string; metadataObjectId: string; }; - ticketCoin: { - coinType: string; - objectId: string; - objectType: string; - treasureCapId: string; - packageId: string; - metadataObjectId: string; - }; }; export type BondingCurveCustomParams = Omit< @@ -35,7 +27,6 @@ export type GetBondingCurveCustomParams = Optional; export type CreateBondingCurvePoolParams = { memeCoin: { treasureCapId: string; metadataObjectId: string; coinType: string }; - ticketCoin: { treasureCapId: string; metadataObjectId: string; coinType: string }; transaction?: TransactionBlock; bondingCurveCustomParams?: BondingCurveCustomParams; }; @@ -47,7 +38,6 @@ export type CreateCoinTransactionParamsWithoutCertainProps = Omit< export type SwapParamsForSuiInput = { memeCoin: { coinType: string }; - ticketCoin: { coinType: string }; transaction?: TransactionBlock; // swap params @@ -64,7 +54,6 @@ export type SwapParamsForSuiInputAndTicketOutput = SwapParamsForSuiInput & { export type SwapParamsForTicketInput = { memeCoin: { coinType: string }; - ticketCoin: { coinType: string }; transaction?: TransactionBlock; bondingCurvePoolObjectId: string; @@ -137,8 +126,6 @@ export interface TokenPolicyCapObjectData extends SuiObjectResponse { export type ExtractedRegistryKeyData = { boundingCurvePackageId: string; - ticketPackageId: string; - ticketCoinType: string; quotePackageId: string; quoteCoinType: string; memePackageId: string; @@ -172,5 +159,81 @@ export interface StakedLpObject { balance: string; balanceWithDecimals: string; untilTimestamp: number; - ticketCoinType: string; + memeCoinType: string; +} + +export interface DetailedPoolInfo extends SuiObjectResponse { + data: { + type: string; + version: string; + objectId: string; + digest: string; + content: { + dataType: "moveObject"; + type: string; + hasPublicTransfer: boolean; + fields: { + accounting: { + type: string; + fields: { + id: { + id: string; + }; + size: string; + }; + }; + admin_balance_m: string; + admin_balance_s: string; + balance_m: string; + balance_s: string; + fees: { + type: string; + fields: { + fee_in_percent: string; + fee_out_percent: string; + }; + }; + id: { + id: string; + }; + launch_balance: string; + locked: boolean; + meme_cap: { + type: string; + fields: { + id: { + id: string; + }; + total_supply: { + type: string; + fields: { + value: string; + }; + }; + }; + }; + params: { + type: string; + fields: { + alpha_abs: string; + beta: string; + gamma_m: string; + gamma_s: string; + omega_m: string; + price_factor: string; + sell_delay_ms: string; + }; + }; + policy_cap: { + type: string; + fields: { + for: string; + id: { + id: string; + }; + }; + }; + }; + }; + }; } diff --git a/src/bonding-pool/utils/extractRegistryKeyData.ts b/src/bonding-pool/utils/extractRegistryKeyData.ts index 9d6afe1..7ef26eb 100644 --- a/src/bonding-pool/utils/extractRegistryKeyData.ts +++ b/src/bonding-pool/utils/extractRegistryKeyData.ts @@ -2,9 +2,9 @@ import { normalizeSuiAddress } from "@mysten/sui.js/utils"; import { ExtractedRegistryKeyData } from "../types"; /** - * Extracts packageId, ticketPackageId, and ticketCoinType from a RegistryKey typename string. + * Extracts data from a RegistryKey typename string. * @param {string} typename - The RegistryKey typename string. - * @return {ExtractedRegistryKeyData} - An object containing packageId, ticketPackageId, and ticketCoinType. + * @return {ExtractedRegistryKeyData} - An object containing extracted data (memeCoin, quoteCoin, packageIds) */ export function extractRegistryKeyData(typename: string): ExtractedRegistryKeyData { const [packageId, rest] = typename.split("::index::RegistryKey<"); @@ -14,22 +14,16 @@ export function extractRegistryKeyData(typename: string): ExtractedRegistryKeyDa throw new Error("Invalid typename format. Expected '::index::RegistryKey' pattern."); } - const [ticketCoinType, quoteCoinType, memeCoinTypeRaw] = rest.split(","); - if (!ticketCoinType) { - throw new Error("Invalid typename format. Missing ticketCoinType."); - } + const [quoteCoinType, memeCoinTypeRaw] = rest.split(","); + const [memeCoinType] = memeCoinTypeRaw.split(">"); - if (!memeCoinTypeRaw) { - throw new Error("Invalid typename format. Missing memeCoinType."); + if (!quoteCoinType) { + throw new Error("Invalid typename format. Missing quoteCoinType."); } - // Ticket (base) - const ticketCoinTypeParts = ticketCoinType.split("::"); - if (ticketCoinTypeParts.length < 2) { - throw new Error("Invalid typename format. Invalid ticketCoinType format."); + if (!memeCoinType) { + throw new Error("Invalid typename format. Missing memeCoinType."); } - const normalizedTicketCoinPackageId = normalizeSuiAddress(ticketCoinTypeParts[0]); - const normalizedTicketCoinType = `${normalizedTicketCoinPackageId}::${ticketCoinTypeParts.slice(1).join("::")}`; // Sui (quote) const quoteCoinTypeParts = quoteCoinType.split("::"); @@ -39,19 +33,19 @@ export function extractRegistryKeyData(typename: string): ExtractedRegistryKeyDa const normalizedQuoteCoinPackageId = normalizeSuiAddress(quoteCoinTypeParts[0]); const normalizedQuoteCoinType = `${normalizedQuoteCoinPackageId}::${quoteCoinTypeParts.slice(1).join("::")}`; - // Meme - const [memeCoinTypeDenormalized] = memeCoinTypeRaw.split(">"); - const memeCoinTypeParts = memeCoinTypeDenormalized.split("::"); - const normalizedMemePackageId = normalizeSuiAddress(memeCoinTypeParts[0]); - const memeCoinType = `${normalizedMemePackageId}::${memeCoinTypeParts.slice(1).join("::")}`; + // Meme (base) + const memeCoinTypeParts = memeCoinType.split("::"); + if (memeCoinTypeParts.length < 2) { + throw new Error("Invalid typename format. Invalid memeCoinType format."); + } + const normalizedMemeCoinPackageId = normalizeSuiAddress(memeCoinTypeParts[0]); + const normalizedMemeCoinType = `${normalizedMemeCoinPackageId}::${memeCoinTypeParts.slice(1).join("::")}`; return { boundingCurvePackageId: normalizedPackageId, - ticketPackageId: normalizedTicketCoinPackageId, - ticketCoinType: normalizedTicketCoinType, quotePackageId: normalizedQuoteCoinPackageId, quoteCoinType: normalizedQuoteCoinType, - memePackageId: normalizedMemePackageId, - memeCoinType, + memePackageId: normalizedMemeCoinPackageId, + memeCoinType: normalizedMemeCoinType, }; } diff --git a/src/bonding-pool/utils/isPoolDetailedInfo.ts b/src/bonding-pool/utils/isPoolDetailedInfo.ts new file mode 100644 index 0000000..837276d --- /dev/null +++ b/src/bonding-pool/utils/isPoolDetailedInfo.ts @@ -0,0 +1,141 @@ +import { SuiObjectResponse } from "@mysten/sui.js/client"; +import { DetailedPoolInfo } from "../types"; + +/** + * Typeguard function to check if the provided object data matches the shape of pool detailed object data. + * @param {SuiObjectResponse} objectData - The object data to check. + * @return {boolean} - Returns true if the object data matches the shape + * of detailed info about pool object data, false otherwise. + */ +export function isPoolDetailedInfo(objectData: SuiObjectResponse): objectData is DetailedPoolInfo { + return !!( + objectData.data && + objectData.data.type && + typeof objectData.data.type === "string" && + objectData.data.version && + typeof objectData.data.version === "string" && + objectData.data.objectId && + typeof objectData.data.objectId === "string" && + objectData.data.digest && + typeof objectData.data.digest === "string" && + objectData.data.content && + objectData.data.content.dataType === "moveObject" && + objectData.data.content.type && + typeof objectData.data.content.type === "string" && + typeof objectData.data.content.hasPublicTransfer === "boolean" && + "fields" in objectData.data.content && + typeof objectData.data.content.fields === "object" && + objectData.data.content.fields !== null && + "accounting" in objectData.data.content.fields && + typeof objectData.data.content.fields.accounting === "object" && + objectData.data.content.fields.accounting !== null && + "type" in objectData.data.content.fields.accounting && + typeof objectData.data.content.fields.accounting.type === "string" && + "fields" in objectData.data.content.fields.accounting && + typeof objectData.data.content.fields.accounting.fields === "object" && + objectData.data.content.fields.accounting.fields !== null && + "id" in objectData.data.content.fields.accounting.fields && + typeof objectData.data.content.fields.accounting.fields.id === "object" && + objectData.data.content.fields.accounting.fields.id !== null && + "id" in objectData.data.content.fields.accounting.fields.id && + typeof objectData.data.content.fields.accounting.fields.id.id === "string" && + "size" in objectData.data.content.fields.accounting.fields && + typeof objectData.data.content.fields.accounting.fields.size === "string" && + "admin_balance_m" in objectData.data.content.fields && + typeof objectData.data.content.fields.admin_balance_m === "string" && + "admin_balance_s" in objectData.data.content.fields && + typeof objectData.data.content.fields.admin_balance_s === "string" && + "balance_m" in objectData.data.content.fields && + typeof objectData.data.content.fields.balance_m === "string" && + "balance_s" in objectData.data.content.fields && + typeof objectData.data.content.fields.balance_s === "string" && + "fees" in objectData.data.content.fields && + typeof objectData.data.content.fields.fees === "object" && + objectData.data.content.fields.fees !== null && + "type" in objectData.data.content.fields.fees && + typeof objectData.data.content.fields.fees.type === "string" && + "fields" in objectData.data.content.fields.fees && + typeof objectData.data.content.fields.fees.fields === "object" && + objectData.data.content.fields.fees.fields !== null && + "fee_in_percent" in objectData.data.content.fields.fees.fields && + typeof objectData.data.content.fields.fees.fields.fee_in_percent === "string" && + "fee_out_percent" in objectData.data.content.fields.fees.fields && + typeof objectData.data.content.fields.fees.fields.fee_out_percent === "string" && + "id" in objectData.data.content.fields && + typeof objectData.data.content.fields.id === "object" && + objectData.data.content.fields.id !== null && + "id" in objectData.data.content.fields.id && + typeof objectData.data.content.fields.id.id === "string" && + "launch_balance" in objectData.data.content.fields && + typeof objectData.data.content.fields.launch_balance === "string" && + "locked" in objectData.data.content.fields && + typeof objectData.data.content.fields.locked === "boolean" && + "meme_cap" in objectData.data.content.fields && + typeof objectData.data.content.fields.meme_cap === "object" && + objectData.data.content.fields.meme_cap !== null && + "type" in objectData.data.content.fields.meme_cap && + typeof objectData.data.content.fields.meme_cap.type === "string" && + "fields" in objectData.data.content.fields.meme_cap && + typeof objectData.data.content.fields.meme_cap.fields === "object" && + objectData.data.content.fields.meme_cap.fields !== null && + "id" in objectData.data.content.fields.meme_cap.fields && + typeof objectData.data.content.fields.meme_cap.fields.id === "object" && + objectData.data.content.fields.meme_cap.fields.id !== null && + "id" in objectData.data.content.fields.meme_cap.fields.id && + typeof objectData.data.content.fields.meme_cap.fields.id.id === "string" && + "total_supply" in objectData.data.content.fields.meme_cap.fields && + typeof objectData.data.content.fields.meme_cap.fields.total_supply === "object" && + objectData.data.content.fields.meme_cap.fields.total_supply !== null && + "type" in objectData.data.content.fields.meme_cap.fields.total_supply && + typeof objectData.data.content.fields.meme_cap.fields.total_supply.type === "string" && + "fields" in objectData.data.content.fields.meme_cap.fields.total_supply && + typeof objectData.data.content.fields.meme_cap.fields.total_supply.fields === "object" && + objectData.data.content.fields.meme_cap.fields.total_supply.fields !== null && + "value" in objectData.data.content.fields.meme_cap.fields.total_supply.fields && + typeof objectData.data.content.fields.meme_cap.fields.total_supply.fields.value === "string" && + "params" in objectData.data.content.fields && + typeof objectData.data.content.fields.params === "object" && + objectData.data.content.fields.params !== null && + "type" in objectData.data.content.fields.params && + typeof objectData.data.content.fields.params.type === "string" && + "fields" in objectData.data.content.fields.params && + typeof objectData.data.content.fields.params.fields === "object" && + objectData.data.content.fields.params.fields !== null && + "alpha_abs" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.alpha_abs === "string" && + "beta" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.beta === "string" && + "gamma_m" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.gamma_m === "string" && + "gamma_s" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.gamma_s === "string" && + "omega_m" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.omega_m === "string" && + "price_factor" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.price_factor === "string" && + "sell_delay_ms" in objectData.data.content.fields.params.fields && + typeof objectData.data.content.fields.params.fields.sell_delay_ms === "string" && + "policy_cap" in objectData.data.content.fields && + typeof objectData.data.content.fields.policy_cap === "object" && + objectData.data.content.fields.policy_cap !== null && + "type" in objectData.data.content.fields.policy_cap && + typeof objectData.data.content.fields.policy_cap.type === "string" && + "fields" in objectData.data.content.fields.policy_cap && + typeof objectData.data.content.fields.policy_cap.fields === "object" && + objectData.data.content.fields.policy_cap.fields !== null && + "for" in objectData.data.content.fields.policy_cap.fields && + typeof objectData.data.content.fields.policy_cap.fields.for === "string" && + "id" in objectData.data.content.fields.policy_cap.fields && + typeof objectData.data.content.fields.policy_cap.fields.id === "object" && + objectData.data.content.fields.policy_cap.fields.id !== null && + "id" in objectData.data.content.fields.policy_cap.fields.id && + typeof objectData.data.content.fields.policy_cap.fields.id.id === "string" + ); +} + +// eslint-disable-next-line require-jsdoc +export function isPoolDetailedInfoList( + suiObjectResponseList: SuiObjectResponse[], +): suiObjectResponseList is DetailedPoolInfo[] { + return suiObjectResponseList.every((el) => isPoolDetailedInfo(el)); +} diff --git a/src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation.ts b/src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation.ts index 3822695..d0b85da 100644 --- a/src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation.ts +++ b/src/bonding-pool/utils/parseTransactionDataCoinAndTicketCreation.ts @@ -1,8 +1,7 @@ import { SuiObjectChange } from "@mysten/sui.js/client"; -import { BondingPoolSingleton } from "../BondingPool"; import { ExtractedCoinDataFromTransaction } from "../types"; -import { validateExtractedCoinDataFromTransaction } from "./validateExtractedCoinDataFromTransaction"; import { extractCoinType } from "./extractCoinType"; +import { validateExtractedCoinDataFromTransaction } from "./validateExtractedCoinDataFromTransaction"; export const parseTransactionDataCoinAndTicketCreation = ( objectChanges: SuiObjectChange[] | null | undefined, @@ -16,14 +15,6 @@ export const parseTransactionDataCoinAndTicketCreation = ( packageId: "", metadataObjectId: "", }, - ticketCoin: { - coinType: "", - objectId: "", - objectType: "", - treasureCapId: "", - packageId: "", - metadataObjectId: "", - }, }; if (!objectChanges) { @@ -33,44 +24,24 @@ export const parseTransactionDataCoinAndTicketCreation = ( const data = objectChanges.reduce((data, change) => { if (change.type === "created" && change.objectId && change.objectType) { const objectInfo = { objectId: change.objectId, objectType: change.objectType }; - if (change.objectType.includes(`${BondingPoolSingleton.TICKET_COIN_MODULE_PREFIX}`)) { - if (change.objectType.includes("0x2::coin::Coin<")) { - data.ticketCoin.objectId = objectInfo.objectId; - data.ticketCoin.objectType = objectInfo.objectType; - } else if (change.objectType.includes("0x2::coin::TreasuryCap<")) { - data.ticketCoin.treasureCapId = objectInfo.objectId; - } else if (change.objectType.includes("0x2::coin::CoinMetadata<")) { - data.ticketCoin.metadataObjectId = objectInfo.objectId; - } - } else { - if (change.objectType.includes("0x2::coin::Coin<")) { - data.memeCoin.objectId = objectInfo.objectId; - data.memeCoin.objectType = objectInfo.objectType; - } else if (change.objectType.includes("0x2::coin::TreasuryCap<")) { - data.memeCoin.treasureCapId = objectInfo.objectId; - } else if (change.objectType.includes("0x2::coin::CoinMetadata<")) { - data.memeCoin.metadataObjectId = objectInfo.objectId; - } + if (change.objectType.includes("0x2::coin::Coin<")) { + data.memeCoin.objectId = objectInfo.objectId; + data.memeCoin.objectType = objectInfo.objectType; + } else if (change.objectType.includes("0x2::coin::TreasuryCap<")) { + data.memeCoin.treasureCapId = objectInfo.objectId; + } else if (change.objectType.includes("0x2::coin::CoinMetadata<")) { + data.memeCoin.metadataObjectId = objectInfo.objectId; } } else if (change.type === "published") { - const isPublishedTicket = change.modules?.some((module) => - module.includes(`${BondingPoolSingleton.TICKET_COIN_MODULE_PREFIX}`), - ); - if (isPublishedTicket) { - data.ticketCoin.packageId = change.packageId; - } else { - data.memeCoin.packageId = change.packageId; - } + data.memeCoin.packageId = change.packageId; } return data; }, initialData); const memeCoinType = extractCoinType(data.memeCoin.objectType); - const ticketCoinType = extractCoinType(data.ticketCoin.objectType); const dataWithCoinTypes = { ...data, memeCoin: { ...data.memeCoin, coinType: memeCoinType }, - ticketCoin: { ...data.ticketCoin, coinType: ticketCoinType }, }; validateExtractedCoinDataFromTransaction(dataWithCoinTypes); diff --git a/src/bonding-pool/utils/registryTableTypenameUtils.ts b/src/bonding-pool/utils/registryTableTypenameUtils.ts index ce6d928..a150303 100644 --- a/src/bonding-pool/utils/registryTableTypenameUtils.ts +++ b/src/bonding-pool/utils/registryTableTypenameUtils.ts @@ -3,7 +3,7 @@ import { RegistryTableTypenameDynamicField } from "../types"; const REGISTRY_TYPENAME_PATTERN = new RegExp( // eslint-disable-next-line max-len - "^[a-f0-9]{64}::index::RegistryKey<[a-f0-9]{64}::[a-zA-Z0-9_]+::[a-zA-Z0-9_]+,0000000000000000000000000000000000000000000000000000000000000002::sui::SUI,[a-f0-9]{64}::[a-zA-Z0-9_]+::[a-zA-Z0-9_]+>$", + "^[a-f0-9]{64}::index::RegistryKey<0000000000000000000000000000000000000000000000000000000000000002::sui::SUI,[a-f0-9]{64}::[a-zA-Z0-9_]+::[a-zA-Z0-9_]+>$", ); /** diff --git a/src/bonding-pool/utils/validateExtractedCoinDataFromTransaction.ts b/src/bonding-pool/utils/validateExtractedCoinDataFromTransaction.ts index 02c019b..f71eef7 100644 --- a/src/bonding-pool/utils/validateExtractedCoinDataFromTransaction.ts +++ b/src/bonding-pool/utils/validateExtractedCoinDataFromTransaction.ts @@ -7,7 +7,6 @@ import { ExtractedCoinDataFromTransaction } from "../types"; */ export const validateExtractedCoinDataFromTransaction = (data: ExtractedCoinDataFromTransaction): void => { validateCoinData("memeCoin", data.memeCoin); - validateCoinData("ticketCoin", data.ticketCoin); }; /** diff --git a/yarn.lock b/yarn.lock index 07694a2..bc616ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,10 +21,10 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@avernikoz/memechan-ts-interface@^1.0.17": - version "1.0.17" - resolved "https://registry.npmjs.org/@avernikoz/memechan-ts-interface/-/memechan-ts-interface-1.0.17.tgz#35c6bd5668eefa17e2f73abebbfb32aa93c9d395" - integrity sha512-J/q0EIClV1RR3P6R8Uk/H7Q8nfdBykK1MLmk9kpgRrbsIDSMjDE66i0bvLLG6RJUrZpFNUAquQbS2lv42Ur64g== +"@avernikoz/memechan-ts-interface@^1.0.18": + version "1.0.18" + resolved "https://registry.npmjs.org/@avernikoz/memechan-ts-interface/-/memechan-ts-interface-1.0.18.tgz#7113fb7d5dd8e8884a56a6cb728f2aa592c1e923" + integrity sha512-J6GIEc+X52VufefcCKNneE7Fb2m9NbCMD0rOJx63+Cl2aT5C8AVfISYSpba+7QvKsR6TvLoaB3IOXQ1uHolcWA== dependencies: "@mysten/bcs" "0.11.1" "@mysten/sui.js" "0.51.2"