@0xslots/sdk 0.5.0 → 0.7.0

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.js CHANGED
@@ -1,10 +1,13 @@
1
1
  import { gql as gql$1, GraphQLClient } from 'graphql-request';
2
2
  import gql from 'graphql-tag';
3
+ import { encodeFunctionData, erc20Abi } from 'viem';
4
+ import { getSlotsHubAddress, slotAbi, slotFactoryAbi } from '@0xslots/contracts';
3
5
 
4
6
  // src/client.ts
5
7
  var AccountFieldsFragmentDoc = gql`
6
8
  fragment AccountFields on Account {
7
9
  id
10
+ type
8
11
  slotCount
9
12
  occupiedCount
10
13
  slotsAsRecipient {
@@ -15,6 +18,14 @@ var AccountFieldsFragmentDoc = gql`
15
18
  }
16
19
  }
17
20
  `;
21
+ var CurrencyFieldsFragmentDoc = gql`
22
+ fragment CurrencyFields on Currency {
23
+ id
24
+ name
25
+ symbol
26
+ decimals
27
+ }
28
+ `;
18
29
  var SlotFieldsFragmentDoc = gql`
19
30
  fragment SlotFields on Slot {
20
31
  id
@@ -24,15 +35,22 @@ var SlotFieldsFragmentDoc = gql`
24
35
  slotCount
25
36
  occupiedCount
26
37
  }
27
- currency
28
- currencyName
29
- currencySymbol
30
- currencyDecimals
38
+ currency {
39
+ id
40
+ name
41
+ symbol
42
+ decimals
43
+ }
31
44
  manager
32
45
  mutableTax
33
46
  mutableModule
34
47
  taxPercentage
35
- module
48
+ module {
49
+ id
50
+ verified
51
+ name
52
+ version
53
+ }
36
54
  occupant
37
55
  occupantAccount {
38
56
  id
@@ -78,6 +96,9 @@ var GetRecentEventsDocument = gql`
78
96
  slot {
79
97
  id
80
98
  }
99
+ currency {
100
+ ...CurrencyFields
101
+ }
81
102
  buyer
82
103
  previousOccupant
83
104
  price
@@ -91,6 +112,9 @@ var GetRecentEventsDocument = gql`
91
112
  slot {
92
113
  id
93
114
  }
115
+ currency {
116
+ ...CurrencyFields
117
+ }
94
118
  occupant
95
119
  refund
96
120
  timestamp
@@ -101,6 +125,9 @@ var GetRecentEventsDocument = gql`
101
125
  slot {
102
126
  id
103
127
  }
128
+ currency {
129
+ ...CurrencyFields
130
+ }
104
131
  liquidator
105
132
  occupant
106
133
  bounty
@@ -112,6 +139,9 @@ var GetRecentEventsDocument = gql`
112
139
  slot {
113
140
  id
114
141
  }
142
+ currency {
143
+ ...CurrencyFields
144
+ }
115
145
  oldPrice
116
146
  newPrice
117
147
  timestamp
@@ -122,6 +152,9 @@ var GetRecentEventsDocument = gql`
122
152
  slot {
123
153
  id
124
154
  }
155
+ currency {
156
+ ...CurrencyFields
157
+ }
125
158
  depositor
126
159
  amount
127
160
  timestamp
@@ -132,6 +165,9 @@ var GetRecentEventsDocument = gql`
132
165
  slot {
133
166
  id
134
167
  }
168
+ currency {
169
+ ...CurrencyFields
170
+ }
135
171
  occupant
136
172
  amount
137
173
  timestamp
@@ -142,13 +178,50 @@ var GetRecentEventsDocument = gql`
142
178
  slot {
143
179
  id
144
180
  }
181
+ currency {
182
+ ...CurrencyFields
183
+ }
145
184
  recipient
146
185
  amount
147
186
  timestamp
148
187
  tx
149
188
  }
189
+ taxUpdateProposedEvents(first: $first, orderBy: timestamp, orderDirection: desc) {
190
+ id
191
+ slot {
192
+ id
193
+ }
194
+ newPercentage
195
+ timestamp
196
+ tx
197
+ }
198
+ moduleUpdateProposedEvents(
199
+ first: $first
200
+ orderBy: timestamp
201
+ orderDirection: desc
202
+ ) {
203
+ id
204
+ slot {
205
+ id
206
+ }
207
+ newModule
208
+ timestamp
209
+ tx
210
+ }
211
+ pendingUpdateCancelledEvents(
212
+ first: $first
213
+ orderBy: timestamp
214
+ orderDirection: desc
215
+ ) {
216
+ id
217
+ slot {
218
+ id
219
+ }
220
+ timestamp
221
+ tx
222
+ }
150
223
  }
151
- `;
224
+ ${CurrencyFieldsFragmentDoc}`;
152
225
  var GetBoughtEventsDocument = gql`
153
226
  query GetBoughtEvents($first: Int!, $skip: Int, $orderBy: BoughtEvent_orderBy, $orderDirection: OrderDirection, $where: BoughtEvent_filter, $block: Block_height) {
154
227
  boughtEvents(
@@ -163,6 +236,9 @@ var GetBoughtEventsDocument = gql`
163
236
  slot {
164
237
  id
165
238
  }
