@0xslots/sdk 0.11.0 → 0.12.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.
@@ -1,7 +1,7 @@
1
1
  import gql from 'graphql-tag';
2
- import { metadataModuleAbi, getSlotsHubAddress, slotAbi, slotFactoryAbi } from '@0xslots/contracts';
2
+ import { metadataModuleAbi, feedRouterAddress, feedModuleAbi, slotAbi, feedRouterAbi, getSlotsHubAddress, slotFactoryAbi } from '@0xslots/contracts';
3
+ import { erc20Abi, encodeFunctionData } from 'viem';
3
4
  import { gql as gql$1, GraphQLClient } from 'graphql-request';
4
- import { encodeFunctionData, erc20Abi } from 'viem';
5
5
 
6
6
  // src/errors.ts
7
7
  var SlotsError = class extends Error {
@@ -86,6 +86,11 @@ var SlotFieldsFragmentDoc = gql`
86
86
  verified
87
87
  name
88
88
  version
89
+ feeBps
90
+ moduleURI
91
+ image
92
+ description
93
+ totalFeesCollected
89
94
  }
90
95
  occupant
91
96
  occupantAccount {
@@ -726,6 +731,11 @@ var GetModulesDocument = gql`
726
731
  verified
727
732
  name
728
733
  version
734
+ feeBps
735
+ moduleURI
736
+ image
737
+ description
738
+ totalFeesCollected
729
739
  }
730
740
  }
