@evefrontier/dapp-kit 0.1.5 → 0.1.6

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/graphql/client.ts CHANGED
@@ -45,7 +45,7 @@ import {
45
45
  * This is the low-level function used by all other GraphQL helper functions.
46
46
  * Use this when you need to execute custom queries not covered by the helper functions.
47
47
  *
48
- * @category GraphQL
48
+ * @category GraphQL Client
49
49
  * @typeParam T - The expected response data type
50
50
  * @param query - The GraphQL query string
51
51
  * @param variables - Variables to pass to the query
@@ -97,7 +97,7 @@ export async function executeGraphQLQuery<T = unknown>(
97
97
  * Use this for low-level object access when you need raw BCS data.
98
98
  * For JSON-decoded data, use {@link getObjectWithJson} instead.
99
99
  *
100
- * @category GraphQL
100
+ * @category GraphQL Client
101
101
  * @param address - The Sui object address (0x...)
102
102
  * @returns Promise resolving to object with BCS contents
103
103
  *
@@ -121,7 +121,7 @@ export async function getObjectByAddress(address: string) {
121
121
  * which is useful for assemblies that store data in dynamic fields
122
122
  * (e.g., inventory items, configuration).
123
123
  *
124
- * @category GraphQL
124
+ * @category GraphQL Client
125
125
  * @param objectId - The Sui object ID
126
126
  * @returns Promise resolving to object with dynamic fields
127
127
  *
@@ -147,7 +147,7 @@ export async function getObjectWithDynamicFields(objectId: string) {
147
147
  * This is the most common way to fetch object data when you need
148
148
  * to read the object's fields as JavaScript objects.
149
149
  *
150
- * @category GraphQL
150
+ * @category GraphQL Client
151
151
  * @param address - The Sui object address
152
152
  * @returns Promise resolving to object with JSON contents
153
153
  *
@@ -170,7 +170,7 @@ export async function getObjectWithJson(address: string) {
170
170
  * Useful for traversing ownership chains, e.g., finding all assemblies
171
171
  * owned by a specific character.
172
172
  *
173
- * @category GraphQL
173
+ * @category GraphQL Client
174
174
  * @param objectAddress - The Sui object address to query owner of
175
175
  * @param ownedObjectType - Optional type filter for owned objects
176
176
  * @returns Promise resolving to owner info and owned objects (BCS format)
@@ -203,7 +203,7 @@ export async function getObjectOwnerAndOwnedObjectsByType(
203
203
  * Similar to {@link getObjectOwnerAndOwnedObjectsByType} but returns
204
204
  * JSON-decoded contents for easier consumption.
205
205
  *
206
- * @category GraphQL
206
+ * @category GraphQL Client
207
207
  * @param objectAddress - The Sui object address
208
208
  * @param ownedObjectType - Optional type filter for owned objects
209
209
  * @returns Promise resolving to owner info and owned objects (JSON format)
@@ -227,7 +227,7 @@ export async function getObjectOwnerAndOwnedObjectsWithJson(
227
227
  * This is a specialized query for EVE Frontier assemblies that
228
228
  * follows the owner_cap_id to resolve the owning character.
229
229
  *
230
- * @category GraphQL
230
+ * @category GraphQL Client
231
231
  * @param objectAddress - The assembly object address
232
232
  * @returns Promise resolving to assembly and character data
233
233
  * @internal
@@ -248,7 +248,7 @@ export async function getObjectAndCharacterOwner(objectAddress: string) {
248
248
  * Returns only object addresses (lightweight). Use this when you need
249
249
  * to find objects and will fetch their details separately.
250
250
  *
251
- * @category GraphQL
251
+ * @category GraphQL Client
252
252
  * @param owner - The owner's Sui address
253
253
  * @param objectType - Optional Move type filter (e.g., "0xpkg::module::Type")
254
254
  * @returns Promise resolving to list of owned object addresses
@@ -281,7 +281,7 @@ export async function getOwnedObjectsByType(
281
281
  * Returns full object data with dynamic fields. Use this when you need
282
282
  * all objects from a specific package (e.g., all EVE Frontier objects).
283
283
  *
284
- * @category GraphQL
284
+ * @category GraphQL Client
285
285
  * @param owner - The owner's Sui address
286
286
  * @param packageId - The Move package ID to filter by
287
287
  * @returns Promise resolving to full object data including dynamic fields
@@ -312,7 +312,7 @@ export async function getOwnedObjectsByPackage(
312
312
  * Get all characters owned by a wallet
313
313
  * Returns the most recent character owned by the wallet
314
314
  *
315
- * @category GraphQL
315
+ * @category GraphQL Client
316
316
  */
317
317
  export async function getWalletCharacters(wallet: string) {
318
318
  return executeGraphQLQuery<GetWalletCharactersResponse>(
@@ -328,7 +328,7 @@ export async function getWalletCharacters(wallet: string) {
328
328
  * Get all characters owned by a wallet
329
329
  * Returns the characters owned by the wallet
330
330
  *
331
- * @category GraphQL
331
+ * @category GraphQL Client
332
332
  */
333
333
  export async function getCharacterAndOwnedObjects(wallet: string) {
334
334
  return executeGraphQLQuery<GetCharacterAndOwnedObjectsResponse>(
@@ -346,7 +346,7 @@ export async function getCharacterAndOwnedObjects(wallet: string) {
346
346
  * Useful for global/singleton objects where there's only one instance
347
347
  * of a particular type on-chain.
348
348
  *
349
- * @category GraphQL
349
+ * @category GraphQL Client
350
350
  * @param objectType - The full Move type string
351
351
  * @returns Promise resolving to the singleton object address
352
352
  *
@@ -372,7 +372,7 @@ export async function getSingletonObjectByType(objectType: string) {
372
372
  * a table of key/value entries via dynamic fields. Returns the first object's full
373
373
  * response including contents.extract...addressAt.dynamicFields.nodes.
374
374
  *
375
- * @category GraphQL
375
+ * @category GraphQL Client
376
376
  * @param objectType - The full Move type string (e.g. from getEnergyConfigType())
377
377
  * @param tableName - The table path for extract (e.g. "assembly_energy", "fuel_efficiency")
378
378
  * @returns Promise resolving to the GraphQL response with objects.nodes[0] and dynamicFields.nodes
@@ -402,7 +402,7 @@ export async function getSingletonConfigObjectByType(
402
402
  * Use with caution as this may return many results. Supports cursor-based
403
403
  * pagination for iterating through large result sets.
404
404
  *
405
- * @category GraphQL
405
+ * @category GraphQL Client
406
406
  * @param objectType - The full Move type string
407
407
  * @param options - Pagination options
408
408
  * @param options.first - Number of results per page (default: 50)
@@ -442,7 +442,7 @@ export async function getObjectsByType(
442
442
  * It fetches the assembly's Move object data, dynamic fields, and
443
443
  * resolves the owner character through the ownership chain.
444
444
  *
445
- * @category GraphQL
445
+ * @category GraphQL Client
446
446
  * @param assemblyId - The assembly's Sui object ID
447
447
  * @returns Promise resolving to:
448
448
  * - `moveObject` - The assembly's Move object data with JSON contents and dynamic fields
@@ -10,7 +10,7 @@
10
10
  * Query for fetching a specific object by address with BCS-encoded contents
11
11
  * Use this for low-level object access with raw BCS data
12
12
  *
13
- * @category GraphQL
13
+ * @category GraphQL Queries
14
14
  */
15
15
  export const GET_OBJECT_BY_ADDRESS = `
16
16
  query GetObjectByAddress($address: SuiAddress!) {
@@ -31,11 +31,9 @@ export const GET_OBJECT_BY_ADDRESS = `
31
31
  `;
32
32
 
33
33
  /**
34
- * Query for fetching a specific assembly by ID with JSON-decoded contents
35
- * Retrieves the assembly contents and dynamic fields from the EVE Frontier world package
36
- * Use this for higher-level object access with parsed JSON data
34
+ * Object by address with JSON contents and dynamic fields (nodes).
37
35
  *
38
- * @category GraphQL
36
+ * @category GraphQL Queries
39
37
  */
40
38
  export const GET_OBJECT_WITH_DYNAMIC_FIELDS = `
41
39
  query GetObjectWithDynamicFields($objectId: SuiAddress!) {
@@ -66,11 +64,9 @@ export const GET_OBJECT_WITH_DYNAMIC_FIELDS = `
66
64
  `;
67
65
 
68
66
  /**
69
- * Query for fetching a specific assembly by ID with JSON-decoded contents
70
- * Retrieves the assembly contents and dynamic fields from the EVE Frontier world package
71
- * Use this for higher-level object access with parsed JSON data
67
+ * Assembly object with owner/character extract and character-owned objects (e.g. inventory).
72
68
  *
73
- * @category GraphQL
69
+ * @category GraphQL Queries
74
70
  */
75
71
  export const GET_OBJECT_DYNAMICFIELD_CHARACTER_WITH_JSON = `
76
72
  query GetObjectOwnerCharacterOwnerAndInventory(
@@ -168,7 +164,7 @@ query GetObjectOwnerCharacterOwnerAndInventory(
168
164
  * Useful for finding related objects (e.g., getting a character's assemblies)
169
165
  * Returns BCS-encoded data only
170
166
  *
171
- * @category GraphQL
167
+ * @category GraphQL Queries
172
168
  */
173
169
  export const GET_OBJECT_OWNER_AND_OWNED_OBJECTS_BY_TYPE = `
174
170
  query GetObjectOwnerAndOwnedObjectByType($object: SuiAddress!, $owned_object_type: String) {
@@ -204,7 +200,7 @@ export const GET_OBJECT_OWNER_AND_OWNED_OBJECTS_BY_TYPE = `
204
200
  * Query to get an object's owner and their owned objects of a specific type
205
201
  * Returns both BCS and JSON-decoded data for easier consumption
206
202
  *
207
- * @category GraphQL
203
+ * @category GraphQL Queries
208
204
  */
209
205
  export const GET_OBJECT_OWNER_AND_OWNED_OBJECTS_WITH_JSON = `
210
206
  query GetObjectOwnerAndOwnedObjectWithJson($object: SuiAddress!, $owned_object_type: String) {
@@ -242,7 +238,7 @@ export const GET_OBJECT_OWNER_AND_OWNED_OBJECTS_WITH_JSON = `
242
238
  * Query to get full object details with JSON contents
243
239
  * Used to fetch character details after getting the character ID from OwnerCap
244
240
  *
245
- * @category GraphQL
241
+ * @category GraphQL Queries
246
242
  */
247
243
  export const GET_OBJECT_WITH_JSON = `
248
244
  query GetObjectWithJson($address: SuiAddress!) {
@@ -267,7 +263,7 @@ export const GET_OBJECT_WITH_JSON = `
267
263
  * Query to get all objects of a specific type owned by an address
268
264
  * Returns object addresses only (lightweight)
269
265
  *
270
- * @category GraphQL
266
+ * @category GraphQL Queries
271
267
  */
272
268
  export const GET_OWNED_OBJECTS_BY_TYPE = `
273
269
  query GetOwnedObjectsByType($owner: SuiAddress!, $object_type: String) {
@@ -289,7 +285,7 @@ export const GET_OWNED_OBJECTS_BY_TYPE = `
289
285
  * Query for fetching objects owned by an address filtered by package
290
286
  * Returns full object data with dynamic fields
291
287
  *
292
- * @category GraphQL
288
+ * @category GraphQL Queries
293
289
  */
294
290
  export const GET_OWNED_OBJECTS_BY_PACKAGE = `
295
291
  query GetOwnedObjectsByPackage($owner: SuiAddress!, $packageId: SuiAddress!) {
@@ -336,7 +332,7 @@ export const GET_OWNED_OBJECTS_BY_PACKAGE = `
336
332
  * Query to get all characters owned by a wallet
337
333
  * Returns the characters owned by the wallet
338
334
  *
339
- * @category GraphQL
335
+ * @category GraphQL Queries
340
336
  */
341
337
  export const GET_WALLET_CHARACTERS = `
342
338
  query GetWalletCharacters($owner: SuiAddress!, $characterPlayerProfileType: String!) {
@@ -376,7 +372,7 @@ export const GET_WALLET_CHARACTERS = `
376
372
  * Query to get character owned by a wallet and objects owned by the character
377
373
  * Returns the character and objects owned by the character
378
374
  *
379
- * @category GraphQL
375
+ * @category GraphQL Queries
380
376
  */
381
377
  export const GET_CHARACTER_AND_OWNED_OBJECTS = `
382
378
  query GetCharacterAndOwnedObjects($owner: SuiAddress!, $characterPlayerProfileType: String!) {
@@ -440,7 +436,7 @@ query GetCharacterAndOwnedObjects($owner: SuiAddress!, $characterPlayerProfileTy
440
436
  * Query to get a singleton object by its type
441
437
  * Returns the first object of the specified type (useful for global/singleton objects)
442
438
  *
443
- * @category GraphQL
439
+ * @category GraphQL Queries
444
440
  */
445
441
  export const GET_SINGLETON_OBJECT_BY_TYPE = `
446
442
  query GetSingletonObjectByType($object_type: String) {
@@ -460,7 +456,7 @@ export const GET_SINGLETON_OBJECT_BY_TYPE = `
460
456
  /**
461
457
  * Query to get a singleton config object by its type
462
458
  *
463
- * @category GraphQL
459
+ * @category GraphQL Queries
464
460
  */
465
461
  export const GET_SINGLETON_CONFIG_OBJECT_BY_TYPE = `
466
462
  query GetSingletonConfigObjectByType($object_type: String!, $table_name: String!) {
@@ -504,7 +500,7 @@ export const GET_SINGLETON_CONFIG_OBJECT_BY_TYPE = `
504
500
  * Query to get all objects of a specific type (global search)
505
501
  * Use with caution - may return many results
506
502
  *
507
- * @category GraphQL
503
+ * @category GraphQL Queries
508
504
  */
509
505
  export const GET_OBJECTS_BY_TYPE = `
510
506
  query GetObjectsByType($object_type: String, $first: Int, $after: String) {
package/graphql/types.ts CHANGED
@@ -6,13 +6,13 @@
6
6
  // Base GraphQL Types
7
7
  // ============================================================================
8
8
 
9
- /** @category GraphQL */
9
+ /** Response wrapper for GraphQL with optional `data` and `errors`. @category GraphQL Types */
10
10
  export interface GraphQLResponse<T = unknown> {
11
11
  data?: T;
12
12
  errors?: Array<{ message: string }>;
13
13
  }
14
14
 
15
- /** @category GraphQL */
15
+ /** Pagination cursor and has-next flag. @category GraphQL Types */
16
16
  export interface PageInfo {
17
17
  hasNextPage: boolean;
18
18
  endCursor: string | null;
@@ -22,44 +22,44 @@ export interface PageInfo {
22
22
  // Shared building blocks (reused across response types)
23
23
  // ============================================================================
24
24
 
25
- /** @category GraphQL */
25
+ /** @category GraphQL Types */
26
26
  export interface TypeRepr {
27
27
  repr: string;
28
28
  }
29
29
 
30
- /** @category GraphQL */
30
+ /** @category GraphQL Types */
31
31
  export interface TypeReprWithLayout extends TypeRepr {
32
32
  layout?: string;
33
33
  }
34
34
 
35
- /** @category GraphQL */
35
+ /** @category GraphQL Types */
36
36
  export interface ContentsBcs {
37
37
  bcs: string;
38
38
  }
39
39
 
40
- /** @category GraphQL */
40
+ /** @category GraphQL Types */
41
41
  export interface ContentsTypeAndBcs extends ContentsBcs {
42
42
  type: TypeRepr;
43
43
  }
44
44
 
45
- /** @category GraphQL */
45
+ /** @category GraphQL Types */
46
46
  export interface ContentsJsonAndBcs extends ContentsBcs {
47
47
  json: Record<string, unknown>;
48
48
  }
49
49
 
50
- /** @category GraphQL */
50
+ /** @category GraphQL Types */
51
51
  export interface ContentsTypeJsonAndBcs extends ContentsJsonAndBcs {
52
52
  type: TypeRepr;
53
53
  }
54
54
 
55
55
  /** Contents with type + json only (no bcs). Reuses ContentsTypeJsonAndBcs shape.
56
- * @category GraphQL
56
+ * @category GraphQL Types
57
57
  */
58
58
  export type ContentsTypeAndJson = Pick<ContentsTypeJsonAndBcs, "type" | "json">;
59
59
 
60
60
  /** Node shape: contents.extract.asAddress.asObject.asMoveObject.contents.
61
61
  * Reusable for any extract-path node whose inner contents are typed as T.
62
- * @category GraphQL
62
+ * @category GraphQL Types
63
63
  */
64
64
  export interface ExtractAsMoveObjectNode<T = ContentsTypeAndJson> {
65
65
  contents: {
@@ -75,24 +75,24 @@ export interface ExtractAsMoveObjectNode<T = ContentsTypeAndJson> {
75
75
  };
76
76
  }
77
77
 
78
- /** @category GraphQL */
78
+ /** @category GraphQL Types */
79
79
  export interface PreviousTransaction {
80
80
  effects?: { timestamp?: string };
81
81
  }
82
82
 
83
- /** @category GraphQL */
83
+ /** @category GraphQL Types */
84
84
  export interface ObjectNodes<T> {
85
85
  nodes: T[];
86
86
  }
87
87
 
88
- /** @category GraphQL */
88
+ /** @category GraphQL Types */
89
89
  export interface AddressWithObjects<T> {
90
90
  address: string;
91
91
  objects: ObjectNodes<T>;
92
92
  }
93
93
 
94
94
  /** GraphQL asAddress → asObject → asMoveObject ref chain.
95
- * @category GraphQL
95
+ * @category GraphQL Types
96
96
  */
97
97
  export interface AsMoveObjectRef<T> {
98
98
  asAddress?: {
@@ -103,14 +103,14 @@ export interface AsMoveObjectRef<T> {
103
103
  }
104
104
 
105
105
  /** Contents with only json (optional payload).
106
- * @category GraphQL
106
+ * @category GraphQL Types
107
107
  */
108
108
  export interface ContentsJsonOnly {
109
109
  json: Record<string, unknown>;
110
110
  }
111
111
 
112
112
  /** Move object ref whose contents have json of type T.
113
- * @category GraphQL
113
+ * @category GraphQL Types
114
114
  */
115
115
  export type MoveObjectRefWithJson<T> = AsMoveObjectRef<{
116
116
  contents: { json: T };
@@ -120,14 +120,14 @@ export type MoveObjectRefWithJson<T> = AsMoveObjectRef<{
120
120
  // Move Object Types
121
121
  // ============================================================================
122
122
 
123
- /** @category GraphQL */
123
+ /** @category GraphQL Types */
124
124
  export interface MoveObjectContents {
125
125
  json?: Record<string, unknown>;
126
126
  bcs?: string;
127
127
  type?: TypeReprWithLayout;
128
128
  }
129
129
 
130
- /** @category GraphQL */
130
+ /** @category GraphQL Types */
131
131
  export interface DynamicFieldNode {
132
132
  contents: {
133
133
  json: Record<string, unknown>;
@@ -139,7 +139,7 @@ export interface DynamicFieldNode {
139
139
  };
140
140
  }
141
141
 
142
- /** @category GraphQL */
142
+ /** @category GraphQL Types */
143
143
  export interface MoveObjectData {
144
144
  contents: MoveObjectContents;
145
145
  dynamicFields?: ObjectNodes<DynamicFieldNode>;
@@ -149,7 +149,7 @@ export interface MoveObjectData {
149
149
  // Object Response Types
150
150
  // ============================================================================
151
151
 
152
- /** @category GraphQL */
152
+ /** @category GraphQL Types */
153
153
  export interface SuiObjectResponse {
154
154
  address?: string;
155
155
  version?: number;
@@ -157,12 +157,12 @@ export interface SuiObjectResponse {
157
157
  asMoveObject: MoveObjectData | null;
158
158
  }
159
159
 
160
- /** @category GraphQL */
160
+ /** @category GraphQL Types */
161
161
  export interface GetObjectResponse {
162
162
  object?: SuiObjectResponse;
163
163
  }
164
164
 
165
- /** @category GraphQL */
165
+ /** @category GraphQL Types */
166
166
  export interface GetObjectByAddressResponse {
167
167
  object?: {
168
168
  address: string;
@@ -176,41 +176,41 @@ export interface GetObjectByAddressResponse {
176
176
  // Owner & Owned Objects Response Types
177
177
  // ============================================================================
178
178
 
179
- /** @category GraphQL */
179
+ /** @category GraphQL Types */
180
180
  export interface OwnedObjectNode {
181
181
  contents: ContentsBcs;
182
182
  previousTransaction?: PreviousTransaction;
183
183
  }
184
184
 
185
- /** @category GraphQL */
185
+ /** @category GraphQL Types */
186
186
  export interface AddressOwner {
187
187
  address: AddressWithObjects<OwnedObjectNode>;
188
188
  }
189
189
 
190
- /** @category GraphQL */
190
+ /** @category GraphQL Types */
191
191
  export interface GetObjectOwnerAndOwnedObjectsResponse {
192
192
  object?: { owner?: { address?: AddressOwner["address"] } };
193
193
  }
194
194
 
195
- /** @category GraphQL */
195
+ /** @category GraphQL Types */
196
196
  export interface OwnedObjectNodeWithJson {
197
197
  address: string;
198
198
  contents: ContentsJsonAndBcs;
199
199
  previousTransaction?: PreviousTransaction;
200
200
  }
201
201
 
202
- /** @category GraphQL */
202
+ /** @category GraphQL Types */
203
203
  export interface AddressOwnerWithJson {
204
204
  address: AddressWithObjects<OwnedObjectNodeWithJson>;
205
205
  }
206
206
 
207
- /** @category GraphQL */
207
+ /** @category GraphQL Types */
208
208
  export interface GetObjectOwnerAndOwnedObjectsWithJsonResponse {
209
209
  object?: { owner?: { address?: AddressOwnerWithJson["address"] } };
210
210
  }
211
211
 
212
212
  /** Node shape for owner's objects in GetObjectAndCharacterOwner (authorizedObj → character).
213
- * @category GraphQL
213
+ * @category GraphQL Types
214
214
  */
215
215
  export interface CharacterOwnerNode {
216
216
  contents: {
@@ -218,7 +218,7 @@ export interface CharacterOwnerNode {
218
218
  };
219
219
  }
220
220
 
221
- /** @category GraphQL */
221
+ /** @category GraphQL Types */
222
222
  export interface GetObjectAndCharacterOwnerResponse {
223
223
  object: {
224
224
  asMoveObject: {
@@ -235,7 +235,7 @@ export interface GetObjectAndCharacterOwnerResponse {
235
235
  };
236
236
  }
237
237
 
238
- /** @category GraphQL */
238
+ /** @category GraphQL Types */
239
239
  export interface GetObjectWithJsonResponse {
240
240
  object?: {
241
241
  address: string;
@@ -249,12 +249,12 @@ export interface GetObjectWithJsonResponse {
249
249
  // GetOwnedObjectsByType Response Types
250
250
  // ============================================================================
251
251
 
252
- /** @category GraphQL */
252
+ /** @category GraphQL Types */
253
253
  export interface OwnedObjectAddressNode {
254
254
  address: string;
255
255
  }
256
256
 
257
- /** @category GraphQL */
257
+ /** @category GraphQL Types */
258
258
  export interface GetOwnedObjectsByTypeResponse {
259
259
  address?: { objects: ObjectNodes<OwnedObjectAddressNode> };
260
260
  }
@@ -263,24 +263,24 @@ export interface GetOwnedObjectsByTypeResponse {
263
263
  // GetOwnedObjectsByPackage Response Types
264
264
  // ============================================================================
265
265
 
266
- /** @category GraphQL */
266
+ /** @category GraphQL Types */
267
267
  export interface OwnedObjectFullNode {
268
268
  address: string;
269
269
  version: number;
270
270
  asMoveObject: MoveObjectData | null;
271
271
  }
272
272
 
273
- /** @category GraphQL */
273
+ /** @category GraphQL Types */
274
274
  export interface GetOwnedObjectsByPackageResponse {
275
275
  objects: ObjectNodes<OwnedObjectFullNode>;
276
276
  }
277
277
 
278
- /** @category GraphQL */
278
+ /** @category GraphQL Types */
279
279
  export interface GetWalletCharactersResponse {
280
280
  address: AddressWithObjects<ExtractAsMoveObjectNode>;
281
281
  }
282
282
 
283
- /** @category GraphQL */
283
+ /** @category GraphQL Types */
284
284
  export interface CharacterAndOwnedObjectsNode {
285
285
  contents: {
286
286
  extract: {
@@ -296,7 +296,7 @@ export interface CharacterAndOwnedObjectsNode {
296
296
  };
297
297
  }
298
298
 
299
- /** @category GraphQL */
299
+ /** @category GraphQL Types */
300
300
  export interface GetCharacterAndOwnedObjectsResponse {
301
301
  address: AddressWithObjects<CharacterAndOwnedObjectsNode>;
302
302
  }
@@ -305,18 +305,18 @@ export interface GetCharacterAndOwnedObjectsResponse {
305
305
  // Singleton & Type-based Query Response Types
306
306
  // ============================================================================
307
307
 
308
- /** @category GraphQL */
308
+ /** @category GraphQL Types */
309
309
  export interface GetSingletonObjectByTypeResponse {
310
310
  objects: ObjectNodes<OwnedObjectAddressNode>;
311
311
  }
312
312
 
313
- /** @category GraphQL */
313
+ /** @category GraphQL Types */
314
314
  export interface ConfigExtractDynamicFieldNode {
315
315
  key: { json: string };
316
316
  value: { json: string };
317
317
  }
318
318
 
319
- /** @category GraphQL */
319
+ /** @category GraphQL Types */
320
320
  export interface GetSingletonConfigObjectByTypeResponse {
321
321
  objects: {
322
322
  nodes: Array<{
@@ -341,7 +341,7 @@ export interface GetSingletonConfigObjectByTypeResponse {
341
341
  };
342
342
  }
343
343
 
344
- /** @category GraphQL */
344
+ /** @category GraphQL Types */
345
345
  export interface ObjectWithContentsNode {
346
346
  address: string;
347
347
  version: number;
@@ -350,7 +350,7 @@ export interface ObjectWithContentsNode {
350
350
  } | null;
351
351
  }
352
352
 
353
- /** @category GraphQL */
353
+ /** @category GraphQL Types */
354
354
  export interface GetObjectsByTypeResponse {
355
355
  objects: ObjectNodes<ObjectWithContentsNode> & { pageInfo: PageInfo };
356
356
  }
@@ -362,7 +362,7 @@ export interface GetObjectsByTypeResponse {
362
362
  /**
363
363
  * Raw Sui object data structure returned from the EVE Frontier package
364
364
  *
365
- * @category GraphQL
365
+ * @category GraphQL Types
366
366
  */
367
367
  export interface RawSuiObjectData {
368
368
  id: string;
@@ -422,7 +422,7 @@ export interface RawSuiObjectData {
422
422
  * OwnerCap JSON structure - returned from Character OwnerCap query
423
423
  * Contains the authorized_object_id which is the Character ID
424
424
  *
425
- * @category GraphQL
425
+ * @category GraphQL Types
426
426
  */
427
427
  export interface OwnerCapData {
428
428
  authorized_object_id: string;
@@ -432,7 +432,7 @@ export interface OwnerCapData {
432
432
  /**
433
433
  * Raw Character data structure from the EVE Frontier package
434
434
  *
435
- * @category GraphQL
435
+ * @category GraphQL Types
436
436
  */
437
437
  export interface RawCharacterData {
438
438
  id: `0x${string}`;
@@ -456,7 +456,7 @@ export interface RawCharacterData {
456
456
  /**
457
457
  * Processed character/owner information
458
458
  *
459
- * @category GraphQL
459
+ * @category GraphQL Types
460
460
  */
461
461
  export interface CharacterInfo {
462
462
  id: string;
@@ -9,7 +9,7 @@ import { VaultContextType } from "../types";
9
9
  * and methods to connect/disconnect wallets. Automatically detects EVE Vault
10
10
  * wallet availability.
11
11
  *
12
- * @category Hooks
12
+ * @category Hooks - Connection
13
13
  * @returns Object containing wallet state and connection methods:
14
14
  * - `currentAccount` - The currently connected wallet account (or null)
15
15
  * - `walletAddress` - The connected wallet's address string
@@ -9,7 +9,7 @@ import { NotificationContextType } from "../types";
9
9
  * and info messages to users. Commonly used after transaction completions
10
10
  * or to display important status updates.
11
11
  *
12
- * @category Hooks
12
+ * @category Hooks - Notification
13
13
  * @returns Object containing notification state and methods:
14
14
  * - `notify` - Function to trigger a notification
15
15
  * - `notification` - Current notification state object with:
@@ -10,7 +10,7 @@ import { SmartObjectContextType } from "../types";
10
10
  * The assembly ID is determined from URL query parameters (`?itemId=` and `?tenant=`)
11
11
  * or environment variables as a Sui object ID (`VITE_OBJECT_ID`).
12
12
  *
13
- * @category Hooks
13
+ * @category Hooks - Smart Object
14
14
  * @returns Object containing assembly state and methods:
15
15
  * - `assembly` - The transformed assembly data (or null if not loaded)
16
16
  * - `character` - The owner character information (or null)
@@ -133,7 +133,7 @@ function resolveAssemblyId(
133
133
  /**
134
134
  * Error union type for {@link useSponsoredTransaction} mutation failures.
135
135
  *
136
- * @category Hooks
136
+ * @category Hooks - Sponsored Transaction
137
137
  */
138
138
  export type UseSponsoredTransactionError =
139
139
  | WalletSponsoredTransactionNotSupportedError
@@ -146,14 +146,14 @@ export type UseSponsoredTransactionError =
146
146
  * Arguments passed to {@link useSponsoredTransaction} mutate/mutateAsync.
147
147
  * With assembly object (id and type derived).
148
148
  *
149
- * @category Hooks
149
+ * @category Hooks - Sponsored Transaction
150
150
  */
151
151
  export type UseSponsoredTransactionArgs = SponsoredTransactionArgs;
152
152
 
153
153
  /**
154
154
  * React Query mutation options for {@link useSponsoredTransaction}.
155
155
  *
156
- * @category Hooks
156
+ * @category Hooks - Sponsored Transaction
157
157
  */
158
158
  export type UseSponsoredTransactionMutationOptions = Omit<
159
159
  UseMutationOptions<
@@ -191,7 +191,7 @@ export type UseSponsoredTransactionMutationOptions = Omit<
191
191
  * - `effects` (optional) – Transaction effects, BCS encoded.
192
192
  * - `rawEffects` (optional) – Raw effects bytes.
193
193
  *
194
- * @category Hooks
194
+ * @category Hooks - Sponsored Transaction
195
195
  * @param options - React Query mutation options (optional)
196
196
  * @returns React Query mutation result with:
197
197
  * - `mutate(args, options?)` - Trigger transaction (fire-and-forget)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evefrontier/dapp-kit",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "React SDK for EVE Frontier dApps on Sui",
5
5
  "main": "index.ts",
6
6
  "author": "",
@@ -14,7 +14,7 @@ import {
14
14
  DetailedSmartCharacterResponse,
15
15
  } from "../types";
16
16
 
17
- import { POLLING_INTERVAL } from "../utils/constants";
17
+ import { DEFAULT_TENANT, POLLING_INTERVAL } from "../utils/constants";
18
18
  import { getAssemblyWithOwner, MoveObjectData } from "../graphql";
19
19
  import {
20
20
  getObjectId,
@@ -25,9 +25,6 @@ import { getDatahubGameInfo } from "../utils/datahub";
25
25
  import { useConnection } from "../hooks/useConnection";
26
26
  import { SmartObjectContextType } from "../types";
27
27
 
28
- /** Tenant when not provided via URL ?tenant= (e.g. dev/default chain). */
29
- const DEFAULT_TENANT = "testevenet";
30
-
31
28
  /** Input for fetching object data: either itemId + tenant (derive object ID) or a Sui object ID directly.
32
29
  * @category Types
33
30
  */
@@ -37,6 +34,7 @@ export type FetchObjectDataInput =
37
34
 
38
35
  /** @category Providers */
39
36
  export const SmartObjectContext = createContext<SmartObjectContextType>({
37
+ tenant: DEFAULT_TENANT,
40
38
  assembly: null,
41
39
  assemblyOwner: null,
42
40
  loading: true,
@@ -269,6 +267,7 @@ const SmartObjectProvider = ({ children }: { children: ReactNode }) => {
269
267
  return (
270
268
  <SmartObjectContext.Provider
271
269
  value={{
270
+ tenant: selectedTenant,
272
271
  assembly,
273
272
  assemblyOwner,
274
273
  loading,
package/types/contexts.ts CHANGED
@@ -7,8 +7,9 @@ import {
7
7
  } from "./types";
8
8
 
9
9
  /**
10
- * Vault Context Type
11
- * @category Types */
10
+ * Vault context: account, connection state, and connect/disconnect handlers.
11
+ * @category Types
12
+ */
12
13
  export interface VaultContextType {
13
14
  currentAccount: WalletAccount | null;
14
15
  walletAddress: string | undefined;
@@ -24,9 +25,11 @@ export enum SupportedWallets {
24
25
  }
25
26
 
26
27
  /**
27
- * Smart Object Context Type
28
- * @category Types */
28
+ * Smart object context: assembly, owner, loading, error, and refetch.
29
+ * @category Types
30
+ */
29
31
  export interface SmartObjectContextType {
32
+ tenant: string;
30
33
  assembly: AssemblyType<Assemblies> | null;
31
34
  assemblyOwner: DetailedSmartCharacterResponse | null;
32
35
  loading: boolean;
package/types/types.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { SUI_GRAPHQL_NETWORKS } from "../utils";
1
2
  import {
2
3
  DetailedAssemblyResponse,
3
4
  StorageModule,
@@ -18,6 +19,9 @@ export enum QueryParams {
18
19
  TENANT = "tenant",
19
20
  }
20
21
 
22
+ /** @category Types */
23
+ export type SuiGraphqlNetwork = (typeof SUI_GRAPHQL_NETWORKS)[number];
24
+
21
25
  // =========================================
22
26
  // Assembly State and Actions
23
27
  // =========================================
@@ -0,0 +1,48 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { resolveTenantFromSearch, resolveDatahubHost } from "../datahub";
3
+ import { DATAHUB_BY_TENANT, DEFAULT_TENANT } from "../constants";
4
+ import { QueryParams } from "../../types";
5
+
6
+ const DEFAULT_HOST = DATAHUB_BY_TENANT[DEFAULT_TENANT];
7
+
8
+ describe("resolveTenantFromSearch (tenant resolution)", () => {
9
+ it("returns DEFAULT_TENANT when search is empty", () => {
10
+ expect(resolveTenantFromSearch("")).toBe(DEFAULT_TENANT);
11
+ });
12
+
13
+ it("returns DEFAULT_TENANT when tenant param is missing", () => {
14
+ expect(resolveTenantFromSearch("?itemId=123")).toBe(DEFAULT_TENANT);
15
+ });
16
+
17
+ it("returns DEFAULT_TENANT when tenant param is blank (?tenant=)", () => {
18
+ expect(resolveTenantFromSearch("?tenant=")).toBe(DEFAULT_TENANT);
19
+ });
20
+
21
+ it("trims tenant value (surrounding spaces)", () => {
22
+ expect(resolveTenantFromSearch("?tenant= stillness ")).toBe("stillness");
23
+ expect(resolveTenantFromSearch("?tenant=nebula ")).toBe("nebula");
24
+ });
25
+
26
+ it("returns trimmed known tenant from param", () => {
27
+ expect(resolveTenantFromSearch(`?${QueryParams.TENANT}=nebula`)).toBe(
28
+ "nebula",
29
+ );
30
+ expect(resolveTenantFromSearch(`?${QueryParams.TENANT}=utopia`)).toBe(
31
+ "utopia",
32
+ );
33
+ });
34
+ });
35
+
36
+ describe("resolveDatahubHost (host fallback)", () => {
37
+ it("returns DEFAULT_TENANT host for unknown tenant", () => {
38
+ expect(resolveDatahubHost("unknown-tenant")).toBe(DEFAULT_HOST);
39
+ expect(resolveDatahubHost("")).toBe(DEFAULT_HOST);
40
+ });
41
+
42
+ it("returns known host for valid tenant keys", () => {
43
+ expect(resolveDatahubHost("stillness")).toBe(DATAHUB_BY_TENANT.stillness);
44
+ expect(resolveDatahubHost("nebula")).toBe(DATAHUB_BY_TENANT.nebula);
45
+ expect(resolveDatahubHost("utopia")).toBe(DATAHUB_BY_TENANT.utopia);
46
+ expect(resolveDatahubHost("testevenet")).toBe(DATAHUB_BY_TENANT.testevenet);
47
+ });
48
+ });
@@ -8,7 +8,6 @@ import { getObjectRegistryType } from "../constants";
8
8
  // Mock env vars for testing
9
9
  const TEST_EVE_WORLD_PACKAGE_ID =
10
10
  "0x2ff3e06b96eb830bdcffbc6cae9b8fe43f005c3b94cef05d9ec23057df16f107";
11
- const TEST_SUI_GRAPHQL_ENDPOINT = "https://graphql.testnet.sui.io/graphql";
12
11
 
13
12
  // Mock the GraphQL client (only for getObjectId/getRegistryAddress tests)
14
13
  vi.mock("../../graphql/client", () => ({
@@ -22,7 +21,6 @@ describe("mapping utilities", () => {
22
21
  vi.clearAllMocks();
23
22
  // Stub environment variables for tests
24
23
  vi.stubEnv("VITE_EVE_WORLD_PACKAGE_ID", TEST_EVE_WORLD_PACKAGE_ID);
25
- vi.stubEnv("VITE_SUI_GRAPHQL_ENDPOINT", TEST_SUI_GRAPHQL_ENDPOINT);
26
24
  });
27
25
 
28
26
  afterEach(() => {
package/utils/burnRate.ts CHANGED
@@ -18,7 +18,7 @@ export interface AdjustedBurnRate {
18
18
  * @param rawBurnTimeMs - Milliseconds to burn one unit at 100% efficiency. If non-finite or negative, treated as 0 so both returned fields are finite and consistent.
19
19
  * @param efficiencyPercent - Efficiency as percentage on a 0–100 scale (e.g. 90 for 90%). Values outside [0, 100] are treated as invalid; when null/undefined, not finite, ≤0, or >100, raw is used as-is for burn time.
20
20
  * @returns { burnTimePerUnitMs, unitsPerHour }
21
- * @category Utilities
21
+ * @category Utilities - Formatting
22
22
  */
23
23
  export function getAdjustedBurnRate(
24
24
  rawBurnTimeMs: number,
package/utils/config.ts CHANGED
@@ -52,7 +52,7 @@ function parseConfig(
52
52
  * caches the result, and returns the map of type_id -> energy usage.
53
53
  * Subsequent calls return the cached map.
54
54
  *
55
- * @category Utilities
55
+ * @category Utilities - Config
56
56
  */
57
57
  export async function getEnergyConfig(): Promise<Record<number, number>> {
58
58
  if (energyConfigCache) {
@@ -88,7 +88,7 @@ export async function getEnergyConfig(): Promise<Record<number, number>> {
88
88
  * caches the result, and returns the map of type_id -> fuel efficiency.
89
89
  * Subsequent calls return the cached map.
90
90
  *
91
- * @category Utilities
91
+ * @category Utilities - Config
92
92
  */
93
93
  export async function getFuelEfficiencyConfig(): Promise<
94
94
  Record<number, number>
@@ -127,7 +127,7 @@ export async function getFuelEfficiencyConfig(): Promise<
127
127
  *
128
128
  * @param typeId - In-game type ID (e.g. from rawData.type_id)
129
129
  * @returns Energy usage (e.g. energy_constant), or 0 if not found or not yet loaded
130
- * @category Utilities
130
+ * @category Utilities - Config
131
131
  */
132
132
  export async function getEnergyUsageForType(typeId: number): Promise<number> {
133
133
  const config = await getEnergyConfig();
@@ -141,7 +141,7 @@ export async function getEnergyUsageForType(typeId: number): Promise<number> {
141
141
  *
142
142
  * @param typeId - In-game type ID (e.g. from rawData.type_id)
143
143
  * @returns Fuel efficiency (e.g. fuel_efficiency), or 0 if not found or not yet loaded
144
- * @category Utilities
144
+ * @category Utilities - Config
145
145
  */
146
146
  export async function getFuelEfficiencyForType(
147
147
  typeId: number,
@@ -2,6 +2,8 @@
2
2
  // Environment Variable Helpers
3
3
  // ============================================================================
4
4
 
5
+ import { SuiGraphqlNetwork } from "../types";
6
+
5
7
  /**
6
8
  * Get a required environment variable, throwing if not set.
7
9
  * @param name - The environment variable name (e.g., "VITE_SUI_GRAPHQL_ENDPOINT")
@@ -22,68 +24,85 @@ function getEnvVar(name: string): string {
22
24
  // Environment-Based Configuration
23
25
  // ============================================================================
24
26
 
27
+ function isSuiGraphqlNetwork(value: string): value is SuiGraphqlNetwork {
28
+ return SUI_GRAPHQL_NETWORKS.includes(value as SuiGraphqlNetwork);
29
+ }
30
+
25
31
  /**
26
- * Get the Sui GraphQL endpoint URL from environment.
32
+ * Get the Sui GraphQL endpoint URL for the given network.
33
+ * Unknown values fall back to testnet to avoid returning undefined.
34
+ * @param env - Network identifier (testnet, devnet, mainnet). Defaults to testnet.
27
35
  * @returns The GraphQL endpoint URL
28
- * @throws {Error} If VITE_SUI_GRAPHQL_ENDPOINT is not set
29
- * @category Utilities
36
+ * @category Utilities - Config
30
37
  */
31
- export const getSuiGraphqlEndpoint = (): string =>
32
- getEnvVar("VITE_SUI_GRAPHQL_ENDPOINT");
38
+ export function getSuiGraphqlEndpoint(
39
+ env: string = DEFAULT_GRAPHQL_NETWORK,
40
+ ): string {
41
+ const network = isSuiGraphqlNetwork(env) ? env : DEFAULT_GRAPHQL_NETWORK;
42
+ return GRAPHQL_ENDPOINTS[network];
43
+ }
33
44
 
34
45
  /**
35
46
  * Get the EVE World package ID from environment.
36
47
  * @returns The package ID (0x-prefixed address)
37
48
  * @throws {Error} If VITE_EVE_WORLD_PACKAGE_ID is not set
38
- * @category Utilities
49
+ * @category Utilities - Config
39
50
  */
40
51
  export const getEveWorldPackageId = (): string =>
41
52
  getEnvVar("VITE_EVE_WORLD_PACKAGE_ID");
42
53
 
43
- /**
44
- * Get the Character OwnerCap type string (derived from package ID).
45
- * @returns The fully qualified type string for Character OwnerCap
46
- * @category Utilities
47
- */
54
+ /** Type string for Character OwnerCap from the EVE World package. @category Utilities - Config */
48
55
  export const getCharacterOwnerCapType = (): string => {
49
56
  const pkg = getEveWorldPackageId();
50
57
  return `${pkg}::access::OwnerCap<${pkg}::character::Character>`;
51
58
  };
52
59
 
53
- /**
54
- * Get the Character PlayerProfile type string (derived from package ID).
55
- * @returns The fully qualified type string for Character PlayerProfile
56
- * @category Utilities
57
- */
60
+ /** Type string for Character PlayerProfile from the EVE World package. @category Utilities - Config */
58
61
  export const getCharacterPlayerProfileType = (): string => {
59
62
  const pkg = getEveWorldPackageId();
60
63
  return `${pkg}::character::PlayerProfile`;
61
64
  };
62
65
 
63
- /**
64
- * Get the ObjectRegistry type string (derived from package ID).
65
- * @returns The fully qualified type string for ObjectRegistry
66
- * @category Utilities
67
- */
66
+ /** Type string for ObjectRegistry from the EVE World package. @category Utilities - Config */
68
67
  export const getObjectRegistryType = (): string =>
69
68
  `${getEveWorldPackageId()}::object_registry::ObjectRegistry`;
70
69
 
71
- /**
72
- * Get the EnergyConfig type string (derived from package ID).
73
- * @returns The fully qualified type string for Energy Config
74
- * @category Utilities
75
- */
70
+ /** Type string for EnergyConfig from the EVE World package. @category Utilities - Config */
76
71
  export const getEnergyConfigType = (): string =>
77
72
  `${getEveWorldPackageId()}::energy::EnergyConfig`;
78
73
 
79
- /**
80
- * Get the Fuel Efficiency Config type string (derived from package ID).
81
- * @returns The fully qualified type string for Fuel Efficiency Config
82
- * @category Utilities
83
- */
74
+ /** Type string for FuelConfig from the EVE World package. @category Utilities - Config */
84
75
  export const getFuelEfficiencyConfigType = (): string =>
85
76
  `${getEveWorldPackageId()}::fuel::FuelConfig`;
86
77
 
78
+ // ============================================================================
79
+ // Constants
80
+ // ============================================================================
81
+
82
+ /** Default Sui network for GraphQL endpoint selection.
83
+ * @category Constants
84
+ */
85
+ export const DEFAULT_GRAPHQL_NETWORK: SuiGraphqlNetwork = "testnet";
86
+
87
+ /** Tenant when not provided via URL ?tenant= (e.g. dev/default chain).
88
+ * @category Constants
89
+ */
90
+ export const DEFAULT_TENANT = "stillness";
91
+
92
+ /** Allowed Sui network identifiers for GraphQL endpoint selection.
93
+ * @category Constants
94
+ */
95
+ export const SUI_GRAPHQL_NETWORKS = ["testnet", "devnet", "mainnet"] as const;
96
+
97
+ /** GraphQL endpoint URLs for each Sui network.
98
+ * @category Constants
99
+ */
100
+ export const GRAPHQL_ENDPOINTS: Record<SuiGraphqlNetwork, string> = {
101
+ testnet: "https://graphql.testnet.sui.io/graphql",
102
+ devnet: "https://graphql.devnet.sui.io/graphql",
103
+ mainnet: "https://graphql.mainnet.sui.io/graphql",
104
+ };
105
+
87
106
  /** Polling interval in milliseconds (10 seconds).
88
107
  * @category Constants
89
108
  */
@@ -128,3 +147,79 @@ export const EXCLUDED_TYPEIDS = [
128
147
  * @category Constants
129
148
  */
130
149
  export const ONE_M3 = 1000000000000000000;
150
+
151
+ export type TenantId = "utopia" | "stillness" | "testevenet" | "nebula";
152
+
153
+ /** Per-tenant config: EVE token package ID (Sui) and Datahub API host. v0.0.18
154
+ * @category Constants
155
+ */
156
+ export interface TenantConfig {
157
+ packageId: string;
158
+ datahubHost: string;
159
+ }
160
+
161
+ /** Single source of truth for the four tenants (package ID + datahub host).
162
+ * @category Constants
163
+ */
164
+ export const TENANT_CONFIG: Record<TenantId, TenantConfig> = {
165
+ nebula: {
166
+ packageId:
167
+ "0x353988e063b4683580e3603dbe9e91fefd8f6a06263a646d43fd3a2f3ef6b8c1",
168
+ datahubHost: "world-api-nebula.test.evefrontier.tech",
169
+ },
170
+ testevenet: {
171
+ packageId:
172
+ "0x353988e063b4683580e3603dbe9e91fefd8f6a06263a646d43fd3a2f3ef6b8c1",
173
+ datahubHost: "world-api-testevenet.test.evefrontier.tech",
174
+ },
175
+ utopia: {
176
+ packageId:
177
+ "0xd12a70c74c1e759445d6f209b01d43d860e97fcf2ef72ccbbd00afd828043f75",
178
+ datahubHost: "world-api-utopia.uat.pub.evefrontier.com",
179
+ },
180
+ stillness: {
181
+ packageId:
182
+ "0x28b497559d65ab320d9da4613bf2498d5946b2c0ae3597ccfda3072ce127448c",
183
+ datahubHost: "world-api-stillness.live.tech.evefrontier.com",
184
+ },
185
+ };
186
+
187
+ /** EVE token package ID per tenant (derived from TENANT_CONFIG).
188
+ * @category Constants
189
+ */
190
+ export const EVE_PACKAGE_ID_BY_TENANT = Object.fromEntries(
191
+ (Object.entries(TENANT_CONFIG) as [TenantId, TenantConfig][]).map(
192
+ ([id, config]) => [id, config.packageId],
193
+ ),
194
+ ) as Record<TenantId, string>;
195
+
196
+ /** Datahub API host per tenant (derived from TENANT_CONFIG).
197
+ * @category Constants
198
+ */
199
+ export const DATAHUB_BY_TENANT = Object.fromEntries(
200
+ (Object.entries(TENANT_CONFIG) as [TenantId, TenantConfig][]).map(
201
+ ([id, config]) => [id, config.datahubHost],
202
+ ),
203
+ ) as Record<TenantId, string>;
204
+
205
+ /** @category Constants */
206
+ const EVE_COIN_TYPE_SUFFIX = "::EVE::EVE";
207
+
208
+ /**
209
+ * Returns the EVE token coin type for the given tenant.
210
+ * Format: `{packageId}::EVE::EVE` (Sui Move type used by RPC/GraphQL).
211
+ * @param tenantId - The tenant identifier (e.g., "utopia", "stillness")
212
+ * @returns The fully qualified EVE coin type string
213
+ *
214
+ * @category Utilities - Config
215
+ */
216
+ export function getEveCoinType(tenantId: TenantId): string {
217
+ return `${EVE_PACKAGE_ID_BY_TENANT[tenantId]}${EVE_COIN_TYPE_SUFFIX}`;
218
+ }
219
+
220
+ /** Known EVE coin types (one per tenant) for strict matching.
221
+ * @category Constants
222
+ */
223
+ export const KNOWN_EVE_COIN_TYPES = new Set(
224
+ (Object.keys(EVE_PACKAGE_ID_BY_TENANT) as TenantId[]).map(getEveCoinType),
225
+ );
package/utils/datahub.ts CHANGED
@@ -1,4 +1,28 @@
1
- import { DatahubGameInfo } from "../types";
1
+ import { DATAHUB_BY_TENANT, DEFAULT_TENANT } from "./constants";
2
+ import { DatahubGameInfo, QueryParams } from "../types";
3
+
4
+ /**
5
+ * Resolves tenant from a URL search string (e.g. window.location.search).
6
+ * Trims the param value and falls back to DEFAULT_TENANT when missing or blank.
7
+ * @internal
8
+ */
9
+ export function resolveTenantFromSearch(search: string): string {
10
+ const tenant =
11
+ new URLSearchParams(search).get(QueryParams.TENANT)?.trim() ||
12
+ DEFAULT_TENANT;
13
+ return tenant;
14
+ }
15
+
16
+ /**
17
+ * Resolves the datahub host for a tenant key. Falls back to DEFAULT_TENANT host for unknown tenants.
18
+ * @internal
19
+ */
20
+ export function resolveDatahubHost(tenant: string): string {
21
+ return (
22
+ DATAHUB_BY_TENANT[tenant as keyof typeof DATAHUB_BY_TENANT] ??
23
+ DATAHUB_BY_TENANT[DEFAULT_TENANT]
24
+ );
25
+ }
2
26
 
3
27
  /**
4
28
  * Fetch game type information from the EVE Frontier Datahub API.
@@ -7,7 +31,9 @@ import { DatahubGameInfo } from "../types";
7
31
  * description, icon URL, and physical properties. This data is used to
8
32
  * enrich on-chain objects with human-readable information.
9
33
  *
10
- * @category Utilities
34
+ * Resolves tenant from the window.location.search param.
35
+ *
36
+ * @category Utilities - Config
11
37
  * @param typeId - The numeric type ID (from on-chain type_id field)
12
38
  * @returns Promise resolving to the type's game info
13
39
  *
@@ -29,9 +55,10 @@ import { DatahubGameInfo } from "../types";
29
55
  export async function getDatahubGameInfo(
30
56
  typeId: number,
31
57
  ): Promise<DatahubGameInfo> {
32
- const response = await fetch(
33
- `https://world-api-stillness.live.tech.evefrontier.com/v2/types/${typeId}`,
34
- );
58
+ const tenant = resolveTenantFromSearch(window.location.search);
59
+ const host = resolveDatahubHost(tenant);
60
+
61
+ const response = await fetch(`https://${host}/v2/types/${typeId}`);
35
62
  const data = await response.json();
36
63
 
37
64
  return data;
package/utils/errors.ts CHANGED
@@ -6,7 +6,7 @@ export type ErrorType = {
6
6
  message: string;
7
7
  };
8
8
 
9
- /** @category Utilities */
9
+ /** @category Utilities - Error helpers */
10
10
  export const ERRORS: Record<number | string, ErrorType> = {
11
11
  1001: {
12
12
  code: 1001,
@@ -144,7 +144,7 @@ export const ERROR_MESSAGES: Record<number, string> = Object.fromEntries(
144
144
  .map(([key, value]) => [Number(key), value.message]),
145
145
  );
146
146
 
147
- /** @category Utilities */
147
+ /** @category Utilities - Error helpers */
148
148
  export const parseErrorFromMessage = (
149
149
  errorMessage: string,
150
150
  ): {
package/utils/mapping.ts CHANGED
@@ -7,7 +7,7 @@ import { getSingletonObjectByType } from "../graphql/client";
7
7
  /**
8
8
  * Convert raw status variant string to State enum
9
9
  *
10
- * @category Utilities
10
+ * @category Utilities - Mapping
11
11
  */
12
12
  export function parseStatus(statusVariant: string | undefined): State {
13
13
  if (!statusVariant) return State.NULL;
@@ -33,7 +33,7 @@ export function parseStatus(statusVariant: string | undefined): State {
33
33
  * @param typeRepr - The Move object type tag
34
34
  * @returns The assembly type as an enum
35
35
  *
36
- * @category Utilities
36
+ * @category Utilities - Mapping
37
37
  */
38
38
  export function getAssemblyType(typeRepr: string): Assemblies {
39
39
  if (typeRepr.includes("::storage_unit::StorageUnit")) {
@@ -68,7 +68,7 @@ let objectRegistryAddress: string | null = null;
68
68
  * Fetches the AssemblyRegistry singleton address from the chain
69
69
  * Caches the result to avoid repeated queries
70
70
  *
71
- * @category Utilities
71
+ * @category Utilities - Mapping
72
72
  */
73
73
  export async function getRegistryAddress(): Promise<string> {
74
74
  if (objectRegistryAddress) {
@@ -92,7 +92,7 @@ export async function getRegistryAddress(): Promise<string> {
92
92
  * @param itemId - The in-game item ID
93
93
  * @returns The derived Sui object ID
94
94
  *
95
- * @category Utilities
95
+ * @category Utilities - Mapping
96
96
  */
97
97
  export async function getObjectId(
98
98
  itemId: string,
@@ -21,7 +21,7 @@ import { getObjectWithJson } from "../graphql";
21
21
  /**
22
22
  * Transform CharacterInfo to DetailedSmartCharacterResponse
23
23
  *
24
- * @category Utilities
24
+ * @category Utilities - Transforms
25
25
  */
26
26
  export function transformToCharacter(
27
27
  characterInfo: CharacterInfo,
@@ -57,7 +57,7 @@ export interface TransformOptions {
57
57
  * @param moveObject - The Move object data from GraphQL
58
58
  * @param options - Optional transform options including character info
59
59
  *
60
- * @category Utilities
60
+ * @category Utilities - Transforms
61
61
  */
62
62
  export async function transformToAssembly(
63
63
  objectId: string,
package/utils/utils.ts CHANGED
@@ -15,7 +15,7 @@ import { ONE_M3 } from "./constants";
15
15
  * Shortens long addresses to show only the beginning and end characters
16
16
  * with ellipsis in the middle.
17
17
  *
18
- * @category Utilities
18
+ * @category Utilities - Formatting
19
19
  * @param string - The address or hex string to abbreviate
20
20
  * @param precision - Number of characters to show on each end (default: 5)
21
21
  * @param expanded - If true, returns the full string without abbreviation
@@ -45,7 +45,7 @@ export const abbreviateAddress = (
45
45
  * Compares the assembly's owner address with the provided account address
46
46
  * to determine ownership.
47
47
  *
48
- * @category Utilities
48
+ * @category Utilities - Assembly
49
49
  * @param assembly - The assembly object to check ownership of
50
50
  * @param account - The account address to check against
51
51
  * @returns True if the account owns the assembly, false otherwise
@@ -71,7 +71,7 @@ export const isOwner = (
71
71
  /**
72
72
  * Generate a Suiscan transaction URL for a given transaction hash.
73
73
  *
74
- * @category Utilities
74
+ * @category Utilities - Assembly
75
75
  * @param suiChain - The Sui chain identifier (e.g., "sui:testnet", "sui:mainnet")
76
76
  * @param txHash - The transaction digest hash
77
77
  * @returns Full Suiscan URL to view the transaction
@@ -88,19 +88,20 @@ export const getTxUrl = (suiChain: SuiChain, txHash: string): string => {
88
88
  return `https://suiscan.xyz/${network}/tx/${txHash}`;
89
89
  };
90
90
 
91
+ /** Strips protocol (e.g. https://) from a URL and returns the rest. @category Utilities - Formatting */
91
92
  export const parseURL = (string: string): string => {
92
93
  if (string.includes("://")) {
93
- // Remove 'http' or 'https'
94
94
  return string.split("://")[1];
95
- } else {
96
- return string;
97
95
  }
96
+ return string;
98
97
  };
99
98
 
99
+ /** Copies the given string to the clipboard. @category Utilities - Formatting */
100
100
  export const clickToCopy = (string: string) => {
101
101
  return navigator.clipboard.writeText(string);
102
102
  };
103
103
 
104
+ /** Returns elements that appear in both arrays. @category Utilities - Formatting */
104
105
  export const getCommonItems = (array1: any[], array2: any[]) => {
105
106
  const commonItems: any[] = [];
106
107
  const set: Set<any> = new Set([]);
@@ -116,19 +117,24 @@ export const getCommonItems = (array1: any[], array2: any[]) => {
116
117
  return commonItems;
117
118
  };
118
119
 
120
+ /** Removes trailing zeros after the last significant decimal. @category Utilities - Formatting */
119
121
  export const removeTrailingZeros = (number: string) => {
120
122
  return number.replace(/(\.\d*?[1-9])0+$|\.0*$/, "$1");
121
123
  };
122
124
 
125
+ /** Returns the env value or fallback if empty. @category Utilities - Config */
123
126
  export const getEnv = (env: string, fallback: string): string => {
124
127
  if (!env) return fallback;
125
128
  return env;
126
129
  };
127
130
 
128
- /** Calculates the volume in M3
129
- * @param quantity - The unit quantity of the item
131
+ /**
132
+ * Volume in from unit quantity and volume per unit (wei, 10^18).
133
+ * @param quantity - Unit quantity of the item
130
134
  * @param volume - Volume per unit in wei (10^18)
131
- * @returns volume in m3 */
135
+ * @returns Volume in
136
+ * @category Utilities - Formatting
137
+ */
132
138
  export const getVolumeM3 = (quantity: bigint, volume: bigint): number => {
133
139
  const totalVolume = Number(quantity) * Number(volume);
134
140
  return totalVolume;
@@ -139,7 +145,7 @@ export const getVolumeM3 = (quantity: bigint, volume: bigint): number => {
139
145
  *
140
146
  * Converts from the on-chain representation (wei-like, 10^18) to m³.
141
147
  *
142
- * @category Utilities
148
+ * @category Utilities - Formatting
143
149
  * @param quantity - The raw volume value as string or bigint
144
150
  * @returns Volume in cubic meters
145
151
  *
@@ -155,7 +161,7 @@ export const formatM3 = (quantity: string | bigint): number => {
155
161
  /**
156
162
  * Get the dApp URL for an assembly, ensuring it has a protocol prefix.
157
163
  *
158
- * @category Utilities
164
+ * @category Utilities - Assembly
159
165
  * @param assembly - The assembly object
160
166
  * @returns The full dApp URL with https:// prefix if needed
161
167
  *
@@ -184,7 +190,7 @@ export const getDappUrl = (assembly: AssemblyType<Assemblies>): string => {
184
190
  /**
185
191
  * Check if two addresses match.
186
192
  *
187
- * @category Utilities
193
+ * @category Utilities - Assembly
188
194
  * @param address1 - First address to compare
189
195
  * @param address2 - Second address to compare
190
196
  * @returns True if addresses match, false otherwise
@@ -202,7 +208,7 @@ export const findOwnerByAddress = (
202
208
  *
203
209
  * Use this to narrow the type of an assembly for type-safe property access.
204
210
  *
205
- * @category Utilities
211
+ * @category Utilities - Assembly
206
212
  * @param assembly - The assembly to check
207
213
  * @param assemblyType - The expected assembly type
208
214
  * @returns True if assembly matches the specified type
@@ -232,7 +238,7 @@ export const assertAssemblyType = (
232
238
  *
233
239
  * Displays the duration in days, hours, minutes, and seconds as appropriate.
234
240
  *
235
- * @category Utilities
241
+ * @category Utilities - Formatting
236
242
  * @param seconds - Duration in seconds
237
243
  * @returns Formatted duration string (e.g., "02d 05h 30m 15s")
238
244
  *