@evefrontier/dapp-kit 0.1.3 → 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.
Files changed (215) hide show
  1. package/README.md +13 -0
  2. package/graphql/client.ts +15 -15
  3. package/graphql/queries.ts +15 -19
  4. package/graphql/types.ts +47 -47
  5. package/hooks/useConnection.ts +1 -1
  6. package/hooks/useNotification.ts +1 -1
  7. package/hooks/useSmartObject.ts +1 -1
  8. package/hooks/useSponsoredTransaction.ts +15 -8
  9. package/package.json +11 -1
  10. package/providers/SmartObjectProvider.tsx +3 -4
  11. package/types/contexts.ts +7 -4
  12. package/types/sponsoredTransaction.ts +8 -0
  13. package/types/types.ts +4 -0
  14. package/utils/__tests__/datahub.test.ts +48 -0
  15. package/utils/__tests__/mapping.test.ts +0 -2
  16. package/utils/burnRate.ts +1 -1
  17. package/utils/config.ts +4 -4
  18. package/utils/constants.ts +126 -31
  19. package/utils/datahub.ts +32 -5
  20. package/utils/errors.ts +2 -2
  21. package/utils/mapping.ts +4 -4
  22. package/utils/transforms.ts +2 -2
  23. package/utils/utils.ts +20 -14
  24. package/wallet/features.ts +5 -10
  25. package/CHANGELOG.md +0 -19
  26. package/docs/api/.nojekyll +0 -1
  27. package/docs/api/assets/hierarchy.js +0 -1
  28. package/docs/api/assets/highlight.css +0 -120
  29. package/docs/api/assets/icons.js +0 -18
  30. package/docs/api/assets/icons.svg +0 -1
  31. package/docs/api/assets/main.js +0 -60
  32. package/docs/api/assets/navigation.js +0 -1
  33. package/docs/api/assets/search.js +0 -1
  34. package/docs/api/assets/style.css +0 -1633
  35. package/docs/api/classes/WalletNoAccountSelectedError.html +0 -3
  36. package/docs/api/classes/WalletNotConnectedError.html +0 -3
  37. package/docs/api/classes/WalletSponsoredTransactionNotSupportedError.html +0 -5
  38. package/docs/api/enums/ActionTypes.html +0 -6
  39. package/docs/api/enums/Assemblies.html +0 -8
  40. package/docs/api/enums/QueryParams.html +0 -3
  41. package/docs/api/enums/Severity.html +0 -5
  42. package/docs/api/enums/SponsoredTransactionActions.html +0 -7
  43. package/docs/api/enums/State.html +0 -6
  44. package/docs/api/enums/SupportedWallets.html +0 -3
  45. package/docs/api/enums/TYPEIDS.html +0 -15
  46. package/docs/api/functions/EveFrontierProvider.html +0 -11
  47. package/docs/api/functions/NotificationProvider.html +0 -2
  48. package/docs/api/functions/SmartObjectProvider.html +0 -10
  49. package/docs/api/functions/VaultProvider.html +0 -1
  50. package/docs/api/functions/abbreviateAddress.html +0 -11
  51. package/docs/api/functions/assertAssemblyType.html +0 -9
  52. package/docs/api/functions/clickToCopy.html +0 -1
  53. package/docs/api/functions/executeGraphQLQuery.html +0 -12
  54. package/docs/api/functions/findOwnerByAddress.html +0 -5
  55. package/docs/api/functions/formatDuration.html +0 -8
  56. package/docs/api/functions/formatM3.html +0 -8
  57. package/docs/api/functions/getAdjustedBurnRate.html +0 -6
  58. package/docs/api/functions/getAssemblyType.html +0 -4
  59. package/docs/api/functions/getAssemblyTypeApiString.html +0 -2
  60. package/docs/api/functions/getAssemblyWithOwner.html +0 -18
  61. package/docs/api/functions/getCharacterAndOwnedObjects.html +0 -3
  62. package/docs/api/functions/getCharacterOwnedObjects.html +0 -5
  63. package/docs/api/functions/getCharacterOwnedObjectsJson.html +0 -5
  64. package/docs/api/functions/getCharacterOwnerCapType.html +0 -3
  65. package/docs/api/functions/getCharacterPlayerProfileType.html +0 -3
  66. package/docs/api/functions/getCommonItems.html +0 -1
  67. package/docs/api/functions/getDappUrl.html +0 -7
  68. package/docs/api/functions/getDatahubGameInfo.html +0 -13
  69. package/docs/api/functions/getEnergyConfig.html +0 -4
  70. package/docs/api/functions/getEnergyConfigType.html +0 -3
  71. package/docs/api/functions/getEnergyUsageForType.html +0 -5
  72. package/docs/api/functions/getEnv.html +0 -1
  73. package/docs/api/functions/getEveWorldPackageId.html +0 -4
  74. package/docs/api/functions/getFuelEfficiencyConfig.html +0 -4
  75. package/docs/api/functions/getFuelEfficiencyConfigType.html +0 -3
  76. package/docs/api/functions/getFuelEfficiencyForType.html +0 -5
  77. package/docs/api/functions/getObjectByAddress.html +0 -9
  78. package/docs/api/functions/getObjectId.html +0 -4
  79. package/docs/api/functions/getObjectOwnerAndOwnedObjectsByType.html +0 -10
  80. package/docs/api/functions/getObjectOwnerAndOwnedObjectsWithJson.html +0 -7
  81. package/docs/api/functions/getObjectRegistryType.html +0 -3
  82. package/docs/api/functions/getObjectWithDynamicFields.html +0 -10
  83. package/docs/api/functions/getObjectWithJson.html +0 -9
  84. package/docs/api/functions/getObjectsByType.html +0 -12
  85. package/docs/api/functions/getOwnedObjectsByPackage.html +0 -10
  86. package/docs/api/functions/getOwnedObjectsByType.html +0 -10
  87. package/docs/api/functions/getRegistryAddress.html +0 -3
  88. package/docs/api/functions/getSingletonObjectByType.html +0 -9
  89. package/docs/api/functions/getSponsoredTransactionFeature.html +0 -11
  90. package/docs/api/functions/getSuiGraphqlEndpoint.html +0 -4
  91. package/docs/api/functions/getTxUrl.html +0 -8
  92. package/docs/api/functions/getVolumeM3.html +0 -5
  93. package/docs/api/functions/getWalletCharacters.html +0 -3
  94. package/docs/api/functions/hasSponsoredTransactionFeature.html +0 -3
  95. package/docs/api/functions/isOwner.html +0 -10
  96. package/docs/api/functions/parseCharacterFromJson.html +0 -5
  97. package/docs/api/functions/parseErrorFromMessage.html +0 -1
  98. package/docs/api/functions/parseStatus.html +0 -2
  99. package/docs/api/functions/parseURL.html +0 -1
  100. package/docs/api/functions/removeTrailingZeros.html +0 -1
  101. package/docs/api/functions/transformToAssembly.html +0 -5
  102. package/docs/api/functions/transformToCharacter.html +0 -2
  103. package/docs/api/functions/useConnection.html +0 -21
  104. package/docs/api/functions/useNotification.html +0 -28
  105. package/docs/api/functions/useSmartObject.html +0 -21
  106. package/docs/api/functions/useSponsoredTransaction.html +0 -50
  107. package/docs/api/functions/walletSupportsSponsoredTransaction.html +0 -13
  108. package/docs/api/hierarchy.html +0 -1
  109. package/docs/api/index.html +0 -24
  110. package/docs/api/interfaces/AddressOwner.html +0 -2
  111. package/docs/api/interfaces/AddressOwnerWithJson.html +0 -2
  112. package/docs/api/interfaces/AddressWithObjects.html +0 -3
  113. package/docs/api/interfaces/AdjustedBurnRate.html +0 -8
  114. package/docs/api/interfaces/AsMoveObjectRef.html +0 -3
  115. package/docs/api/interfaces/AssemblyProperties.html +0 -17
  116. package/docs/api/interfaces/CharacterAndOwnedObjectsNode.html +0 -2
  117. package/docs/api/interfaces/CharacterInfo.html +0 -8
  118. package/docs/api/interfaces/CharacterOwnerNode.html +0 -3
  119. package/docs/api/interfaces/ConfigExtractDynamicFieldNode.html +0 -3
  120. package/docs/api/interfaces/ContentsBcs.html +0 -2
  121. package/docs/api/interfaces/ContentsJsonAndBcs.html +0 -3
  122. package/docs/api/interfaces/ContentsJsonOnly.html +0 -3
  123. package/docs/api/interfaces/ContentsTypeAndBcs.html +0 -3
  124. package/docs/api/interfaces/ContentsTypeJsonAndBcs.html +0 -4
  125. package/docs/api/interfaces/DatahubGameInfo.html +0 -28
  126. package/docs/api/interfaces/DetailedAssemblyResponse.html +0 -17
  127. package/docs/api/interfaces/DetailedSmartCharacterResponse.html +0 -7
  128. package/docs/api/interfaces/DynamicFieldNode.html +0 -3
  129. package/docs/api/interfaces/EphemeralInventory.html +0 -6
  130. package/docs/api/interfaces/EveFrontierSponsoredTransactionFeature.html +0 -7
  131. package/docs/api/interfaces/ExtractAsMoveObjectNode.html +0 -4
  132. package/docs/api/interfaces/GateModule.html +0 -2
  133. package/docs/api/interfaces/GetCharacterAndOwnedObjectsResponse.html +0 -2
  134. package/docs/api/interfaces/GetObjectAndCharacterOwnerResponse.html +0 -2
  135. package/docs/api/interfaces/GetObjectByAddressResponse.html +0 -2
  136. package/docs/api/interfaces/GetObjectOwnerAndOwnedObjectsResponse.html +0 -2
  137. package/docs/api/interfaces/GetObjectOwnerAndOwnedObjectsWithJsonResponse.html +0 -2
  138. package/docs/api/interfaces/GetObjectResponse.html +0 -2
  139. package/docs/api/interfaces/GetObjectWithJsonResponse.html +0 -2
  140. package/docs/api/interfaces/GetObjectsByTypeResponse.html +0 -2
  141. package/docs/api/interfaces/GetOwnedObjectsByPackageResponse.html +0 -2
  142. package/docs/api/interfaces/GetOwnedObjectsByTypeResponse.html +0 -2
  143. package/docs/api/interfaces/GetSingletonConfigObjectByTypeResponse.html +0 -2
  144. package/docs/api/interfaces/GetSingletonObjectByTypeResponse.html +0 -2
  145. package/docs/api/interfaces/GetWalletCharactersResponse.html +0 -2
  146. package/docs/api/interfaces/GraphQLResponse.html +0 -3
  147. package/docs/api/interfaces/InventoryItem.html +0 -8
  148. package/docs/api/interfaces/ManufacturingModule.html +0 -1
  149. package/docs/api/interfaces/MoveObjectContents.html +0 -4
  150. package/docs/api/interfaces/MoveObjectData.html +0 -3
  151. package/docs/api/interfaces/NetworkNodeModule.html +0 -6
  152. package/docs/api/interfaces/NotificationContextType.html +0 -4
  153. package/docs/api/interfaces/NotificationState.html +0 -6
  154. package/docs/api/interfaces/Notify.html +0 -6
  155. package/docs/api/interfaces/ObjectNodes.html +0 -2
  156. package/docs/api/interfaces/ObjectWithContentsNode.html +0 -4
  157. package/docs/api/interfaces/OwnedObjectAddressNode.html +0 -2
  158. package/docs/api/interfaces/OwnedObjectFullNode.html +0 -4
  159. package/docs/api/interfaces/OwnedObjectNode.html +0 -3
  160. package/docs/api/interfaces/OwnedObjectNodeWithJson.html +0 -4
  161. package/docs/api/interfaces/OwnerCapData.html +0 -5
  162. package/docs/api/interfaces/PageInfo.html +0 -3
  163. package/docs/api/interfaces/PreviousTransaction.html +0 -2
  164. package/docs/api/interfaces/RawCharacterData.html +0 -8
  165. package/docs/api/interfaces/RawSuiObjectData.html +0 -21
  166. package/docs/api/interfaces/RefineryModule.html +0 -1
  167. package/docs/api/interfaces/SmartAssemblyResponse.html +0 -15
  168. package/docs/api/interfaces/SmartObjectContextType.html +0 -7
  169. package/docs/api/interfaces/SponsoredTransactionInput.html +0 -14
  170. package/docs/api/interfaces/SponsoredTransactionOutput.html +0 -8
  171. package/docs/api/interfaces/StorageModule.html +0 -3
  172. package/docs/api/interfaces/SuiObjectResponse.html +0 -5
  173. package/docs/api/interfaces/TransformOptions.html +0 -10
  174. package/docs/api/interfaces/TurretModule.html +0 -1
  175. package/docs/api/interfaces/TypeRepr.html +0 -2
  176. package/docs/api/interfaces/TypeReprWithLayout.html +0 -3
  177. package/docs/api/interfaces/VaultContextType.html +0 -8
  178. package/docs/api/modules.html +0 -1
  179. package/docs/api/types/AssemblyType.html +0 -1
  180. package/docs/api/types/ContentsTypeAndJson.html +0 -2
  181. package/docs/api/types/ErrorType.html +0 -5
  182. package/docs/api/types/MoveObjectRefWithJson.html +0 -2
  183. package/docs/api/types/SendSponsoredTransactionFn.html +0 -1
  184. package/docs/api/types/SponsoredTransactionArgs.html +0 -2
  185. package/docs/api/types/SponsoredTransactionAssemblyType.html +0 -2
  186. package/docs/api/types/SponsoredTransactionMethod.html +0 -2
  187. package/docs/api/types/UseSponsoredTransactionArgs.html +0 -3
  188. package/docs/api/types/UseSponsoredTransactionError.html +0 -2
  189. package/docs/api/types/UseSponsoredTransactionMutationOptions.html +0 -2
  190. package/docs/api/variables/ASSEMBLY_TYPE_API_STRING.html +0 -2
  191. package/docs/api/variables/ERRORS.html +0 -1
  192. package/docs/api/variables/ERROR_MESSAGES.html +0 -1
  193. package/docs/api/variables/EVEFRONTIER_SPONSORED_TRANSACTION.html +0 -4
  194. package/docs/api/variables/EXCLUDED_TYPEIDS.html +0 -1
  195. package/docs/api/variables/GET_OBJECTS_BY_TYPE.html +0 -3
  196. package/docs/api/variables/GET_OBJECT_BY_ADDRESS.html +0 -3
  197. package/docs/api/variables/GET_OBJECT_OWNER_AND_OWNED_OBJECTS_BY_TYPE.html +0 -4
  198. package/docs/api/variables/GET_OBJECT_OWNER_AND_OWNED_OBJECTS_WITH_JSON.html +0 -3
  199. package/docs/api/variables/GET_OBJECT_WITH_DYNAMIC_FIELDS.html +0 -4
  200. package/docs/api/variables/GET_OBJECT_WITH_JSON.html +0 -3
  201. package/docs/api/variables/GET_OWNED_OBJECTS_BY_PACKAGE.html +0 -3
  202. package/docs/api/variables/GET_OWNED_OBJECTS_BY_TYPE.html +0 -3
  203. package/docs/api/variables/GET_SINGLETON_CONFIG_OBJECT_BY_TYPE.html +0 -2
  204. package/docs/api/variables/GET_SINGLETON_OBJECT_BY_TYPE.html +0 -3
  205. package/docs/api/variables/GET_WALLET_CHARACTERS.html +0 -3
  206. package/docs/api/variables/NotificationContext.html +0 -1
  207. package/docs/api/variables/ONE_M3.html +0 -2
  208. package/docs/api/variables/POLLING_INTERVAL.html +0 -2
  209. package/docs/api/variables/STORAGE_KEYS.html +0 -2
  210. package/docs/api/variables/SmartObjectContext.html +0 -1
  211. package/docs/api/variables/VaultContext.html +0 -1
  212. package/docs/api/variables/dAppKit.html +0 -2
  213. package/tsconfig.json +0 -22
  214. package/typedoc.json +0 -38
  215. package/vite-env.d.ts +0 -14