731
741
  `;
@@ -1035,6 +1045,189 @@ var MetadataModuleClient = class {
1035
1045
  });
1036
1046
  }
1037
1047
  };
1048
+ var EXPECTED_MODULE_NAME2 = "FeedPostModule";
1049
+ var FeedModuleClient = class {
1050
+ constructor(opts) {
1051
+ this.sdk = opts.sdk;
1052
+ this.chainId = opts.chainId;
1053
+ this._publicClient = opts.publicClient;
1054
+ this._walletClient = opts.walletClient;
1055
+ }
1056
+ get wallet() {
1057
+ if (!this._walletClient)
1058
+ throw new SlotsError("feed", "No walletClient provided");
1059
+ return this._walletClient;
1060
+ }
1061
+ get account() {
1062
+ const account = this.wallet.account;
1063
+ if (!account)
1064
+ throw new SlotsError("feed", "WalletClient must have an account");
1065
+ return account.address;
1066
+ }
1067
+ get chain() {
1068
+ const chain = this.wallet.chain;
1069
+ if (!chain)
1070
+ throw new SlotsError("feed", "WalletClient must have a chain");
1071
+ return chain;
1072
+ }
1073
+ get publicClient() {
1074
+ if (!this._publicClient)
1075
+ throw new SlotsError("feed", "No publicClient provided");
1076
+ return this._publicClient;
1077
+ }
1078
+ get routerAddress() {
1079
+ const addr = feedRouterAddress[this.chainId];
1080
+ if (!addr)
1081
+ throw new SlotsError("feed", `No FeedRouter for chain ${this.chainId}`);
1082
+ return addr;
1083
+ }
1084
+ async query(operation, fn) {
1085
+ try {
1086
+ return await fn();
1087
+ } catch (error) {
1088
+ throw new SlotsError(operation, error);
1089
+ }
1090
+ }
1091
+ /**
1092
+ * Verify that a given address is a FeedPostModule by calling `name()` on-chain.
1093
+ */
1094
+ async verifyModule(moduleAddress) {
1095
+ const name = await this.publicClient.readContract({
1096
+ address: moduleAddress,
1097
+ abi: feedModuleAbi,
1098
+ functionName: "name"
1099
+ });
1100
+ if (name !== EXPECTED_MODULE_NAME2) {
1101
+ throw new SlotsError(
1102
+ "feed",
1103
+ `Contract at ${moduleAddress} is not a FeedPostModule (name: "${name}")`
1104
+ );
1105
+ }
1106
+ }
1107
+ // ═══════════════════════════════════════════════════════════════════════════
1108
+ // READ — Subgraph (reuses MetadataSlot entities)
1109
+ // ═══════════════════════════════════════════════════════════════════════════
1110
+ /** Get all slots with metadata, ordered by most recently updated. */
1111
+ getSlots(...args) {
1112
+ return this.query(
1113
+ "feed.getSlots",
1114
+ () => this.sdk.GetMetadataSlots(...args)
1115
+ );
1116
+ }
1117
+ /** Get a single metadata slot by slot address. */
1118
+ getSlot(...args) {
1119
+ return this.query(
1120
+ "feed.getSlot",
1121
+ () => this.sdk.GetMetadataSlot(...args)
1122
+ );
1123
+ }
1124
+ /** Get metadata update history for a slot. */
1125
+ getUpdateHistory(...args) {
1126
+ return this.query(
1127
+ "feed.getUpdateHistory",
1128
+ () => this.sdk.GetMetadataUpdatedEvents(...args)
1129
+ );
1130
+ }
1131
+ // ═══════════════════════════════════════════════════════════════════════════
1132
+ // READ — RPC
1133
+ // ═══════════════════════════════════════════════════════════════════════════
1134
+ /**
1135
+ * Read the current URI for a slot directly from chain.
1136
+ */
1137
+ async getURI(moduleAddress, slot) {
1138
+ return this.query(
1139
+ "feed.getURI",
1140
+ () => this.publicClient.readContract({
1141
+ address: moduleAddress,
1142
+ abi: feedModuleAbi,
1143
+ functionName: "tokenURI",
1144
+ args: [slot]
1145
+ })
1146
+ );
1147
+ }
1148
+ // ═══════════════════════════════════════════════════════════════════════════
1149
+ // WRITE — Direct (occupant only)
1150
+ // ═══════════════════════════════════════════════════════════════════════════
1151
+ /**
1152
+ * Update the metadata URI for a slot. Only callable by the current occupant.
1153
+ */
1154
+ async updateMetadata(moduleAddress, slot, uri) {
1155
+ await this.verifyModule(moduleAddress);
1156
+ return this.wallet.writeContract({
1157
+ address: moduleAddress,
1158
+ abi: feedModuleAbi,
1159
+ functionName: "updateMetadata",
1160
+ args: [slot, uri],
1161
+ account: this.account,
1162
+ chain: this.chain
1163
+ });
1164
+ }
1165
+ // ═══════════════════════════════════════════════════════════════════════════
1166
+ // WRITE — Router (atomic buy + post)
1167
+ // ═══════════════════════════════════════════════════════════════════════════
1168
+ /**
1169
+ * Buy a slot and post metadata in one transaction via FeedRouter.
1170
+ * User must approve the router for the slot's currency.
1171
+ * Handles ERC-20 approval automatically.
1172
+ *
1173
+ * @param slot - The slot contract address
1174
+ * @param depositAmount - Amount to deposit for tax escrow
1175
+ * @param selfAssessedPrice - The price you're setting
1176
+ * @param uri - The metadata URI to post
1177
+ * @returns Transaction hash
1178
+ */
1179
+ async buyAndPost(slot, depositAmount, selfAssessedPrice, uri) {
1180
+ const router = this.routerAddress;
1181
+ const [occupant, currentPrice, currency] = await Promise.all([
1182
+ this.publicClient.readContract({
1183
+ address: slot,
1184
+ abi: slotAbi,
1185
+ functionName: "occupant"
1186
+ }),
1187
+ this.publicClient.readContract({
1188
+ address: slot,
1189
+ abi: slotAbi,
1190
+ functionName: "price"
1191
+ }),
1192
+ this.publicClient.readContract({
1193
+ address: slot,
1194
+ abi: slotAbi,
1195
+ functionName: "currency"
1196
+ })
1197
+ ]);
1198
+ const price = occupant !== "0x0000000000000000000000000000000000000000" ? currentPrice : 0n;
1199
+ const total = price + depositAmount;
1200
+ if (total > 0n) {
1201
+ const allowance = await this.publicClient.readContract({
1202
+ address: currency,
1203
+ abi: erc20Abi,
1204
+ functionName: "allowance",
1205
+ args: [this.account, router]
1206
+ });
1207
+ if (allowance < total) {
1208
+ const approveTx = await this.wallet.writeContract({
1209
+ address: currency,
1210
+ abi: erc20Abi,
1211
+ functionName: "approve",
1212
+ args: [router, total],
1213
+ account: this.account,
1214
+ chain: this.chain
1215
+ });
1216
+ await this.publicClient.waitForTransactionReceipt({
1217
+ hash: approveTx
1218
+ });
1219
+ }
1220
+ }
1221
+ return this.wallet.writeContract({
1222
+ address: router,
1223
+ abi: feedRouterAbi,
1224
+ functionName: "buyAndPost",
1225
+ args: [slot, depositAmount, selfAssessedPrice, uri],
1226
+ account: this.account,
1227
+ chain: this.chain
1228
+ });
1229
+ }
1230
+ };
1038
1231
  var META_QUERY = gql$1`
