@alpha-arcade/sdk 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -147,6 +147,18 @@ type ProposeMatchParams = {
147
147
  /** Quantity to match in microunits */
148
148
  quantityMatched: number;
149
149
  };
150
+ /**
151
+ * Parameters for matching two existing limit orders (e.g. after an amend).
152
+ * The taker is the order placed last and pays the fee; the maker is the counterparty.
153
+ */
154
+ type ProcessMatchParams = {
155
+ /** Market app ID */
156
+ marketAppId: number;
157
+ /** Maker escrow app ID (existing order — was on the book first) */
158
+ makerEscrowAppId: number;
159
+ /** Taker escrow app ID (existing order — placed last, pays the fee) */
160
+ takerEscrowAppId: number;
161
+ };
150
162
  /** Parameters for amending (editing) an existing unfilled order */
151
163
  type AmendOrderParams = {
152
164
  /** Market app ID */
@@ -202,6 +214,15 @@ type ProposeMatchResult = {
202
214
  /** Confirmed round number */
203
215
  confirmedRound: number;
204
216
  };
217
+ /** Result of processing a match between two existing orders */
218
+ type ProcessMatchResult = {
219
+ /** Whether the match succeeded */
220
+ success: boolean;
221
+ /** Transaction IDs */
222
+ txIds: string[];
223
+ /** Confirmed round number */
224
+ confirmedRound: number;
225
+ };
205
226
  /** Result of amending an order */
206
227
  type AmendOrderResult = {
207
228
  /** Whether the amendment succeeded */
@@ -210,6 +231,10 @@ type AmendOrderResult = {
210
231
  txIds: string[];
211
232
  /** Confirmed round number */
212
233
  confirmedRound: number;
234
+ /** Total quantity matched against counterparty orders (if matching was performed) */
235
+ matchedQuantity?: number;
236
+ /** Volume-weighted average fill price in microunits (if any matches) */
237
+ matchedPrice?: number;
213
238
  };
214
239
  /** A single entry in the orderbook (one price level, one order) */
215
240
  type OrderbookEntry = {
@@ -423,6 +448,17 @@ declare class AlphaClient {
423
448
  * @returns Whether the match succeeded
424
449
  */
425
450
  proposeMatch(params: ProposeMatchParams): Promise<ProposeMatchResult>;
451
+ /**
452
+ * Matches two existing limit orders (no create-escrow in the group).
453
+ *
454
+ * Calls the market app's process_potential_match(maker, taker). Use this
455
+ * after amending an order: the amended order is the taker (pays the fee),
456
+ * the counterparty is the maker.
457
+ *
458
+ * @param params - Process match params (marketAppId, makerEscrowAppId, takerEscrowAppId)
459
+ * @returns Whether the match succeeded
460
+ */
461
+ processMatch(params: ProcessMatchParams): Promise<ProcessMatchResult>;
426
462
  /**
427
463
  * Amends (edits) an existing unfilled order in-place.
428
464
  *
@@ -684,4 +720,4 @@ declare const getEscrowGlobalState: (indexerClient: algosdk.Indexer, escrowAppId
684
720
  */
685
721
  declare const checkAssetOptIn: (algodClient: algosdk.Algodv2, address: string, assetId: number) => Promise<boolean>;
686
722
 
687
- export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
723
+ export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
package/dist/index.d.ts CHANGED
@@ -147,6 +147,18 @@ type ProposeMatchParams = {
147
147
  /** Quantity to match in microunits */
148
148
  quantityMatched: number;
149
149
  };
150
+ /**
151
+ * Parameters for matching two existing limit orders (e.g. after an amend).
152
+ * The taker is the order placed last and pays the fee; the maker is the counterparty.
153
+ */
154
+ type ProcessMatchParams = {
155
+ /** Market app ID */
156
+ marketAppId: number;
157
+ /** Maker escrow app ID (existing order — was on the book first) */
158
+ makerEscrowAppId: number;
159
+ /** Taker escrow app ID (existing order — placed last, pays the fee) */
160
+ takerEscrowAppId: number;
161
+ };
150
162
  /** Parameters for amending (editing) an existing unfilled order */
151
163
  type AmendOrderParams = {
152
164
  /** Market app ID */
@@ -202,6 +214,15 @@ type ProposeMatchResult = {
202
214
  /** Confirmed round number */
203
215
  confirmedRound: number;
204
216
  };
217
+ /** Result of processing a match between two existing orders */
218
+ type ProcessMatchResult = {
219
+ /** Whether the match succeeded */
220
+ success: boolean;
221
+ /** Transaction IDs */
222
+ txIds: string[];
223
+ /** Confirmed round number */
224
+ confirmedRound: number;
225
+ };
205
226
  /** Result of amending an order */
206
227
  type AmendOrderResult = {
207
228
  /** Whether the amendment succeeded */
@@ -210,6 +231,10 @@ type AmendOrderResult = {
210
231
  txIds: string[];
211
232
  /** Confirmed round number */
212
233
  confirmedRound: number;
234
+ /** Total quantity matched against counterparty orders (if matching was performed) */
235
+ matchedQuantity?: number;
236
+ /** Volume-weighted average fill price in microunits (if any matches) */
237
+ matchedPrice?: number;
213
238
  };
214
239
  /** A single entry in the orderbook (one price level, one order) */
215
240
  type OrderbookEntry = {
@@ -423,6 +448,17 @@ declare class AlphaClient {
423
448
  * @returns Whether the match succeeded
424
449
  */
425
450
  proposeMatch(params: ProposeMatchParams): Promise<ProposeMatchResult>;
451
+ /**
452
+ * Matches two existing limit orders (no create-escrow in the group).
453
+ *
454
+ * Calls the market app's process_potential_match(maker, taker). Use this
455
+ * after amending an order: the amended order is the taker (pays the fee),
456
+ * the counterparty is the maker.
457
+ *
458
+ * @param params - Process match params (marketAppId, makerEscrowAppId, takerEscrowAppId)
459
+ * @returns Whether the match succeeded
460
+ */
461
+ processMatch(params: ProcessMatchParams): Promise<ProcessMatchResult>;
426
462
  /**
427
463
  * Amends (edits) an existing unfilled order in-place.
428
464
  *
@@ -684,4 +720,4 @@ declare const getEscrowGlobalState: (indexerClient: algosdk.Indexer, escrowAppId
684
720
  */
685
721
  declare const checkAssetOptIn: (algodClient: algosdk.Algodv2, address: string, assetId: number) => Promise<boolean>;
686
722
 
687
- export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
723
+ export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
package/dist/index.js CHANGED
@@ -2492,6 +2492,89 @@ var proposeMatch = async (config, params) => {
2492
2492
  confirmedRound: Number(result.confirmedRound)
2493
2493
  };
2494
2494
  };
2495
+ var processMatch = async (config, params) => {
2496
+ const { algodClient, signer, activeAddress, usdcAssetId } = config;
2497
+ const { marketAppId, makerEscrowAppId, takerEscrowAppId } = params;
2498
+ const [marketState, makerAppInfo, takerAppInfo] = await Promise.all([
2499
+ getMarketGlobalState(algodClient, marketAppId),
2500
+ algodClient.getApplicationByID(makerEscrowAppId).do(),
2501
+ algodClient.getApplicationByID(takerEscrowAppId).do()
2502
+ ]);
2503
+ const marketFeeAddress = marketState.fee_address;
2504
+ const yesAssetId = marketState.yes_asset_id;
2505
+ const noAssetId = marketState.no_asset_id;
2506
+ const makerState = decodeGlobalState(
2507
+ makerAppInfo.params?.globalState ?? makerAppInfo.params?.["global-state"] ?? []
2508
+ );
2509
+ const takerState = decodeGlobalState(
2510
+ takerAppInfo.params?.globalState ?? takerAppInfo.params?.["global-state"] ?? []
2511
+ );
2512
+ const makerOwner = makerState.owner ?? "";
2513
+ const takerOwner = takerState.owner ?? "";
2514
+ const makerRemaining = (makerState.quantity ?? 0) - (makerState.quantity_filled ?? 0);
2515
+ const takerRemaining = (takerState.quantity ?? 0) - (takerState.quantity_filled ?? 0);
2516
+ const matchedQuantity = Math.min(makerRemaining, takerRemaining);
2517
+ if (matchedQuantity <= 0) {
2518
+ throw new Error("processMatch: no quantity left to match on maker or taker escrow.");
2519
+ }
2520
+ const signerAccount = { signer, addr: activeAddress };
2521
+ const makerEscrowClient = new EscrowAppClient(
2522
+ { resolveBy: "id", id: makerEscrowAppId, sender: signerAccount },
2523
+ algodClient
2524
+ );
2525
+ const takerEscrowClient = new EscrowAppClient(
2526
+ { resolveBy: "id", id: takerEscrowAppId, sender: signerAccount },
2527
+ algodClient
2528
+ );
2529
+ const marketClient = new MarketAppClient(
2530
+ { resolveBy: "id", id: marketAppId, sender: signerAccount },
2531
+ algodClient
2532
+ );
2533
+ const atc = new AtomicTransactionComposer();
2534
+ const assets = [usdcAssetId, yesAssetId, noAssetId];
2535
+ const sendParamsWithFee = { skipSending: true, fee: algokit4.microAlgos(3e3) };
2536
+ const sendParamsNoop = { skipSending: true, fee: algokit4.microAlgos(1e3) };
2537
+ const matchMakerTxn = await makerEscrowClient.matchMaker(
2538
+ { taker: takerEscrowAppId, matchQuantity: matchedQuantity },
2539
+ {
2540
+ assets,
2541
+ apps: [marketAppId],
2542
+ accounts: [takerOwner, marketFeeAddress],
2543
+ sendParams: sendParamsWithFee
2544
+ }
2545
+ );
2546
+ atc.addTransaction({ txn: matchMakerTxn.transaction, signer });
2547
+ const matchTakerTxn = await takerEscrowClient.matchTaker(
2548
+ { maker: makerEscrowAppId },
2549
+ {
2550
+ assets,
2551
+ apps: [marketAppId],
2552
+ accounts: [makerOwner, marketFeeAddress],
2553
+ sendParams: sendParamsWithFee
2554
+ }
2555
+ );
2556
+ atc.addTransaction({ txn: matchTakerTxn.transaction, signer });
2557
+ const processMatchTxn = await marketClient.processPotentialMatch(
2558
+ { maker: makerEscrowAppId, taker: takerEscrowAppId },
2559
+ {
2560
+ assets,
2561
+ accounts: [makerOwner, takerOwner, marketFeeAddress],
2562
+ sendParams: sendParamsNoop
2563
+ }
2564
+ );
2565
+ atc.addTransaction({ txn: processMatchTxn.transaction, signer });
2566
+ const doNoopTxn = await marketClient.doNoop(
2567
+ { callNumber: 1 },
2568
+ { sendParams: sendParamsNoop }
2569
+ );
2570
+ atc.addTransaction({ txn: doNoopTxn.transaction, signer });
2571
+ const result = await atc.execute(algodClient, 4);
2572
+ return {
2573
+ success: true,
2574
+ txIds: result.txIDs,
2575
+ confirmedRound: Number(result.confirmedRound)
2576
+ };
2577
+ };
2495
2578
  var amendOrder = async (config, params) => {
2496
2579
  const { algodClient, signer, activeAddress, usdcAssetId } = config;
2497
2580
  const { marketAppId, escrowAppId, price, quantity, slippage = 0 } = params;
@@ -2548,10 +2631,47 @@ var amendOrder = async (config, params) => {
2548
2631
  );
2549
2632
  atc.addTransaction({ txn: amendCall.transaction, signer });
2550
2633
  const result = await atc.execute(algodClient, 4);
2634
+ const allTxIds = [...result.txIDs];
2635
+ let lastConfirmedRound = Number(result.confirmedRound);
2636
+ const orderbook = await getOrderbook(config, marketAppId);
2637
+ let matchingOrders = calculateMatchingOrders(orderbook, isBuy, position === 1, quantity, price, slippage);
2638
+ matchingOrders = matchingOrders.filter((m) => m.escrowAppId !== escrowAppId);
2639
+ if (matchingOrders.length > 0) {
2640
+ let quantityLeft = quantity;
2641
+ const matchedQuantities = [];
2642
+ const matchedPrices = [];
2643
+ for (const m of matchingOrders) {
2644
+ if (quantityLeft <= 0) break;
2645
+ try {
2646
+ const matchResult = await processMatch(config, {
2647
+ marketAppId,
2648
+ makerEscrowAppId: m.escrowAppId,
2649
+ takerEscrowAppId: escrowAppId
2650
+ });
2651
+ allTxIds.push(...matchResult.txIds);
2652
+ lastConfirmedRound = matchResult.confirmedRound;
2653
+ const q = Math.min(m.quantity, quantityLeft);
2654
+ matchedQuantities.push(q);
2655
+ matchedPrices.push((m.price ?? price) * q);
2656
+ quantityLeft -= q;
2657
+ } catch (err) {
2658
+ console.log(`Error matching order: ${JSON.stringify(err)}`);
2659
+ break;
2660
+ }
2661
+ }
2662
+ const totalMatchedQuantity = matchedQuantities.reduce((a, b) => a + b, 0);
2663
+ const matchedPrice = totalMatchedQuantity > 0 ? Math.round(matchedPrices.reduce((a, b) => a + b, 0) / totalMatchedQuantity) : void 0;
2664
+ return {
2665
+ success: true,
2666
+ txIds: allTxIds,
2667
+ confirmedRound: lastConfirmedRound,
2668
+ ...totalMatchedQuantity > 0 && { matchedQuantity: totalMatchedQuantity, matchedPrice }
2669
+ };
2670
+ }
2551
2671
  return {
2552
2672
  success: true,
2553
- txIds: result.txIDs,
2554
- confirmedRound: Number(result.confirmedRound)
2673
+ txIds: allTxIds,
2674
+ confirmedRound: lastConfirmedRound
2555
2675
  };
2556
2676
  };
2557
2677
  var splitShares = async (config, params) => {
@@ -3034,6 +3154,19 @@ var AlphaClient = class {
3034
3154
  async proposeMatch(params) {
3035
3155
  return proposeMatch(this.config, params);
3036
3156
  }
3157
+ /**
3158
+ * Matches two existing limit orders (no create-escrow in the group).
3159
+ *
3160
+ * Calls the market app's process_potential_match(maker, taker). Use this
3161
+ * after amending an order: the amended order is the taker (pays the fee),
3162
+ * the counterparty is the maker.
3163
+ *
3164
+ * @param params - Process match params (marketAppId, makerEscrowAppId, takerEscrowAppId)
3165
+ * @returns Whether the match succeeded
3166
+ */
3167
+ async processMatch(params) {
3168
+ return processMatch(this.config, params);
3169
+ }
3037
3170
  /**
3038
3171
  * Amends (edits) an existing unfilled order in-place.
3039
3172
  *