239
+ currency {
240
+ ...CurrencyFields
241
+ }
166
242
  buyer
167
243
  previousOccupant
168
244
  price
@@ -173,7 +249,7 @@ var GetBoughtEventsDocument = gql`
173
249
  tx
174
250
  }
175
251
  }
176
- `;
252
+ ${CurrencyFieldsFragmentDoc}`;
177
253
  var GetReleasedEventsDocument = gql`
178
254
  query GetReleasedEvents($first: Int!, $skip: Int, $orderBy: ReleasedEvent_orderBy, $orderDirection: OrderDirection, $where: ReleasedEvent_filter, $block: Block_height) {
179
255
  releasedEvents(
@@ -188,6 +264,9 @@ var GetReleasedEventsDocument = gql`
188
264
  slot {
189
265
  id
190
266
  }
267
+ currency {
268
+ ...CurrencyFields
269
+ }
191
270
  occupant
192
271
  refund
193
272
  timestamp
@@ -195,7 +274,7 @@ var GetReleasedEventsDocument = gql`
195
274
  tx
196
275
  }
197
276
  }
198
- `;
277
+ ${CurrencyFieldsFragmentDoc}`;
199
278
  var GetLiquidatedEventsDocument = gql`
200
279
  query GetLiquidatedEvents($first: Int!, $skip: Int, $orderBy: LiquidatedEvent_orderBy, $orderDirection: OrderDirection, $where: LiquidatedEvent_filter, $block: Block_height) {
201
280
  liquidatedEvents(
@@ -210,6 +289,9 @@ var GetLiquidatedEventsDocument = gql`
210
289
  slot {
211
290
  id
212
291
  }
292
+ currency {
293
+ ...CurrencyFields
294
+ }
213
295
  liquidator
214
296
  occupant
215
297
  bounty
@@ -218,7 +300,7 @@ var GetLiquidatedEventsDocument = gql`
218
300
  tx
219
301
  }
220
302
  }
221
- `;
303
+ ${CurrencyFieldsFragmentDoc}`;
222
304
  var GetSettledEventsDocument = gql`
223
305
  query GetSettledEvents($first: Int!, $skip: Int, $orderBy: SettledEvent_orderBy, $orderDirection: OrderDirection, $where: SettledEvent_filter, $block: Block_height) {
224
306
  settledEvents(
@@ -233,6 +315,9 @@ var GetSettledEventsDocument = gql`
233
315
  slot {
234
316
  id
235
317
  }
318
+ currency {
319
+ ...CurrencyFields
320
+ }
236
321
  taxOwed
237
322
  taxPaid
238
323
  depositRemaining
@@ -241,7 +326,7 @@ var GetSettledEventsDocument = gql`
241
326
  tx
242
327
  }
243
328
  }
244
- `;
329
+ ${CurrencyFieldsFragmentDoc}`;
245
330
  var GetTaxCollectedEventsDocument = gql`
246
331
  query GetTaxCollectedEvents($first: Int!, $skip: Int, $orderBy: TaxCollectedEvent_orderBy, $orderDirection: OrderDirection, $where: TaxCollectedEvent_filter, $block: Block_height) {
247
332
  taxCollectedEvents(
@@ -256,6 +341,9 @@ var GetTaxCollectedEventsDocument = gql`
256
341
  slot {
257
342
  id
258
343
  }
344
+ currency {
345
+ ...CurrencyFields
346
+ }
259
347
  recipient
260
348
  amount
261
349
  timestamp
@@ -263,7 +351,7 @@ var GetTaxCollectedEventsDocument = gql`
263
351
  tx
264
352
  }
265
353
  }
266
- `;
354
+ ${CurrencyFieldsFragmentDoc}`;
267
355
  var GetDepositedEventsDocument = gql`
268
356
  query GetDepositedEvents($first: Int!, $skip: Int, $orderBy: DepositedEvent_orderBy, $orderDirection: OrderDirection, $where: DepositedEvent_filter, $block: Block_height) {
269
357
  depositedEvents(
@@ -278,6 +366,9 @@ var GetDepositedEventsDocument = gql`
278
366
  slot {
279
367
  id
280
368
  }
369
+ currency {
370
+ ...CurrencyFields
371
+ }
281
372
  depositor
282
373
  amount
283
374
  timestamp
@@ -285,7 +376,7 @@ var GetDepositedEventsDocument = gql`
285
376
  tx
286
377
  }
287
378
  }
288
- `;
379
+ ${CurrencyFieldsFragmentDoc}`;
289
380
  var GetWithdrawnEventsDocument = gql`
290
381
  query GetWithdrawnEvents($first: Int!, $skip: Int, $orderBy: WithdrawnEvent_orderBy, $orderDirection: OrderDirection, $where: WithdrawnEvent_filter, $block: Block_height) {
291
382
  withdrawnEvents(
@@ -300,6 +391,9 @@ var GetWithdrawnEventsDocument = gql`
300
391
  slot {
301
392
  id
302
393
  }