1039
1232
  query GetMeta {
1040
1233
  _meta {
@@ -1075,6 +1268,12 @@ var SlotsClient = class {
1075
1268
  sdk: this.sdk,
1076
1269
  publicClient: config.publicClient,
1077
1270
  walletClient: config.walletClient
1271
+ }),
1272
+ feed: new FeedModuleClient({
1273
+ sdk: this.sdk,
1274
+ chainId: config.chainId,
1275
+ publicClient: config.publicClient,
1276
+ walletClient: config.walletClient
1078
1277
  })
1079
1278
  };
1080
1279
  }
@@ -1599,6 +1798,6 @@ function createSlotsClient(config) {
1599
1798
  return new SlotsClient(config);
1600
1799
  }
1601
1800
 
1602
- export { AccountFieldsFragmentDoc, CurrencyFieldsFragmentDoc, GetAccountDocument, GetAccountsDocument, GetBoughtEventsDocument, GetDepositedEventsDocument, GetFactoryDocument, GetLiquidatedEventsDocument, GetMetadataSlotDocument, GetMetadataSlotsByRecipientDocument, GetMetadataSlotsDocument, GetMetadataUpdatedEventsDocument, GetModulesDocument, GetPriceUpdatedEventsDocument, GetRecentEventsDocument, GetReleasedEventsDocument, GetSettledEventsDocument, GetSlotActivityDocument, GetSlotDeployedEventsDocument, GetSlotDocument, GetSlotsByOccupantDocument, GetSlotsByRecipientDocument, GetSlotsDocument, GetTaxCollectedEventsDocument, GetWithdrawnEventsDocument, MetadataModuleClient, MetadataSlotFieldsFragmentDoc, SUBGRAPH_URLS, SlotFieldsFragmentDoc, SlotsChain, SlotsClient, SlotsError, createSlotsClient, getSdk };
1603
- //# sourceMappingURL=chunk-XQG6GMWZ.js.map
1604
- //# sourceMappingURL=chunk-XQG6GMWZ.js.map
1801
+ export { AccountFieldsFragmentDoc, CurrencyFieldsFragmentDoc, FeedModuleClient, GetAccountDocument, GetAccountsDocument, GetBoughtEventsDocument, GetDepositedEventsDocument, GetFactoryDocument, GetLiquidatedEventsDocument, GetMetadataSlotDocument, GetMetadataSlotsByRecipientDocument, GetMetadataSlotsDocument, GetMetadataUpdatedEventsDocument, GetModulesDocument, GetPriceUpdatedEventsDocument, GetRecentEventsDocument, GetReleasedEventsDocument, GetSettledEventsDocument, GetSlotActivityDocument, GetSlotDeployedEventsDocument, GetSlotDocument, GetSlotsByOccupantDocument, GetSlotsByRecipientDocument, GetSlotsDocument, GetTaxCollectedEventsDocument, GetWithdrawnEventsDocument, MetadataModuleClient, MetadataSlotFieldsFragmentDoc, SUBGRAPH_URLS, SlotFieldsFragmentDoc, SlotsChain, SlotsClient, SlotsError, createSlotsClient, getSdk };
1802
+ //# sourceMappingURL=chunk-52RYU3VZ.js.map
1803
+ //# sourceMappingURL=chunk-52RYU3VZ.js.map