@evefrontier/dapp-kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +53 -0
  2. package/config/dapp-kit.ts +20 -0
  3. package/config/index.ts +1 -0
  4. package/docs/api/.nojekyll +1 -0
  5. package/docs/api/assets/hierarchy.js +1 -0
  6. package/docs/api/assets/highlight.css +120 -0
  7. package/docs/api/assets/icons.js +18 -0
  8. package/docs/api/assets/icons.svg +1 -0
  9. package/docs/api/assets/main.js +60 -0
  10. package/docs/api/assets/navigation.js +1 -0
  11. package/docs/api/assets/search.js +1 -0
  12. package/docs/api/assets/style.css +1633 -0
  13. package/docs/api/classes/WalletNoAccountSelectedError.html +3 -0
  14. package/docs/api/classes/WalletNotConnectedError.html +3 -0
  15. package/docs/api/classes/WalletSponsoredTransactionNotSupportedError.html +5 -0
  16. package/docs/api/enums/ActionTypes.html +6 -0
  17. package/docs/api/enums/Assemblies.html +7 -0
  18. package/docs/api/enums/QueryParams.html +3 -0
  19. package/docs/api/enums/Severity.html +5 -0
  20. package/docs/api/enums/SponsoredTransactionActions.html +7 -0
  21. package/docs/api/enums/State.html +6 -0
  22. package/docs/api/enums/TYPEIDS.html +15 -0
  23. package/docs/api/functions/EveFrontierProvider.html +11 -0
  24. package/docs/api/functions/NotificationProvider.html +2 -0
  25. package/docs/api/functions/SmartObjectProvider.html +10 -0
  26. package/docs/api/functions/VaultProvider.html +1 -0
  27. package/docs/api/functions/abbreviateAddress.html +11 -0
  28. package/docs/api/functions/assertAssemblyType.html +9 -0
  29. package/docs/api/functions/clickToCopy.html +1 -0
  30. package/docs/api/functions/executeGraphQLQuery.html +12 -0
  31. package/docs/api/functions/findOwnerByAddress.html +5 -0
  32. package/docs/api/functions/formatDuration.html +8 -0
  33. package/docs/api/functions/formatM3.html +8 -0
  34. package/docs/api/functions/getAssemblyType.html +4 -0
  35. package/docs/api/functions/getAssemblyTypeApiString.html +2 -0
  36. package/docs/api/functions/getAssemblyWithOwner.html +18 -0
  37. package/docs/api/functions/getCharacterOwnerCapType.html +3 -0
  38. package/docs/api/functions/getCommonItems.html +1 -0
  39. package/docs/api/functions/getDappUrl.html +7 -0
  40. package/docs/api/functions/getDatahubGameInfo.html +13 -0
  41. package/docs/api/functions/getEnv.html +1 -0
  42. package/docs/api/functions/getEveWorldPackageId.html +4 -0
  43. package/docs/api/functions/getObjectByAddress.html +9 -0
  44. package/docs/api/functions/getObjectId.html +4 -0
  45. package/docs/api/functions/getObjectOwnerAndOwnedObjectsByType.html +10 -0
  46. package/docs/api/functions/getObjectRegistryType.html +3 -0
  47. package/docs/api/functions/getObjectWithDynamicFields.html +10 -0
  48. package/docs/api/functions/getObjectWithJson.html +9 -0
  49. package/docs/api/functions/getObjectsByType.html +12 -0
  50. package/docs/api/functions/getOwnedObjectsByPackage.html +10 -0
  51. package/docs/api/functions/getOwnedObjectsByType.html +10 -0
  52. package/docs/api/functions/getRegistryAddress.html +3 -0
  53. package/docs/api/functions/getSingletonObjectByType.html +9 -0
  54. package/docs/api/functions/getSponsoredTransactionFeature.html +11 -0
  55. package/docs/api/functions/getSuiGraphqlEndpoint.html +4 -0
  56. package/docs/api/functions/getTxUrl.html +8 -0
  57. package/docs/api/functions/getVolumeM3.html +5 -0
  58. package/docs/api/functions/hasSponsoredTransactionFeature.html +3 -0
  59. package/docs/api/functions/isOwner.html +10 -0
  60. package/docs/api/functions/parseErrorFromMessage.html +1 -0
  61. package/docs/api/functions/parseStatus.html +2 -0
  62. package/docs/api/functions/parseURL.html +1 -0
  63. package/docs/api/functions/removeTrailingZeros.html +1 -0
  64. package/docs/api/functions/transformToAssembly.html +5 -0
  65. package/docs/api/functions/transformToCharacter.html +2 -0
  66. package/docs/api/functions/useConnection.html +21 -0
  67. package/docs/api/functions/useNotification.html +28 -0
  68. package/docs/api/functions/useSmartObject.html +26 -0
  69. package/docs/api/functions/useSponsoredTransaction.html +50 -0
  70. package/docs/api/functions/walletSupportsSponsoredTransaction.html +13 -0
  71. package/docs/api/hierarchy.html +1 -0
  72. package/docs/api/index.html +26 -0
  73. package/docs/api/interfaces/AddressOwner.html +2 -0
  74. package/docs/api/interfaces/AddressOwnerWithJson.html +2 -0
  75. package/docs/api/interfaces/AssemblyProperties.html +14 -0
  76. package/docs/api/interfaces/CharacterInfo.html +8 -0
  77. package/docs/api/interfaces/DatahubGameInfo.html +30 -0
  78. package/docs/api/interfaces/DetailedAssemblyResponse.html +14 -0
  79. package/docs/api/interfaces/DetailedSmartCharacterResponse.html +7 -0
  80. package/docs/api/interfaces/DynamicFieldNode.html +3 -0
  81. package/docs/api/interfaces/EphemeralInventory.html +6 -0
  82. package/docs/api/interfaces/EveFrontierSponsoredTransactionFeature.html +7 -0
  83. package/docs/api/interfaces/GameTypeResponse.html +13 -0
  84. package/docs/api/interfaces/GateModule.html +5 -0
  85. package/docs/api/interfaces/GetObjectByAddressResponse.html +2 -0
  86. package/docs/api/interfaces/GetObjectOwnerAndOwnedObjectsResponse.html +2 -0
  87. package/docs/api/interfaces/GetObjectOwnerAndOwnedObjectsWithJsonResponse.html +2 -0
  88. package/docs/api/interfaces/GetObjectResponse.html +2 -0
  89. package/docs/api/interfaces/GetObjectWithJsonResponse.html +2 -0
  90. package/docs/api/interfaces/GetObjectsByTypeResponse.html +2 -0
  91. package/docs/api/interfaces/GetOwnedObjectsByPackageResponse.html +2 -0
  92. package/docs/api/interfaces/GetOwnedObjectsByTypeResponse.html +2 -0
  93. package/docs/api/interfaces/GetSingletonObjectByTypeResponse.html +2 -0
  94. package/docs/api/interfaces/GraphQLResponse.html +3 -0
  95. package/docs/api/interfaces/InventoryItem.html +8 -0
  96. package/docs/api/interfaces/ManufacturingModule.html +2 -0
  97. package/docs/api/interfaces/MoveObjectContents.html +4 -0
  98. package/docs/api/interfaces/MoveObjectData.html +3 -0
  99. package/docs/api/interfaces/NetworkNodeModule.html +7 -0
  100. package/docs/api/interfaces/NotificationContextType.html +4 -0
  101. package/docs/api/interfaces/NotificationState.html +6 -0
  102. package/docs/api/interfaces/Notify.html +6 -0
  103. package/docs/api/interfaces/ObjectWithContentsNode.html +4 -0
  104. package/docs/api/interfaces/OwnedObjectAddressNode.html +2 -0
  105. package/docs/api/interfaces/OwnedObjectFullNode.html +4 -0
  106. package/docs/api/interfaces/OwnedObjectNode.html +3 -0
  107. package/docs/api/interfaces/OwnedObjectNodeWithJson.html +4 -0
  108. package/docs/api/interfaces/OwnerCapData.html +5 -0
  109. package/docs/api/interfaces/PageInfo.html +3 -0
  110. package/docs/api/interfaces/RawCharacterData.html +8 -0
  111. package/docs/api/interfaces/RawSuiObjectData.html +17 -0
  112. package/docs/api/interfaces/RefineryModule.html +2 -0
  113. package/docs/api/interfaces/SmartAssemblyResponse.html +11 -0
  114. package/docs/api/interfaces/SmartObjectContextType.html +8 -0
  115. package/docs/api/interfaces/SponsoredTransactionInput.html +15 -0
  116. package/docs/api/interfaces/SponsoredTransactionOutput.html +8 -0
  117. package/docs/api/interfaces/StorageModule.html +4 -0
  118. package/docs/api/interfaces/SuiObjectResponse.html +5 -0
  119. package/docs/api/interfaces/TransformOptions.html +6 -0
  120. package/docs/api/interfaces/TurretModule.html +2 -0
  121. package/docs/api/interfaces/VaultContextType.html +7 -0
  122. package/docs/api/modules.html +1 -0
  123. package/docs/api/types/AssemblyType.html +1 -0
  124. package/docs/api/types/ErrorType.html +5 -0
  125. package/docs/api/types/SendSponsoredTransactionFn.html +1 -0
  126. package/docs/api/types/SponsoredTransactionArgs.html +2 -0
  127. package/docs/api/types/SponsoredTransactionAssemblyType.html +2 -0
  128. package/docs/api/types/SponsoredTransactionMethod.html +2 -0
  129. package/docs/api/types/UseSponsoredTransactionArgs.html +3 -0
  130. package/docs/api/types/UseSponsoredTransactionError.html +2 -0
  131. package/docs/api/types/UseSponsoredTransactionMutationOptions.html +2 -0
  132. package/docs/api/variables/ERRORS.html +1 -0
  133. package/docs/api/variables/ERROR_MESSAGES.html +1 -0
  134. package/docs/api/variables/EVEFRONTIER_SPONSORED_TRANSACTION.html +4 -0
  135. package/docs/api/variables/EXCLUDED_TYPEIDS.html +1 -0
  136. package/docs/api/variables/GET_OBJECTS_BY_TYPE.html +3 -0
  137. package/docs/api/variables/GET_OBJECT_BY_ADDRESS.html +3 -0
  138. package/docs/api/variables/GET_OBJECT_OWNER_AND_OWNED_OBJECTS_BY_TYPE.html +4 -0
  139. package/docs/api/variables/GET_OBJECT_OWNER_AND_OWNED_OBJECTS_WITH_JSON.html +3 -0
  140. package/docs/api/variables/GET_OBJECT_WITH_DYNAMIC_FIELDS.html +4 -0
  141. package/docs/api/variables/GET_OBJECT_WITH_JSON.html +3 -0
  142. package/docs/api/variables/GET_OWNED_OBJECTS_BY_PACKAGE.html +3 -0
  143. package/docs/api/variables/GET_OWNED_OBJECTS_BY_TYPE.html +3 -0
  144. package/docs/api/variables/GET_SINGLETON_OBJECT_BY_TYPE.html +3 -0
  145. package/docs/api/variables/NotificationContext.html +1 -0
  146. package/docs/api/variables/ONE_M3.html +2 -0
  147. package/docs/api/variables/POLLING_INTERVAL.html +2 -0
  148. package/docs/api/variables/STORAGE_KEYS.html +2 -0
  149. package/docs/api/variables/SmartObjectContext.html +1 -0
  150. package/docs/api/variables/VaultContext.html +1 -0
  151. package/docs/api/variables/dAppKit.html +2 -0
  152. package/graphql/client.ts +480 -0
  153. package/graphql/index.ts +73 -0
  154. package/graphql/queries.ts +371 -0
  155. package/graphql/types.ts +443 -0
  156. package/hooks/index.ts +14 -0
  157. package/hooks/useConnection.ts +58 -0
  158. package/hooks/useNotification.ts +80 -0
  159. package/hooks/useSmartObject.ts +78 -0
  160. package/hooks/useSponsoredTransaction.ts +323 -0
  161. package/index.ts +162 -0
  162. package/package.json +48 -0
  163. package/providers/EveFrontierProvider.tsx +41 -0
  164. package/providers/NotificationProvider.tsx +115 -0
  165. package/providers/SmartObjectProvider.tsx +282 -0
  166. package/providers/VaultProvider.tsx +114 -0
  167. package/providers/index.ts +17 -0
  168. package/tsconfig.json +22 -0
  169. package/typedoc.json +38 -0
  170. package/types/global.d.ts +7 -0
  171. package/types/index.ts +4 -0
  172. package/types/sponsoredTransaction.ts +26 -0
  173. package/types/types.ts +113 -0
  174. package/types/worldApiReturnTypes.ts +166 -0
  175. package/utils/__tests__/mapping.test.ts +441 -0
  176. package/utils/constants.ts +96 -0
  177. package/utils/datahub.ts +76 -0
  178. package/utils/errors.ts +171 -0
  179. package/utils/index.ts +38 -0
  180. package/utils/mapping.ts +115 -0
  181. package/utils/transforms.ts +258 -0
  182. package/utils/utils.ts +270 -0
  183. package/vite-env.d.ts +16 -0
  184. package/wallet/features.ts +165 -0
  185. package/wallet/index.ts +28 -0
  186. package/wallet/utils.ts +117 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Game item/type information from the EVE Frontier Datahub API.
