From d92ee0266f5104ed7f6e2757ef9648422f4195c2 Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Tue, 17 Mar 2026 15:55:29 +0700 Subject: [PATCH 1/5] fix lib exports and add prefixes to export type names Signed-off-by: Nguyen Le Vu Long --- src/dex-v2.ts | 83 ++++++++++++++++++++-------------------- src/dex.ts | 42 ++++++++++---------- src/index.ts | 5 ++- src/lbe-v2/lbe-v2.ts | 49 +++++++++++++----------- src/lbe-v2/type.ts | 18 ++++----- src/lbe-v2/validation.ts | 32 ++++++++-------- src/stableswap.ts | 58 +++++++++++++++------------- 7 files changed, 149 insertions(+), 138 deletions(-) diff --git a/src/dex-v2.ts b/src/dex-v2.ts index 194f3f7..27b34c3 100644 --- a/src/dex-v2.ts +++ b/src/dex-v2.ts @@ -14,7 +14,7 @@ import { } from "@spacebudz/lucid"; import { Adapter, DataObject, DataType } from "."; -import { BATCHER_FEE_DEX_V2, DexVersion } from "./batcher-fee/configs.internal"; +import { BATCHER_FEE_DEX_V2 } from "./batcher-fee/configs.internal"; import { compareUtxo, DexV2Calculation } from "./calculate"; import { Asset } from "./types/asset"; import { @@ -23,13 +23,12 @@ import { MetadataMessage, } from "./types/constants"; import { FactoryV2 } from "./types/factory"; -import { NetworkEnvironment, NetworkId } from "./types/network"; +import { NetworkId } from "./types/network"; import { OrderV2 } from "./types/order"; import { PoolV2 } from "./types/pool"; -import { lucidToNetworkEnv } from "./utils/network.internal"; import { buildUtxoToStoreDatum } from "./utils/tx.internal"; -export type V2CustomReceiver = { +export type DexV2CustomReceiver = { refundReceiver: string; refundReceiverDatum?: { type: @@ -58,7 +57,7 @@ export type V2CustomReceiver = { * - fee 0.3% -> tradingFeeNumerator 30 * - fee 1% -> tradingFeeNumerator 100 */ -export type CreatePoolV2Options = { +export type DexV2CreatePoolOptions = { assetA: Asset; assetB: Asset; amountA: bigint; @@ -66,19 +65,19 @@ export type CreatePoolV2Options = { tradingFeeNumerator: bigint; }; -export type BulkOrdersOption = { +export type DexV2BulkOrdersOption = { sender: string; - orderOptions: OrderOptions[]; + orderOptions: DexV2OrderOptions[]; expiredOptions?: OrderV2.ExpirySetting; composeTx?: Tx; authorizationMethodType?: OrderV2.AuthorizationMethodType; }; -export type OrderV2SwapRouting = { +export type DexV2SwapRouting = { lpAsset: Asset; direction: OrderV2.Direction; }; -export type DepositOptions = { +export type DexV2DepositOptions = { type: OrderV2.StepType.DEPOSIT; assetA: Asset; assetB: Asset; @@ -88,7 +87,7 @@ export type DepositOptions = { killOnFailed: boolean; }; -export type WithdrawOptions = { +export type DexV2WithdrawOptions = { type: OrderV2.StepType.WITHDRAW; lpAmount: bigint; minimumAssetAReceived: bigint; @@ -96,7 +95,7 @@ export type WithdrawOptions = { killOnFailed: boolean; }; -export type SwapExactInOptions = { +export type DexV2SwapExactInOptions = { type: OrderV2.StepType.SWAP_EXACT_IN; assetIn: Asset; amountIn: bigint; @@ -106,7 +105,7 @@ export type SwapExactInOptions = { isLimitOrder: boolean; }; -export type SwapExactOutOptions = { +export type DexV2SwapExactOutOptions = { type: OrderV2.StepType.SWAP_EXACT_OUT; assetIn: Asset; maximumAmountIn: bigint; @@ -115,7 +114,7 @@ export type SwapExactOutOptions = { killOnFailed: boolean; }; -export type StopOptions = { +export type DexV2StopOptions = { type: OrderV2.StepType.STOP; assetIn: Asset; amountIn: bigint; @@ -123,7 +122,7 @@ export type StopOptions = { direction: OrderV2.Direction; }; -export type OCOOptions = { +export type DexV2OCOOptions = { type: OrderV2.StepType.OCO; assetIn: Asset; amountIn: bigint; @@ -132,7 +131,7 @@ export type OCOOptions = { direction: OrderV2.Direction; }; -export type ZapOutOptions = { +export type DexV2ZapOutOptions = { type: OrderV2.StepType.ZAP_OUT; lpAmount: bigint; direction: OrderV2.Direction; @@ -140,7 +139,7 @@ export type ZapOutOptions = { killOnFailed: boolean; }; -export type PartialSwapOptions = { +export type DexV2PartialSwapOptions = { type: OrderV2.StepType.PARTIAL_SWAP; assetIn: Asset; amountIn: bigint; @@ -150,7 +149,7 @@ export type PartialSwapOptions = { minimumSwapAmountRequired: bigint; }; -export type WithdrawImbalanceOptions = { +export type DexV2WithdrawImbalanceOptions = { type: OrderV2.StepType.WITHDRAW_IMBALANCE; lpAmount: bigint; ratioAssetA: bigint; @@ -159,7 +158,7 @@ export type WithdrawImbalanceOptions = { killOnFailed: boolean; }; -export type MultiRoutingOptions = { +export type DexV2MultiRoutingOptions = { type: OrderV2.StepType.SWAP_ROUTING; assetIn: Asset; amountIn: bigint; @@ -167,29 +166,29 @@ export type MultiRoutingOptions = { minimumReceived: bigint; }; -export type OrderOptions = ( - | DepositOptions - | WithdrawOptions - | SwapExactInOptions - | SwapExactOutOptions - | StopOptions - | OCOOptions - | ZapOutOptions - | PartialSwapOptions - | WithdrawImbalanceOptions - | MultiRoutingOptions +export type DexV2OrderOptions = ( + | DexV2DepositOptions + | DexV2WithdrawOptions + | DexV2SwapExactInOptions + | DexV2SwapExactOutOptions + | DexV2StopOptions + | DexV2OCOOptions + | DexV2ZapOutOptions + | DexV2PartialSwapOptions + | DexV2WithdrawImbalanceOptions + | DexV2MultiRoutingOptions ) & { lpAsset: Asset; - customReceiver?: V2CustomReceiver; + customReceiver?: DexV2CustomReceiver; }; -export type CancelBulkOrdersOptions = { +export type DexV2CancelBulkOrdersOptions = { orderOutRefs: OutRef[]; composeTx?: Tx; AuthorizationMethodType?: OrderV2.AuthorizationMethodType; }; -export type CancelExpiredOrderOptions = { +export type DexV2CancelExpiredOrderOptions = { orderUtxos: Utxo[]; availableUtxos: Utxo[]; currentSlot: number; @@ -200,15 +199,12 @@ export class DexV2 { private readonly lucid: Lucid; private readonly networkId: NetworkId; private readonly adapter: Adapter; - private readonly networkEnv: NetworkEnvironment; - private readonly dexVersion = DexVersion.DEX_V2; constructor(lucid: Lucid, adapter: Adapter) { this.lucid = lucid; this.networkId = lucid.network === "Mainnet" ? NetworkId.MAINNET : NetworkId.TESTNET; this.adapter = adapter; - this.networkEnv = lucidToNetworkEnv(lucid.network); } async createPoolTx({ @@ -217,7 +213,7 @@ export class DexV2 { amountA, amountB, tradingFeeNumerator, - }: CreatePoolV2Options): Promise { + }: DexV2CreatePoolOptions): Promise { const config = DexV2Constant.CONFIG[this.networkId]; // Sort ascendingly assets and its amount const [sortedAssetA, sortedAssetB, sortedAmountA, sortedAmountB] = @@ -366,7 +362,7 @@ export class DexV2 { .commit(); } - private buildOrderValue(options: OrderOptions): Assets { + private buildOrderValue(options: DexV2OrderOptions): Assets { const orderAssets: Assets = {}; switch (options.type) { case OrderV2.StepType.DEPOSIT: { @@ -473,7 +469,10 @@ export class DexV2 { return orderAssets; } - buildOrderStep(options: OrderOptions, finalBatcherFee: bigint): OrderV2.Step { + buildOrderStep( + options: DexV2OrderOptions, + finalBatcherFee: bigint + ): OrderV2.Step { switch (options.type) { case OrderV2.StepType.DEPOSIT: { const { amountA, amountB, minimumLPReceived, killOnFailed } = options; @@ -699,7 +698,7 @@ export class DexV2 { ); } - private getOrderMetadata(orderOption: OrderOptions): string { + private getOrderMetadata(orderOption: DexV2OrderOptions): string { switch (orderOption.type) { case OrderV2.StepType.SWAP_EXACT_IN: { if (orderOption.isLimitOrder) { @@ -750,7 +749,7 @@ export class DexV2 { expiredOptions, composeTx, authorizationMethodType, - }: BulkOrdersOption): Promise { + }: DexV2BulkOrdersOption): Promise { // calculate total order value const totalOrderAssets: Record = {}; for (const option of orderOptions) { @@ -916,7 +915,7 @@ export class DexV2 { async cancelOrder({ orderOutRefs, composeTx, - }: CancelBulkOrdersOptions): Promise { + }: DexV2CancelBulkOrdersOptions): Promise { const orderUtxos = await this.lucid.utxosByOutRef(orderOutRefs); if (orderUtxos.length === 0) { throw new Error("Order Utxos are empty"); @@ -985,7 +984,7 @@ export class DexV2 { currentSlot, availableUtxos, extraDatumMap, - }: CancelExpiredOrderOptions): Promise { + }: DexV2CancelExpiredOrderOptions): Promise { const refScript = await this.lucid.utxosByOutRef([ DexV2Constant.DEPLOYED_SCRIPTS[this.networkId].order, DexV2Constant.DEPLOYED_SCRIPTS[this.networkId].expiredOrderCancellation, diff --git a/src/dex.ts b/src/dex.ts index 5d75e01..7351400 100644 --- a/src/dex.ts +++ b/src/dex.ts @@ -3,19 +3,18 @@ import { Addresses, Assets, Constr, Lucid, TxComplete } from "@spacebudz/lucid"; import { Utxo } from "@spacebudz/lucid"; import { DataObject, DataType } from "."; -import { BATCHER_FEE_DEX_V1, DexVersion } from "./batcher-fee/configs.internal"; +import { BATCHER_FEE_DEX_V1 } from "./batcher-fee/configs.internal"; import { Asset } from "./types/asset"; import { DexV1Constant, FIXED_DEPOSIT_ADA, MetadataMessage, } from "./types/constants"; -import { NetworkEnvironment, NetworkId } from "./types/network"; +import { NetworkId } from "./types/network"; import { OrderV1 } from "./types/order"; -import { lucidToNetworkEnv } from "./utils/network.internal"; import { buildUtxoToStoreDatum } from "./utils/tx.internal"; -export type V1AndStableswapCustomReceiver = { +export type DexV1CustomReceiver = { receiver: string; receiverDatum?: { hash: string; @@ -38,7 +37,7 @@ type CommonOptions = { * @orderTxId Transaction ID which order is created * @sender The owner of this order. The @sender must be matched with data in Order's Datum */ -export type BuildCancelOrderOptions = { +export type DexV1BuildCancelOrderOptions = { orderUtxo: Utxo; sender: string; }; @@ -49,7 +48,7 @@ export type BuildCancelOrderOptions = { * @amountA @amountB Define amount which you want to deposit to * @minimumLPReceived Minimum Received Amount you can accept after order is executed */ -export type BuildDepositTxOptions = CommonOptions & { +export type DexV1BuildDepositTxOptions = CommonOptions & { assetA: Asset; assetB: Asset; amountA: bigint; @@ -64,7 +63,7 @@ export type BuildDepositTxOptions = CommonOptions & { * For eg, in Pool ADA-MIN, if @assetIn is ADA then @assetOut will be MIN and vice versa * @minimumLPReceived Minimum Received Amount you can accept after order is executed */ -export type BuildZapInTxOptions = CommonOptions & { +export type DexV1BuildZapInTxOptions = CommonOptions & { sender: string; assetIn: Asset; amountIn: bigint; @@ -79,7 +78,7 @@ export type BuildZapInTxOptions = CommonOptions & { * @minimumAssetAReceived Minimum Received of Asset A in the Pool you can accept after order is executed * @minimumAssetBReceived Minimum Received of Asset A in the Pool you can accept after order is executed */ -export type BuildWithdrawTxOptions = CommonOptions & { +export type DexV1BuildWithdrawTxOptions = CommonOptions & { lpAsset: Asset; lpAmount: bigint; minimumAssetAReceived: bigint; @@ -93,8 +92,8 @@ export type BuildWithdrawTxOptions = CommonOptions & { * @maximumAmountIn The maximum Amount of Asset In which will be spent after order is executed * @expectedAmountOut The expected Amount of Asset Out you want to receive after order is executed */ -export type BuildSwapExactOutTxOptions = CommonOptions & { - customReceiver?: V1AndStableswapCustomReceiver; +export type DexV1BuildSwapExactOutTxOptions = CommonOptions & { + customReceiver?: DexV1CustomReceiver; assetIn: Asset; assetOut: Asset; maximumAmountIn: bigint; @@ -109,8 +108,8 @@ export type BuildSwapExactOutTxOptions = CommonOptions & { * @minimumAmountOut The minimum Amount of Asset Out you can accept after order is executed * @isLimitOrder Define this order is Limit Order or not */ -export type BuildSwapExactInTxOptions = CommonOptions & { - customReceiver?: V1AndStableswapCustomReceiver; +export type DexV1BuildSwapExactInTxOptions = CommonOptions & { + customReceiver?: DexV1CustomReceiver; assetIn: Asset; amountIn: bigint; assetOut: Asset; @@ -121,18 +120,15 @@ export type BuildSwapExactInTxOptions = CommonOptions & { export class Dex { private readonly lucid: Lucid; private readonly networkId: NetworkId; - private readonly networkEnv: NetworkEnvironment; - private readonly dexVersion = DexVersion.DEX_V1; constructor(lucid: Lucid) { this.lucid = lucid; this.networkId = lucid.network === "Mainnet" ? NetworkId.MAINNET : NetworkId.TESTNET; - this.networkEnv = lucidToNetworkEnv(lucid.network); } async buildSwapExactInTx( - options: BuildSwapExactInTxOptions + options: DexV1BuildSwapExactInTxOptions ): Promise { const { sender, @@ -197,7 +193,7 @@ export class Dex { } async buildSwapExactOutTx( - options: BuildSwapExactOutTxOptions + options: DexV1BuildSwapExactOutTxOptions ): Promise { const { sender, @@ -259,7 +255,9 @@ export class Dex { return await tx.commit(); } - async buildWithdrawTx(options: BuildWithdrawTxOptions): Promise { + async buildWithdrawTx( + options: DexV1BuildWithdrawTxOptions + ): Promise { const { sender, lpAsset, @@ -303,7 +301,7 @@ export class Dex { .commit(); } - async buildZapInTx(options: BuildZapInTxOptions): Promise { + async buildZapInTx(options: DexV1BuildZapInTxOptions): Promise { const { sender, assetIn, amountIn, assetOut, minimumLPReceived } = options; invariant(amountIn > 0n, "amount in must be positive"); invariant(minimumLPReceived > 0n, "minimum LP received must be positive"); @@ -339,7 +337,9 @@ export class Dex { .commit(); } - async buildDepositTx(options: BuildDepositTxOptions): Promise { + async buildDepositTx( + options: DexV1BuildDepositTxOptions + ): Promise { const { sender, assetA, assetB, amountA, amountB, minimumLPReceived } = options; invariant(amountA > 0n && amountB > 0n, "amount must be positive"); @@ -378,7 +378,7 @@ export class Dex { } async buildCancelOrder( - options: BuildCancelOrderOptions + options: DexV1BuildCancelOrderOptions ): Promise { const { orderUtxo } = options; const redeemer = DataObject.to( diff --git a/src/index.ts b/src/index.ts index 3c420c9..b5868c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,16 @@ export * from "./adapters"; export * from "./calculate"; +export * from "./dao"; export * from "./dex"; export * from "./dex-v2"; export * from "./expired-order-monitor"; export * from "./lbe-v2/lbe-v2"; +export * from "./lbe-v2/type"; export * from "./lbe-v2-worker/worker"; -export { Stableswap } from "./stableswap"; +export * from "./stableswap"; export * from "./types/asset"; export * from "./types/constants"; +export * from "./types/factory"; export * from "./types/lbe-v2"; export * from "./types/network"; export * from "./types/order"; diff --git a/src/lbe-v2/lbe-v2.ts b/src/lbe-v2/lbe-v2.ts index d0536ed..88170f9 100644 --- a/src/lbe-v2/lbe-v2.ts +++ b/src/lbe-v2/lbe-v2.ts @@ -21,22 +21,21 @@ import { Asset } from "../types/asset"; import { RedeemerWrapper } from "../types/common"; import { FactoryV2 } from "../types/factory"; import { LbeV2Types } from "../types/lbe-v2"; -import { NetworkEnvironment, NetworkId } from "../types/network"; -import { lucidToNetworkEnv } from "../utils/network.internal"; +import { NetworkId } from "../types/network"; import { - AddSellersOptions, - CalculationRedeemAmountParams, - CloseEventOptions, - CollectManagerOptions, - CollectOrdersOptions, - CountingSellersOptions, - CreateAmmPoolTxOptions, + LbeV2AddSellersOptions, + LbeV2CalculationRedeemAmountParams, LbeV2CancelEventOptions, + LbeV2CloseEventOptions, + LbeV2CollectManagerOptions, + LbeV2CollectOrdersOptions, + LbeV2CountingSellersOptions, + LbeV2CreateAmmPoolTxOptions, LbeV2CreateEventOptions, LbeV2DepositOrWithdrawOptions, + LbeV2RedeemOrdersOptions, + LbeV2RefundOrdersOptions, LbeV2UpdateEventOptions, - RedeemOrdersOptions, - RefundOrdersOptions, } from "./type"; import { validateAddSeller, @@ -58,13 +57,11 @@ const THREE_HOUR_IN_MS = 3 * 60 * 60 * 1000; export class LbeV2 { private readonly lucid: Lucid; private readonly networkId: NetworkId; - private readonly networkEnv: NetworkEnvironment; constructor(lucid: Lucid) { this.lucid = lucid; this.networkId = lucid.network === "Mainnet" ? NetworkId.MAINNET : NetworkId.TESTNET; - this.networkEnv = lucidToNetworkEnv(lucid.network); } async createEvent(options: LbeV2CreateEventOptions): Promise { @@ -637,7 +634,7 @@ export class LbeV2 { return lucidTx.commit(); } - async closeEventTx(options: CloseEventOptions): Promise { + async closeEventTx(options: LbeV2CloseEventOptions): Promise { validateCloseEvent(options, this.networkId); const { treasuryUtxo, headFactoryUtxo, tailFactoryUtxo, currentSlot } = options; @@ -752,7 +749,7 @@ export class LbeV2 { return await lucidTx.commit(); } - async addSellers(options: AddSellersOptions): Promise { + async addSellers(options: LbeV2AddSellersOptions): Promise { validateAddSeller(options, this.lucid, this.networkId); const { treasuryUtxo, @@ -872,7 +869,9 @@ export class LbeV2 { return lucidTx.commit(); } - async countingSellers(options: CountingSellersOptions): Promise { + async countingSellers( + options: LbeV2CountingSellersOptions + ): Promise { validateCountingSeller(options, this.lucid, this.networkId); const { treasuryUtxo, managerUtxo, sellerUtxos, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); @@ -997,7 +996,9 @@ export class LbeV2 { return lucidTx.commit(); } - async collectManager(options: CollectManagerOptions): Promise { + async collectManager( + options: LbeV2CollectManagerOptions + ): Promise { validateCollectManager(options, this.lucid, this.networkId); const { treasuryUtxo, managerUtxo, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); @@ -1101,7 +1102,9 @@ export class LbeV2 { return lucidTx.commit(); } - async collectOrders(options: CollectOrdersOptions): Promise { + async collectOrders( + options: LbeV2CollectOrdersOptions + ): Promise { validateCollectOrders(options, this.networkId); const { treasuryUtxo, orderUtxos, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); @@ -1241,7 +1244,7 @@ export class LbeV2 { return lucidTx.commit(); } - calculateRedeemAmount(params: CalculationRedeemAmountParams): { + calculateRedeemAmount(params: LbeV2CalculationRedeemAmountParams): { liquidityAmount: bigint; returnedRaiseAmount: bigint; } { @@ -1269,7 +1272,7 @@ export class LbeV2 { }; } - async redeemOrders(options: RedeemOrdersOptions): Promise { + async redeemOrders(options: LbeV2RedeemOrdersOptions): Promise { validateRedeemOrders(options, this.networkId); const { treasuryUtxo, orderUtxos, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); @@ -1449,7 +1452,7 @@ export class LbeV2 { return lucidTx.commit(); } - async refundOrders(options: RefundOrdersOptions): Promise { + async refundOrders(options: LbeV2RefundOrdersOptions): Promise { validateRefundOrders(options, this.networkId); const { treasuryUtxo, orderUtxos, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); @@ -1602,7 +1605,9 @@ export class LbeV2 { return lucidTx.commit(); } - async createAmmPool(options: CreateAmmPoolTxOptions): Promise { + async createAmmPool( + options: LbeV2CreateAmmPoolTxOptions + ): Promise { validateCreateAmmPool(options, this.networkId); const { treasuryUtxo, ammFactoryUtxo, currentSlot } = options; const currentTime = this.lucid.utils.slotsToUnixTime(currentSlot); diff --git a/src/lbe-v2/type.ts b/src/lbe-v2/type.ts index d6e72f6..9bf3454 100644 --- a/src/lbe-v2/type.ts +++ b/src/lbe-v2/type.ts @@ -66,7 +66,7 @@ export type LbeV2DepositOrWithdrawOptions = { action: LbeV2ManageOrderAction; }; -export type CloseEventOptions = { +export type LbeV2CloseEventOptions = { treasuryUtxo: Utxo; headFactoryUtxo: Utxo; tailFactoryUtxo: Utxo; @@ -74,7 +74,7 @@ export type CloseEventOptions = { owner: string; }; -export type AddSellersOptions = { +export type LbeV2AddSellersOptions = { treasuryUtxo: Utxo; managerUtxo: Utxo; addSellerCount: number; @@ -82,44 +82,44 @@ export type AddSellersOptions = { currentSlot: number; }; -export type CountingSellersOptions = { +export type LbeV2CountingSellersOptions = { treasuryUtxo: Utxo; managerUtxo: Utxo; sellerUtxos: Utxo[]; currentSlot: number; }; -export type CollectManagerOptions = { +export type LbeV2CollectManagerOptions = { treasuryUtxo: Utxo; managerUtxo: Utxo; currentSlot: number; }; -export type CollectOrdersOptions = { +export type LbeV2CollectOrdersOptions = { treasuryUtxo: Utxo; orderUtxos: Utxo[]; currentSlot: number; }; -export type RedeemOrdersOptions = { +export type LbeV2RedeemOrdersOptions = { treasuryUtxo: Utxo; orderUtxos: Utxo[]; currentSlot: number; }; -export type RefundOrdersOptions = { +export type LbeV2RefundOrdersOptions = { treasuryUtxo: Utxo; orderUtxos: Utxo[]; currentSlot: number; }; -export type CreateAmmPoolTxOptions = { +export type LbeV2CreateAmmPoolTxOptions = { treasuryUtxo: Utxo; ammFactoryUtxo: Utxo; currentSlot: number; }; -export type CalculationRedeemAmountParams = { +export type LbeV2CalculationRedeemAmountParams = { userAmount: bigint; totalPenalty: bigint; reserveRaise: bigint; diff --git a/src/lbe-v2/validation.ts b/src/lbe-v2/validation.ts index 128c8fc..b5d610e 100644 --- a/src/lbe-v2/validation.ts +++ b/src/lbe-v2/validation.ts @@ -13,19 +13,19 @@ import { import { FactoryV2 } from "../types/factory"; import { LbeV2Types } from "../types/lbe-v2"; import { - AddSellersOptions, - CloseEventOptions, - CollectManagerOptions, - CollectOrdersOptions, - CountingSellersOptions, - CreateAmmPoolTxOptions, + LbeV2AddSellersOptions, LbeV2CancelEventOptions, + LbeV2CloseEventOptions, + LbeV2CollectManagerOptions, + LbeV2CollectOrdersOptions, + LbeV2CountingSellersOptions, + LbeV2CreateAmmPoolTxOptions, LbeV2CreateEventOptions, LbeV2DepositOrWithdrawOptions, LbeV2ProjectDetails, + LbeV2RedeemOrdersOptions, + LbeV2RefundOrdersOptions, LbeV2UpdateEventOptions, - RedeemOrdersOptions, - RefundOrdersOptions, } from "./type"; export function validateCreateEvent( @@ -375,7 +375,7 @@ export function validateDepositOrWithdrawOrder( } export function validateCloseEvent( - options: CloseEventOptions, + options: LbeV2CloseEventOptions, networkId: NetworkId ): void { const { treasuryUtxo, headFactoryUtxo, tailFactoryUtxo, owner } = options; @@ -429,7 +429,7 @@ export function validateCloseEvent( } export function validateAddSeller( - options: AddSellersOptions, + options: LbeV2AddSellersOptions, lucid: Lucid, networkId: NetworkId ): void { @@ -477,7 +477,7 @@ export function validateAddSeller( } export function validateCountingSeller( - options: CountingSellersOptions, + options: LbeV2CountingSellersOptions, lucid: Lucid, networkId: NetworkId ): void { @@ -555,7 +555,7 @@ export function validateCountingSeller( } export function validateCollectManager( - options: CollectManagerOptions, + options: LbeV2CollectManagerOptions, lucid: Lucid, networkId: NetworkId ): void { @@ -610,7 +610,7 @@ export function validateCollectManager( } export function validateCollectOrders( - options: CollectOrdersOptions, + options: LbeV2CollectOrdersOptions, networkId: NetworkId ): void { const { treasuryUtxo, orderUtxos } = options; @@ -666,7 +666,7 @@ export function validateCollectOrders( } export function validateRedeemOrders( - options: RedeemOrdersOptions, + options: LbeV2RedeemOrdersOptions, networkId: NetworkId ): void { const { treasuryUtxo, orderUtxos } = options; @@ -714,7 +714,7 @@ export function validateRedeemOrders( } export function validateRefundOrders( - options: RefundOrdersOptions, + options: LbeV2RefundOrdersOptions, networkId: NetworkId ): void { const { treasuryUtxo, orderUtxos } = options; @@ -766,7 +766,7 @@ export function validateRefundOrders( } export function validateCreateAmmPool( - options: CreateAmmPoolTxOptions, + options: LbeV2CreateAmmPoolTxOptions, networkId: NetworkId ): void { const { treasuryUtxo, ammFactoryUtxo } = options; diff --git a/src/stableswap.ts b/src/stableswap.ts index 63a8627..2e5ab9b 100644 --- a/src/stableswap.ts +++ b/src/stableswap.ts @@ -9,22 +9,27 @@ import { MetadataMessage, StableOrder, StableswapConstant, - V1AndStableswapCustomReceiver, } from "."; import { BATCHER_FEE_STABLESWAP, - DexVersion, } from "./batcher-fee/configs.internal"; import { Asset } from "./types/asset"; -import { NetworkEnvironment, NetworkId } from "./types/network"; -import { lucidToNetworkEnv } from "./utils/network.internal"; +import { NetworkId } from "./types/network"; import { buildUtxoToStoreDatum } from "./utils/tx.internal"; +export type StableswapCustomReceiver = { + receiver: string; + receiverDatum?: { + hash: string; + datum: string; + }; +}; + /** * @property {bigint} assetInIndex - Index of asset you want to swap in config assets * @property {bigint} assetOutIndex - Index of asset you want to receive in config assets */ -export type SwapOptions = { +export type StableswapSwapOptions = { type: StableOrder.StepType.SWAP; assetInAmount: bigint; assetInIndex: bigint; @@ -32,20 +37,20 @@ export type SwapOptions = { minimumAssetOut: bigint; }; -export type DepositOptions = { +export type StableswapDepositOptions = { type: StableOrder.StepType.DEPOSIT; assetsAmount: [Asset, bigint][]; minimumLPReceived: bigint; totalLiquidity: bigint; }; -export type WithdrawOptions = { +export type StableswapWithdrawOptions = { type: StableOrder.StepType.WITHDRAW; lpAmount: bigint; minimumAmounts: bigint[]; }; -export type WithdrawImbalanceOptions = { +export type StableswapWithdrawImbalanceOptions = { type: StableOrder.StepType.WITHDRAW_IMBALANCE; lpAmount: bigint; withdrawAmounts: bigint[]; @@ -54,48 +59,45 @@ export type WithdrawImbalanceOptions = { /** * @property {bigint} assetOutIndex - Index of asset you want to receive in config assets */ -export type ZapOutOptions = { +export type StableswapZapOutOptions = { type: StableOrder.StepType.ZAP_OUT; lpAmount: bigint; assetOutIndex: bigint; minimumAssetOut: bigint; }; -export type OrderOptions = ( - | DepositOptions - | WithdrawOptions - | SwapOptions - | WithdrawImbalanceOptions - | ZapOutOptions +export type StableswapOrderOptions = ( + | StableswapDepositOptions + | StableswapWithdrawOptions + | StableswapSwapOptions + | StableswapWithdrawImbalanceOptions + | StableswapZapOutOptions ) & { lpAsset: Asset; - customReceiver?: V1AndStableswapCustomReceiver; + customReceiver?: StableswapCustomReceiver; }; -export type BulkOrdersOption = { - options: OrderOptions[]; +export type StableswapBulkOrdersOption = { + options: StableswapOrderOptions[]; sender: string; availableUtxos: Utxo[]; }; -export type BuildCancelOrderOptions = { +export type StableswapBuildCancelOrderOptions = { orderUtxos: Utxo[]; }; export class Stableswap { private readonly lucid: Lucid; private readonly networkId: NetworkId; - private readonly networkEnv: NetworkEnvironment; - private readonly dexVersion = DexVersion.STABLESWAP; constructor(lucid: Lucid) { this.lucid = lucid; this.networkId = lucid.network === "Mainnet" ? NetworkId.MAINNET : NetworkId.TESTNET; - this.networkEnv = lucidToNetworkEnv(lucid.network); } - buildOrderValue(option: OrderOptions): Assets { + buildOrderValue(option: StableswapOrderOptions): Assets { const orderAssets: Assets = {}; switch (option.type) { @@ -151,7 +153,7 @@ export class Stableswap { return orderAssets; } - buildOrderStep(option: OrderOptions): StableOrder.Step { + buildOrderStep(option: StableswapOrderOptions): StableOrder.Step { switch (option.type) { case StableOrder.StepType.DEPOSIT: { const { minimumLPReceived } = option; @@ -253,7 +255,7 @@ export class Stableswap { } } - private getOrderMetadata(options: OrderOptions): string { + private getOrderMetadata(options: StableswapOrderOptions): string { switch (options.type) { case StableOrder.StepType.SWAP: { return MetadataMessage.SWAP_EXACT_IN_ORDER; @@ -283,7 +285,9 @@ export class Stableswap { } } - async createBulkOrdersTx(options: BulkOrdersOption): Promise { + async createBulkOrdersTx( + options: StableswapBulkOrdersOption + ): Promise { const { sender, options: orderOptions } = options; invariant( @@ -359,7 +363,7 @@ export class Stableswap { } async buildCancelOrdersTx( - options: BuildCancelOrderOptions + options: StableswapBuildCancelOrderOptions ): Promise { const tx = this.lucid.newTx(); From 89ad24474891b37d103dd1f3c7de901c26a40f42 Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Tue, 17 Mar 2026 16:05:11 +0700 Subject: [PATCH 2/5] fix format Signed-off-by: Nguyen Le Vu Long --- src/stableswap.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/stableswap.ts b/src/stableswap.ts index 2e5ab9b..d33a509 100644 --- a/src/stableswap.ts +++ b/src/stableswap.ts @@ -10,9 +10,7 @@ import { StableOrder, StableswapConstant, } from "."; -import { - BATCHER_FEE_STABLESWAP, -} from "./batcher-fee/configs.internal"; +import { BATCHER_FEE_STABLESWAP } from "./batcher-fee/configs.internal"; import { Asset } from "./types/asset"; import { NetworkId } from "./types/network"; import { buildUtxoToStoreDatum } from "./utils/tx.internal"; From 3a810c54582ce198e74a3e10b21f60a73e16ecec Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Thu, 19 Mar 2026 14:21:10 +0700 Subject: [PATCH 3/5] test build Signed-off-by: Nguyen Le Vu Long --- AGENTS.md | 1 + CLAUDE.md | 1 + examples/test-build-swap-build.ts | 105 ++++++++++++++++++++++++++++++ examples/test-build-swap.ts | 102 +++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 AGENTS.md create mode 120000 CLAUDE.md create mode 100644 examples/test-build-swap-build.ts create mode 100644 examples/test-build-swap.ts diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9c1f028 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +- To run a single file in this repo, use `npm run exec `. Example: `npm run exec examples/example.ts` \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/examples/test-build-swap-build.ts b/examples/test-build-swap-build.ts new file mode 100644 index 0000000..0a4ead8 --- /dev/null +++ b/examples/test-build-swap-build.ts @@ -0,0 +1,105 @@ +import { BlockFrostAPI } from "@blockfrost/blockfrost-js"; +import { Blockfrost, Data, Lucid } from "lucid-cardano"; + +import { + ADA, + BlockfrostAdapter, + calculateSwapExactIn, + Dex, + NetworkId, + PoolV1, +} from "../build/index.es.js"; + +function mustGetEnv(key: string): string { + const value = process.env[key]; + if (!value) { + throw new Error(`${key} not found`); + } + return value; +} + +async function main(): Promise { + const networkId = NetworkId.TESTNET; + const blockfrostProjectId = mustGetEnv("BLOCKFROST_PROJECT_ID_TESTNET"); + const blockfrostUrl = "https://cardano-preprod.blockfrost.io/api/v0"; + + // This public preprod address currently has a 5 ADA UTxO, which is enough + // for a small unsigned V1 swap build test. + const address = + "addr_test1qpssc0r090a9u0pyvdr9y76sm2xzx04n6d4j0y5hukcx6rxz4dtgkhfdynadkea0qezv99wljdl076xkg2krm96nn8jszmh3w7"; + const poolId = + "3bb0079303c57812462dec9de8fb867cef8fd3768de7f12c77f6f0dd80381d0d"; + + const lucid = await Lucid.new( + new Blockfrost(blockfrostUrl, blockfrostProjectId), + "Preprod" + ); + lucid.selectWalletFrom({ address: address }); + + const adapter = new BlockfrostAdapter({ + networkId: networkId, + blockFrost: new BlockFrostAPI({ + projectId: blockfrostProjectId, + network: "preprod", + }), + }); + + const availableUtxos = await lucid.utxosAt(address); + if (availableUtxos.length === 0) { + throw new Error("No UTxOs available for the selected testnet address"); + } + + const poolState = await adapter.getV1PoolById({ id: poolId }); + if (!poolState) { + throw new Error(`Pool ${poolId} not found on testnet`); + } + + const rawPoolDatum = await adapter.getDatumByDatumHash(poolState.datumHash); + const poolDatum = PoolV1.Datum.fromPlutusData( + networkId, + Data.from(rawPoolDatum) + ); + + // Keep the swap small enough to leave room for deposit ADA, batcher fee, + // and the final transaction fee inside the source UTxO. + const amountIn = 100_000n; + const { amountOut } = calculateSwapExactIn({ + amountIn: amountIn, + reserveIn: poolState.reserveA, + reserveOut: poolState.reserveB, + }); + const minimumAmountOut = (amountOut * 80n) / 100n; + + const tx = await new Dex(lucid).buildSwapExactInTx({ + sender: address, + availableUtxos: availableUtxos, + amountIn: amountIn, + assetIn: ADA, + assetOut: poolDatum.assetB, + minimumAmountOut: minimumAmountOut, + isLimitOrder: false, + }); + + console.info( + JSON.stringify( + { + address, + poolId, + inputUtxoCount: availableUtxos.length, + amountIn: amountIn.toString(), + expectedAmountOut: amountOut.toString(), + minimumAmountOut: minimumAmountOut.toString(), + fee: tx.fee, + txHash: tx.toHash(), + txCborPrefix: tx.toString().slice(0, 64), + }, + null, + 2 + ) + ); +} + +main().catch((error: unknown) => { + console.error(error); + process.exit(1); +}); diff --git a/examples/test-build-swap.ts b/examples/test-build-swap.ts new file mode 100644 index 0000000..f1d605f --- /dev/null +++ b/examples/test-build-swap.ts @@ -0,0 +1,102 @@ +import { BlockFrostAPI } from "@blockfrost/blockfrost-js"; +import { Constr } from "@spacebudz/lucid"; + +import { + ADA, + BlockfrostAdapter, + calculateSwapExactIn, + DataObject, + DataType, + Dex, + getBackendBlockfrostLucidInstance, + NetworkId, + PoolV1, +} from "../src"; + +const blockfrostProjectId = "preprodel6eWcyCZddTV1wezpV1uNlt0GpUVAcw"; +const blockfrostUrl = "https://cardano-preprod.blockfrost.io/api/v0"; +const networkId = NetworkId.TESTNET; + +// This public preprod address has a single 5 ADA UTxO, which is enough +// for a small build-only swap test without signing or submitting. +const address = + "addr_test1qpssc0r090a9u0pyvdr9y76sm2xzx04n6d4j0y5hukcx6rxz4dtgkhfdynadkea0qezv99wljdl076xkg2krm96nn8jszmh3w7"; + +const poolId = + "3bb0079303c57812462dec9de8fb867cef8fd3768de7f12c77f6f0dd80381d0d"; + +async function main(): Promise { + const lucid = await getBackendBlockfrostLucidInstance( + networkId, + blockfrostProjectId, + blockfrostUrl, + address + ); + + const adapter = new BlockfrostAdapter( + networkId, + new BlockFrostAPI({ + projectId: blockfrostProjectId, + network: "preprod", + }) + ); + + const availableUtxos = await lucid.utxosAt(address); + if (availableUtxos.length === 0) { + throw new Error("No UTxOs available for the selected testnet address"); + } + + const poolState = await adapter.getV1PoolById({ id: poolId }); + if (!poolState) { + throw new Error(`Pool ${poolId} not found on testnet`); + } + + const rawPoolDatum = await adapter.getDatumByDatumHash(poolState.datumHash); + const poolDatum = PoolV1.Datum.fromPlutusData( + networkId, + DataObject.from(rawPoolDatum) as Constr + ); + + // Keep the swap small enough to fit inside the 5 ADA source UTxO after + // the order deposit, batcher fee, and transaction fee are added. + const amountIn = 100_000n; + const { amountOut } = calculateSwapExactIn({ + amountIn: amountIn, + reserveIn: poolState.reserveA, + reserveOut: poolState.reserveB, + }); + const minimumAmountOut = (amountOut * 80n) / 100n; + + const tx = await new Dex(lucid).buildSwapExactInTx({ + sender: address, + availableUtxos: availableUtxos, + amountIn: amountIn, + assetIn: ADA, + assetOut: poolDatum.assetB, + minimumAmountOut: minimumAmountOut, + isLimitOrder: false, + }); + + console.info( + JSON.stringify( + { + address, + poolId, + inputUtxoCount: availableUtxos.length, + amountIn: amountIn.toString(), + expectedAmountOut: amountOut.toString(), + minimumAmountOut: minimumAmountOut.toString(), + fee: tx.fee, + txHash: tx.toHash(), + txCborPrefix: tx.toString().slice(0, 64), + }, + null, + 2 + ) + ); +} + +main().catch((error: unknown) => { + console.error(error); + process.exit(1); +}); From 97400763d804eb3957b88d4b6e86fd2041e44f2e Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Thu, 19 Mar 2026 16:43:47 +0700 Subject: [PATCH 4/5] remove test files Signed-off-by: Nguyen Le Vu Long --- examples/test-build-swap-build.ts | 105 ------------------------------ examples/test-build-swap.ts | 102 ----------------------------- 2 files changed, 207 deletions(-) delete mode 100644 examples/test-build-swap-build.ts delete mode 100644 examples/test-build-swap.ts diff --git a/examples/test-build-swap-build.ts b/examples/test-build-swap-build.ts deleted file mode 100644 index 0a4ead8..0000000 --- a/examples/test-build-swap-build.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { BlockFrostAPI } from "@blockfrost/blockfrost-js"; -import { Blockfrost, Data, Lucid } from "lucid-cardano"; - -import { - ADA, - BlockfrostAdapter, - calculateSwapExactIn, - Dex, - NetworkId, - PoolV1, -} from "../build/index.es.js"; - -function mustGetEnv(key: string): string { - const value = process.env[key]; - if (!value) { - throw new Error(`${key} not found`); - } - return value; -} - -async function main(): Promise { - const networkId = NetworkId.TESTNET; - const blockfrostProjectId = mustGetEnv("BLOCKFROST_PROJECT_ID_TESTNET"); - const blockfrostUrl = "https://cardano-preprod.blockfrost.io/api/v0"; - - // This public preprod address currently has a 5 ADA UTxO, which is enough - // for a small unsigned V1 swap build test. - const address = - "addr_test1qpssc0r090a9u0pyvdr9y76sm2xzx04n6d4j0y5hukcx6rxz4dtgkhfdynadkea0qezv99wljdl076xkg2krm96nn8jszmh3w7"; - const poolId = - "3bb0079303c57812462dec9de8fb867cef8fd3768de7f12c77f6f0dd80381d0d"; - - const lucid = await Lucid.new( - new Blockfrost(blockfrostUrl, blockfrostProjectId), - "Preprod" - ); - lucid.selectWalletFrom({ address: address }); - - const adapter = new BlockfrostAdapter({ - networkId: networkId, - blockFrost: new BlockFrostAPI({ - projectId: blockfrostProjectId, - network: "preprod", - }), - }); - - const availableUtxos = await lucid.utxosAt(address); - if (availableUtxos.length === 0) { - throw new Error("No UTxOs available for the selected testnet address"); - } - - const poolState = await adapter.getV1PoolById({ id: poolId }); - if (!poolState) { - throw new Error(`Pool ${poolId} not found on testnet`); - } - - const rawPoolDatum = await adapter.getDatumByDatumHash(poolState.datumHash); - const poolDatum = PoolV1.Datum.fromPlutusData( - networkId, - Data.from(rawPoolDatum) - ); - - // Keep the swap small enough to leave room for deposit ADA, batcher fee, - // and the final transaction fee inside the source UTxO. - const amountIn = 100_000n; - const { amountOut } = calculateSwapExactIn({ - amountIn: amountIn, - reserveIn: poolState.reserveA, - reserveOut: poolState.reserveB, - }); - const minimumAmountOut = (amountOut * 80n) / 100n; - - const tx = await new Dex(lucid).buildSwapExactInTx({ - sender: address, - availableUtxos: availableUtxos, - amountIn: amountIn, - assetIn: ADA, - assetOut: poolDatum.assetB, - minimumAmountOut: minimumAmountOut, - isLimitOrder: false, - }); - - console.info( - JSON.stringify( - { - address, - poolId, - inputUtxoCount: availableUtxos.length, - amountIn: amountIn.toString(), - expectedAmountOut: amountOut.toString(), - minimumAmountOut: minimumAmountOut.toString(), - fee: tx.fee, - txHash: tx.toHash(), - txCborPrefix: tx.toString().slice(0, 64), - }, - null, - 2 - ) - ); -} - -main().catch((error: unknown) => { - console.error(error); - process.exit(1); -}); diff --git a/examples/test-build-swap.ts b/examples/test-build-swap.ts deleted file mode 100644 index f1d605f..0000000 --- a/examples/test-build-swap.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { BlockFrostAPI } from "@blockfrost/blockfrost-js"; -import { Constr } from "@spacebudz/lucid"; - -import { - ADA, - BlockfrostAdapter, - calculateSwapExactIn, - DataObject, - DataType, - Dex, - getBackendBlockfrostLucidInstance, - NetworkId, - PoolV1, -} from "../src"; - -const blockfrostProjectId = "preprodel6eWcyCZddTV1wezpV1uNlt0GpUVAcw"; -const blockfrostUrl = "https://cardano-preprod.blockfrost.io/api/v0"; -const networkId = NetworkId.TESTNET; - -// This public preprod address has a single 5 ADA UTxO, which is enough -// for a small build-only swap test without signing or submitting. -const address = - "addr_test1qpssc0r090a9u0pyvdr9y76sm2xzx04n6d4j0y5hukcx6rxz4dtgkhfdynadkea0qezv99wljdl076xkg2krm96nn8jszmh3w7"; - -const poolId = - "3bb0079303c57812462dec9de8fb867cef8fd3768de7f12c77f6f0dd80381d0d"; - -async function main(): Promise { - const lucid = await getBackendBlockfrostLucidInstance( - networkId, - blockfrostProjectId, - blockfrostUrl, - address - ); - - const adapter = new BlockfrostAdapter( - networkId, - new BlockFrostAPI({ - projectId: blockfrostProjectId, - network: "preprod", - }) - ); - - const availableUtxos = await lucid.utxosAt(address); - if (availableUtxos.length === 0) { - throw new Error("No UTxOs available for the selected testnet address"); - } - - const poolState = await adapter.getV1PoolById({ id: poolId }); - if (!poolState) { - throw new Error(`Pool ${poolId} not found on testnet`); - } - - const rawPoolDatum = await adapter.getDatumByDatumHash(poolState.datumHash); - const poolDatum = PoolV1.Datum.fromPlutusData( - networkId, - DataObject.from(rawPoolDatum) as Constr - ); - - // Keep the swap small enough to fit inside the 5 ADA source UTxO after - // the order deposit, batcher fee, and transaction fee are added. - const amountIn = 100_000n; - const { amountOut } = calculateSwapExactIn({ - amountIn: amountIn, - reserveIn: poolState.reserveA, - reserveOut: poolState.reserveB, - }); - const minimumAmountOut = (amountOut * 80n) / 100n; - - const tx = await new Dex(lucid).buildSwapExactInTx({ - sender: address, - availableUtxos: availableUtxos, - amountIn: amountIn, - assetIn: ADA, - assetOut: poolDatum.assetB, - minimumAmountOut: minimumAmountOut, - isLimitOrder: false, - }); - - console.info( - JSON.stringify( - { - address, - poolId, - inputUtxoCount: availableUtxos.length, - amountIn: amountIn.toString(), - expectedAmountOut: amountOut.toString(), - minimumAmountOut: minimumAmountOut.toString(), - fee: tx.fee, - txHash: tx.toHash(), - txCborPrefix: tx.toString().slice(0, 64), - }, - null, - 2 - ) - ); -} - -main().catch((error: unknown) => { - console.error(error); - process.exit(1); -}); From 42388f0ded0073f5c75365074c5152dcc89c456d Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Thu, 19 Mar 2026 16:45:23 +0700 Subject: [PATCH 5/5] add GEMINI.md Signed-off-by: Nguyen Le Vu Long --- GEMINI.md | 1 + 1 file changed, 1 insertion(+) create mode 120000 GEMINI.md diff --git a/GEMINI.md b/GEMINI.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file