394
+ currency {
395
+ ...CurrencyFields
396
+ }
303
397
  occupant
304
398
  amount
305
399
  timestamp
@@ -307,7 +401,7 @@ var GetWithdrawnEventsDocument = gql`
307
401
  tx
308
402
  }
309
403
  }
310
- `;
404
+ ${CurrencyFieldsFragmentDoc}`;
311
405
  var GetPriceUpdatedEventsDocument = gql`
312
406
  query GetPriceUpdatedEvents($first: Int!, $skip: Int, $orderBy: PriceUpdatedEvent_orderBy, $orderDirection: OrderDirection, $where: PriceUpdatedEvent_filter, $block: Block_height) {
313
407
  priceUpdatedEvents(
@@ -322,6 +416,9 @@ var GetPriceUpdatedEventsDocument = gql`
322
416
  slot {
323
417
  id
324
418
  }
419
+ currency {
420
+ ...CurrencyFields
421
+ }
325
422
  oldPrice
326
423
  newPrice
327
424
  timestamp
@@ -329,7 +426,7 @@ var GetPriceUpdatedEventsDocument = gql`
329
426
  tx
330
427
  }
331
428
  }
332
- `;
429
+ ${CurrencyFieldsFragmentDoc}`;
333
430
  var GetSlotActivityDocument = gql`
334
431
  query GetSlotActivity($slotId: String!, $first: Int!) {
335
432
  boughtEvents(
@@ -339,6 +436,9 @@ var GetSlotActivityDocument = gql`
339
436
  where: {slot: $slotId}
340
437
  ) {
341
438
  id
439
+ currency {
440
+ ...CurrencyFields
441
+ }
342
442
  buyer
343
443
  previousOccupant
344
444
  price
@@ -354,6 +454,9 @@ var GetSlotActivityDocument = gql`
354
454
  where: {slot: $slotId}
355
455
  ) {
356
456
  id
457
+ currency {
458
+ ...CurrencyFields
459
+ }
357
460
  occupant
358
461
  refund
359
462
  timestamp
@@ -366,6 +469,9 @@ var GetSlotActivityDocument = gql`
366
469
  where: {slot: $slotId}
367
470
  ) {
368
471
  id
472
+ currency {
473
+ ...CurrencyFields
474
+ }
369
475
  liquidator
370
476
  occupant
371
477
  bounty
@@ -379,6 +485,9 @@ var GetSlotActivityDocument = gql`
379
485
  where: {slot: $slotId}
380
486
  ) {
381
487
  id
488
+ currency {
489
+ ...CurrencyFields
490
+ }
382
491
  oldPrice
383
492
  newPrice
384
493
  timestamp
@@ -391,6 +500,9 @@ var GetSlotActivityDocument = gql`
391
500
  where: {slot: $slotId}
392
501
  ) {
393
502
  id
503
+ currency {
504
+ ...CurrencyFields
505
+ }
394
506
  depositor
395
507
  amount
396
508
  timestamp
@@ -403,6 +515,9 @@ var GetSlotActivityDocument = gql`
403
515
  where: {slot: $slotId}
404
516
  ) {
405
517
  id
518
+ currency {
519
+ ...CurrencyFields
520
+ }
406
521
  occupant
407
522
  amount
408
523
  timestamp
@@ -415,13 +530,48 @@ var GetSlotActivityDocument = gql`
415
530
  where: {slot: $slotId}
416
531
  ) {
417
532
  id
533
+ currency {
534
+ ...CurrencyFields
535
+ }
418
536
  recipient
419
537
  amount
420
538
  timestamp
421
539
  tx
422
540
  }
541
+ taxUpdateProposedEvents(
542
+ first: $first
543
+ orderBy: timestamp
544
+ orderDirection: desc
545
+ where: {slot: $slotId}
546
+ ) {
547
+ id
548
+ newPercentage
549
+ timestamp
550
+ tx
551
+ }
552
+ moduleUpdateProposedEvents(
553
+ first: $first
554
+ orderBy: timestamp
555
+ orderDirection: desc
556
+ where: {slot: $slotId}
557
+ ) {
558
+ id
559
+ newModule
560
+ timestamp
561
+ tx
562
+ }
563
+ pendingUpdateCancelledEvents(
564
+ first: $first
565
+ orderBy: timestamp
566
+ orderDirection: desc
567
+ where: {slot: $slotId}
568
+ ) {
569
+ id
570
+ timestamp
571
+ tx
572
+ }
423
573
  }
424
- `;
574
+ ${CurrencyFieldsFragmentDoc}`;
425
575
  var GetFactoryDocument = gql`
426
576
  query GetFactory {
427
577
  factories(first: 1) {
@@ -549,6 +699,17 @@ function getSdk(client, withWrapper = defaultWrapper) {
549
699
  };
550
700
  }
551
701
 
702
+ // src/errors.ts
703
+ var SlotsError = class extends Error {
704
+ constructor(operation, cause) {
705
+ const msg = cause instanceof Error ? cause.message : String(cause);
706
+ super(`${operation}: ${msg}`);
707
+ this.operation = operation;
708
+ this.name = "SlotsError";
709
+ this.cause = cause;
710
+ }
711
+ };
712
+
552
713
  // src/client.ts
553
714
  var META_QUERY = gql$1`
