@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 +15 -15
- package/graphql/queries.ts +15 -19
- package/graphql/types.ts +47 -47
- package/hooks/useConnection.ts +1 -1
- package/hooks/useNotification.ts +1 -1
- package/hooks/useSmartObject.ts +1 -1
- package/hooks/useSponsoredTransaction.ts +4 -4
- package/package.json +1 -1
- package/providers/SmartObjectProvider.tsx +3 -4
- package/types/contexts.ts +7 -4
- package/types/types.ts +4 -0
- package/utils/__tests__/datahub.test.ts +48 -0
- package/utils/__tests__/mapping.test.ts +0 -2
- package/utils/burnRate.ts +1 -1
- package/utils/config.ts +4 -4
- package/utils/constants.ts +126 -31
- package/utils/datahub.ts +32 -5
- package/utils/errors.ts +2 -2
- package/utils/mapping.ts +4 -4
- package/utils/transforms.ts +2 -2
- package/utils/utils.ts +20 -14
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
|
package/graphql/queries.ts
CHANGED
|
@@ -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
|
-
*
|
|
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
|
-
*
|
|
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;
|
package/hooks/useConnection.ts
CHANGED
|
@@ -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
|
package/hooks/useNotification.ts
CHANGED
|
@@ -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:
|
package/hooks/useSmartObject.ts
CHANGED
|
@@ -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
|
@@ -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
|
|
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
|
|
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,
|
package/utils/constants.ts
CHANGED
|
@@ -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
|
|
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
|
-
* @
|
|
29
|
-
* @category Utilities
|
|
36
|
+
* @category Utilities - Config
|
|
30
37
|
*/
|
|
31
|
-
export
|
|
32
|
-
|
|
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 {
|
|
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
|
-
*
|
|
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
|
|
33
|
-
|
|
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,
|
package/utils/transforms.ts
CHANGED
|
@@ -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
|
-
/**
|
|
129
|
-
*
|
|
131
|
+
/**
|
|
132
|
+
* Volume in m³ 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
|
|
135
|
+
* @returns Volume in m³
|
|
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
|
*
|