3
+ *
4
+ * Contains metadata about items, assemblies, and other game objects
5
+ * including display names, descriptions, icons, and physical properties.
6
+ *
7
+ * @category Types
8
+ */
9
+ export interface DatahubGameInfo {
10
+ /** The type ID (matches on-chain type_id) */
11
+ id: number;
12
+ /** Display name of the item/type */
13
+ name: string;
14
+ /** Description text */
15
+ description: string;
16
+ /** Mass in kg */
17
+ mass: number;
18
+ /** Radius in meters */
19
+ radius: number;
20
+ /** Volume in cubic meters */
21
+ volume: number;
22
+ /** Portion size for stacking */
23
+ portionSize: number;
24
+ /** Category group name (e.g., "Structures") */
25
+ groupName: string;
26
+ /** Category group ID */
27
+ groupId: number;
28
+ /** Top-level category name */
29
+ categoryName: string;
30
+ /** Top-level category ID */
31
+ categoryId: number;
32
+ /** URL to the item's icon image */
33
+ iconUrl: string;
34
+ /** Additional type-specific attributes */
35
+ attributes?: {
36
+ energyConstant?: number;
37
+ [key: string]: unknown;
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Fetch game type information from the EVE Frontier Datahub API.
43
+ *
44
+ * Retrieves metadata about a game type by its ID, including display name,
45
+ * description, icon URL, and physical properties. This data is used to
46
+ * enrich on-chain objects with human-readable information.
47
+ *
48
+ * @category Utilities
49
+ * @param typeId - The numeric type ID (from on-chain type_id field)
50
+ * @returns Promise resolving to the type's game info
51
+ *
52
+ * @example Fetch assembly type info
53
+ * ```typescript
54
+ * const typeInfo = await getDatahubGameInfo(83463);
55
+ * console.log(typeInfo.name); // "Smart Storage Unit"
56
+ * console.log(typeInfo.iconUrl); // URL to icon
57
+ * console.log(typeInfo.description); // Description text
58
+ * ```
59
+ *
60
+ * @example Enrich inventory items
61
+ * ```typescript
62
+ * const inventoryItem = { type_id: 12345, quantity: 100 };
63
+ * const info = await getDatahubGameInfo(inventoryItem.type_id);
64
+ * console.log(`${info.name} x${inventoryItem.quantity}`);
65
+ * ```
66
+ */
67
+ export async function getDatahubGameInfo(
68
+ typeId: number
69
+ ): Promise<DatahubGameInfo> {
70
+ const response = await fetch(
71
+ `https://world-api-stillness.live.tech.evefrontier.com/v2/types/${typeId}`
72
+ );
73
+ const data = await response.json();
74
+
75
+ return data;
76
+ }
@@ -0,0 +1,171 @@
1
+ /** @category Types */
2
+ export type ErrorType = {
3
+ code: number;
4
+ name: string;
5
+ patterns: string[];
6
+ message: string;
7
+ };
8
+
9
+ /** @category Utilities */
10
+ export const ERRORS: Record<number | string, ErrorType> = {
11
+ 1001: {
12
+ code: 1001,
13
+ name: "Unknown Error",
14
+ patterns: ["unknown error"],
15
+ message: "An unknown error occurred.",
16
+ },
17
+ 1002: {
18
+ code: 1002,
19
+ name: "Network Error",
20
+ patterns: ["network error", "connection failed", "failed to fetch"],
21
+ message: "",
22
+ },
23
+ 1003: {
24
+ code: 1003,
25
+ name: "Invalid Input Error",
26
+ patterns: ["invalid input", "bad request", "malformed"],
27
+ message: "",
28
+ },
29
+ 2001: {
30
+ code: 2001,
31
+ name: "Contract Call Error",
32
+ patterns: ["contract call error", "execution reverted", "out of gas"],
33
+ message: "Error calling the smart contract.",
34
+ },
35
+ 2002: {
36
+ code: 2002,
37
+ name: "Contract Deployment Error",
38
+ patterns: ["contract deployment error", "contract creation failed"],
39
+ message: "",
40
+ },
41
+ 2003: {
42
+ code: 2003,
43
+ name: "World Resource Not Found Error",
44
+ patterns: ["Error: World_ResourceNotFound"],
45
+ message: "World resource not found.",
46
+ },
47
+ 2004: {
48
+ code: 2004,
49
+ name: "ABI Function Not Found Error",
50
+ patterns: ["AbiErrorSignatureNotFoundError"],
51
+ message: "Function not found in ABI",
52
+ },
53
+ 2005: {
54
+ code: 2005,
55
+ name: "ERC2771 Forwarder contract Not Found Error",
56
+ patterns: ["Forwarder contract"],
57
+ message: "ERC2771 forwarder contract could not be found",
58
+ },
59
+ 2006: {
60
+ code: 2006,
61
+ name: "callFrom Function Not Found Error",
62
+ patterns: ["callFrom Function"],
63
+ message: "callFrom Function not found in ABI",
64
+ },
65
+ 2007: {
66
+ code: 2007,
67
+ name: "Abi Encoding Bytes Size Mismatch Error",
68
+ patterns: ["does not match expected size"],
69
+ message: "Size of bytes does not match expected size.",
70
+ },
71
+ 2008: {
72
+ code: 2008,
73
+ name: "Contract Revert Error",
74
+ patterns: ["contract revert", "reverted"],
75
+ message: "Function simulation reverted",
76
+ },
77
+ 3001: {
78
+ code: 3001,
79
+ name: "Insufficient Gas",
80
+ patterns: ["insufficient gas", "not enough gas", "balance too low"],
81
+ message: "Insufficient funds for GAS.",
82
+ },
83
+ 3002: {
84
+ code: 3002,
85
+ name: "Insufficient Eve",
86
+ patterns: ["insufficient EVE", "not enough EVE"],
87
+ message: "Insufficient EVE.",
88
+ },
89
+ 3003: {
90
+ code: 3003,
91
+ name: "User Denied Transaction",
92
+ patterns: [
93
+ "User denied transaction signature.",
94
+ "transaction rejected",
95
+ "User rejected the request",
96
+ ],
97
+ message: "User rejected the transaction.",
98
+ },
99
+ 3004: {
100
+ code: 3004,
101
+ name: "Transaction Timeout",
102
+ patterns: ["transaction timeout", "timeout exceeded"],
103
+ message: "",
104
+ },
105
+ 4001: {
106
+ code: 4001,
107
+ name: "Unauthorized Access",
108
+ patterns: ["unauthorized access", "permission denied"],
109
+ message: "",
110
+ },
111
+ 4002: {
112
+ code: 4002,
113
+ name: "User Not Logged In",
114
+ patterns: ["user not logged in", "authentication required"],
115
+ message: "",
116
+ },
117
+ 4003: {
118
+ code: 4003,
119
+ name: "Chain Mismatch",
120
+ patterns: ["does not match the target chain"],
121
+ message: "Please check the chain your wallet is connected to.",
122
+ },
123
+ 5001: {
124
+ code: 5001,
125
+ name: "Lens Unavailable",
126
+ patterns: ["no lens"],
127
+ message: "There are no lenses available here",
128
+ },
129
+ };
130
+
131
+ /* Manually assign additional aliases for the ERRORS object */
132
+ ERRORS.UNKNOWN_ERROR = ERRORS[1001];
133
+ ERRORS.CONTRACT_CALL = ERRORS[2001];
134
+ ERRORS.ABI_FUNCTION_NOT_FOUND = ERRORS[2004];
135
+ ERRORS.FORWARDER_NOT_FOUND = ERRORS[2005];
136
+ ERRORS.CALLFROM_NOT_FOUND = ERRORS[2006];
137
+ ERRORS.INSUFFICIENT_EVE = ERRORS[3002];
138
+ ERRORS.LENS_UNAVAILABLE = ERRORS[5001];
139
+
140
+ /** @category Utilities */
141
+ export const ERROR_MESSAGES: Record<number, string> = Object.fromEntries(
142
+ Object.entries(ERRORS)
143
+ .filter(([key]) => /^\d+$/.test(key))
144
+ .map(([key, value]) => [Number(key), value.message]),
145
+ );
146
+
147
+ /** @category Utilities */
148
+ export const parseErrorFromMessage = (
149
+ errorMessage: string,
150
+ ): {
151
+ code: number;
152
+ name: string;
153
+ patterns: string[];
154
+ } => {
155
+ for (const error of Object.values(ERRORS)) {
156
+ for (const pattern of error.patterns) {
157
+ if (new RegExp(pattern, "i").test(errorMessage)) {
158
+ return {
159
+ code: +error.code,
160
+ name: error.name,
161
+ patterns: error.patterns,
162
+ };
163
+ }
164
+ }
165
+ }
166
+ return {
167
+ code: 1001,
168
+ name: "Unknown Error",
169
+ patterns: ["unknown error"],
170
+ };
171
+ };
package/utils/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ // Transform utilities
2
+ export {
3
+ parseStatus,
4
+ getAssemblyType,
5
+ getObjectId,
6
+ getRegistryAddress,
7
+ } from "./mapping";
8
+ export { transformToAssembly, transformToCharacter } from "./transforms";
9
+ export type { TransformOptions } from "./transforms";
10
+
11
+ // Datahub utilities
12
+ export { getDatahubGameInfo } from "./datahub";
13
+ export type { DatahubGameInfo } from "./datahub";
14
+
15
+ // General utilities
16
+ export {
17
+ assertAssemblyType,
18
+ abbreviateAddress,
19
+ clickToCopy,
20
+ findOwnerByAddress,
21
+ formatM3,
22
+ formatDuration,
23
+ getCommonItems,
24
+ getDappUrl,
25
+ getEnv,
26
+ getTxUrl,
27
+ getVolumeM3,
28
+ isOwner,
29
+ parseURL,
30
+ removeTrailingZeros,
31
+ } from "./utils";
32
+
33
+ // Constants
34
+ export * from "./constants";
35
+
36
+ // Error handling
37
+ export { ERRORS, ERROR_MESSAGES, parseErrorFromMessage } from "./errors";
38
+ export type { ErrorType } from "./errors";
@@ -0,0 +1,115 @@
1
+ import { bcs } from "@mysten/sui/bcs";
2
+ import { Assemblies, State } from "../types";
3
+ import { deriveObjectID } from "@mysten/sui/utils";
4
+ import { getEveWorldPackageId, getObjectRegistryType } from "./constants";
5
+ import { getSingletonObjectByType } from "../graphql/client";
6
+
7
+ /**
8
+ * Convert raw status variant string to State enum
9
+ *
10
+ * @category Utilities
11
+ */
12
+ export function parseStatus(statusVariant: string | undefined): State {
13
+ if (!statusVariant) return State.NULL;
14
+
15
+ switch (statusVariant.toUpperCase()) {
16
+ case "ONLINE":
17
+ return State.ONLINE;
18
+ case "OFFLINE":
19
+ return State.ANCHORED;
20
+ case "ANCHORED":
21
+ return State.ANCHORED;
22
+ case "UNANCHORED":
23
+ return State.UNANCHORED;
24
+ case "DESTROYED":
25
+ return State.DESTROYED;
26
+ default:
27
+ return State.NULL;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Get assembly type from Move object type tag
33
+ * @param typeRepr - The Move object type tag
34
+ * @returns The assembly type as an enum
35
+ *
36
+ * @category Utilities
37
+ */
38
+ export function getAssemblyType(typeRepr: string): Assemblies {
39
+ if (typeRepr.includes("::storage_unit::StorageUnit")) {
40
+ return Assemblies.SmartStorageUnit;
41
+ }
42
+ if (typeRepr.includes("::turret::Turret")) {
43
+ return Assemblies.SmartTurret;
44
+ }
45
+ if (typeRepr.includes("::gate::Gate")) {
46
+ return Assemblies.SmartGate;
47
+ }
48
+ if (typeRepr.includes("::network_node::NetworkNode")) {
49
+ return Assemblies.NetworkNode;
50
+ }
51
+ if (typeRepr.includes("::manufacturing::Manufacturing")) {
52
+ return Assemblies.Manufacturing;
53
+ }
54
+ if (typeRepr.includes("::refinery::Refinery")) {
55
+ return Assemblies.Refinery;
56
+ }
57
+
58
+ // Assembly type not found, return default SmartStorageUnit
59
+ return Assemblies.SmartStorageUnit;
60
+ }
61
+
62
+ // Cache for the Registry address
63
+ let objectRegistryAddress: string | null = null;
64
+ /**
65
+ * Fetches the AssemblyRegistry singleton address from the chain
66
+ * Caches the result to avoid repeated queries
67
+ *
68
+ * @category Utilities
69
+ */
70
+ export async function getRegistryAddress(): Promise<string> {
71
+ if (objectRegistryAddress) {
72
+ return objectRegistryAddress;
73
+ }
74
+
75
+ const registryType = getObjectRegistryType();
76
+ const result = await getSingletonObjectByType(registryType);
77
+
78
+ const address = result.data?.objects?.nodes?.[0]?.address;
79
+ if (!address) {
80
+ throw new Error(`ObjectRegistry not found for type: ${registryType}`);
81
+ }
82
+
83
+ objectRegistryAddress = address;
84
+ return address;
85
+ }
86
+
87
+ /**
88
+ * Derives an object ID from an in-game item ID using the AssemblyRegistry
89
+ * @param itemId - The in-game item ID
90
+ * @returns The derived Sui object ID
91
+ *
92
+ * @category Utilities
93
+ */
94
+ export async function getObjectId(
95
+ itemId: string,
96
+ selectedTenant: string,
97
+ ): Promise<string> {
98
+ const registryAddress = await getRegistryAddress();
99
+
100
+ const bcsType = bcs.struct("TenantItemId", {
101
+ id: bcs.u64(),
102
+ tenant: bcs.string(),
103
+ });
104
+ const key = bcsType
105
+ .serialize({ id: BigInt(itemId), tenant: selectedTenant })
106
+ .toBytes();
107
+
108
+ const objectId = deriveObjectID(
109
+ registryAddress,
110
+ `${getEveWorldPackageId()}::in_game_id::TenantItemId`,
111
+ key,
112
+ );
113
+
114
+ return objectId;
115
+ }
@@ -0,0 +1,258 @@
1
+ import {
2
+ Assemblies,
3
+ AssemblyType,
4
+ State,
5
+ DetailedSmartCharacterResponse,
6
+ SmartAssemblyResponse,
7
+ InventoryItem,
8
+ } from "../types";
9
+ import type {
10
+ MoveObjectData,
11
+ RawSuiObjectData,
12
+ CharacterInfo,
13
+ } from "../graphql/types";
14
+ import { getAssemblyType, parseStatus } from "./mapping";
15
+ import { getDatahubGameInfo, type DatahubGameInfo } from "./datahub";
16
+ import { getObjectWithJson } from "../graphql";
17
+
18
+ /**
19
+ * Transform CharacterInfo to DetailedSmartCharacterResponse
20
+ *
21
+ * @category Utilities
22
+ */
23
+ export function transformToCharacter(
24
+ characterInfo: CharacterInfo,
25
+ ): DetailedSmartCharacterResponse {
26
+ return {
27
+ id: characterInfo.id,
28
+ address: characterInfo.address,
29
+ name: characterInfo.name,
30
+ tribeId: characterInfo.tribeId,
31
+ smartAssemblies: [],
32
+ portrait: "",
33
+ };
34
+ }
35
+
36
+ /**
37
+ * Additional options for transformToAssembly
38
+ */
39
+ export interface TransformOptions {
40
+ /** Character/owner information */
41
+ character?: CharacterInfo | null;
42
+ /** Pre-fetched datahub game info (name, description, image) */
43
+ datahubInfo?: DatahubGameInfo | null;
44
+ }
45
+
46
+ /**
47
+ * Transform raw Sui Move object data to AssemblyType
48
+ *
49
+ * @param objectId - The Sui object address
50
+ * @param moveObject - The Move object data from GraphQL
51
+ * @param options - Optional transform options including character info
52
+ *
53
+ * @category Utilities
54
+ */
55
+ export async function transformToAssembly(
56
+ objectId: string,
57
+ moveObject: MoveObjectData,
58
+ options?: TransformOptions,
59
+ ): Promise<AssemblyType<Assemblies> | null> {
60
+ const rawData = moveObject.contents?.json as unknown as RawSuiObjectData;
61
+
62
+ if (!rawData) {
63
+ console.warn("[DappKit] transformToAssembly: No raw data found");
64
+ return null;
65
+ }
66
+
67
+ // Determine assembly type from Move object
68
+ const typeId = rawData.type_id || rawData.status?.type_id || "0";
69
+ const assemblyType = getAssemblyType(moveObject.contents.type?.repr || ""); // This is the Move object type tag, not the typeId
70
+
71
+ // Parse dynamic fields for additional data (such as inventory)
72
+ const dynamicFields: Record<string, unknown> = {};
73
+ if (moveObject.dynamicFields?.nodes) {
74
+ for (const field of moveObject.dynamicFields.nodes) {
75
+ const fieldName =
76
+ typeof field.name.json === "string"
77
+ ? field.name.json
78
+ : JSON.stringify(field.name.json);
79
+
80
+ dynamicFields[fieldName] = field.contents.json;
81
+ }
82
+ }
83
+
84
+ // Build base assembly properties
85
+ const state = parseStatus(rawData.status?.status?.["@variant"]);
86
+
87
+ // Use pre-fetched datahub info for defaults
88
+ const datahubInfo = options?.datahubInfo;
89
+
90
+ const baseAssembly = {
91
+ id: rawData.id || objectId,
92
+ item_id: parseInt(rawData.key?.item_id || "0", 10) || 0,
93
+ type: assemblyType,
94
+ name: rawData.metadata?.name || "",
95
+ description: rawData.metadata?.description || "",
96
+ dappURL: rawData.metadata?.url || "",
97
+ state,
98
+ typeId: parseInt(typeId, 10) || 0,
99
+ energyUsage: 0,
100
+ location: {
101
+ x: 0,
102
+ y: 0,
103
+ z: 0,
104
+ },
105
+ typeDetails: datahubInfo,
106
+ // Owner information
107
+ character: options?.character || undefined,
108
+ // Include raw data for debugging/extension
109
+ _raw: moveObject,
110
+ };
111
+
112
+ // Add module-specific data based on assembly type
113
+ switch (assemblyType) {
114
+ case Assemblies.SmartStorageUnit:
115
+ const inventoryKey = rawData.inventory_keys?.[0];
116
+ const inventoryData = dynamicFields[inventoryKey || ""] as
117
+ | {
118
+ key: string;
119
+ value?: {
120
+ max_capacity: string;
121
+ used_capacity: string;
122
+ items?: {
123
+ contents?: Array<{ key: string; value: unknown }>;
124
+ };
125
+ };
126
+ }
127
+ | undefined;
128
+
129
+ const inventoryItems = inventoryData?.value?.items?.contents?.map(
130
+ (item) => {
131
+ return item.value as InventoryItem;
132
+ },
133
+ );
134
+
135
+ return {
136
+ ...baseAssembly,
137
+ storage: {
138
+ mainInventory: {
139
+ capacity: inventoryData?.value?.max_capacity,
140
+ usedCapacity: inventoryData?.value?.used_capacity,
141
+ items: inventoryItems,
142
+ },
143
+ ephemeralInventories: [],
144
+ isParentNodeOnline: state === State.ONLINE,
145
+ },
146
+ } as AssemblyType<Assemblies.SmartStorageUnit>;
147
+
148
+ case Assemblies.SmartTurret:
149
+ return {
150
+ ...baseAssembly,
151
+ turret: {
152
+ isParentNodeOnline: state === State.ONLINE,
153
+ },
154
+ } as AssemblyType<Assemblies.SmartTurret>;
155
+
156
+ case Assemblies.SmartGate:
157
+ return {
158
+ ...baseAssembly,
159
+ gate: {
160
+ linked: false,
161
+ destinationId: undefined,
162
+ inRange: [],
163
+ isParentNodeOnline: state === State.ONLINE,
164
+ },
165
+ } as AssemblyType<Assemblies.SmartGate>;
166
+
167
+ case Assemblies.NetworkNode:
168
+ // TODO: Batch this call so that it can fetch all assemblies at once
169
+ const linkedAssemblies: SmartAssemblyResponse[] = await Promise.all(
170
+ (rawData.connected_assembly_ids || []).map(async (id) => {
171
+ const assemblyResult = await getObjectWithJson(id);
172
+ const assemblyJson = assemblyResult.data?.object?.asMoveObject
173
+ ?.contents?.json as RawSuiObjectData | undefined;
174
+
175
+ // TODO: Change this so that it doesn't need to be fetched for each assembly
176
+ const typeDetails = await getDatahubGameInfo(
177
+ parseInt(assemblyJson?.type_id || "0", 10),
178
+ );
179
+
180
+ return {
181
+ id,
182
+ item_id: parseInt(assemblyJson?.key?.item_id || "0", 10),
183
+ state: parseStatus(assemblyJson?.status?.status?.["@variant"]),
184
+ energyUsage: 0,
185
+ typeId: parseInt(assemblyJson?.type_id || "0", 10),
186
+ name: assemblyJson?.metadata?.name || "",
187
+ type: getAssemblyType(assemblyJson?.type_id || ""),
188
+ typeDetails: typeDetails,
189
+ };
190
+ }),
191
+ );
192
+
193
+ return {
194
+ ...baseAssembly,
195
+ networkNode: {
196
+ fuel: {
197
+ amount: parseInt(rawData.fuel?.quantity || "0", 10),
198
+ burnRateInMs: parseInt(rawData.fuel?.burn_rate_in_ms || "0", 10),
199
+ efficiency: 0,
200
+ unitVolume: parseInt(rawData.fuel?.unit_volume || "0", 10),
201
+ typeId: parseInt(rawData.fuel?.type_id || "0", 10),
202
+ },
203
+ burn: {
204
+ isBurning: rawData.fuel?.is_burning || false,
205
+ startTime: rawData.fuel?.burn_start_time || "",
206
+ previousCycleElapsedTimeInSec: parseInt(
207
+ rawData.fuel?.previous_cycle_elapsed_time || "0",
208
+ 10,
209
+ ),
210
+ },
211
+ energyProduction: parseInt(
212
+ rawData.energy_source?.current_energy_production || "0",
213
+ 10,
214
+ ),
215
+ energyMaxCapacity: parseInt(
216
+ rawData.energy_source?.max_energy_production || "0",
217
+ 10,
218
+ ),
219
+ totalReservedEnergy: parseInt(
220
+ rawData.energy_source?.total_reserved_energy || "0",
221
+ 10,
222
+ ),
223
+ linkedAssemblies: linkedAssemblies || [],
224
+ },
225
+ } as AssemblyType<Assemblies.NetworkNode>;
226
+
227
+ case Assemblies.Manufacturing:
228
+ return {
229
+ ...baseAssembly,
230
+ manufacturing: {
231
+ isParentNodeOnline: state === State.ONLINE,
232
+ },
233
+ } as AssemblyType<Assemblies.Manufacturing>;
234
+
235
+ case Assemblies.Refinery:
236
+ return {
237
+ ...baseAssembly,
238
+ refinery: {
239
+ isParentNodeOnline: state === State.ONLINE,
240
+ },
241
+ } as AssemblyType<Assemblies.Refinery>;
242
+
243
+ default:
244
+ // Default to SmartStorageUnit
245
+ return {
246
+ ...baseAssembly,
247
+ storage: {
248
+ mainInventory: {
249
+ capacity: "0",
250
+ usedCapacity: "0",
251
+ items: [],
252
+ },
253
+ ephemeralInventories: [],
254
+ isParentNodeOnline: state === State.ONLINE,
255
+ },
256
+ } as AssemblyType<Assemblies.SmartStorageUnit>;
257
+ }
258
+ }