554
715
  query GetMeta {
@@ -568,94 +729,511 @@ var SlotsChain = /* @__PURE__ */ ((SlotsChain2) => {
568
729
  return SlotsChain2;
569
730
  })(SlotsChain || {});
570
731
  var SUBGRAPH_URLS = {
571
- [84532 /* BASE_SEPOLIA */]: "https://api.studio.thegraph.com/query/958/0-x-slots-base-sepolia/v3.5.0",
732
+ [84532 /* BASE_SEPOLIA */]: "https://api.studio.thegraph.com/query/958/0-x-slots-base-sepolia/version/latest",
572
733
  [42161 /* ARBITRUM */]: "https://api.studio.thegraph.com/query/958/0-x-slots-arb/version/latest"
573
734
  };
574
735
  var SlotsClient = class {
575
736
  constructor(config) {
576
737
  this.chainId = config.chainId;
738
+ this._publicClient = config.publicClient;
739
+ this.walletClient = config.walletClient;
740
+ this._factory = config.factoryAddress ?? getSlotsHubAddress(config.chainId);
577
741
  const url = config.subgraphUrl || SUBGRAPH_URLS[config.chainId];
578
742
  if (!url) throw new Error(`No subgraph URL for chain ${config.chainId}`);
579
- this.client = new GraphQLClient(url, { headers: config.headers });
580
- this.sdk = getSdk(this.client);
743
+ this.gqlClient = new GraphQLClient(url, { headers: config.headers });
744
+ this.sdk = getSdk(this.gqlClient);
581
745
  }
746
+ // ─── Accessors ──────────────────────────────────────────────────────────────
747
+ /** Returns the chain ID this client was configured for. */
582
748
  getChainId() {
583
749
  return this.chainId;
584
750
  }
751
+ /** Returns the underlying GraphQL client (for advanced usage). */
585
752
  getClient() {
586
- return this.client;
753
+ return this.gqlClient;
587
754
  }
755
+ /** Returns the generated GraphQL SDK (for queries not wrapped by this client). */
588
756
  getSdk() {
589
757
  return this.sdk;
590
758
  }
759
+ get publicClient() {
760
+ if (!this._publicClient) throw new Error("No publicClient provided");
761
+ return this._publicClient;
762
+ }
763
+ get factory() {
764
+ if (!this._factory) throw new Error("No factoryAddress provided");
765
+ return this._factory;
766
+ }
767
+ get wallet() {
768
+ if (!this.walletClient) throw new Error("No walletClient provided");
769
+ return this.walletClient;
770
+ }
771
+ get account() {
772
+ const account = this.wallet.account;
773
+ if (!account) throw new Error("WalletClient must have an account");
774
+ return account.address;
775
+ }
776
+ get chain() {
777
+ const chain = this.wallet.chain;
778
+ if (!chain) throw new Error("WalletClient must have a chain");
779
+ return chain;
780
+ }
781
+ // ─── Helpers ────────────────────────────────────────────────────────────────
782
+ assertPositive(value, name) {
783
+ if (value <= 0n) throw new SlotsError(name, `${name} must be > 0`);
784
+ }
785
+ async query(operation, fn) {
786
+ try {
787
+ return await fn();
788
+ } catch (error) {
789
+ throw new SlotsError(operation, error);
790
+ }
791
+ }
792
+ // ═══════════════════════════════════════════════════════════════════════════
793
+ // READ — Subgraph Queries
794
+ // ═══════════════════════════════════════════════════════════════════════════
591
795
  // Slot queries
796
+ /** Fetch a paginated list of slots. */
592
797
  getSlots(...args) {
593
- return this.sdk.GetSlots(...args);
798
+ return this.query("getSlots", () => this.sdk.GetSlots(...args));
594
799
  }
800
+ /** Fetch a single slot by its address. */
595
801
  getSlot(...args) {
596
- return this.sdk.GetSlot(...args);
802
+ return this.query("getSlot", () => this.sdk.GetSlot(...args));
597
803
  }
804
+ /** Fetch all slots owned by a given recipient address. */
598
805
  getSlotsByRecipient(...args) {
599
- return this.sdk.GetSlotsByRecipient(...args);
806
+ return this.query("getSlotsByRecipient", () => this.sdk.GetSlotsByRecipient(...args));
600
807
  }
808
+ /** Fetch all slots currently occupied by a given address. */
601
809
  getSlotsByOccupant(...args) {
602
- return this.sdk.GetSlotsByOccupant(...args);
810
+ return this.query("getSlotsByOccupant", () => this.sdk.GetSlotsByOccupant(...args));
603
811
  }
604
812
  // Factory queries
813
+ /** Fetch factory configuration. */
605
814
  getFactory() {
606
- return this.sdk.GetFactory();
815
+ return this.query("getFactory", () => this.sdk.GetFactory());
607
816
  }
817
+ /** Fetch registered modules. */
608
818
  getModules(...args) {
609
- return this.sdk.GetModules(...args);
819
+ return this.query("getModules", () => this.sdk.GetModules(...args));
610
820
  }
611
821
  // Event queries
822
+ /** Fetch bought events with optional filters. */
612
823
  getBoughtEvents(...args) {
613
- return this.sdk.GetBoughtEvents(...args);
824
+ return this.query("getBoughtEvents", () => this.sdk.GetBoughtEvents(...args));
614
825
  }
826
+ /** Fetch settled events with optional filters. */
615
827
  getSettledEvents(...args) {
616
- return this.sdk.GetSettledEvents(...args);
828
+ return this.query("getSettledEvents", () => this.sdk.GetSettledEvents(...args));
617
829
  }
830
+ /** Fetch tax-collected events with optional filters. */
618
831
  getTaxCollectedEvents(...args) {
619
- return this.sdk.GetTaxCollectedEvents(...args);
832
+ return this.query("getTaxCollectedEvents", () => this.sdk.GetTaxCollectedEvents(...args));
620
833
  }
834
+ /** Fetch all activity for a specific slot (all event types). */
621
835
  getSlotActivity(...args) {
622
- return this.sdk.GetSlotActivity(...args);
836
+ return this.query("getSlotActivity", () => this.sdk.GetSlotActivity(...args));
623
837
  }
838
+ /** Fetch the most recent events across all slots. */
624
839
  getRecentEvents(...args) {
625
- return this.sdk.GetRecentEvents(...args);
840
+ return this.query("getRecentEvents", () => this.sdk.GetRecentEvents(...args));
626
841
  }
627
842
  // Account queries
843
+ /** Fetch a single account by address. */
628
844
  getAccount(...args) {
629
- return this.sdk.GetAccount(...args);
845
+ return this.query("getAccount", () => this.sdk.GetAccount(...args));
630
846
  }
847
+ /** Fetch a paginated list of accounts. */
631
848
  getAccounts(...args) {
632
- return this.sdk.GetAccounts(...args);
849
+ return this.query("getAccounts", () => this.sdk.GetAccounts(...args));
633
850
  }
634
- // Individual event queries (full params)
851
+ // Individual event queries
852
+ /** Fetch released events with optional filters. */
635
853
  getReleasedEvents(...args) {
636
- return this.sdk.GetReleasedEvents(...args);
854
+ return this.query("getReleasedEvents", () => this.sdk.GetReleasedEvents(...args));
637
855
  }
856
+ /** Fetch liquidated events with optional filters. */
638
857
  getLiquidatedEvents(...args) {
639
- return this.sdk.GetLiquidatedEvents(...args);
858
+ return this.query("getLiquidatedEvents", () => this.sdk.GetLiquidatedEvents(...args));
640
859
  }
860
+ /** Fetch deposited events with optional filters. */
641
861
  getDepositedEvents(...args) {
642
- return this.sdk.GetDepositedEvents(...args);
862
+ return this.query("getDepositedEvents", () => this.sdk.GetDepositedEvents(...args));
643
863
  }
864
+ /** Fetch withdrawn events with optional filters. */
644
865
  getWithdrawnEvents(...args) {
645
- return this.sdk.GetWithdrawnEvents(...args);
866
+ return this.query("getWithdrawnEvents", () => this.sdk.GetWithdrawnEvents(...args));
646
867
  }
868
+ /** Fetch price-updated events with optional filters. */
647
869
  getPriceUpdatedEvents(...args) {
648
- return this.sdk.GetPriceUpdatedEvents(...args);
870
+ return this.query("getPriceUpdatedEvents", () => this.sdk.GetPriceUpdatedEvents(...args));
649
871
  }
650
872
  // Meta
873
+ /** Fetch subgraph indexing metadata (latest block, indexing errors). */
651
874
  getMeta() {
652
- return this.client.request(META_QUERY);
875
+ return this.query("getMeta", () => this.gqlClient.request(META_QUERY));
876
+ }
877
+ // ═══════════════════════════════════════════════════════════════════════════
878
+ // READ — On-chain (RPC)
879
+ // ═══════════════════════════════════════════════════════════════════════════
880
+ /**
881
+ * Read full slot info from on-chain (RPC, not subgraph).
882
+ * @param slot - Slot contract address.
883
+ * @returns On-chain slot info tuple.
884
+ * @throws {SlotsError} If the RPC call fails.
885
+ */
886
+ getSlotInfo(slot) {
887
+ return this.query(
888
+ "getSlotInfo",
889
+ () => this.publicClient.readContract({
890
+ address: slot,
891
+ abi: slotAbi,
892
+ functionName: "getSlotInfo"
893
+ })
894
+ );
895
+ }
896
+ // ═══════════════════════════════════════════════════════════════════════════
897
+ // WRITE — Factory Functions
898
+ // ═══════════════════════════════════════════════════════════════════════════
899
+ /**
900
+ * Deploy a new slot via the factory contract.
901
+ * @param params - Slot creation parameters (recipient, currency, config, initParams).
902
+ * @returns Transaction hash.
903
+ */
904
+ async createSlot(params) {
905
+ return this.wallet.writeContract({
906
+ address: this.factory,
907
+ abi: slotFactoryAbi,
908
+ functionName: "createSlot",
909
+ args: [params.recipient, params.currency, params.config, params.initParams],
910
+ account: this.account,
911
+ chain: this.chain
912
+ });
913
+ }
914
+ /**
915
+ * Deploy multiple identical slots in a single transaction via the factory contract.
916
+ * @param params - Slot creation parameters including count.
917
+ * @returns Transaction hash.
918
+ */
919
+ async createSlots(params) {
920
+ return this.wallet.writeContract({
921
+ address: this.factory,
922
+ abi: slotFactoryAbi,
923
+ functionName: "createSlots",
924
+ args: [params.recipient, params.currency, params.config, params.initParams, params.count],
925
+ account: this.account,
926
+ chain: this.chain
927
+ });
928
+ }
929
+ // ═══════════════════════════════════════════════════════════════════════════
930
+ // WRITE — Slot Functions
931
+ // ═══════════════════════════════════════════════════════════════════════════
932
+ /**
933
+ * Buy a slot (or force-buy an occupied one). Handles ERC-20 approval automatically.
934
+ * @param params - Buy parameters (slot address, deposit amount, self-assessed price).
935
+ * @returns Transaction hash.
936
+ * @throws {SlotsError} If depositAmount or selfAssessedPrice is not positive, or the transaction fails.
937
+ */
938
+ async buy(params) {
939
+ this.assertPositive(params.depositAmount, "depositAmount");
940
+ this.assertPositive(params.selfAssessedPrice, "selfAssessedPrice");
941
+ return this.withAllowance(params.slot, params.depositAmount, {
942
+ to: params.slot,
943
+ abi: slotAbi,
944
+ functionName: "buy",
945
+ args: [params.depositAmount, params.selfAssessedPrice]
946
+ });
947
+ }
948
+ /**
949
+ * Self-assess a new price for an occupied slot (occupant only).
950
+ * @param slot - The slot contract address.
951
+ * @param newPrice - The new self-assessed price (can be 0).
952
+ * @returns Transaction hash.
953
+ */
954
+ async selfAssess(slot, newPrice) {
955
+ return this.wallet.writeContract({
956
+ address: slot,
957
+ abi: slotAbi,
958
+ functionName: "selfAssess",
959
+ args: [newPrice],
960
+ account: this.account,
961
+ chain: this.chain
962
+ });
963
+ }
964
+ /**
965
+ * Top up deposit on a slot (occupant only). Handles ERC-20 approval automatically.
966
+ * @param slot - The slot contract address.
967
+ * @param amount - The amount to deposit (must be > 0).
968
+ * @returns Transaction hash.
969
+ * @throws {SlotsError} If amount is not positive, or the transaction fails.
970
+ */
971
+ async topUp(slot, amount) {
972
+ this.assertPositive(amount, "amount");
973
+ return this.withAllowance(slot, amount, {
974
+ to: slot,
975
+ abi: slotAbi,
976
+ functionName: "topUp",
977
+ args: [amount]
978
+ });
979
+ }
980
+ /**
981
+ * Withdraw from deposit (occupant only). Cannot go below minimum deposit.
982
+ * @param slot - The slot contract address.
983
+ * @param amount - The amount to withdraw (must be > 0).
984
+ * @returns Transaction hash.
985
+ * @throws {SlotsError} If amount is not positive, or the transaction fails.
986
+ */
987
+ async withdraw(slot, amount) {
988
+ this.assertPositive(amount, "amount");
989
+ return this.wallet.writeContract({
990
+ address: slot,
991
+ abi: slotAbi,
992
+ functionName: "withdraw",
993
+ args: [amount],
994
+ account: this.account,
995
+ chain: this.chain
996
+ });
997
+ }
998
+ /**
999
+ * Release a slot (occupant only). Returns remaining deposit to the occupant.
1000
+ * @param slot - The slot contract address.
1001
+ * @returns Transaction hash.
1002
+ */
1003
+ async release(slot) {
1004
+ return this.wallet.writeContract({
1005
+ address: slot,
1006
+ abi: slotAbi,
1007
+ functionName: "release",
1008
+ account: this.account,
1009
+ chain: this.chain
1010
+ });
1011
+ }
1012
+ /**
1013
+ * Collect accumulated tax (permissionless).
1014
+ * @param slot - The slot contract address.
1015
+ * @returns Transaction hash.
1016
+ */
1017
+ async collect(slot) {
1018
+ return this.wallet.writeContract({
1019
+ address: slot,
1020
+ abi: slotAbi,
1021
+ functionName: "collect",
1022
+ account: this.account,
1023
+ chain: this.chain
1024
+ });
1025
+ }
1026
+ /**
1027
+ * Liquidate an insolvent slot (permissionless). Caller receives bounty.
1028
+ * @param slot - The slot contract address.
1029
+ * @returns Transaction hash.
1030
+ */
1031
+ async liquidate(slot) {
1032
+ return this.wallet.writeContract({
1033
+ address: slot,
1034
+ abi: slotAbi,
1035
+ functionName: "liquidate",
1036
+ account: this.account,
1037
+ chain: this.chain
1038
+ });
1039
+ }
1040
+ // ═══════════════════════════════════════════════════════════════════════════
1041
+ // WRITE — Manager Functions
1042
+ // ═══════════════════════════════════════════════════════════════════════════
1043
+ /**
1044
+ * Propose a tax rate update (manager only, slot must have mutableTax).
1045
+ * @param slot - The slot contract address.
1046
+ * @param newPct - The new tax percentage.
1047
+ * @returns Transaction hash.
1048
+ */
1049
+ async proposeTaxUpdate(slot, newPct) {
1050
+ return this.wallet.writeContract({
1051
+ address: slot,
1052
+ abi: slotAbi,
1053
+ functionName: "proposeTaxUpdate",
1054
+ args: [newPct],
1055
+ account: this.account,
1056
+ chain: this.chain
1057
+ });
1058
+ }
1059
+ /**
1060
+ * Propose a module update (manager only, slot must have mutableModule).
1061
+ * @param slot - The slot contract address.
1062
+ * @param newModule - The new module contract address.
1063
+ * @returns Transaction hash.
1064
+ */
1065
+ async proposeModuleUpdate(slot, newModule) {
1066
+ return this.wallet.writeContract({
1067
+ address: slot,
1068
+ abi: slotAbi,
1069
+ functionName: "proposeModuleUpdate",
1070
+ args: [newModule],
1071
+ account: this.account,
1072
+ chain: this.chain
1073
+ });
1074
+ }
1075
+ /**
1076
+ * Cancel pending updates (manager only).
1077
+ * @param slot - The slot contract address.
1078
+ * @returns Transaction hash.
1079
+ */
1080
+ async cancelPendingUpdates(slot) {
1081
+ return this.wallet.writeContract({
1082
+ address: slot,
1083
+ abi: slotAbi,
1084
+ functionName: "cancelPendingUpdates",
1085
+ account: this.account,
1086
+ chain: this.chain
1087
+ });
1088
+ }
1089
+ /**
1090
+ * Set liquidation bounty bps (manager only).
1091
+ * @param slot - The slot contract address.
1092
+ * @param newBps - The new bounty in basis points (0-10000).
1093
+ * @returns Transaction hash.
1094
+ * @throws {SlotsError} If newBps is outside 0-10000, or the transaction fails.
1095
+ */
1096
+ async setLiquidationBounty(slot, newBps) {
1097
+ if (newBps < 0n || newBps > 10000n) throw new SlotsError("setLiquidationBounty", "newBps must be 0-10000");
1098
+ return this.wallet.writeContract({
1099
+ address: slot,
1100
+ abi: slotAbi,
1101
+ functionName: "setLiquidationBounty",
1102
+ args: [newBps],
1103
+ account: this.account,
1104
+ chain: this.chain
1105
+ });
1106
+ }
1107
+ // ═══════════════════════════════════════════════════════════════════════════
1108
+ // WRITE — Multicall
1109
+ // ═══════════════════════════════════════════════════════════════════════════
1110
+ /**
1111
+ * Batch multiple slot calls into one transaction via multicall.
1112
+ * @param slot - The slot contract address.
1113
+ * @param calls - Array of function calls to batch.
1114
+ * @returns Transaction hash.
1115
+ * @throws {SlotsError} If calls array is empty, or the transaction fails.
1116
+ */
1117
+ async multicall(slot, calls) {
1118
+ if (calls.length === 0) throw new SlotsError("multicall", "calls array must not be empty");
1119
+ const data = calls.map(
1120
+ (call) => encodeFunctionData({
1121
+ abi: slotAbi,
1122
+ functionName: call.functionName,
1123
+ args: call.args
1124
+ })
1125
+ );
1126
+ return this.wallet.writeContract({
1127
+ address: slot,
1128
+ abi: slotAbi,
1129
+ functionName: "multicall",
1130
+ args: [data],
1131
+ account: this.account,
1132
+ chain: this.chain
1133
+ });
1134
+ }
1135
+ // ─── Internals ──────────────────────────────────────────────────────────────
1136
+ /** Check if wallet supports atomic batch calls (EIP-5792). */
1137
+ async supportsAtomicBatch() {
1138
+ if (this._atomicSupport !== void 0) return this._atomicSupport;
1139
+ try {
1140
+ const capabilities = await this.wallet.getCapabilities?.();
1141
+ if (!capabilities) {
1142
+ this._atomicSupport = false;
1143
+ return false;
1144
+ }
1145
+ const chainId = this.chain.id;
1146
+ const chainCaps = capabilities[chainId] || capabilities[`0x${chainId.toString(16)}`];
1147
+ const atomic = chainCaps?.atomicBatch ?? chainCaps?.atomic;
1148
+ const status = atomic && typeof atomic === "object" && "status" in atomic ? atomic.status : void 0;
1149
+ this._atomicSupport = status === "supported" || status === "ready";
1150
+ } catch {
1151
+ this._atomicSupport = false;
1152
+ }
1153
+ return this._atomicSupport;
1154
+ }
1155
+ /** Poll EIP-5792 getCallsStatus until the batch settles, then return a tx hash. */
1156
+ async pollBatchReceipt(id) {
1157
+ const MAX_ATTEMPTS = 60;
1158
+ const INTERVAL = 1500;
1159
+ for (let i = 0; i < MAX_ATTEMPTS; i++) {
1160
+ const result = await this.wallet.getCallsStatus({ id });
1161
+ if (result.status === "success") {
1162
+ const receipts = result.receipts ?? [];
1163
+ return receipts[receipts.length - 1]?.transactionHash ?? id;
1164
+ }
1165
+ if (result.status === "failure") {
1166
+ throw new Error("Batch transaction reverted");
1167
+ }
1168
+ await new Promise((r) => setTimeout(r, INTERVAL));
1169
+ }
1170
+ throw new Error("Batch transaction timed out");
1171
+ }
1172
+ /**
1173
+ * Execute a contract call that needs ERC-20 allowance.
1174
+ * If wallet supports atomic batch (EIP-5792): sends approve + action as one atomic call.
1175
+ * Otherwise: chains approve tx (if needed) then action tx.
1176
+ */
1177
+ async withAllowance(spender, amount, call) {
1178
+ const currency = await this.publicClient.readContract({
1179
+ address: spender,
1180
+ abi: slotAbi,
1181
+ functionName: "currency"
1182
+ });
1183
+ const allowance = await this.publicClient.readContract({
1184
+ address: currency,
1185
+ abi: erc20Abi,
1186
+ functionName: "allowance",
1187
+ args: [this.account, spender]
1188
+ });
1189
+ const needsApproval = allowance < amount;
1190
+ if (needsApproval && await this.supportsAtomicBatch()) {
1191
+ const approveData = encodeFunctionData({
1192
+ abi: erc20Abi,
1193
+ functionName: "approve",
1194
+ args: [spender, amount]
1195
+ });
1196
+ const actionData = encodeFunctionData({
1197
+ abi: call.abi,
1198
+ functionName: call.functionName,
1199
+ args: call.args
1200
+ });
1201
+ const id = await this.wallet.sendCalls({
1202
+ account: this.account,
1203
+ chain: this.chain,
1204
+ calls: [
1205
+ { to: currency, data: approveData },
1206
+ { to: call.to, data: actionData }
1207
+ ]
1208
+ });
1209
+ const txHash = await this.pollBatchReceipt(id);
1210
+ return txHash;
1211
+ }
1212
+ if (needsApproval) {
1213
+ const hash = await this.wallet.writeContract({
1214
+ address: currency,
1215
+ abi: erc20Abi,
1216
+ functionName: "approve",
1217
+ args: [spender, amount],
1218
+ account: this.account,
1219
+ chain: this.chain
1220
+ });
1221
+ await this.publicClient.waitForTransactionReceipt({ hash });
1222
+ }
1223
+ return this.wallet.writeContract({
1224
+ address: call.to,
1225
+ abi: call.abi,
1226
+ functionName: call.functionName,
1227
+ args: call.args,
1228
+ account: this.account,
1229
+ chain: this.chain
1230
+ });
653
1231
  }
654
1232
  };
655
1233
  function createSlotsClient(config) {
656
1234
  return new SlotsClient(config);
657
1235
  }
658
1236
 
659
- export { AccountFieldsFragmentDoc, GetAccountDocument, GetAccountsDocument, GetBoughtEventsDocument, GetDepositedEventsDocument, GetFactoryDocument, GetLiquidatedEventsDocument, GetModulesDocument, GetPriceUpdatedEventsDocument, GetRecentEventsDocument, GetReleasedEventsDocument, GetSettledEventsDocument, GetSlotActivityDocument, GetSlotDocument, GetSlotsByOccupantDocument, GetSlotsByRecipientDocument, GetSlotsDocument, GetTaxCollectedEventsDocument, GetWithdrawnEventsDocument, SUBGRAPH_URLS, SlotFieldsFragmentDoc, SlotsChain, SlotsClient, createSlotsClient, getSdk };
1237
+ export { AccountFieldsFragmentDoc, CurrencyFieldsFragmentDoc, GetAccountDocument, GetAccountsDocument, GetBoughtEventsDocument, GetDepositedEventsDocument, GetFactoryDocument, GetLiquidatedEventsDocument, GetModulesDocument, GetPriceUpdatedEventsDocument, GetRecentEventsDocument, GetReleasedEventsDocument, GetSettledEventsDocument, GetSlotActivityDocument, GetSlotDocument, GetSlotsByOccupantDocument, GetSlotsByRecipientDocument, GetSlotsDocument, GetTaxCollectedEventsDocument, GetWithdrawnEventsDocument, SUBGRAPH_URLS, SlotFieldsFragmentDoc, SlotsChain, SlotsClient, SlotsError, createSlotsClient, getSdk };
660
1238
  //# sourceMappingURL=index.js.map
661
1239
  //# sourceMappingURL=index.js.map