@0xobelisk/graphql-client 1.2.0-pre.124 → 1.2.0-pre.125

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/types.d.ts CHANGED
@@ -118,6 +118,48 @@ export interface DubheUserStorageRow {
118
118
  lastUpdateDigest: string;
119
119
  lastEventSeq: string;
120
120
  }
121
+ export interface SceneStorageRow {
122
+ sceneId: string;
123
+ dappKey: string;
124
+ sceneType: string;
125
+ sceneTypeRaw: string;
126
+ authorizationKind?: string | null;
127
+ authorizationKindRaw?: string | null;
128
+ authorizedPermitId?: string | null;
129
+ isDestroyed: boolean;
130
+ createdAtCheckpoint: string;
131
+ destroyedAtCheckpoint?: string | null;
132
+ updatedAtCheckpoint: string;
133
+ lastUpdateDigest: string;
134
+ lastEventSeq: string;
135
+ }
136
+ export interface SceneStorageFieldRow {
137
+ sceneId: string;
138
+ fieldNameRaw: string;
139
+ dappKey: string;
140
+ sceneType: string;
141
+ sceneTypeRaw: string;
142
+ fieldName: string;
143
+ fieldValueRaw?: string | null;
144
+ isDeleted: boolean;
145
+ deletedAtCheckpoint?: string | null;
146
+ updatedAtCheckpoint: string;
147
+ lastUpdateDigest: string;
148
+ lastEventSeq: string;
149
+ }
150
+ export interface ObjectStorageRow {
151
+ objectId: string;
152
+ dappKey: string;
153
+ objectType: string;
154
+ objectTypeRaw: string;
155
+ entityIdRaw: string;
156
+ isDestroyed: boolean;
157
+ createdAtCheckpoint: string;
158
+ destroyedAtCheckpoint?: string | null;
159
+ updatedAtCheckpoint: string;
160
+ lastUpdateDigest: string;
161
+ lastEventSeq: string;
162
+ }
121
163
  export interface DubheDappRuntimeStateRow {
122
164
  dappKey: string;
123
165
  admin?: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xobelisk/graphql-client",
3
- "version": "1.2.0-pre.124",
3
+ "version": "1.2.0-pre.125",
4
4
  "description": "Tookit for interacting with dubhe graphql client",
5
5
  "keywords": [
6
6
  "sui",
package/src/client.ts CHANGED
@@ -122,7 +122,10 @@ import {
122
122
  MarketplaceListingRow,
123
123
  DubheSessionRow,
124
124
  DubheUserStorageRow,
125
- DubheDappRuntimeStateRow
125
+ DubheDappRuntimeStateRow,
126
+ SceneStorageRow,
127
+ SceneStorageFieldRow,
128
+ ObjectStorageRow
126
129
  } from './types';
127
130
 
128
131
  // Convert cache policy type
@@ -1208,6 +1211,228 @@ export class DubheGraphqlClient {
1208
1211
  );
1209
1212
  }
1210
1213
 
1214
+ /**
1215
+ * Query SceneStorage system rows indexed by the Dubhe indexer
1216
+ * (scene_storages table, exposed as dubheSceneStorages in GraphQL).
1217
+ * Field values live in the companion scene_storage_fields table —
1218
+ * see getSceneStorageFields.
1219
+ */
1220
+ async getSceneStorages(options?: {
1221
+ dappKey?: string;
1222
+ sceneType?: string;
1223
+ sceneId?: string;
1224
+ isDestroyed?: boolean;
1225
+ first?: number;
1226
+ after?: string;
1227
+ }): Promise<Connection<SceneStorageRow>> {
1228
+ const filter: Record<string, any> = {};
1229
+ if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
1230
+ if (options?.sceneType) filter.sceneType = { equalTo: options.sceneType };
1231
+ if (options?.sceneId) filter.sceneId = { equalTo: options.sceneId };
1232
+ if (options?.isDestroyed !== undefined) filter.isDestroyed = { equalTo: options.isDestroyed };
1233
+
1234
+ const query = gql`
1235
+ query GetSceneStorages(
1236
+ $first: Int
1237
+ $after: Cursor
1238
+ $filter: StoreDubheSceneStorageFilter
1239
+ $orderBy: [StoreDubheSceneStoragesOrderBy!]
1240
+ ) {
1241
+ dubheSceneStorages(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
1242
+ totalCount
1243
+ pageInfo {
1244
+ hasNextPage
1245
+ hasPreviousPage
1246
+ startCursor
1247
+ endCursor
1248
+ }
1249
+ edges {
1250
+ cursor
1251
+ node {
1252
+ sceneId
1253
+ dappKey
1254
+ sceneType
1255
+ authorizationKind
1256
+ authorizedPermitId
1257
+ isDestroyed
1258
+ createdAtCheckpoint
1259
+ updatedAtCheckpoint
1260
+ lastUpdateDigest
1261
+ lastEventSeq
1262
+ }
1263
+ }
1264
+ }
1265
+ }
1266
+ `;
1267
+
1268
+ const result = await this.apolloClient.query({
1269
+ query,
1270
+ variables: {
1271
+ first: options?.first ?? 100,
1272
+ after: options?.after,
1273
+ filter: Object.keys(filter).length > 0 ? filter : undefined,
1274
+ orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
1275
+ },
1276
+ fetchPolicy: 'network-only'
1277
+ });
1278
+
1279
+ if (result.error) throw result.error;
1280
+ return (
1281
+ (result.data as any)?.dubheSceneStorages ?? {
1282
+ edges: [],
1283
+ pageInfo: { hasNextPage: false, hasPreviousPage: false },
1284
+ totalCount: 0
1285
+ }
1286
+ );
1287
+ }
1288
+
1289
+ /**
1290
+ * Query raw field rows of SceneStorages (scene_storage_fields table,
1291
+ * exposed as dubheSceneStorageFields in GraphQL). Values are hex-encoded
1292
+ * BCS — decode with the decoders exported from this package.
1293
+ */
1294
+ async getSceneStorageFields(options?: {
1295
+ dappKey?: string;
1296
+ sceneIds?: string[];
1297
+ sceneId?: string;
1298
+ fieldName?: string;
1299
+ isDeleted?: boolean;
1300
+ first?: number;
1301
+ after?: string;
1302
+ }): Promise<Connection<SceneStorageFieldRow>> {
1303
+ const filter: Record<string, any> = {};
1304
+ if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
1305
+ if (options?.sceneIds && options.sceneIds.length > 0) filter.sceneId = { in: options.sceneIds };
1306
+ if (options?.sceneId) filter.sceneId = { equalTo: options.sceneId };
1307
+ if (options?.fieldName) filter.fieldName = { equalTo: options.fieldName };
1308
+ if (options?.isDeleted !== undefined) filter.isDeleted = { equalTo: options.isDeleted };
1309
+
1310
+ const query = gql`
1311
+ query GetSceneStorageFields(
1312
+ $first: Int
1313
+ $after: Cursor
1314
+ $filter: StoreDubheSceneStorageFieldFilter
1315
+ $orderBy: [StoreDubheSceneStorageFieldsOrderBy!]
1316
+ ) {
1317
+ dubheSceneStorageFields(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
1318
+ totalCount
1319
+ pageInfo {
1320
+ hasNextPage
1321
+ hasPreviousPage
1322
+ startCursor
1323
+ endCursor
1324
+ }
1325
+ edges {
1326
+ cursor
1327
+ node {
1328
+ sceneId
1329
+ dappKey
1330
+ sceneType
1331
+ fieldName
1332
+ fieldValueRaw
1333
+ isDeleted
1334
+ updatedAtCheckpoint
1335
+ lastUpdateDigest
1336
+ lastEventSeq
1337
+ }
1338
+ }
1339
+ }
1340
+ }
1341
+ `;
1342
+
1343
+ const result = await this.apolloClient.query({
1344
+ query,
1345
+ variables: {
1346
+ first: options?.first ?? 1000,
1347
+ after: options?.after,
1348
+ filter: Object.keys(filter).length > 0 ? filter : undefined,
1349
+ orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
1350
+ },
1351
+ fetchPolicy: 'network-only'
1352
+ });
1353
+
1354
+ if (result.error) throw result.error;
1355
+ return (
1356
+ (result.data as any)?.dubheSceneStorageFields ?? {
1357
+ edges: [],
1358
+ pageInfo: { hasNextPage: false, hasPreviousPage: false },
1359
+ totalCount: 0
1360
+ }
1361
+ );
1362
+ }
1363
+
1364
+ /**
1365
+ * Query ObjectStorage system rows indexed by the Dubhe indexer
1366
+ * (object_storages table, exposed as dubheObjectStorages in GraphQL).
1367
+ */
1368
+ async getObjectStorages(options?: {
1369
+ dappKey?: string;
1370
+ objectType?: string;
1371
+ objectId?: string;
1372
+ isDestroyed?: boolean;
1373
+ first?: number;
1374
+ after?: string;
1375
+ }): Promise<Connection<ObjectStorageRow>> {
1376
+ const filter: Record<string, any> = {};
1377
+ if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
1378
+ if (options?.objectType) filter.objectType = { equalTo: options.objectType };
1379
+ if (options?.objectId) filter.objectId = { equalTo: options.objectId };
1380
+ if (options?.isDestroyed !== undefined) filter.isDestroyed = { equalTo: options.isDestroyed };
1381
+
1382
+ const query = gql`
1383
+ query GetObjectStorages(
1384
+ $first: Int
1385
+ $after: Cursor
1386
+ $filter: StoreDubheObjectStorageFilter
1387
+ $orderBy: [StoreDubheObjectStoragesOrderBy!]
1388
+ ) {
1389
+ dubheObjectStorages(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
1390
+ totalCount
1391
+ pageInfo {
1392
+ hasNextPage
1393
+ hasPreviousPage
1394
+ startCursor
1395
+ endCursor
1396
+ }
1397
+ edges {
1398
+ cursor
1399
+ node {
1400
+ objectId
1401
+ dappKey
1402
+ objectType
1403
+ entityIdRaw
1404
+ isDestroyed
1405
+ createdAtCheckpoint
1406
+ updatedAtCheckpoint
1407
+ lastUpdateDigest
1408
+ lastEventSeq
1409
+ }
1410
+ }
1411
+ }
1412
+ }
1413
+ `;
1414
+
1415
+ const result = await this.apolloClient.query({
1416
+ query,
1417
+ variables: {
1418
+ first: options?.first ?? 100,
1419
+ after: options?.after,
1420
+ filter: Object.keys(filter).length > 0 ? filter : undefined,
1421
+ orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
1422
+ },
1423
+ fetchPolicy: 'network-only'
1424
+ });
1425
+
1426
+ if (result.error) throw result.error;
1427
+ return (
1428
+ (result.data as any)?.dubheObjectStorages ?? {
1429
+ edges: [],
1430
+ pageInfo: { hasNextPage: false, hasPreviousPage: false },
1431
+ totalCount: 0
1432
+ }
1433
+ );
1434
+ }
1435
+
1211
1436
  /**
1212
1437
  * Query DApp runtime state (credit pool, admin, package version, etc.).
1213
1438
  * Exposed as dubheDappRuntimeStates in GraphQL.
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Minimal BCS decoders for indexer raw values.
3
+ *
4
+ * The Dubhe indexer stores scene/object field values and marketplace record
5
+ * data as hex-encoded BCS bytes (e.g. "0x0c00000000000000" for u64 12).
6
+ * These helpers decode the primitive types commonly stored in system tables.
7
+ */
8
+
9
+ export const ZERO_ADDRESS = '0x' + '0'.repeat(64);
10
+
11
+ export function hexToBytes(hex: string): Uint8Array {
12
+ const clean = hex.replace(/^0x/i, '');
13
+ const pairs = clean.match(/../g) ?? [];
14
+ return Uint8Array.from(pairs.map((b) => parseInt(b, 16)));
15
+ }
16
+
17
+ function readUIntLE(bytes: Uint8Array, offset: number, width: number): bigint {
18
+ let n = 0n;
19
+ for (let i = width - 1; i >= 0; i--) {
20
+ n = (n << 8n) | BigInt(bytes[offset + i] ?? 0);
21
+ }
22
+ return n;
23
+ }
24
+
25
+ /** Read a ULEB128-encoded length prefix. Returns [value, bytesConsumed]. */
26
+ function readUleb(bytes: Uint8Array, offset: number): [number, number] {
27
+ let value = 0;
28
+ let shift = 0;
29
+ let consumed = 0;
30
+ for (;;) {
31
+ const byte = bytes[offset + consumed] ?? 0;
32
+ value |= (byte & 0x7f) << shift;
33
+ consumed++;
34
+ if ((byte & 0x80) === 0) break;
35
+ shift += 7;
36
+ }
37
+ return [value, consumed];
38
+ }
39
+
40
+ export function decodeU8(hex: string): number {
41
+ return Number(readUIntLE(hexToBytes(hex), 0, 1));
42
+ }
43
+
44
+ export function decodeU16(hex: string): number {
45
+ return Number(readUIntLE(hexToBytes(hex), 0, 2));
46
+ }
47
+
48
+ export function decodeU32(hex: string): number {
49
+ return Number(readUIntLE(hexToBytes(hex), 0, 4));
50
+ }
51
+
52
+ export function decodeU64(hex: string): bigint {
53
+ return readUIntLE(hexToBytes(hex), 0, 8);
54
+ }
55
+
56
+ export function decodeU128(hex: string): bigint {
57
+ return readUIntLE(hexToBytes(hex), 0, 16);
58
+ }
59
+
60
+ export function decodeBool(hex: string): boolean {
61
+ return (hexToBytes(hex)[0] ?? 0) !== 0;
62
+ }
63
+
64
+ export function decodeAddress(hex: string): string {
65
+ const bytes = hexToBytes(hex);
66
+ return '0x' + Array.from(bytes.slice(0, 32), (b) => b.toString(16).padStart(2, '0')).join('');
67
+ }
68
+
69
+ export function decodeVectorAddress(hex: string): string[] {
70
+ const bytes = hexToBytes(hex);
71
+ const [len, consumed] = readUleb(bytes, 0);
72
+ const out: string[] = [];
73
+ for (let i = 0; i < len; i++) {
74
+ const start = consumed + i * 32;
75
+ out.push(
76
+ '0x' +
77
+ Array.from(bytes.slice(start, start + 32), (b) => b.toString(16).padStart(2, '0')).join('')
78
+ );
79
+ }
80
+ return out;
81
+ }
82
+
83
+ /** Decode a BCS ascii/utf8 String (ULEB length prefix + bytes). */
84
+ export function decodeString(hex: string): string {
85
+ const bytes = hexToBytes(hex);
86
+ const [len, consumed] = readUleb(bytes, 0);
87
+ return new TextDecoder().decode(bytes.slice(consumed, consumed + len));
88
+ }
89
+
90
+ /**
91
+ * Marketplace recordDataRaw is a JSON array of per-field hex strings
92
+ * (non-key fields, in schema order).
93
+ */
94
+ export function parseRecordData(recordDataRaw: string): string[] {
95
+ try {
96
+ return JSON.parse(recordDataRaw) as string[];
97
+ } catch {
98
+ return [recordDataRaw];
99
+ }
100
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { DubheGraphqlClient, createDubheGraphqlClient, QueryBuilders } from './client';
2
2
  export * from './types';
3
3
  export type * from './types';
4
+ export * from './decoders';
package/src/types.ts CHANGED
@@ -154,6 +154,51 @@ export interface DubheUserStorageRow {
154
154
  lastEventSeq: string;
155
155
  }
156
156
 
157
+ export interface SceneStorageRow {
158
+ sceneId: string;
159
+ dappKey: string;
160
+ sceneType: string;
161
+ sceneTypeRaw: string;
162
+ authorizationKind?: string | null;
163
+ authorizationKindRaw?: string | null;
164
+ authorizedPermitId?: string | null;
165
+ isDestroyed: boolean;
166
+ createdAtCheckpoint: string;
167
+ destroyedAtCheckpoint?: string | null;
168
+ updatedAtCheckpoint: string;
169
+ lastUpdateDigest: string;
170
+ lastEventSeq: string;
171
+ }
172
+
173
+ export interface SceneStorageFieldRow {
174
+ sceneId: string;
175
+ fieldNameRaw: string;
176
+ dappKey: string;
177
+ sceneType: string;
178
+ sceneTypeRaw: string;
179
+ fieldName: string;
180
+ fieldValueRaw?: string | null;
181
+ isDeleted: boolean;
182
+ deletedAtCheckpoint?: string | null;
183
+ updatedAtCheckpoint: string;
184
+ lastUpdateDigest: string;
185
+ lastEventSeq: string;
186
+ }
187
+
188
+ export interface ObjectStorageRow {
189
+ objectId: string;
190
+ dappKey: string;
191
+ objectType: string;
192
+ objectTypeRaw: string;
193
+ entityIdRaw: string;
194
+ isDestroyed: boolean;
195
+ createdAtCheckpoint: string;
196
+ destroyedAtCheckpoint?: string | null;
197
+ updatedAtCheckpoint: string;
198
+ lastUpdateDigest: string;
199
+ lastEventSeq: string;
200
+ }
201
+
157
202
  export interface DubheDappRuntimeStateRow {
158
203
  dappKey: string;
159
204
  admin?: string | null;