@@ -17,7 +17,7 @@ import {
17
17
  type SponsoredTransactionOutput,
18
18
  SponsoredTransactionArgs,
19
19
  } from "../wallet";
20
- import { QueryParams, SponsoredTransactionActions } from "../types";
20
+ import { Assemblies, QueryParams, SponsoredTransactionActions } from "../types";
21
21
 
22
22
  /** Wallet-like shape from dApp Kit (UiWallet or connection store). */
23
23
  type ResolvableWallet = {
@@ -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)
@@ -375,15 +375,22 @@ export function useSponsoredTransaction({
375
375
 
376
376
  const assemblyId = resolveAssemblyId(args.assembly.item_id, queryItemId);
377
377
 
378
+ // If the txAction is UPDATE_METADATA, it goes through the standard assembly type
379
+ const assemblyType = getAssemblyTypeApiString(
380
+ args.txAction === SponsoredTransactionActions.UPDATE_METADATA
381
+ ? Assemblies.Assembly
382
+ : args.assembly.type,
383
+ );
384
+
378
385
  const payload: SponsoredTransactionInput = {
379
386
  txAction: args.txAction,
380
387
  assembly: assemblyId,
381
- assemblyType: getAssemblyTypeApiString(args.assembly.type),
382
- chain: args.chain,
388
+ assemblyType: assemblyType,
389
+ metadata: args.metadata,
383
390
  tenant,
384
391
  };
385
392
 
386
- console.log("payload", payload);
393
+ console.log("Sponsored Transaction Payload:", payload);
387
394
 
388
395
  return await signSponsoredTransaction(payload);
389
396
  },
package/package.json CHANGED
@@ -1,11 +1,21 @@
1
1
  {
2
2
  "name": "@evefrontier/dapp-kit",
3
- "version": "0.1.3",
3
+ "version": "0.1.6",
4
4
  "description": "React SDK for EVE Frontier dApps on Sui",
5
5
  "main": "index.ts",
6
6
  "author": "",
7
7
  "license": "MIT",
8
8
  "type": "module",
9
+ "files": [
10
+ "index.ts",
11
+ "config",
12
+ "graphql",
13
+ "hooks",
14
+ "providers",
15
+ "types",
16
+ "utils",
17
+ "wallet"
18
+ ],
9
19
  "exports": {
10
20
  ".": "./index.ts",
11
21
  "./types": "./types/index.ts",
@@ -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;
@@ -12,7 +12,9 @@ import { Assemblies } from "./types";
12
12
  export enum SponsoredTransactionActions {
13
13
  BRING_ONLINE = "online",
14
14
  BRING_OFFLINE = "offline",
15
+ /** @deprecated Use UPDATE_METADATA instead */
15
16
  EDIT_UNIT = "edit-unit",
17
+ UPDATE_METADATA = "update-metadata",
16
18
  LINK_SMART_GATE = "link-smart-gate",
17
19
  UNLINK_SMART_GATE = "unlink-smart-gate",
18
20
  }
@@ -60,3 +62,9 @@ export const ASSEMBLY_TYPE_API_STRING: Record<Assemblies, string> = {
60
62
  /** API slug for assembly type in sponsored transaction payloads (e.g. "storage-units"). */
61
63
  export type SponsoredTransactionAssemblyType =
62
64
  (typeof ASSEMBLY_TYPE_API_STRING)[Assemblies];
65
+
66
+ export interface SponsoredTransactionMetadata {
67
+ name?: string;
68
+ description?: string;
69
+ url?: string;
70
+ }
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,