From 2c79c5fc1e426d8740f147fb6a514f3fc8ae17df Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Thu, 23 May 2024 16:59:21 +0200 Subject: [PATCH 01/10] feat: Add orderLabel, updateOrderResultFromLogs, getDefaultLimitOrderGasreq. --- src/actions/order/update.test.ts | 45 ++++++++++++++ src/index.ts | 9 +++ src/lib/index.ts | 5 ++ src/lib/limit-order.ts | 102 +++++++++++++++++++++++++++++++ test/setup.ts | 8 ++- test/src/client.ts | 11 +++- 6 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 src/actions/order/update.test.ts diff --git a/src/actions/order/update.test.ts b/src/actions/order/update.test.ts new file mode 100644 index 0000000..69e97db --- /dev/null +++ b/src/actions/order/update.test.ts @@ -0,0 +1,45 @@ +import { parseUnits } from 'viem' +import { describe, it, expect, inject } from 'vitest' +import { BS, Order } from '~mgv/lib/enums.js' +import { limitOrderResultFromLogs } from '~mgv/lib/limit-order.js' +import { getClient } from '~test/src/client.js' +import { getBook } from '../book.js' +import { simulateLimitOrder } from './new.js' +import { tickFromVolumes } from '~mgv/lib/tick.js' + +const client = getClient() +const { wethUSDC } = inject('markets') +const params = inject('mangrove') + +describe('update order', () => { + it('updates an order', async () => { + // create an order + const book = await getBook(client, params, wethUSDC) + + let baseAmount = parseUnits('1', wethUSDC.base.decimals) + let quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) + + const { request } = await simulateLimitOrder(client, params, wethUSDC, { + baseAmount, + quoteAmount, + restingOrderGasreq: 250_000n, + bs: BS.buy, + book, + orderType: Order.PO, + }) + const tx = await client.writeContract(request) + const receipt = await client.waitForTransactionReceipt({ hash: tx }) + const result = limitOrderResultFromLogs(params, wethUSDC, { + logs: receipt.logs, + user: client.account.address, + bs: BS.buy, + }) + expect(result.offer).toBeDefined() + expect(result.offer!.id).toBe(1n) + expect(result.offer!.gives).toApproximateEqual(quoteAmount) + expect(result.offer!.wants).toApproximateEqual(baseAmount) + expect(result.offer!.tick).toBe( + -tickFromVolumes(quoteAmount, baseAmount, wethUSDC.tickSpacing), + ) + }) +}) diff --git a/src/index.ts b/src/index.ts index f3dabae..21c7ce5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,8 +3,12 @@ export type { MarketOrderSimulationParams, MarketOrderResultFromLogsParams, + RawLimitOrderResultFromLogsParams, LimitOrderResultFromLogsParams, LimitOrderResult, + GetDefaultLimitOrderGasreqParams, + RawUpdateOrderResultFromLogsParams, + UpdateOrderResultFromLogsParams, AmountsToHumanPriceParams, AmountsParams, AmountsOutput, @@ -41,11 +45,16 @@ export { marketOrderSimulation, marketOrderResultFromLogs, limitOrderResultFromLogs, + orderLabel, + rawUpdateOrderResultFromLogs, + updateOrderResultFromLogs, + ParseUpdateOrderLogsError, CreateDistributionError, createGeometricDistribution, seederEventsABI, getKandelsFromLogs, validateKandelParams, + getDefaultLimitOrderGasreq, } from './lib/index.js' // --- Types --- diff --git a/src/lib/index.ts b/src/lib/index.ts index f4ba039..8df5ffa 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -60,6 +60,8 @@ export type { LimitOrderResultFromLogsParams, LimitOrderResult, GetDefaultLimitOrderGasreqParams, + RawUpdateOrderResultFromLogsParams, + UpdateOrderResultFromLogsParams, } from './limit-order.js' export { @@ -67,6 +69,9 @@ export { limitOrderResultFromLogs, getDefaultLimitOrderGasreq, orderLabel, + rawUpdateOrderResultFromLogs, + updateOrderResultFromLogs, + ParseUpdateOrderLogsError, } from './limit-order.js' // local diff --git a/src/lib/limit-order.ts b/src/lib/limit-order.ts index 7ac9ba7..59c4d71 100644 --- a/src/lib/limit-order.ts +++ b/src/lib/limit-order.ts @@ -227,3 +227,105 @@ export function orderLabel( ): (typeof _orderLabel)[TOrder] { return _orderLabel[order] } + +export type RawUpdateOrderResultFromLogsParams = { + logs: Log[] + user: Address + mgv: Address + mgvOrder: Address + olKey: OLKey + offerId: bigint +} + +export type UpdateOrderResult = { + tick: bigint + gives: bigint + wants: bigint + gasprice: bigint + gasreq: bigint + expiry?: bigint +} + +export class ParseUpdateOrderLogsError extends Error { + constructor(message: string) { + super(message) + this.name = 'ParseUpdateOrderLogsError' + } +} + +export function rawUpdateOrderResultFromLogs( + params: RawUpdateOrderResultFromLogsParams, +): UpdateOrderResult { + const events = parseEventLogs({ + abi: mgvEventsABI, + eventName: 'OfferWrite', + logs: params.logs.filter((log) => { + return isAddressEqual(log.address, params.mgv) + }), + }) + + const writeEvent = events.findLast((e) => { + return ( + e.args.olKeyHash.toLowerCase() === hash(params.olKey).toLowerCase() && + isAddressEqual(e.args.maker, params.mgvOrder) + ) + }) + + if (!writeEvent) + throw new ParseUpdateOrderLogsError('OfferWrite event not found') + + const orderEvents = parseEventLogs({ + abi: mgvOrderEventsABI, + eventName: 'SetReneging', + logs: params.logs.filter((log) => { + return isAddressEqual(log.address, params.mgvOrder) + }), + }) + + const expiryEvent = orderEvents.findLast((e) => { + return ( + e.args.offerId === params.offerId && + e.args.olKeyHash.toLowerCase() === hash(params.olKey).toLowerCase() + ) + }) + + return { + tick: writeEvent.args.tick, + gives: writeEvent.args.gives, + wants: inboundFromOutbound(writeEvent.args.tick, writeEvent.args.gives), + gasprice: writeEvent.args.gasprice, + gasreq: writeEvent.args.gasreq, + expiry: expiryEvent?.args.date, + } +} + +export type UpdateOrderResultFromLogsParams = { + logs: Log[] + user: Address + offerId: bigint + bs: BS +} + +export function updateOrderResultFromLogs( + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: UpdateOrderResultFromLogsParams, +): UpdateOrderResult { + const { + base: { address: base }, + quote: { address: quote }, + tickSpacing, + } = market + // if we buy, the resulting order has outbound as quote and inbound as base + // if we sell, the resulting order has outbound as base and inbound as quote + const olKey: OLKey = + params.bs === BS.buy + ? { outbound_tkn: quote, inbound_tkn: base, tickSpacing } + : { outbound_tkn: base, inbound_tkn: quote, tickSpacing } + + return rawUpdateOrderResultFromLogs({ + ...params, + ...actionParams, + olKey, + }) +} diff --git a/test/setup.ts b/test/setup.ts index a890689..7566e54 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,5 +1,6 @@ import { type Address, isAddress, isAddressEqual } from 'viem' -import { expect } from 'vitest' +import { afterEach, expect } from 'vitest' +import { getClient } from './src/client.js' expect.extend({ toApproximateEqual: ( @@ -40,3 +41,8 @@ expect.extend({ } }, }) + +afterEach(async () => { + const client = getClient() + await client.reset() +}) diff --git a/test/src/client.ts b/test/src/client.ts index 2bfe3cc..a60bcdd 100644 --- a/test/src/client.ts +++ b/test/src/client.ts @@ -5,6 +5,7 @@ import { publicActions, walletActions, } from 'viem' +// import { ipc } from 'viem/node' import { privateKeyToAccount } from 'viem/accounts' import { foundry } from 'viem/chains' import { multicall } from '~test/globalSetup.js' @@ -43,11 +44,15 @@ export function getClient() { }, }) + const httpTransport = http( + `http://localhost:${process.env.PROXY_PORT || 8545}/${poolId}`, + ) + + // const ipcTransport = ipc(`/tmp/anvil-${poolId}.ipc`) + return createTestClient({ chain: mgvTestChain, - transport: http( - `http://localhost:${process.env.PROXY_PORT || 8545}/${poolId}`, - ), + transport: httpTransport, mode: 'anvil', account: privateKeyToAccount(accounts[0].privateKey), }) From aee3f8587fa54beece82850dec49d598bcfbc52d Mon Sep 17 00:00:00 2001 From: maxencerb Date: Thu, 23 May 2024 14:59:51 +0000 Subject: [PATCH 02/10] chore: format --- src/actions/order/update.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/actions/order/update.test.ts b/src/actions/order/update.test.ts index 69e97db..5f6a042 100644 --- a/src/actions/order/update.test.ts +++ b/src/actions/order/update.test.ts @@ -1,11 +1,11 @@ import { parseUnits } from 'viem' -import { describe, it, expect, inject } from 'vitest' +import { describe, expect, inject, it } from 'vitest' import { BS, Order } from '~mgv/lib/enums.js' import { limitOrderResultFromLogs } from '~mgv/lib/limit-order.js' +import { tickFromVolumes } from '~mgv/lib/tick.js' import { getClient } from '~test/src/client.js' import { getBook } from '../book.js' import { simulateLimitOrder } from './new.js' -import { tickFromVolumes } from '~mgv/lib/tick.js' const client = getClient() const { wethUSDC } = inject('markets') @@ -16,8 +16,8 @@ describe('update order', () => { // create an order const book = await getBook(client, params, wethUSDC) - let baseAmount = parseUnits('1', wethUSDC.base.decimals) - let quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) + const baseAmount = parseUnits('1', wethUSDC.base.decimals) + const quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) const { request } = await simulateLimitOrder(client, params, wethUSDC, { baseAmount, From ff6ff6e39ffe56b79bdd51aaaf4b4c9447675706 Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Thu, 23 May 2024 17:34:18 +0200 Subject: [PATCH 03/10] feat: Refactor update order test and fix variable declaration. --- src/actions/order/update.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/actions/order/update.test.ts b/src/actions/order/update.test.ts index 33ae080..63ffbe7 100644 --- a/src/actions/order/update.test.ts +++ b/src/actions/order/update.test.ts @@ -3,13 +3,13 @@ import { describe, expect, inject, it } from 'vitest' import { BS, Order } from '~mgv/lib/enums.js' import { limitOrderResultFromLogs, - updateOrderResultFromLogs, setExpirationResultFromLogs, + updateOrderResultFromLogs, } from '~mgv/lib/limit-order.js' +import { tickFromVolumes } from '~mgv/lib/tick.js' import { getClient } from '~test/src/client.js' import { getBook } from '../book.js' import { simulateLimitOrder } from './new.js' -import { tickFromVolumes } from '~mgv/lib/tick.js' import { simulateSetExpiration, simulateUpdateOrder } from './update.js' const client = getClient() @@ -21,8 +21,8 @@ describe('update order', () => { // create an order const book = await getBook(client, params, wethUSDC) - const baseAmount = parseUnits('1', wethUSDC.base.decimals) - const quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) + let baseAmount = parseUnits('1', wethUSDC.base.decimals) + let quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) const { request } = await simulateLimitOrder(client, params, wethUSDC, { baseAmount, From 4a76d4c79848586e0fc26f16c092ca4d77cca1a0 Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Thu, 23 May 2024 17:36:36 +0200 Subject: [PATCH 04/10] feat: Add set expiration result from logs params to limit order exports. --- src/index.ts | 4 ++++ src/lib/index.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/index.ts b/src/index.ts index 21c7ce5..3b5c164 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,8 @@ export type { RawKandelParams, KandelParams, ValidateParamsResult, + RawSetExpirationResultFromLogsParams, + SetExpirationResultFromLogsParams, } from './lib/index.js' export { @@ -55,6 +57,8 @@ export { getKandelsFromLogs, validateKandelParams, getDefaultLimitOrderGasreq, + rawSetExpirationResultFromLogs, + setExpirationResultFromLogs, } from './lib/index.js' // --- Types --- diff --git a/src/lib/index.ts b/src/lib/index.ts index 8df5ffa..bf9fd0b 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -62,6 +62,8 @@ export type { GetDefaultLimitOrderGasreqParams, RawUpdateOrderResultFromLogsParams, UpdateOrderResultFromLogsParams, + RawSetExpirationResultFromLogsParams, + SetExpirationResultFromLogsParams, } from './limit-order.js' export { @@ -72,6 +74,8 @@ export { rawUpdateOrderResultFromLogs, updateOrderResultFromLogs, ParseUpdateOrderLogsError, + rawSetExpirationResultFromLogs, + setExpirationResultFromLogs, } from './limit-order.js' // local From 7c2a63150910683f5e49730bb099bce34489cccd Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Thu, 23 May 2024 17:53:02 +0200 Subject: [PATCH 05/10] feat: Add remove order functionality with deprovision flag. --- src/actions/order/remove.test.ts | 113 +++++++++++++++++++++++++++++++ src/actions/order/update.test.ts | 1 - src/index.ts | 5 ++ src/lib/index.ts | 5 ++ src/lib/limit-order.ts | 61 +++++++++++++++++ 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/actions/order/remove.test.ts diff --git a/src/actions/order/remove.test.ts b/src/actions/order/remove.test.ts new file mode 100644 index 0000000..f315e32 --- /dev/null +++ b/src/actions/order/remove.test.ts @@ -0,0 +1,113 @@ +import { parseUnits } from 'viem' +import { describe, expect, inject, it } from 'vitest' +import { BS, Order } from '~mgv/lib/enums.js' +import { + limitOrderResultFromLogs, + removeOrderResultFromLogs, +} from '~mgv/lib/limit-order.js' +import { getClient } from '~test/src/client.js' +import { getBook } from '../book.js' +import { simulateLimitOrder } from './new.js' +import { simulateRemoveOrder } from './remove.js' + +const client = getClient() +const { wethUSDC } = inject('markets') +const params = inject('mangrove') + +describe('remove order', () => { + it('removes the order: no deprovisionning', async () => { + // create an order + const book = await getBook(client, params, wethUSDC) + + const baseAmount = parseUnits('1', wethUSDC.base.decimals) + const quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) + + const { request } = await simulateLimitOrder(client, params, wethUSDC, { + baseAmount, + quoteAmount, + restingOrderGasreq: 250_000n, + bs: BS.buy, + book, + orderType: Order.PO, + }) + const tx = await client.writeContract(request) + const receipt = await client.waitForTransactionReceipt({ hash: tx }) + const result = limitOrderResultFromLogs(params, wethUSDC, { + logs: receipt.logs, + user: client.account.address, + bs: BS.buy, + }) + expect(result.offer).toBeDefined() + expect(result.offer!.id).toBe(1n) + + const { request: removeRequest } = await simulateRemoveOrder( + client, + params, + wethUSDC, + { + bs: BS.buy, + offerId: 1n, + deprovision: false, + }, + ) + const removeTx = await client.writeContract(removeRequest) + const removeReceipt = await client.waitForTransactionReceipt({ + hash: removeTx, + }) + const removeResult = removeOrderResultFromLogs(params, wethUSDC, { + logs: removeReceipt.logs, + offerId: 1n, + bs: BS.buy, + }) + expect(removeResult.success).toBeTruthy() + expect(removeResult.deprovision).toBeFalsy() + }) + + it('removes the order: deprovisionning', async () => { + // create an order + const book = await getBook(client, params, wethUSDC) + + const baseAmount = parseUnits('1', wethUSDC.base.decimals) + const quoteAmount = parseUnits('3000', wethUSDC.quote.decimals) + + const { request } = await simulateLimitOrder(client, params, wethUSDC, { + baseAmount, + quoteAmount, + restingOrderGasreq: 250_000n, + bs: BS.buy, + book, + orderType: Order.PO, + }) + const tx = await client.writeContract(request) + const receipt = await client.waitForTransactionReceipt({ hash: tx }) + const result = limitOrderResultFromLogs(params, wethUSDC, { + logs: receipt.logs, + user: client.account.address, + bs: BS.buy, + }) + expect(result.offer).toBeDefined() + expect(result.offer!.id).toBe(1n) + + const { request: removeRequest } = await simulateRemoveOrder( + client, + params, + wethUSDC, + { + bs: BS.buy, + offerId: 1n, + deprovision: true, + }, + ) + const removeTx = await client.writeContract(removeRequest) + const removeReceipt = await client.waitForTransactionReceipt({ + hash: removeTx, + }) + const removeResult = removeOrderResultFromLogs(params, wethUSDC, { + logs: removeReceipt.logs, + offerId: 1n, + bs: BS.buy, + }) + expect(removeResult.success).toBeTruthy() + expect(removeResult.deprovision).toBeTruthy() + }) +}) diff --git a/src/actions/order/update.test.ts b/src/actions/order/update.test.ts index 63ffbe7..e6f2aa0 100644 --- a/src/actions/order/update.test.ts +++ b/src/actions/order/update.test.ts @@ -69,7 +69,6 @@ describe('update order', () => { }) const updateResult = updateOrderResultFromLogs(params, wethUSDC, { logs: updateReceipt.logs, - user: client.account.address, bs: BS.buy, offerId: 1n, }) diff --git a/src/index.ts b/src/index.ts index 3b5c164..c14d3b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,9 @@ export type { ValidateParamsResult, RawSetExpirationResultFromLogsParams, SetExpirationResultFromLogsParams, + RawRemoveOrderResultFromLogsParams, + RemoveOrderResult, + RemoveOrderResultFromLogsParams, } from './lib/index.js' export { @@ -59,6 +62,8 @@ export { getDefaultLimitOrderGasreq, rawSetExpirationResultFromLogs, setExpirationResultFromLogs, + rawRemoveOrderResultFromLogs, + removeOrderResultFromLogs, } from './lib/index.js' // --- Types --- diff --git a/src/lib/index.ts b/src/lib/index.ts index bf9fd0b..2c267fb 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -64,6 +64,9 @@ export type { UpdateOrderResultFromLogsParams, RawSetExpirationResultFromLogsParams, SetExpirationResultFromLogsParams, + RawRemoveOrderResultFromLogsParams, + RemoveOrderResult, + RemoveOrderResultFromLogsParams, } from './limit-order.js' export { @@ -76,6 +79,8 @@ export { ParseUpdateOrderLogsError, rawSetExpirationResultFromLogs, setExpirationResultFromLogs, + rawRemoveOrderResultFromLogs, + removeOrderResultFromLogs, } from './limit-order.js' // local diff --git a/src/lib/limit-order.ts b/src/lib/limit-order.ts index 13657b4..bd95802 100644 --- a/src/lib/limit-order.ts +++ b/src/lib/limit-order.ts @@ -365,3 +365,64 @@ export function setExpirationResultFromLogs( olKey, }) } + +export type RawRemoveOrderResultFromLogsParams = { + logs: Log[] + mgv: Address + olKey: OLKey + offerId: bigint +} + +export type RemoveOrderResult = { + success: boolean + deprovision: boolean +} + +export function rawRemoveOrderResultFromLogs( + params: RawRemoveOrderResultFromLogsParams, +): RemoveOrderResult { + const events = parseEventLogs({ + abi: mgvEventsABI, + eventName: 'OfferRetract', + logs: params.logs.filter((log) => { + return isAddressEqual(log.address, params.mgv) + }), + }) + const event = events.findLast((e) => { + return ( + e.args.olKeyHash.toLowerCase() === hash(params.olKey).toLowerCase() && + e.args.id === params.offerId + ) + }) + return { + success: !!event, + deprovision: event?.args.deprovision ?? false, + } +} + +export type RemoveOrderResultFromLogsParams = { + logs: Log[] + offerId: bigint + bs: BS +} + +export function removeOrderResultFromLogs( + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: RemoveOrderResultFromLogsParams, +): RemoveOrderResult { + const { + base: { address: base }, + quote: { address: quote }, + tickSpacing, + } = market + const olKey: OLKey = + params.bs === BS.buy + ? { outbound_tkn: quote, inbound_tkn: base, tickSpacing } + : { outbound_tkn: base, inbound_tkn: quote, tickSpacing } + return rawRemoveOrderResultFromLogs({ + ...params, + ...actionParams, + olKey, + }) +} From e91b7c4e7240e0578b3243ee13c2e3c08e6bdf0c Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Thu, 23 May 2024 17:53:51 +0200 Subject: [PATCH 06/10] feat: Add logs result on update and remove unnecessary code. --- .changeset/chatty-maps-do.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chatty-maps-do.md diff --git a/.changeset/chatty-maps-do.md b/.changeset/chatty-maps-do.md new file mode 100644 index 0000000..c7f5ded --- /dev/null +++ b/.changeset/chatty-maps-do.md @@ -0,0 +1,5 @@ +--- +"@mangrovedao/mgv": patch +--- + +Add result from logs on update, and remove From 46050ac342238b9313a6b5154737e7c0fc15aca3 Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Fri, 24 May 2024 15:01:12 +0200 Subject: [PATCH 07/10] feat(market-actions): Add functions to wait for order results. --- src/actions/index.ts | 10 +++ src/actions/market-order.ts | 34 +++++++- src/actions/order/index.ts | 14 ++++ src/actions/order/results.ts | 114 ++++++++++++++++++++++++++ src/bundle/public/market-actions.ts | 120 ++++++++++++++++++++++++++++ src/index.ts | 10 +++ 6 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 src/actions/order/results.ts diff --git a/src/actions/index.ts b/src/actions/index.ts index b7aa21c..438de29 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -17,6 +17,10 @@ export type { SimulateRawRemoveOrderArgs, SimulateRemoveOrderArgs, RetractOrderResult, + WaitForLimitOrderResultParams, + WaitForLimitOrderUpdateResultParams, + WaitForSetExpirationResultParams, + WaitForRemoveLimitOrderResult, } from './order/index.js' export { @@ -32,6 +36,10 @@ export { simulateSetExpiration, simulateRawRemoveOrder, simulateRemoveOrder, + waitForLimitOrderResult, + waitForLimitOrderUpdateResult, + waitForSetExpirationResult, + waitForRemoveLimitOrderResult, } from './order/index.js' export type { @@ -71,6 +79,7 @@ export type { SimulateMarketOrderByTickArgs, SimulateMarketOrderByVolumeArgs, SimulateMarketOrderByVolumeAndMarketArgs, + WaitForMarketOrderResultParams, } from './market-order.js' export { @@ -78,4 +87,5 @@ export { simulateMarketOrderByTick, simulateMarketOrderByVolume, simulateMarketOrderByVolumeAndMarket, + waitForMarketOrderResult, } from './market-order.js' diff --git a/src/actions/market-order.ts b/src/actions/market-order.ts index a1c1c8e..ee5d0ac 100644 --- a/src/actions/market-order.ts +++ b/src/actions/market-order.ts @@ -3,11 +3,16 @@ import { type Client, type ReadContractParameters, type SimulateContractParameters, + type WaitForTransactionReceiptParameters, type erc20Abi, maxUint128, maxUint256, } from 'viem' -import { readContract, simulateContract } from 'viem/actions' +import { + readContract, + simulateContract, + waitForTransactionReceipt, +} from 'viem/actions' import type { MarketOrderByTickParams, MarketOrderByVolumeAndMarketParams, @@ -21,6 +26,10 @@ import { } from '../builder/market-order.js' import { tokenAllowanceParams } from '../builder/tokens.js' import { BS } from '../lib/enums.js' +import { + type MarketOrderResultFromLogsParams, + marketOrderResultFromLogs, +} from '../lib/market-order.js' import type { BuiltArgs, MangroveActionsDefaultParams, @@ -30,6 +39,7 @@ import type { MarketOrderResult } from '../types/actions/market-order.js' import type { MarketOrderSteps } from '../types/actions/steps.js' import type { Prettify } from '../types/lib.js' import { getAction } from '../utils/getAction.js' +import type { ResultWithReceipt } from './order/results.js' export type GetMarketOrderStepsParams = { user: Address @@ -172,3 +182,25 @@ export async function simulateMarketOrderByVolumeAndMarket( request, } } + +export type WaitForMarketOrderResultParams = + WaitForTransactionReceiptParameters & + Omit + +export async function waitForMarketOrderResult( + client: Client, + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: WaitForMarketOrderResultParams, +): Promise> { + const receipt = await getAction( + client, + waitForTransactionReceipt, + 'waitForTransactionReceipt', + )(params) + const result = marketOrderResultFromLogs(actionParams, market, { + ...params, + logs: receipt.logs, + }) + return { result, receipt } +} diff --git a/src/actions/order/index.ts b/src/actions/order/index.ts index 97bbf00..191c820 100644 --- a/src/actions/order/index.ts +++ b/src/actions/order/index.ts @@ -45,3 +45,17 @@ export { simulateRawRemoveOrder, simulateRemoveOrder, } from './remove.js' + +export type { + WaitForLimitOrderResultParams, + WaitForLimitOrderUpdateResultParams, + WaitForSetExpirationResultParams, + WaitForRemoveLimitOrderResult, +} from './results.js' + +export { + waitForLimitOrderResult, + waitForLimitOrderUpdateResult, + waitForSetExpirationResult, + waitForRemoveLimitOrderResult, +} from './results.js' diff --git a/src/actions/order/results.ts b/src/actions/order/results.ts new file mode 100644 index 0000000..a666875 --- /dev/null +++ b/src/actions/order/results.ts @@ -0,0 +1,114 @@ +import type { + Client, + TransactionReceipt, + WaitForTransactionReceiptParameters, +} from 'viem' +import { waitForTransactionReceipt } from 'viem/actions' +import { + type LimitOrderResult, + type LimitOrderResultFromLogsParams, + type RemoveOrderResult, + type RemoveOrderResultFromLogsParams, + type SetExpirationResultFromLogsParams, + type UpdateOrderResult, + type UpdateOrderResultFromLogsParams, + limitOrderResultFromLogs, + removeOrderResultFromLogs, + setExpirationResultFromLogs, + updateOrderResultFromLogs, +} from '../../lib/limit-order.js' +import type { + MangroveActionsDefaultParams, + MarketParams, +} from '../../types/index.js' +import { getAction } from '../../utils/getAction.js' + +export type WaitForLimitOrderResultParams = + WaitForTransactionReceiptParameters & + Omit + +export type ResultWithReceipt = { receipt: TransactionReceipt; result: T } + +export async function waitForLimitOrderResult( + client: Client, + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: WaitForLimitOrderResultParams, +): Promise> { + const receipt = await getAction( + client, + waitForTransactionReceipt, + 'waitForTransactionReceipt', + )(params) + const result = limitOrderResultFromLogs(actionParams, market, { + ...params, + logs: receipt.logs, + }) + return { receipt, result } +} + +export type WaitForLimitOrderUpdateResultParams = + WaitForTransactionReceiptParameters & + Omit + +export async function waitForLimitOrderUpdateResult( + client: Client, + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: WaitForLimitOrderUpdateResultParams, +): Promise> { + const receipt = await getAction( + client, + waitForTransactionReceipt, + 'waitForTransactionReceipt', + )(params) + const result = updateOrderResultFromLogs(actionParams, market, { + ...params, + logs: receipt.logs, + }) + return { receipt, result } +} + +export type WaitForSetExpirationResultParams = + WaitForTransactionReceiptParameters & + Omit + +export async function waitForSetExpirationResult( + client: Client, + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: WaitForSetExpirationResultParams, +): Promise> { + const receipt = await getAction( + client, + waitForTransactionReceipt, + 'waitForTransactionReceipt', + )(params) + const result = setExpirationResultFromLogs(actionParams, market, { + ...params, + logs: receipt.logs, + }) + return { receipt, result } +} + +export type WaitForRemoveLimitOrderResult = + WaitForTransactionReceiptParameters & + Omit + +export async function waitForRemoveLimitOrderResult( + client: Client, + actionParams: MangroveActionsDefaultParams, + market: MarketParams, + params: WaitForRemoveLimitOrderResult, +): Promise> { + const receipt = await getAction( + client, + waitForTransactionReceipt, + 'waitForTransactionReceipt', + )(params) + const result = removeOrderResultFromLogs(actionParams, market, { + ...params, + logs: receipt.logs, + }) + return { receipt, result } +} diff --git a/src/bundle/public/market-actions.ts b/src/bundle/public/market-actions.ts index d6fc3da..e8eea75 100644 --- a/src/bundle/public/market-actions.ts +++ b/src/bundle/public/market-actions.ts @@ -6,6 +6,10 @@ import { getMarketOrderSteps, simulateMarketOrderByVolumeAndMarket, } from '../../actions/market-order.js' +import { + type WaitForMarketOrderResultParams, + waitForMarketOrderResult, +} from '../../actions/market-order.js' import { type GetLimitOrderStepsArgs, type SimulateLimitOrderArgs, @@ -18,11 +22,27 @@ import { type SimulateRemoveOrderArgs, simulateRemoveOrder, } from '../../actions/order/remove.js' +import { + type ResultWithReceipt, + type WaitForLimitOrderResultParams, + type WaitForLimitOrderUpdateResultParams, + type WaitForRemoveLimitOrderResult, + type WaitForSetExpirationResultParams, + waitForLimitOrderResult, + waitForLimitOrderUpdateResult, + waitForRemoveLimitOrderResult, + waitForSetExpirationResult, +} from '../../actions/order/results.js' import { type SimulateUpdateOrderArgs, type SimulateUpdateOrderResult, simulateUpdateOrder, } from '../../actions/order/update.js' +import type { + LimitOrderResult, + RemoveOrderResult, + UpdateOrderResult, +} from '../../lib/limit-order.js' import type { Book } from '../../types/actions/book.js' import type { MangroveActionsDefaultParams, @@ -137,6 +157,96 @@ export type PublicMarketActions = { simulateRemoveOrder: ( args: SimulateRemoveOrderArgs, ) => Promise + + /** + * Wait for the limit order result + * @param args args for the wait for limit order result call + * @returns the limit order result + * @example + * ```ts + * const { request, result } = await publicMarketActions.simulateLimitOrder({ ... }); + * const tx = await walletClient.writeContract(request); + * const { receipt, result } = await publicMarketActions.waitForLimitOrderResult({ + * hash: tx, + * bs: BS.buy, + * user: userAddress, + * }); + */ + waitForLimitOrderResult: ( + args: WaitForLimitOrderResultParams, + ) => Promise> + + /** + * Wait for the limit order update result + * @param args args for the wait for limit order update result call + * @returns the limit order result + * @example + * ```ts + * const { request, result } = await publicMarketActions.simulateUpdateOrder({ ...}); + * const tx = await walletClient.writeContract(request); + * const { receipt, result } = await publicMarketActions.waitForLimitOrderUpdateResult({ + * hash: tx, + * bs: BS.buy, + * offerId: 1n, + * }); + */ + waitForLimitOrderUpdateResult: ( + args: WaitForLimitOrderUpdateResultParams, + ) => Promise> + + /** + * Wait for the limit order remove result + * @param args args for the wait for limit order remove result call + * @returns the limit order result + * @example + * ```ts + * const { request, result } = await publicMarketActions.simulateRemoveOrder({ ... }); + * const tx = await walletClient.writeContract(request); + * const { receipt, result } = await publicMarketActions.waitForRemoveOrderResult({ + * hash: tx, + * bs: BS.buy, + * offerId: 1n, + * }); + */ + waitForRemoveLimitOrderResult: ( + args: WaitForRemoveLimitOrderResult, + ) => Promise> + + /** + * Wait for the set expiration result + * @param args args for the wait for set expiration result call + * @returns the set expiration result + * @example + * ```ts + * const { request, result } = await publicMarketActions.simulateSetExpiration({ ... }); + * const tx = await walletClient.writeContract(request); + * const { receipt, result } = await publicMarketActions.waitForSetExpirationResult({ + * hash: tx, + * bs: BS.buy, + * offerId: 1n, + * }); + */ + waitForSetExpirationResult: ( + args: WaitForSetExpirationResultParams, + ) => Promise> + + /** + * Wait for the market order result + * @param args args for the wait for market order result call + * @returns the market order result + * @example + * ```ts + * const { request, result } = await publicMarketActions.simulateMarketOrderByVolumeAndMarket({ ... }); + * const tx = await walletClient.writeContract(request); + * const { receipt, result } = await publicMarketActions.waitForMarketOrderResult({ + * hash: tx, + * bs: BS.buy, + * taker: userAddress, + * }); + */ + waitForMarketOrderResult: ( + args: WaitForMarketOrderResultParams, + ) => Promise> } export function publicMarketActions( @@ -156,5 +266,15 @@ export function publicMarketActions( simulateUpdateOrder(client, actionParams, market, args), simulateRemoveOrder: (args) => simulateRemoveOrder(client, actionParams, market, args), + waitForLimitOrderResult: (args) => + waitForLimitOrderResult(client, actionParams, market, args), + waitForLimitOrderUpdateResult: (args) => + waitForLimitOrderUpdateResult(client, actionParams, market, args), + waitForRemoveLimitOrderResult: (args) => + waitForRemoveLimitOrderResult(client, actionParams, market, args), + waitForSetExpirationResult: (args) => + waitForSetExpirationResult(client, actionParams, market, args), + waitForMarketOrderResult: (args) => + waitForMarketOrderResult(client, actionParams, market, args), }) } diff --git a/src/index.ts b/src/index.ts index c14d3b0..8fae729 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,13 @@ +// -- actions -- + +export type { + WaitForLimitOrderResultParams, + WaitForLimitOrderUpdateResultParams, + WaitForSetExpirationResultParams, + WaitForRemoveLimitOrderResult, + WaitForMarketOrderResultParams, +} from './actions/index.js' + // -- lib functions -- export type { From 4961723819b08d6e9d8fe976fec67f28637157ea Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Fri, 24 May 2024 15:03:23 +0200 Subject: [PATCH 08/10] feat: Remove changeset --- .changeset/chatty-maps-do.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/chatty-maps-do.md diff --git a/.changeset/chatty-maps-do.md b/.changeset/chatty-maps-do.md deleted file mode 100644 index c7f5ded..0000000 --- a/.changeset/chatty-maps-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@mangrovedao/mgv": patch ---- - -Add result from logs on update, and remove From 5192c044a3820b3d66ef0c565e4e53cd4a027782 Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Fri, 24 May 2024 15:04:01 +0200 Subject: [PATCH 09/10] chore: changeset --- .changeset/lucky-birds-kneel.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lucky-birds-kneel.md diff --git a/.changeset/lucky-birds-kneel.md b/.changeset/lucky-birds-kneel.md new file mode 100644 index 0000000..6823907 --- /dev/null +++ b/.changeset/lucky-birds-kneel.md @@ -0,0 +1,5 @@ +--- +"@mangrovedao/mgv": patch +--- + +Add wait for result on orders From 765f4b7cfd4a80fab90346b1a6cd4950c35d8001 Mon Sep 17 00:00:00 2001 From: Maxence Raballand Date: Fri, 24 May 2024 15:08:26 +0200 Subject: [PATCH 10/10] refactor: Update return type of waitForMarketOrderResult to exclude 'request' field. --- src/actions/market-order.ts | 2 +- src/bundle/public/market-actions.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/actions/market-order.ts b/src/actions/market-order.ts index ee5d0ac..406aa72 100644 --- a/src/actions/market-order.ts +++ b/src/actions/market-order.ts @@ -192,7 +192,7 @@ export async function waitForMarketOrderResult( actionParams: MangroveActionsDefaultParams, market: MarketParams, params: WaitForMarketOrderResultParams, -): Promise> { +): Promise>> { const receipt = await getAction( client, waitForTransactionReceipt, diff --git a/src/bundle/public/market-actions.ts b/src/bundle/public/market-actions.ts index e8eea75..c34863c 100644 --- a/src/bundle/public/market-actions.ts +++ b/src/bundle/public/market-actions.ts @@ -246,7 +246,7 @@ export type PublicMarketActions = { */ waitForMarketOrderResult: ( args: WaitForMarketOrderResultParams, - ) => Promise> + ) => Promise>> } export function publicMarketActions(