@p2pdotme/sdk 1.2.18 → 1.2.19

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/orders.d.cts CHANGED
@@ -36,7 +36,7 @@ declare class SdkError<TCode extends string = string> extends Error {
36
36
  });
37
37
  }
38
38
 
39
- type OrdersErrorCode = "VALIDATION_ERROR" | "INVALID_ORDER_ID" | "INVALID_GET_ORDERS_PARAMS" | "INVALID_FEE_CONFIG_PARAMS" | "ORDER_NOT_FOUND" | "CONTRACT_READ_FAILED" | "SUBGRAPH_REQUEST_FAILED" | "SUBGRAPH_VALIDATION_FAILED" | "MALFORMED_ORDER" | "CIRCLE_SELECTION_FAILED" | "ENCRYPTION_FAILED" | "RELAY_IDENTITY_CORRUPT" | "RELAY_IDENTITY_STORE_FAILED" | "TX_SUBMISSION_FAILED" | "RECEIPT_TIMEOUT" | "TX_REVERTED" | "EVENT_WATCH_FAILED";
39
+ type OrdersErrorCode = "VALIDATION_ERROR" | "INVALID_ORDER_ID" | "INVALID_GET_ORDERS_PARAMS" | "INVALID_FEE_CONFIG_PARAMS" | "INVALID_PLACEMENT_LIMITS_PARAMS" | "ORDER_NOT_FOUND" | "CONTRACT_READ_FAILED" | "SUBGRAPH_REQUEST_FAILED" | "SUBGRAPH_VALIDATION_FAILED" | "MALFORMED_ORDER" | "CIRCLE_SELECTION_FAILED" | "ENCRYPTION_FAILED" | "RELAY_IDENTITY_CORRUPT" | "RELAY_IDENTITY_STORE_FAILED" | "TX_SUBMISSION_FAILED" | "RECEIPT_TIMEOUT" | "TX_REVERTED" | "EVENT_WATCH_FAILED";
40
40
  declare class OrdersError extends SdkError<OrdersErrorCode> {
41
41
  constructor(message: string, options: {
42
42
  code: OrdersErrorCode;
@@ -104,6 +104,10 @@ declare const ZodGetFeeConfigParamsSchema: z.ZodObject<{
104
104
  }>;
105
105
  }, z.core.$strip>;
106
106
  type GetFeeConfigParams = z.infer<typeof ZodGetFeeConfigParamsSchema>;
107
+ declare const ZodGetPlacementLimitsParamsSchema: z.ZodObject<{
108
+ userAddress: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>;
109
+ }, z.core.$strip>;
110
+ type GetPlacementLimitsParams = z.infer<typeof ZodGetPlacementLimitsParamsSchema>;
107
111
  declare const ZodGetOrdersParamsSchema: z.ZodObject<{
108
112
  userAddress: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>;
109
113
  skip: z.ZodDefault<z.ZodNumber>;
@@ -214,6 +218,40 @@ interface FeeConfig {
214
218
  /** Fixed fee applied to small orders (6 decimals). */
215
219
  smallOrderFixedFee: bigint;
216
220
  }
221
+ /**
222
+ * Whether a daily placement cap is actually in force.
223
+ * - `enforced` — a cap is set and the contract will reject placements past it.
224
+ * - `unlimited` — the cap is explicitly zero, which the contract reads as no
225
+ * cap at all (sell/pay only; a zero buy cap blocks every buy instead).
226
+ * - `unknown` — no cap has been indexed yet, so nothing here should be shown
227
+ * as a limit. Let the contract be the judge.
228
+ */
229
+ type PlacementLimitState = "enforced" | "unlimited" | "unknown";
230
+ /**
231
+ * One daily placement bucket. `used` counts every order placed today INCLUDING
232
+ * ones that were later cancelled — the on-chain counter is never credited back,
233
+ * so cancelling does not free up an allowance.
234
+ */
235
+ interface PlacementBucket {
236
+ used: number;
237
+ /** The cap itself. Null unless `state` is `enforced`. */
238
+ limit: number | null;
239
+ /** `limit - used`, floored at zero. Null unless `state` is `enforced`. */
240
+ remaining: number | null;
241
+ state: PlacementLimitState;
242
+ }
243
+ /**
244
+ * Per-user daily order placement allowances, read from the subgraph. SELL and
245
+ * PAY draw on one shared bucket; BUY has its own. Both reset at UTC midnight.
246
+ */
247
+ interface PlacementLimits {
248
+ /** UTC day these counts belong to (unix seconds / 86400). */
249
+ dayIndex: number;
250
+ /** Unix seconds at which the buckets reset (the next UTC midnight). */
251
+ resetsAt: number;
252
+ buy: PlacementBucket;
253
+ sellPay: PlacementBucket;
254
+ }
217
255
  interface OrdersConfig {
218
256
  readonly publicClient: PublicClientLike;
219
257
  readonly diamondAddress: Address;
@@ -331,6 +369,15 @@ interface OrdersClient {
331
369
  * fee itself. Both are 6-decimal bigints.
332
370
  */
333
371
  getFeeConfig(params: GetFeeConfigParams): ResultAsync<FeeConfig, OrdersError>;
372
+ /**
373
+ * Reads the user's daily order placement allowances from the subgraph — how
374
+ * many buy and sell/pay orders they have placed today and the caps in force.
375
+ * Cancelled orders still count; SELL and PAY share one bucket.
376
+ *
377
+ * Advisory only: the subgraph lags the chain, so use it to warn or disable a
378
+ * button, never as the final word on whether a placement will succeed.
379
+ */
380
+ getPlacementLimits(params: GetPlacementLimitsParams): ResultAsync<PlacementLimits, OrdersError>;
334
381
  readonly placeOrder: PlaceOrderAction;
335
382
  readonly cancelOrder: CancelOrderAction;
336
383
  readonly setSellOrderUpi: SetSellOrderUpiAction;
@@ -423,6 +470,8 @@ declare const contractErrors: {
423
470
  readonly CashbackTransferFailed: "CASHBACK_TRANSFER_FAILED";
424
471
  readonly DailyBuyOrderLimitExceeded: "DAILY_BUY_ORDER_LIMIT_EXCEEDED";
425
472
  readonly MonthlyBuyOrderLimitExceeded: "MONTHLY_BUY_ORDER_LIMIT_EXCEEDED";
473
+ readonly DailyBuyOrderPlacementLimitExceeded: "DAILY_BUY_ORDER_PLACEMENT_LIMIT_EXCEEDED";
474
+ readonly DailySellOrderPlacementLimitExceeded: "DAILY_SELL_ORDER_PLACEMENT_LIMIT_EXCEEDED";
426
475
  readonly SellOrderAmountLimitExceeded: "SELL_ORDER_AMOUNT_LIMIT_EXCEEDED";
427
476
  readonly BuyOrderAmountExceedsLimit: "BUY_ORDER_AMOUNT_EXCEEDS_LIMIT";
428
477
  readonly SellOrderAmountExceedsLimit: "SELL_ORDER_AMOUNT_EXCEEDS_LIMIT";
@@ -627,4 +676,4 @@ interface DecryptPaymentAddressInput {
627
676
  */
628
677
  declare function decryptPaymentAddress(input: DecryptPaymentAddressInput): ResultAsync<string, OrdersError>;
629
678
 
630
- export { type ApproveUsdcParams, type CancelOrderParams, type ContractErrorCode, type DisputeStatus, type ExecuteBase, type FeeConfig, type GetFeeConfigParams, type GetOrderParams, type GetOrdersParams, type Order, type OrderEvent, type OrderStatus, type OrderType, type OrdersClient, type OrdersConfig, OrdersError, type OrdersErrorCode, type PaidBuyOrderAction, type PaidBuyOrderParams, type PlaceOrderParams, type PreparedTx, type PreparedTxMeta, type RaiseDisputeParams, type RelayIdentity, type RelayIdentityStore, type SetSellOrderUpiParams, type TxResult, type TxResultMeta, type WatchEventsParams, cipherParse, cipherStringify, contractErrorMessages, contractErrors, createInMemoryRelayStore, createLocalStorageRelayStore, createOrders, createRelayIdentity, decryptPaymentAddress, encryptPaymentAddress, getContractErrorMessage, hexContractErrors, parseContractError };
679
+ export { type ApproveUsdcParams, type CancelOrderParams, type ContractErrorCode, type DisputeStatus, type ExecuteBase, type FeeConfig, type GetFeeConfigParams, type GetOrderParams, type GetOrdersParams, type GetPlacementLimitsParams, type Order, type OrderEvent, type OrderStatus, type OrderType, type OrdersClient, type OrdersConfig, OrdersError, type OrdersErrorCode, type PaidBuyOrderAction, type PaidBuyOrderParams, type PlaceOrderParams, type PlacementBucket, type PlacementLimitState, type PlacementLimits, type PreparedTx, type PreparedTxMeta, type RaiseDisputeParams, type RelayIdentity, type RelayIdentityStore, type SetSellOrderUpiParams, type TxResult, type TxResultMeta, type WatchEventsParams, cipherParse, cipherStringify, contractErrorMessages, contractErrors, createInMemoryRelayStore, createLocalStorageRelayStore, createOrders, createRelayIdentity, decryptPaymentAddress, encryptPaymentAddress, getContractErrorMessage, hexContractErrors, parseContractError };
package/dist/orders.d.ts CHANGED
@@ -36,7 +36,7 @@ declare class SdkError<TCode extends string = string> extends Error {
36
36
  });
37
37
  }
38
38
 
39
- type OrdersErrorCode = "VALIDATION_ERROR" | "INVALID_ORDER_ID" | "INVALID_GET_ORDERS_PARAMS" | "INVALID_FEE_CONFIG_PARAMS" | "ORDER_NOT_FOUND" | "CONTRACT_READ_FAILED" | "SUBGRAPH_REQUEST_FAILED" | "SUBGRAPH_VALIDATION_FAILED" | "MALFORMED_ORDER" | "CIRCLE_SELECTION_FAILED" | "ENCRYPTION_FAILED" | "RELAY_IDENTITY_CORRUPT" | "RELAY_IDENTITY_STORE_FAILED" | "TX_SUBMISSION_FAILED" | "RECEIPT_TIMEOUT" | "TX_REVERTED" | "EVENT_WATCH_FAILED";
39
+ type OrdersErrorCode = "VALIDATION_ERROR" | "INVALID_ORDER_ID" | "INVALID_GET_ORDERS_PARAMS" | "INVALID_FEE_CONFIG_PARAMS" | "INVALID_PLACEMENT_LIMITS_PARAMS" | "ORDER_NOT_FOUND" | "CONTRACT_READ_FAILED" | "SUBGRAPH_REQUEST_FAILED" | "SUBGRAPH_VALIDATION_FAILED" | "MALFORMED_ORDER" | "CIRCLE_SELECTION_FAILED" | "ENCRYPTION_FAILED" | "RELAY_IDENTITY_CORRUPT" | "RELAY_IDENTITY_STORE_FAILED" | "TX_SUBMISSION_FAILED" | "RECEIPT_TIMEOUT" | "TX_REVERTED" | "EVENT_WATCH_FAILED";
40
40
  declare class OrdersError extends SdkError<OrdersErrorCode> {
41
41
  constructor(message: string, options: {
42
42
  code: OrdersErrorCode;
@@ -104,6 +104,10 @@ declare const ZodGetFeeConfigParamsSchema: z.ZodObject<{
104
104
  }>;
105
105
  }, z.core.$strip>;
106
106
  type GetFeeConfigParams = z.infer<typeof ZodGetFeeConfigParamsSchema>;
107
+ declare const ZodGetPlacementLimitsParamsSchema: z.ZodObject<{
108
+ userAddress: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>;
109
+ }, z.core.$strip>;
110
+ type GetPlacementLimitsParams = z.infer<typeof ZodGetPlacementLimitsParamsSchema>;
107
111
  declare const ZodGetOrdersParamsSchema: z.ZodObject<{
108
112
  userAddress: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>;
109
113
  skip: z.ZodDefault<z.ZodNumber>;
@@ -214,6 +218,40 @@ interface FeeConfig {
214
218
  /** Fixed fee applied to small orders (6 decimals). */
215
219
  smallOrderFixedFee: bigint;
216
220
  }
221
+ /**
222
+ * Whether a daily placement cap is actually in force.
223
+ * - `enforced` — a cap is set and the contract will reject placements past it.
224
+ * - `unlimited` — the cap is explicitly zero, which the contract reads as no
225
+ * cap at all (sell/pay only; a zero buy cap blocks every buy instead).
226
+ * - `unknown` — no cap has been indexed yet, so nothing here should be shown
227
+ * as a limit. Let the contract be the judge.
228
+ */
229
+ type PlacementLimitState = "enforced" | "unlimited" | "unknown";
230
+ /**
231
+ * One daily placement bucket. `used` counts every order placed today INCLUDING
232
+ * ones that were later cancelled — the on-chain counter is never credited back,
233
+ * so cancelling does not free up an allowance.
234
+ */
235
+ interface PlacementBucket {
236
+ used: number;
237
+ /** The cap itself. Null unless `state` is `enforced`. */
238
+ limit: number | null;
239
+ /** `limit - used`, floored at zero. Null unless `state` is `enforced`. */
240
+ remaining: number | null;
241
+ state: PlacementLimitState;
242
+ }
243
+ /**
244
+ * Per-user daily order placement allowances, read from the subgraph. SELL and
245
+ * PAY draw on one shared bucket; BUY has its own. Both reset at UTC midnight.
246
+ */
247
+ interface PlacementLimits {
248
+ /** UTC day these counts belong to (unix seconds / 86400). */
249
+ dayIndex: number;
250
+ /** Unix seconds at which the buckets reset (the next UTC midnight). */
251
+ resetsAt: number;
252
+ buy: PlacementBucket;
253
+ sellPay: PlacementBucket;
254
+ }
217
255
  interface OrdersConfig {
218
256
  readonly publicClient: PublicClientLike;
219
257
  readonly diamondAddress: Address;
@@ -331,6 +369,15 @@ interface OrdersClient {
331
369
  * fee itself. Both are 6-decimal bigints.
332
370
  */
333
371
  getFeeConfig(params: GetFeeConfigParams): ResultAsync<FeeConfig, OrdersError>;
372
+ /**
373
+ * Reads the user's daily order placement allowances from the subgraph — how
374
+ * many buy and sell/pay orders they have placed today and the caps in force.
375
+ * Cancelled orders still count; SELL and PAY share one bucket.
376
+ *
377
+ * Advisory only: the subgraph lags the chain, so use it to warn or disable a
378
+ * button, never as the final word on whether a placement will succeed.
379
+ */
380
+ getPlacementLimits(params: GetPlacementLimitsParams): ResultAsync<PlacementLimits, OrdersError>;
334
381
  readonly placeOrder: PlaceOrderAction;
335
382
  readonly cancelOrder: CancelOrderAction;
336
383
  readonly setSellOrderUpi: SetSellOrderUpiAction;
@@ -423,6 +470,8 @@ declare const contractErrors: {
423
470
  readonly CashbackTransferFailed: "CASHBACK_TRANSFER_FAILED";
424
471
  readonly DailyBuyOrderLimitExceeded: "DAILY_BUY_ORDER_LIMIT_EXCEEDED";
425
472
  readonly MonthlyBuyOrderLimitExceeded: "MONTHLY_BUY_ORDER_LIMIT_EXCEEDED";
473
+ readonly DailyBuyOrderPlacementLimitExceeded: "DAILY_BUY_ORDER_PLACEMENT_LIMIT_EXCEEDED";
474
+ readonly DailySellOrderPlacementLimitExceeded: "DAILY_SELL_ORDER_PLACEMENT_LIMIT_EXCEEDED";
426
475
  readonly SellOrderAmountLimitExceeded: "SELL_ORDER_AMOUNT_LIMIT_EXCEEDED";
427
476
  readonly BuyOrderAmountExceedsLimit: "BUY_ORDER_AMOUNT_EXCEEDS_LIMIT";
428
477
  readonly SellOrderAmountExceedsLimit: "SELL_ORDER_AMOUNT_EXCEEDS_LIMIT";
@@ -627,4 +676,4 @@ interface DecryptPaymentAddressInput {
627
676
  */
628
677
  declare function decryptPaymentAddress(input: DecryptPaymentAddressInput): ResultAsync<string, OrdersError>;
629
678
 
630
- export { type ApproveUsdcParams, type CancelOrderParams, type ContractErrorCode, type DisputeStatus, type ExecuteBase, type FeeConfig, type GetFeeConfigParams, type GetOrderParams, type GetOrdersParams, type Order, type OrderEvent, type OrderStatus, type OrderType, type OrdersClient, type OrdersConfig, OrdersError, type OrdersErrorCode, type PaidBuyOrderAction, type PaidBuyOrderParams, type PlaceOrderParams, type PreparedTx, type PreparedTxMeta, type RaiseDisputeParams, type RelayIdentity, type RelayIdentityStore, type SetSellOrderUpiParams, type TxResult, type TxResultMeta, type WatchEventsParams, cipherParse, cipherStringify, contractErrorMessages, contractErrors, createInMemoryRelayStore, createLocalStorageRelayStore, createOrders, createRelayIdentity, decryptPaymentAddress, encryptPaymentAddress, getContractErrorMessage, hexContractErrors, parseContractError };
679
+ export { type ApproveUsdcParams, type CancelOrderParams, type ContractErrorCode, type DisputeStatus, type ExecuteBase, type FeeConfig, type GetFeeConfigParams, type GetOrderParams, type GetOrdersParams, type GetPlacementLimitsParams, type Order, type OrderEvent, type OrderStatus, type OrderType, type OrdersClient, type OrdersConfig, OrdersError, type OrdersErrorCode, type PaidBuyOrderAction, type PaidBuyOrderParams, type PlaceOrderParams, type PlacementBucket, type PlacementLimitState, type PlacementLimits, type PreparedTx, type PreparedTxMeta, type RaiseDisputeParams, type RelayIdentity, type RelayIdentityStore, type SetSellOrderUpiParams, type TxResult, type TxResultMeta, type WatchEventsParams, cipherParse, cipherStringify, contractErrorMessages, contractErrors, createInMemoryRelayStore, createLocalStorageRelayStore, createOrders, createRelayIdentity, decryptPaymentAddress, encryptPaymentAddress, getContractErrorMessage, hexContractErrors, parseContractError };
package/dist/orders.mjs CHANGED
@@ -1182,6 +1182,9 @@ var ZodGetOrderParamsSchema = z2.object({
1182
1182
  var ZodGetFeeConfigParamsSchema = z2.object({
1183
1183
  currency: ZodCurrencySchema
1184
1184
  });
1185
+ var ZodGetPlacementLimitsParamsSchema = z2.object({
1186
+ userAddress: ZodAddressSchema
1187
+ });
1185
1188
  var ZodGetOrdersParamsSchema = z2.object({
1186
1189
  userAddress: ZodAddressSchema,
1187
1190
  skip: z2.number().int().min(0).default(0),
@@ -1242,6 +1245,19 @@ var ZodSubgraphOrderSchema = z2.object({
1242
1245
  var ZodSubgraphOrdersResponseSchema = z2.object({
1243
1246
  orders_collection: z2.array(ZodSubgraphOrderSchema)
1244
1247
  });
1248
+ var ZodSubgraphPlacementLimitsResponseSchema = z2.object({
1249
+ userDailyPlacements: z2.object({
1250
+ dayIndex: z2.string(),
1251
+ buyPlacements: z2.string(),
1252
+ sellPlacements: z2.string()
1253
+ }).nullish(),
1254
+ orderPlacementLimitConfig: z2.object({
1255
+ dailyBuyOrderPlacementLimit: z2.string(),
1256
+ buyLimitConfigured: z2.boolean(),
1257
+ dailySellOrderPlacementLimit: z2.string(),
1258
+ sellLimitConfigured: z2.boolean()
1259
+ }).nullish()
1260
+ });
1245
1261
 
1246
1262
  // src/orders/actions/approve-usdc.ts
1247
1263
  function createApproveUsdcAction(input) {
@@ -4632,6 +4648,8 @@ var contractErrorMessages = {
4632
4648
  CASHBACK_TRANSFER_FAILED: "Cashback transfer failed",
4633
4649
  // Order limits
4634
4650
  DAILY_BUY_ORDER_LIMIT_EXCEEDED: "Daily buy order count limit exceeded",
4651
+ DAILY_BUY_ORDER_PLACEMENT_LIMIT_EXCEEDED: "You've reached today's buy order limit. Cancelled orders still count towards it \u2014 try again tomorrow.",
4652
+ DAILY_SELL_ORDER_PLACEMENT_LIMIT_EXCEEDED: "You've reached today's sell and pay order limit. Cancelled orders still count towards it \u2014 try again tomorrow.",
4635
4653
  MONTHLY_BUY_ORDER_LIMIT_EXCEEDED: "Monthly buy order count limit exceeded",
4636
4654
  SELL_ORDER_AMOUNT_LIMIT_EXCEEDED: "Sell order amount limit exceeded",
4637
4655
  BUY_ORDER_AMOUNT_EXCEEDS_LIMIT: "Buy order amount exceeds limit",
@@ -4850,6 +4868,10 @@ var contractErrors = {
4850
4868
  // Order limits
4851
4869
  DailyBuyOrderLimitExceeded: "DAILY_BUY_ORDER_LIMIT_EXCEEDED",
4852
4870
  MonthlyBuyOrderLimitExceeded: "MONTHLY_BUY_ORDER_LIMIT_EXCEEDED",
4871
+ // Gross placement caps: counted when the order is placed and never given
4872
+ // back when it is cancelled, unlike the volume limits above.
4873
+ DailyBuyOrderPlacementLimitExceeded: "DAILY_BUY_ORDER_PLACEMENT_LIMIT_EXCEEDED",
4874
+ DailySellOrderPlacementLimitExceeded: "DAILY_SELL_ORDER_PLACEMENT_LIMIT_EXCEEDED",
4853
4875
  SellOrderAmountLimitExceeded: "SELL_ORDER_AMOUNT_LIMIT_EXCEEDED",
4854
4876
  BuyOrderAmountExceedsLimit: "BUY_ORDER_AMOUNT_EXCEEDS_LIMIT",
4855
4877
  SellOrderAmountExceedsLimit: "SELL_ORDER_AMOUNT_EXCEEDS_LIMIT",
@@ -5061,6 +5083,8 @@ var hexContractErrors = {
5061
5083
  // Order limits
5062
5084
  "0xe595a7bf": contractErrors.DailyBuyOrderLimitExceeded,
5063
5085
  "0x675dbc86": contractErrors.MonthlyBuyOrderLimitExceeded,
5086
+ "0x917c7aef": contractErrors.DailyBuyOrderPlacementLimitExceeded,
5087
+ "0x4688ce73": contractErrors.DailySellOrderPlacementLimitExceeded,
5064
5088
  "0x64301cb8": contractErrors.SellOrderAmountLimitExceeded,
5065
5089
  "0x91da284f": contractErrors.BuyOrderAmountExceedsLimit,
5066
5090
  "0xb407b9ec": contractErrors.SellOrderAmountExceedsLimit,
@@ -5853,6 +5877,7 @@ function normalizeSubgraphOrder(raw) {
5853
5877
 
5854
5878
  // src/orders/subgraph/index.ts
5855
5879
  import { Result as Result4 } from "neverthrow";
5880
+ import { stringToHex as stringToHex8 } from "viem";
5856
5881
 
5857
5882
  // src/orders/subgraph/queries.ts
5858
5883
  var ORDERS_BY_USER_QUERY = (
@@ -5889,8 +5914,35 @@ var ORDERS_BY_USER_QUERY = (
5889
5914
  }
5890
5915
  `
5891
5916
  );
5917
+ var PLACEMENT_LIMITS_QUERY = (
5918
+ /* GraphQL */
5919
+ `
5920
+ query PlacementLimits($placementsId: ID!, $configId: ID!) {
5921
+ userDailyPlacements(id: $placementsId) {
5922
+ dayIndex
5923
+ buyPlacements
5924
+ sellPlacements
5925
+ }
5926
+ orderPlacementLimitConfig(id: $configId) {
5927
+ dailyBuyOrderPlacementLimit
5928
+ buyLimitConfigured
5929
+ dailySellOrderPlacementLimit
5930
+ sellLimitConfigured
5931
+ }
5932
+ }
5933
+ `
5934
+ );
5892
5935
 
5893
5936
  // src/orders/subgraph/index.ts
5937
+ var SECONDS_PER_DAY = 86400;
5938
+ var PLACEMENT_LIMIT_CONFIG_ID = stringToHex8("placement-limits");
5939
+ function bucket(used, limit, configured, zeroMeansUnlimited) {
5940
+ if (!configured) return { used, limit: null, remaining: null, state: "unknown" };
5941
+ if (limit === 0 && zeroMeansUnlimited) {
5942
+ return { used, limit: null, remaining: null, state: "unlimited" };
5943
+ }
5944
+ return { used, limit, remaining: Math.max(0, limit - used), state: "enforced" };
5945
+ }
5894
5946
  function getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger = noopLogger) {
5895
5947
  const user = userAddress.toLowerCase();
5896
5948
  logger.debug("fetching orders from subgraph", { subgraphUrl, user, skip, limit });
@@ -5917,6 +5969,54 @@ function getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger = noopLo
5917
5969
  )
5918
5970
  );
5919
5971
  }
5972
+ function getPlacementLimitsForUser(subgraphUrl, userAddress, nowSeconds, logger = noopLogger) {
5973
+ const user = userAddress.toLowerCase();
5974
+ const dayIndex = Math.floor(nowSeconds / SECONDS_PER_DAY);
5975
+ const placementsId = stringToHex8(`${user}-${dayIndex}`);
5976
+ logger.debug("fetching placement limits from subgraph", { subgraphUrl, user, dayIndex });
5977
+ return querySubgraph(subgraphUrl, {
5978
+ query: PLACEMENT_LIMITS_QUERY,
5979
+ variables: { placementsId, configId: PLACEMENT_LIMIT_CONFIG_ID }
5980
+ }).mapErr(
5981
+ (e) => new OrdersError(e.message, {
5982
+ code: "SUBGRAPH_REQUEST_FAILED",
5983
+ cause: e.cause ?? e,
5984
+ context: { user, dayIndex, ...e.context ?? {} }
5985
+ })
5986
+ ).andThen(
5987
+ (data) => validate(
5988
+ ZodSubgraphPlacementLimitsResponseSchema,
5989
+ data,
5990
+ (message, cause, d) => new OrdersError(message, {
5991
+ code: "SUBGRAPH_VALIDATION_FAILED",
5992
+ cause,
5993
+ context: { data: d }
5994
+ })
5995
+ )
5996
+ ).map((validated) => {
5997
+ const placements = validated.userDailyPlacements;
5998
+ const config = validated.orderPlacementLimitConfig;
5999
+ const buyUsed = placements ? Number(placements.buyPlacements) : 0;
6000
+ const sellUsed = placements ? Number(placements.sellPlacements) : 0;
6001
+ return {
6002
+ dayIndex,
6003
+ resetsAt: (dayIndex + 1) * SECONDS_PER_DAY,
6004
+ // A zero BUY cap is a hard block on-chain, not "unlimited".
6005
+ buy: bucket(
6006
+ buyUsed,
6007
+ config ? Number(config.dailyBuyOrderPlacementLimit) : 0,
6008
+ config?.buyLimitConfigured ?? false,
6009
+ false
6010
+ ),
6011
+ sellPay: bucket(
6012
+ sellUsed,
6013
+ config ? Number(config.dailySellOrderPlacementLimit) : 0,
6014
+ config?.sellLimitConfigured ?? false,
6015
+ true
6016
+ )
6017
+ };
6018
+ });
6019
+ }
5920
6020
 
5921
6021
  // src/orders/watch-events.ts
5922
6022
  var PLACED_CONFIG = {
@@ -6092,6 +6192,19 @@ function createOrders(config) {
6092
6192
  ({ userAddress, skip, limit }) => getOrdersForUser(subgraphUrl, userAddress, skip, limit, logger)
6093
6193
  );
6094
6194
  },
6195
+ getPlacementLimits(params) {
6196
+ return validate(
6197
+ ZodGetPlacementLimitsParamsSchema,
6198
+ params,
6199
+ (message, cause, d) => new OrdersError(message, {
6200
+ code: "INVALID_PLACEMENT_LIMITS_PARAMS",
6201
+ cause,
6202
+ context: { params: d }
6203
+ })
6204
+ ).asyncAndThen(
6205
+ ({ userAddress }) => getPlacementLimitsForUser(subgraphUrl, userAddress, Math.floor(Date.now() / 1e3), logger)
6206
+ );
6207
+ },
6095
6208
  getFeeConfig(params) {
6096
6209
  return validate(
6097
6210
  ZodGetFeeConfigParamsSchema,