@hashgraphonline/standards-sdk 0.0.157-canary.2 → 0.0.157-canary.4

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 (178) hide show
  1. package/dist/cjs/hcs-10/base-client.d.ts +1 -1
  2. package/dist/cjs/hcs-10/base-client.d.ts.map +1 -1
  3. package/dist/cjs/hcs-10/sdk.d.ts +1 -1
  4. package/dist/cjs/hcs-10/sdk.d.ts.map +1 -1
  5. package/dist/cjs/hcs-11/agent-builder.d.ts +2 -0
  6. package/dist/cjs/hcs-11/agent-builder.d.ts.map +1 -1
  7. package/dist/cjs/hcs-11/client.d.ts +2 -0
  8. package/dist/cjs/hcs-11/client.d.ts.map +1 -1
  9. package/dist/cjs/hcs-11/types.d.ts +4 -2
  10. package/dist/cjs/hcs-11/types.d.ts.map +1 -1
  11. package/dist/cjs/hcs-15/index.d.ts +3 -0
  12. package/dist/cjs/hcs-15/index.d.ts.map +1 -0
  13. package/dist/cjs/hcs-15/petal-manager.d.ts +27 -0
  14. package/dist/cjs/hcs-15/petal-manager.d.ts.map +1 -0
  15. package/dist/cjs/hcs-15/types.d.ts +41 -0
  16. package/dist/cjs/hcs-15/types.d.ts.map +1 -0
  17. package/dist/cjs/hcs-16/flora-account-manager.d.ts.map +1 -1
  18. package/dist/cjs/hcs-16/types.d.ts +3 -5
  19. package/dist/cjs/hcs-16/types.d.ts.map +1 -1
  20. package/dist/cjs/hcs-18/discovery.d.ts +1 -0
  21. package/dist/cjs/hcs-18/discovery.d.ts.map +1 -1
  22. package/dist/cjs/hcs-18/types.d.ts +1 -0
  23. package/dist/cjs/hcs-18/types.d.ts.map +1 -1
  24. package/dist/cjs/hcs-20/sdk.d.ts.map +1 -1
  25. package/dist/cjs/hcs-7/evm-bridge.d.ts.map +1 -1
  26. package/dist/cjs/hcs-7/redis-cache.d.ts.map +1 -1
  27. package/dist/cjs/hcs-7/wasm-bridge.d.ts.map +1 -1
  28. package/dist/cjs/{index-xZmk-HBD.cjs → index-CJsmyij2.cjs} +12 -12
  29. package/dist/cjs/index-CJsmyij2.cjs.map +1 -0
  30. package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs → index-CyAbgH2f-Dn5WQtPx.cjs} +2 -2
  31. package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs.map → index-CyAbgH2f-Dn5WQtPx.cjs.map} +1 -1
  32. package/dist/cjs/index.d.ts +1 -1
  33. package/dist/cjs/services/types.d.ts +1 -1
  34. package/dist/cjs/services/types.d.ts.map +1 -1
  35. package/dist/cjs/standards-sdk.cjs +1 -1
  36. package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs} +2 -2
  37. package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs.map → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs.map} +1 -1
  38. package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs} +2 -2
  39. package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs.map → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs.map} +1 -1
  40. package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs} +2 -2
  41. package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs.map → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs.map} +1 -1
  42. package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs} +2 -2
  43. package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs.map → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs.map} +1 -1
  44. package/dist/cjs/utils/logger.d.ts.map +1 -1
  45. package/dist/es/hcs-10/base-client.d.ts +1 -1
  46. package/dist/es/hcs-10/base-client.d.ts.map +1 -1
  47. package/dist/es/hcs-10/sdk.d.ts +1 -1
  48. package/dist/es/hcs-10/sdk.d.ts.map +1 -1
  49. package/dist/es/hcs-11/agent-builder.d.ts +2 -0
  50. package/dist/es/hcs-11/agent-builder.d.ts.map +1 -1
  51. package/dist/es/hcs-11/client.d.ts +2 -0
  52. package/dist/es/hcs-11/client.d.ts.map +1 -1
  53. package/dist/es/hcs-11/types.d.ts +4 -2
  54. package/dist/es/hcs-11/types.d.ts.map +1 -1
  55. package/dist/es/hcs-15/index.d.ts +3 -0
  56. package/dist/es/hcs-15/index.d.ts.map +1 -0
  57. package/dist/es/hcs-15/petal-manager.d.ts +27 -0
  58. package/dist/es/hcs-15/petal-manager.d.ts.map +1 -0
  59. package/dist/es/hcs-15/types.d.ts +41 -0
  60. package/dist/es/hcs-15/types.d.ts.map +1 -0
  61. package/dist/es/hcs-16/flora-account-manager.d.ts.map +1 -1
  62. package/dist/es/hcs-16/types.d.ts +3 -5
  63. package/dist/es/hcs-16/types.d.ts.map +1 -1
  64. package/dist/es/hcs-18/discovery.d.ts +1 -0
  65. package/dist/es/hcs-18/discovery.d.ts.map +1 -1
  66. package/dist/es/hcs-18/types.d.ts +1 -0
  67. package/dist/es/hcs-18/types.d.ts.map +1 -1
  68. package/dist/es/hcs-20/sdk.d.ts.map +1 -1
  69. package/dist/es/hcs-7/evm-bridge.d.ts.map +1 -1
  70. package/dist/es/hcs-7/redis-cache.d.ts.map +1 -1
  71. package/dist/es/hcs-7/wasm-bridge.d.ts.map +1 -1
  72. package/dist/es/index.d.ts +1 -1
  73. package/dist/es/services/types.d.ts +1 -1
  74. package/dist/es/services/types.d.ts.map +1 -1
  75. package/dist/es/standards-sdk.es.js +19 -22
  76. package/dist/es/standards-sdk.es.js.map +1 -1
  77. package/dist/es/standards-sdk.es10.js +1 -1
  78. package/dist/es/standards-sdk.es11.js +10 -2
  79. package/dist/es/standards-sdk.es11.js.map +1 -1
  80. package/dist/es/standards-sdk.es12.js +1 -1
  81. package/dist/es/standards-sdk.es13.js +1 -1
  82. package/dist/es/standards-sdk.es13.js.map +1 -1
  83. package/dist/es/standards-sdk.es14.js +1 -1
  84. package/dist/es/standards-sdk.es15.js +39 -9
  85. package/dist/es/standards-sdk.es15.js.map +1 -1
  86. package/dist/es/standards-sdk.es16.js +1 -0
  87. package/dist/es/standards-sdk.es16.js.map +1 -1
  88. package/dist/es/standards-sdk.es18.js +1 -1
  89. package/dist/es/standards-sdk.es19.js +1 -1
  90. package/dist/es/standards-sdk.es2.js +1 -1
  91. package/dist/es/standards-sdk.es20.js +2 -2
  92. package/dist/es/standards-sdk.es23.js +2 -2
  93. package/dist/es/standards-sdk.es25.js +4 -2
  94. package/dist/es/standards-sdk.es25.js.map +1 -1
  95. package/dist/es/standards-sdk.es26.js +2 -2
  96. package/dist/es/standards-sdk.es27.js +152 -6
  97. package/dist/es/standards-sdk.es27.js.map +1 -1
  98. package/dist/es/standards-sdk.es28.js +26 -189
  99. package/dist/es/standards-sdk.es28.js.map +1 -1
  100. package/dist/es/standards-sdk.es29.js +446 -26
  101. package/dist/es/standards-sdk.es29.js.map +1 -1
  102. package/dist/es/standards-sdk.es3.js +1 -1
  103. package/dist/es/standards-sdk.es3.js.map +1 -1
  104. package/dist/es/standards-sdk.es30.js +6 -342
  105. package/dist/es/standards-sdk.es30.js.map +1 -1
  106. package/dist/es/standards-sdk.es31.js +202 -6
  107. package/dist/es/standards-sdk.es31.js.map +1 -1
  108. package/dist/es/standards-sdk.es32.js +34 -202
  109. package/dist/es/standards-sdk.es32.js.map +1 -1
  110. package/dist/es/standards-sdk.es33.js +529 -34
  111. package/dist/es/standards-sdk.es33.js.map +1 -1
  112. package/dist/es/standards-sdk.es34.js +87 -501
  113. package/dist/es/standards-sdk.es34.js.map +1 -1
  114. package/dist/es/standards-sdk.es35.js +19 -98
  115. package/dist/es/standards-sdk.es35.js.map +1 -1
  116. package/dist/es/standards-sdk.es36.js +156 -18
  117. package/dist/es/standards-sdk.es36.js.map +1 -1
  118. package/dist/es/standards-sdk.es37.js +146 -150
  119. package/dist/es/standards-sdk.es37.js.map +1 -1
  120. package/dist/es/standards-sdk.es38.js +561 -134
  121. package/dist/es/standards-sdk.es38.js.map +1 -1
  122. package/dist/es/standards-sdk.es39.js +562 -543
  123. package/dist/es/standards-sdk.es39.js.map +1 -1
  124. package/dist/es/standards-sdk.es4.js +6 -4
  125. package/dist/es/standards-sdk.es4.js.map +1 -1
  126. package/dist/es/standards-sdk.es40.js +4 -601
  127. package/dist/es/standards-sdk.es40.js.map +1 -1
  128. package/dist/es/standards-sdk.es41.js +415 -4
  129. package/dist/es/standards-sdk.es41.js.map +1 -1
  130. package/dist/es/standards-sdk.es42.js +1536 -389
  131. package/dist/es/standards-sdk.es42.js.map +1 -1
  132. package/dist/es/standards-sdk.es43.js +133 -1541
  133. package/dist/es/standards-sdk.es43.js.map +1 -1
  134. package/dist/es/standards-sdk.es44.js +7 -155
  135. package/dist/es/standards-sdk.es44.js.map +1 -1
  136. package/dist/es/standards-sdk.es45.js +2 -7
  137. package/dist/es/standards-sdk.es45.js.map +1 -1
  138. package/dist/es/standards-sdk.es46.js +5 -5
  139. package/dist/es/standards-sdk.es48.js +1 -1
  140. package/dist/es/standards-sdk.es49.js +1 -1
  141. package/dist/es/standards-sdk.es5.js +4 -6
  142. package/dist/es/standards-sdk.es5.js.map +1 -1
  143. package/dist/es/standards-sdk.es50.js +1 -1
  144. package/dist/es/standards-sdk.es51.js +1 -1
  145. package/dist/es/standards-sdk.es52.js +1 -1
  146. package/dist/es/standards-sdk.es54.js +7135 -2
  147. package/dist/es/standards-sdk.es54.js.map +1 -1
  148. package/dist/es/standards-sdk.es55.js +7134 -41
  149. package/dist/es/standards-sdk.es55.js.map +1 -1
  150. package/dist/es/standards-sdk.es56.js +37 -37
  151. package/dist/es/standards-sdk.es56.js.map +1 -1
  152. package/dist/es/standards-sdk.es57.js +37 -37
  153. package/dist/es/standards-sdk.es57.js.map +1 -1
  154. package/dist/es/standards-sdk.es58.js +78 -72
  155. package/dist/es/standards-sdk.es58.js.map +1 -1
  156. package/dist/es/standards-sdk.es59.js +41 -7134
  157. package/dist/es/standards-sdk.es59.js.map +1 -1
  158. package/dist/es/standards-sdk.es6.js.map +1 -1
  159. package/dist/es/standards-sdk.es7.js +28 -22
  160. package/dist/es/standards-sdk.es7.js.map +1 -1
  161. package/dist/es/standards-sdk.es8.js +5 -5
  162. package/dist/es/utils/logger.d.ts.map +1 -1
  163. package/package.json +37 -35
  164. package/dist/cjs/hcs-21/index.d.ts +0 -4
  165. package/dist/cjs/hcs-21/index.d.ts.map +0 -1
  166. package/dist/cjs/hcs-21/petal-account-manager.d.ts +0 -52
  167. package/dist/cjs/hcs-21/petal-account-manager.d.ts.map +0 -1
  168. package/dist/cjs/hcs-21/types.d.ts +0 -44
  169. package/dist/cjs/hcs-21/types.d.ts.map +0 -1
  170. package/dist/cjs/index-xZmk-HBD.cjs.map +0 -1
  171. package/dist/es/hcs-21/index.d.ts +0 -4
  172. package/dist/es/hcs-21/index.d.ts.map +0 -1
  173. package/dist/es/hcs-21/petal-account-manager.d.ts +0 -52
  174. package/dist/es/hcs-21/petal-account-manager.d.ts.map +0 -1
  175. package/dist/es/hcs-21/types.d.ts +0 -44
  176. package/dist/es/hcs-21/types.d.ts.map +0 -1
  177. package/dist/es/standards-sdk.es60.js +0 -7144
  178. package/dist/es/standards-sdk.es60.js.map +0 -1
@@ -1,347 +1,11 @@
1
- import { KeyList, AccountCreateTransaction, Hbar, AccountInfoQuery, TopicCreateTransaction, CustomFixedFee, AccountId, TopicMessageSubmitTransaction, TokenId } from "@hashgraph/sdk";
2
- import { Logger } from "./standards-sdk.es35.js";
3
- import { FloraError, FloraTopicType, FloraOperation } from "./standards-sdk.es29.js";
4
- import { FloraBuilder } from "./standards-sdk.es14.js";
5
- import { HCS11Client } from "./standards-sdk.es15.js";
6
- class FloraAccountManager {
7
- constructor(client, network, logger) {
8
- this.client = client;
9
- this.logger = logger || new Logger({ module: "FloraAccountManager" });
10
- this.network = network || "testnet";
11
- }
12
- /**
13
- * Create a Flora account with threshold key and required topics
14
- */
15
- async createFlora(config) {
16
- try {
17
- this.logger.info("Creating Flora account");
18
- const keyList = new KeyList(
19
- config.members.map((m) => m.publicKey),
20
- config.threshold
21
- );
22
- const transaction = new AccountCreateTransaction().setKey(keyList).setInitialBalance(new Hbar(config.initialBalance || 1)).setMaxAutomaticTokenAssociations(
23
- config.maxAutomaticTokenAssociations || -1
24
- );
25
- const response = await transaction.execute(this.client);
26
- const receipt = await response.getReceipt(this.client);
27
- if (!receipt.accountId) {
28
- throw new Error("Failed to create Flora account");
29
- }
30
- const floraAccountId = receipt.accountId;
31
- const floraAccount = await this.createFloraAccount(keyList, config);
32
- const topics = await this.createFloraTopics(
33
- floraAccount,
34
- keyList,
35
- config
36
- );
37
- await this.createFloraProfile(floraAccount, topics, config);
38
- this.logger.info("Flora created successfully", {
39
- floraAccountId: floraAccount.toString(),
40
- topics: {
41
- communication: topics.communication.toString(),
42
- transaction: topics.transaction.toString(),
43
- state: topics.state.toString()
44
- }
45
- });
46
- return {
47
- floraAccountId: floraAccount,
48
- topics,
49
- keyList,
50
- transactionId: ""
51
- };
52
- } catch (error) {
53
- this.logger.error("Failed to create Flora", error);
54
- throw error;
55
- }
56
- }
57
- /**
58
- * Build KeyList from member public keys
59
- */
60
- async buildKeyList(members, threshold) {
61
- const keyList = new KeyList();
62
- keyList.setThreshold(threshold);
63
- for (const member of members) {
64
- if (member.publicKey) {
65
- keyList.push(member.publicKey);
66
- } else {
67
- const accountInfo = await new AccountInfoQuery().setAccountId(member.accountId).execute(this.client);
68
- keyList.push(accountInfo.key);
69
- }
70
- }
71
- return keyList;
72
- }
73
- /**
74
- * Create the Flora account with threshold key
75
- */
76
- async createFloraAccount(keyList, config) {
77
- const transaction = new AccountCreateTransaction().setKey(keyList).setInitialBalance(new Hbar(config.initialBalance || 20)).setMaxAutomaticTokenAssociations(
78
- config.maxAutomaticTokenAssociations || -1
79
- );
80
- const response = await transaction.execute(this.client);
81
- const receipt = await response.getReceipt(this.client);
82
- if (!receipt.accountId) {
83
- throw new FloraError(
84
- "Failed to create Flora account",
85
- "ACCOUNT_CREATION_FAILED"
86
- );
87
- }
88
- return receipt.accountId;
89
- }
90
- /**
91
- * Create the three required Flora topics with HCS-16 memo format
92
- */
93
- async createFloraTopics(floraAccountId, adminKey, config) {
94
- const submitKeyList = new KeyList();
95
- submitKeyList.setThreshold(1);
96
- for (const member of config.members) {
97
- if (member.publicKey) {
98
- submitKeyList.push(member.publicKey);
99
- } else {
100
- throw new FloraError(
101
- `Public key required for member ${member.accountId}`,
102
- "MISSING_PUBLIC_KEY"
103
- );
104
- }
105
- }
106
- const [communication, transaction, state] = await Promise.all([
107
- this.createTopic(
108
- floraAccountId,
109
- FloraTopicType.COMMUNICATION,
110
- adminKey,
111
- submitKeyList,
112
- config.customFees
113
- ),
114
- this.createTopic(
115
- floraAccountId,
116
- FloraTopicType.TRANSACTION,
117
- adminKey,
118
- submitKeyList,
119
- config.customFees
120
- ),
121
- this.createTopic(
122
- floraAccountId,
123
- FloraTopicType.STATE,
124
- adminKey,
125
- submitKeyList,
126
- config.customFees
127
- )
128
- ]);
129
- return { communication, transaction, state };
130
- }
131
- /**
132
- * Create a single topic with HCS-16 memo format
133
- */
134
- async createTopic(floraAccountId, topicType, adminKey, submitKey, customFees) {
135
- const memo = `hcs-16:${floraAccountId}:${topicType}`;
136
- const transaction = new TopicCreateTransaction().setTopicMemo(memo).setAdminKey(adminKey).setSubmitKey(submitKey);
137
- if (customFees && customFees.length > 0) {
138
- const fees = customFees.map(
139
- (fee) => new CustomFixedFee().setAmount(fee.amount).setFeeCollectorAccountId(
140
- AccountId.fromString(fee.feeCollectorAccountId)
141
- )
142
- );
143
- transaction.setCustomFees(fees);
144
- }
145
- const response = await transaction.execute(this.client);
146
- const receipt = await response.getReceipt(this.client);
147
- if (!receipt.topicId) {
148
- throw new FloraError(
149
- `Failed to create ${FloraTopicType[topicType]} topic`,
150
- "TOPIC_CREATION_FAILED"
151
- );
152
- }
153
- return receipt.topicId;
154
- }
155
- /**
156
- * Create and store Flora profile using HCS-11
157
- */
158
- async createFloraProfile(floraAccountId, topics, config) {
159
- this.logger.info("Creating Flora profile using HCS-11");
160
- const operatorMember = config.members[0];
161
- if (!operatorMember.privateKey) {
162
- throw new FloraError(
163
- "First member must have private key to create profile",
164
- "MISSING_PRIVATE_KEY"
165
- );
166
- }
167
- const hcs11Client = new HCS11Client({
168
- network: this.network,
169
- auth: {
170
- operatorId: floraAccountId.toString(),
171
- privateKey: operatorMember.privateKey
172
- }
173
- });
174
- const floraBuilder = new FloraBuilder().setDisplayName(config.displayName).setMembers(config.members).setThreshold(config.threshold).setTopics({
175
- communication: topics.communication.toString(),
176
- transaction: topics.transaction.toString(),
177
- state: topics.state.toString()
178
- }).setPolicies(config.policies);
179
- if (config.bio) {
180
- floraBuilder.setBio(config.bio);
181
- }
182
- if (config.metadata) {
183
- floraBuilder.setMetadata(config.metadata);
184
- }
185
- const profile = floraBuilder.build();
186
- const inscriptionResult = await hcs11Client.createAndInscribeProfile(
187
- profile,
188
- true
189
- );
190
- if (!inscriptionResult.success) {
191
- throw new FloraError(
192
- `Failed to inscribe Flora profile: ${inscriptionResult.error}`,
193
- "PROFILE_INSCRIPTION_FAILED"
194
- );
195
- }
196
- this.logger.info("Flora profile inscribed successfully", {
197
- profileTopicId: inscriptionResult.profileTopicId,
198
- transactionId: inscriptionResult.transactionId
199
- });
200
- return inscriptionResult.profileTopicId;
201
- }
202
- /**
203
- * Send a message to a Flora topic
204
- */
205
- async sendFloraMessage(topicId, message) {
206
- try {
207
- message.p = "hcs-16";
208
- const transaction = new TopicMessageSubmitTransaction().setTopicId(topicId).setMessage(JSON.stringify(message));
209
- const response = await transaction.execute(this.client);
210
- await response.getReceipt(this.client);
211
- this.logger.debug("Flora message sent", {
212
- topicId: topicId.toString(),
213
- operation: message.op
214
- });
215
- } catch (error) {
216
- this.logger.error("Failed to send Flora message", error);
217
- throw error;
218
- }
219
- }
220
- /**
221
- * Send flora_created notification to all members
222
- */
223
- async notifyFloraCreated(result, memberTopics) {
224
- const message = {
225
- p: "hcs-16",
226
- op: FloraOperation.FLORA_CREATED,
227
- operator_id: `${this.client.operatorAccountId}@${result.floraAccountId}`,
228
- flora_account_id: result.floraAccountId.toString(),
229
- topics: {
230
- communication: result.topics.communication.toString(),
231
- transaction: result.topics.transaction.toString(),
232
- state: result.topics.state.toString()
233
- }
234
- };
235
- await Promise.all(
236
- memberTopics.map((topicId) => this.sendFloraMessage(topicId, message))
237
- );
238
- }
239
- /**
240
- * Parse HCS-16 topic memo
241
- */
242
- parseTopicMemo(memo) {
243
- const match = memo.match(/^hcs-16:([0-9.]+):(\d)$/);
244
- if (!match) {
245
- return null;
246
- }
247
- return {
248
- protocol: "hcs-16",
249
- floraAccountId: match[1],
250
- topicType: parseInt(match[2])
251
- };
252
- }
253
- /**
254
- * Create a proposal for a scheduled transaction
255
- */
256
- async createTransactionProposal(transactionTopicId, scheduledTxId, description, operatorAccountId, floraAccountId) {
257
- const message = {
258
- p: "hcs-16",
259
- op: FloraOperation.TX_PROPOSAL,
260
- operator_id: `${operatorAccountId}@${floraAccountId}`,
261
- scheduled_tx_id: scheduledTxId,
262
- description,
263
- m: description
264
- };
265
- await this.sendFloraMessage(transactionTopicId, message);
266
- }
267
- /**
268
- * Submit a state update to the state topic
269
- */
270
- async submitStateUpdate(stateTopicId, stateHash, operatorAccountId, floraAccountId, epoch) {
271
- const message = {
272
- p: "hcs-16",
273
- op: FloraOperation.STATE_UPDATE,
274
- operator_id: `${operatorAccountId}@${floraAccountId}`,
275
- hash: stateHash,
276
- epoch,
277
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
278
- };
279
- await this.sendFloraMessage(stateTopicId, message);
280
- }
281
- /**
282
- * Create a generic HCS-16 transaction topic with HIP-991 support
283
- * This can be used for any HCS-16 compliant topic, not just Flora accounts
284
- */
285
- async createTransactionTopic(config) {
286
- const transaction = new TopicCreateTransaction().setTopicMemo(config.memo);
287
- if (config.adminKey) {
288
- transaction.setAdminKey(config.adminKey);
289
- }
290
- if (config.submitKey) {
291
- transaction.setSubmitKey(config.submitKey);
292
- }
293
- if (config.feeScheduleKey) {
294
- transaction.setFeeScheduleKey(config.feeScheduleKey);
295
- }
296
- if (config.customFees && config.customFees.length > 0) {
297
- const fees = config.customFees.map((fee) => {
298
- const customFee = new CustomFixedFee().setAmount(fee.amount).setFeeCollectorAccountId(
299
- AccountId.fromString(fee.feeCollectorAccountId)
300
- );
301
- if (fee.denominatingTokenId) {
302
- customFee.setDenominatingTokenId(
303
- TokenId.fromString(fee.denominatingTokenId)
304
- );
305
- }
306
- return customFee;
307
- });
308
- transaction.setCustomFees(fees);
309
- }
310
- if (config.feeExemptKeys && config.feeExemptKeys.length > 0) {
311
- transaction.setFeeExemptKeyList(config.feeExemptKeys);
312
- }
313
- const response = await transaction.execute(this.client);
314
- const receipt = await response.getReceipt(this.client);
315
- if (!receipt.topicId) {
316
- throw new FloraError(
317
- "Failed to create transaction topic",
318
- "TOPIC_CREATION_FAILED"
319
- );
320
- }
321
- this.logger.info("Created HCS-16 transaction topic", {
322
- topicId: receipt.topicId.toString(),
323
- memo: config.memo,
324
- hasFees: !!config.customFees
325
- });
326
- return receipt.topicId;
327
- }
328
- /**
329
- * Submit HCS-16 compliant credit purchase message
330
- */
331
- async submitCreditPurchase(topicId, purchaser, amount, floraAccountId) {
332
- const message = {
333
- p: "hcs-16",
334
- op: FloraOperation.CREDIT_PURCHASE,
335
- operator_id: floraAccountId ? `${purchaser}@${floraAccountId}` : purchaser,
336
- amount,
337
- purchaser,
338
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
339
- m: `Purchase ${amount} credits`
340
- };
341
- await this.sendFloraMessage(topicId, message);
1
+ class StateHashError extends Error {
2
+ constructor(message, code) {
3
+ super(message);
4
+ this.code = code;
5
+ this.name = "StateHashError";
342
6
  }
343
7
  }
344
8
  export {
345
- FloraAccountManager
9
+ StateHashError
346
10
  };
347
11
  //# sourceMappingURL=standards-sdk.es30.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es30.js","sources":["../../src/hcs-16/flora-account-manager.ts"],"sourcesContent":["import {\n Client,\n AccountCreateTransaction,\n AccountUpdateTransaction,\n AccountInfoQuery,\n TopicCreateTransaction,\n TopicMessageSubmitTransaction,\n KeyList,\n PublicKey,\n PrivateKey,\n Hbar,\n AccountId,\n TopicId,\n CustomFixedFee,\n TokenId,\n} from '@hashgraph/sdk';\nimport { Logger } from '../utils/logger';\nimport {\n FloraConfig,\n FloraCreationResult,\n FloraTopics,\n FloraTopicType,\n FloraMessage,\n FloraOperation,\n FloraProfile,\n FloraError,\n FloraMember,\n TransactionTopicConfig,\n TransactionTopicFee,\n CreditPurchaseMessage,\n} from './types';\nimport { HCS11Client, FloraBuilder } from '../hcs-11';\nimport type { NetworkType } from '../utils/types';\n\n/**\n * HCS-16 Flora Account Manager\n * Manages creation and operation of Flora multi-party accounts\n */\nexport class FloraAccountManager {\n private readonly logger: Logger;\n private readonly network: NetworkType;\n\n constructor(\n private readonly client: Client,\n network?: NetworkType,\n logger?: Logger,\n ) {\n this.logger = logger || new Logger({ module: 'FloraAccountManager' });\n this.network = network || 'testnet';\n }\n\n /**\n * Create a Flora account with threshold key and required topics\n */\n async createFlora(config: FloraConfig): Promise<FloraCreationResult> {\n try {\n this.logger.info('Creating Flora account');\n\n const keyList = new KeyList(\n config.members.map(m => m.publicKey),\n config.threshold,\n );\n\n const transaction = new AccountCreateTransaction()\n .setKey(keyList)\n .setInitialBalance(new Hbar(config.initialBalance || 1))\n .setMaxAutomaticTokenAssociations(\n config.maxAutomaticTokenAssociations || -1,\n );\n\n const response = await transaction.execute(this.client);\n const receipt = await response.getReceipt(this.client);\n\n if (!receipt.accountId) {\n throw new Error('Failed to create Flora account');\n }\n\n const floraAccountId = receipt.accountId;\n\n const floraAccount = await this.createFloraAccount(keyList, config);\n\n const topics = await this.createFloraTopics(\n floraAccount,\n keyList,\n config,\n );\n await this.createFloraProfile(floraAccount, topics, config);\n\n this.logger.info('Flora created successfully', {\n floraAccountId: floraAccount.toString(),\n topics: {\n communication: topics.communication.toString(),\n transaction: topics.transaction.toString(),\n state: topics.state.toString(),\n },\n });\n\n return {\n floraAccountId: floraAccount,\n topics,\n keyList,\n transactionId: '',\n };\n } catch (error) {\n this.logger.error('Failed to create Flora', error);\n throw error;\n }\n }\n\n /**\n * Build KeyList from member public keys\n */\n private async buildKeyList(\n members: FloraMember[],\n threshold: number,\n ): Promise<KeyList> {\n const keyList = new KeyList();\n keyList.setThreshold(threshold);\n\n for (const member of members) {\n if (member.publicKey) {\n keyList.push(member.publicKey);\n } else {\n const accountInfo = await new AccountInfoQuery()\n .setAccountId(member.accountId)\n .execute(this.client);\n keyList.push(accountInfo.key);\n }\n }\n\n return keyList;\n }\n\n /**\n * Create the Flora account with threshold key\n */\n private async createFloraAccount(\n keyList: KeyList,\n config: FloraConfig,\n ): Promise<AccountId> {\n const transaction = new AccountCreateTransaction()\n .setKey(keyList)\n .setInitialBalance(new Hbar(config.initialBalance || 20))\n .setMaxAutomaticTokenAssociations(\n config.maxAutomaticTokenAssociations || -1,\n );\n\n const response = await transaction.execute(this.client);\n const receipt = await response.getReceipt(this.client);\n\n if (!receipt.accountId) {\n throw new FloraError(\n 'Failed to create Flora account',\n 'ACCOUNT_CREATION_FAILED',\n );\n }\n\n return receipt.accountId;\n }\n\n /**\n * Create the three required Flora topics with HCS-16 memo format\n */\n private async createFloraTopics(\n floraAccountId: AccountId,\n adminKey: KeyList,\n config: FloraConfig,\n ): Promise<FloraTopics> {\n const submitKeyList = new KeyList();\n submitKeyList.setThreshold(1);\n\n for (const member of config.members) {\n if (member.publicKey) {\n submitKeyList.push(member.publicKey);\n } else {\n throw new FloraError(\n `Public key required for member ${member.accountId}`,\n 'MISSING_PUBLIC_KEY',\n );\n }\n }\n\n const [communication, transaction, state] = await Promise.all([\n this.createTopic(\n floraAccountId,\n FloraTopicType.COMMUNICATION,\n adminKey,\n submitKeyList,\n config.customFees,\n ),\n this.createTopic(\n floraAccountId,\n FloraTopicType.TRANSACTION,\n adminKey,\n submitKeyList,\n config.customFees,\n ),\n this.createTopic(\n floraAccountId,\n FloraTopicType.STATE,\n adminKey,\n submitKeyList,\n config.customFees,\n ),\n ]);\n\n return { communication, transaction, state };\n }\n\n /**\n * Create a single topic with HCS-16 memo format\n */\n private async createTopic(\n floraAccountId: AccountId,\n topicType: FloraTopicType,\n adminKey: KeyList,\n submitKey: KeyList,\n customFees?: Array<{ amount: number; feeCollectorAccountId: string }>,\n ): Promise<TopicId> {\n const memo = `hcs-16:${floraAccountId}:${topicType}`;\n\n const transaction = new TopicCreateTransaction()\n .setTopicMemo(memo)\n .setAdminKey(adminKey)\n .setSubmitKey(submitKey);\n\n if (customFees && customFees.length > 0) {\n const fees = customFees.map(fee =>\n new CustomFixedFee()\n .setAmount(fee.amount)\n .setFeeCollectorAccountId(\n AccountId.fromString(fee.feeCollectorAccountId),\n ),\n );\n transaction.setCustomFees(fees);\n }\n\n const response = await transaction.execute(this.client);\n const receipt = await response.getReceipt(this.client);\n\n if (!receipt.topicId) {\n throw new FloraError(\n `Failed to create ${FloraTopicType[topicType]} topic`,\n 'TOPIC_CREATION_FAILED',\n );\n }\n\n return receipt.topicId;\n }\n\n /**\n * Create and store Flora profile using HCS-11\n */\n private async createFloraProfile(\n floraAccountId: AccountId,\n topics: FloraTopics,\n config: FloraConfig,\n ): Promise<string> {\n this.logger.info('Creating Flora profile using HCS-11');\n\n const operatorMember = config.members[0];\n if (!operatorMember.privateKey) {\n throw new FloraError(\n 'First member must have private key to create profile',\n 'MISSING_PRIVATE_KEY',\n );\n }\n\n const hcs11Client = new HCS11Client({\n network: this.network,\n auth: {\n operatorId: floraAccountId.toString(),\n privateKey: operatorMember.privateKey,\n },\n });\n\n const floraBuilder = new FloraBuilder()\n .setDisplayName(config.displayName)\n .setMembers(config.members)\n .setThreshold(config.threshold)\n .setTopics({\n communication: topics.communication.toString(),\n transaction: topics.transaction.toString(),\n state: topics.state.toString(),\n })\n .setPolicies(config.policies);\n\n if (config.bio) {\n floraBuilder.setBio(config.bio);\n }\n\n if (config.metadata) {\n floraBuilder.setMetadata(config.metadata);\n }\n\n const profile = floraBuilder.build();\n\n const inscriptionResult = await hcs11Client.createAndInscribeProfile(\n profile,\n true,\n );\n\n if (!inscriptionResult.success) {\n throw new FloraError(\n `Failed to inscribe Flora profile: ${inscriptionResult.error}`,\n 'PROFILE_INSCRIPTION_FAILED',\n );\n }\n\n this.logger.info('Flora profile inscribed successfully', {\n profileTopicId: inscriptionResult.profileTopicId,\n transactionId: inscriptionResult.transactionId,\n });\n\n return inscriptionResult.profileTopicId;\n }\n\n /**\n * Send a message to a Flora topic\n */\n async sendFloraMessage(\n topicId: string | TopicId,\n message: FloraMessage,\n ): Promise<void> {\n try {\n message.p = 'hcs-16';\n\n const transaction = new TopicMessageSubmitTransaction()\n .setTopicId(topicId)\n .setMessage(JSON.stringify(message));\n\n const response = await transaction.execute(this.client);\n await response.getReceipt(this.client);\n\n this.logger.debug('Flora message sent', {\n topicId: topicId.toString(),\n operation: message.op,\n });\n } catch (error) {\n this.logger.error('Failed to send Flora message', error);\n throw error;\n }\n }\n\n /**\n * Send flora_created notification to all members\n */\n async notifyFloraCreated(\n result: FloraCreationResult,\n memberTopics: string[],\n ): Promise<void> {\n const message: FloraMessage = {\n p: 'hcs-16',\n op: FloraOperation.FLORA_CREATED,\n operator_id: `${this.client.operatorAccountId}@${result.floraAccountId}`,\n flora_account_id: result.floraAccountId.toString(),\n topics: {\n communication: result.topics.communication.toString(),\n transaction: result.topics.transaction.toString(),\n state: result.topics.state.toString(),\n },\n };\n\n await Promise.all(\n memberTopics.map(topicId => this.sendFloraMessage(topicId, message)),\n );\n }\n\n /**\n * Parse HCS-16 topic memo\n */\n parseTopicMemo(memo: string): {\n protocol: string;\n floraAccountId: string;\n topicType: FloraTopicType;\n } | null {\n const match = memo.match(/^hcs-16:([0-9.]+):(\\d)$/);\n if (!match) {\n return null;\n }\n\n return {\n protocol: 'hcs-16',\n floraAccountId: match[1],\n topicType: parseInt(match[2]) as FloraTopicType,\n };\n }\n\n /**\n * Create a proposal for a scheduled transaction\n */\n async createTransactionProposal(\n transactionTopicId: string | TopicId,\n scheduledTxId: string,\n description: string,\n operatorAccountId: string,\n floraAccountId: string,\n ): Promise<void> {\n const message: FloraMessage = {\n p: 'hcs-16',\n op: FloraOperation.TX_PROPOSAL,\n operator_id: `${operatorAccountId}@${floraAccountId}`,\n scheduled_tx_id: scheduledTxId,\n description,\n m: description,\n };\n\n await this.sendFloraMessage(transactionTopicId, message);\n }\n\n /**\n * Submit a state update to the state topic\n */\n async submitStateUpdate(\n stateTopicId: string | TopicId,\n stateHash: string,\n operatorAccountId: string,\n floraAccountId: string,\n epoch?: number,\n ): Promise<void> {\n const message: FloraMessage = {\n p: 'hcs-16',\n op: FloraOperation.STATE_UPDATE,\n operator_id: `${operatorAccountId}@${floraAccountId}`,\n hash: stateHash,\n epoch,\n timestamp: new Date().toISOString(),\n };\n\n await this.sendFloraMessage(stateTopicId, message);\n }\n\n /**\n * Create a generic HCS-16 transaction topic with HIP-991 support\n * This can be used for any HCS-16 compliant topic, not just Flora accounts\n */\n async createTransactionTopic(\n config: TransactionTopicConfig,\n ): Promise<TopicId> {\n const transaction = new TopicCreateTransaction().setTopicMemo(config.memo);\n\n if (config.adminKey) {\n transaction.setAdminKey(config.adminKey);\n }\n if (config.submitKey) {\n transaction.setSubmitKey(config.submitKey);\n }\n if (config.feeScheduleKey) {\n transaction.setFeeScheduleKey(config.feeScheduleKey);\n }\n\n if (config.customFees && config.customFees.length > 0) {\n const fees = config.customFees.map(fee => {\n const customFee = new CustomFixedFee()\n .setAmount(fee.amount)\n .setFeeCollectorAccountId(\n AccountId.fromString(fee.feeCollectorAccountId),\n );\n\n if (fee.denominatingTokenId) {\n customFee.setDenominatingTokenId(\n TokenId.fromString(fee.denominatingTokenId),\n );\n }\n\n return customFee;\n });\n transaction.setCustomFees(fees);\n }\n\n if (config.feeExemptKeys && config.feeExemptKeys.length > 0) {\n (transaction as any).setFeeExemptKeyList(config.feeExemptKeys);\n }\n\n const response = await transaction.execute(this.client);\n const receipt = await response.getReceipt(this.client);\n\n if (!receipt.topicId) {\n throw new FloraError(\n 'Failed to create transaction topic',\n 'TOPIC_CREATION_FAILED',\n );\n }\n\n this.logger.info('Created HCS-16 transaction topic', {\n topicId: receipt.topicId.toString(),\n memo: config.memo,\n hasFees: !!config.customFees,\n });\n\n return receipt.topicId;\n }\n\n /**\n * Submit HCS-16 compliant credit purchase message\n */\n async submitCreditPurchase(\n topicId: string | TopicId,\n purchaser: string,\n amount: number,\n floraAccountId?: string,\n ): Promise<void> {\n const message: CreditPurchaseMessage = {\n p: 'hcs-16',\n op: FloraOperation.CREDIT_PURCHASE,\n operator_id: floraAccountId\n ? `${purchaser}@${floraAccountId}`\n : purchaser,\n amount,\n purchaser,\n timestamp: new Date().toISOString(),\n m: `Purchase ${amount} credits`,\n };\n\n await this.sendFloraMessage(topicId, message);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"standards-sdk.es30.js","sources":["../../src/hcs-17/types.ts"],"sourcesContent":["import { PublicKey } from '@hashgraph/sdk';\n\n/**\n * HCS-17 Topic state information\n */\nexport interface TopicState {\n topicId: string;\n latestRunningHash: string;\n}\n\n/**\n * HCS-17 Account state hash input\n */\nexport interface AccountStateInput {\n accountId: string;\n publicKey: PublicKey | string;\n topics: TopicState[];\n}\n\n/**\n * HCS-17 Composite state hash input for Flora/Bloom\n */\nexport interface CompositeStateInput {\n compositeAccountId: string;\n compositePublicKeyFingerprint: string;\n memberStates: Array<{\n accountId: string;\n stateHash: string;\n }>;\n compositeTopics: TopicState[];\n}\n\n/**\n * HCS-17 State hash message format\n */\nexport interface StateHashMessage {\n p: 'hcs-17';\n op: 'state_hash';\n state_hash: string;\n topics: string[];\n account_id: string;\n timestamp?: string;\n m?: string;\n}\n\n/**\n * HCS-17 State hash result\n */\nexport interface StateHashResult {\n stateHash: string;\n accountId: string;\n timestamp: Date;\n topicCount: number;\n}\n\n/**\n * HCS-17 Composite state hash result\n */\nexport interface CompositeStateHashResult extends StateHashResult {\n memberCount: number;\n compositeTopicCount: number;\n}\n\n/**\n * HCS-17 errors\n */\nexport class StateHashError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = 'StateHashError';\n }\n}\n"],"names":[],"mappings":"AAkEO,MAAM,uBAAuB,MAAM;AAAA,EACxC,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG,SAAA,OAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;"}
@@ -1,11 +1,207 @@
1
- class StateHashError extends Error {
2
- constructor(message, code) {
3
- super(message);
4
- this.code = code;
5
- this.name = "StateHashError";
1
+ import { createHash } from "crypto";
2
+ import { Logger } from "./standards-sdk.es34.js";
3
+ import { StateHashError } from "./standards-sdk.es30.js";
4
+ class StateHashCalculator {
5
+ constructor(logger) {
6
+ this.logger = logger || new Logger({ module: "StateHashCalculator" });
7
+ }
8
+ /**
9
+ * Calculate state hash for a single account
10
+ * StateHash = SHA384(topicId_1 || latestRunningHash_1 || ... || topicId_n || latestRunningHash_n || account_publicKey)
11
+ */
12
+ calculateAccountStateHash(input) {
13
+ try {
14
+ this.logger.debug("Calculating account state hash", {
15
+ accountId: input.accountId,
16
+ topicCount: input.topics.length
17
+ });
18
+ const sortedTopics = [...input.topics].sort(
19
+ (a, b) => a.topicId.localeCompare(b.topicId)
20
+ );
21
+ let concatenated = "";
22
+ for (const topic of sortedTopics) {
23
+ concatenated += topic.topicId + topic.latestRunningHash;
24
+ }
25
+ const publicKeyString = typeof input.publicKey === "string" ? input.publicKey : input.publicKey.toString();
26
+ concatenated += publicKeyString;
27
+ const hash = createHash("sha384");
28
+ hash.update(concatenated);
29
+ const stateHash = hash.digest("hex");
30
+ this.logger.debug("Account state hash calculated", {
31
+ accountId: input.accountId,
32
+ stateHash
33
+ });
34
+ return {
35
+ stateHash,
36
+ accountId: input.accountId,
37
+ timestamp: /* @__PURE__ */ new Date(),
38
+ topicCount: input.topics.length
39
+ };
40
+ } catch (error) {
41
+ this.logger.error("Failed to calculate account state hash", error);
42
+ throw new StateHashError(
43
+ "Failed to calculate account state hash",
44
+ "CALCULATION_FAILED"
45
+ );
46
+ }
47
+ }
48
+ /**
49
+ * Calculate composite state hash for Flora/Bloom
50
+ * CompositeStateHash = SHA384(
51
+ * Σ_sorted(accountId_i || StateHash_i) ||
52
+ * Σ_sorted(topicId_j || runningHash_j) ||
53
+ * composite_publicKeyFingerprint
54
+ * )
55
+ */
56
+ calculateCompositeStateHash(input) {
57
+ try {
58
+ this.logger.debug("Calculating composite state hash", {
59
+ compositeAccountId: input.compositeAccountId,
60
+ memberCount: input.memberStates.length,
61
+ topicCount: input.compositeTopics.length
62
+ });
63
+ const sortedMembers = [...input.memberStates].sort(
64
+ (a, b) => a.accountId.localeCompare(b.accountId)
65
+ );
66
+ const sortedTopics = [...input.compositeTopics].sort(
67
+ (a, b) => a.topicId.localeCompare(b.topicId)
68
+ );
69
+ let concatenated = "";
70
+ for (const member of sortedMembers) {
71
+ concatenated += member.accountId + member.stateHash;
72
+ }
73
+ for (const topic of sortedTopics) {
74
+ concatenated += topic.topicId + topic.latestRunningHash;
75
+ }
76
+ concatenated += input.compositePublicKeyFingerprint;
77
+ const hash = createHash("sha384");
78
+ hash.update(concatenated);
79
+ const stateHash = hash.digest("hex");
80
+ this.logger.debug("Composite state hash calculated", {
81
+ compositeAccountId: input.compositeAccountId,
82
+ stateHash
83
+ });
84
+ return {
85
+ stateHash,
86
+ accountId: input.compositeAccountId,
87
+ timestamp: /* @__PURE__ */ new Date(),
88
+ topicCount: input.compositeTopics.length,
89
+ memberCount: input.memberStates.length,
90
+ compositeTopicCount: input.compositeTopics.length
91
+ };
92
+ } catch (error) {
93
+ this.logger.error("Failed to calculate composite state hash", error);
94
+ throw new StateHashError(
95
+ "Failed to calculate composite state hash",
96
+ "CALCULATION_FAILED"
97
+ );
98
+ }
99
+ }
100
+ /**
101
+ * Calculate deterministic public key fingerprint for KeyList/Threshold keys
102
+ * Used for Flora/Bloom accounts
103
+ */
104
+ calculateKeyFingerprint(keys, threshold) {
105
+ try {
106
+ const sortedKeys = [...keys].sort(
107
+ (a, b) => a.toString().localeCompare(b.toString())
108
+ );
109
+ const keyData = {
110
+ threshold,
111
+ keys: sortedKeys.map((k) => k.toString())
112
+ };
113
+ const hash = createHash("sha384");
114
+ hash.update(JSON.stringify(keyData));
115
+ return hash.digest("hex");
116
+ } catch (error) {
117
+ this.logger.error("Failed to calculate key fingerprint", error);
118
+ throw new StateHashError(
119
+ "Failed to calculate key fingerprint",
120
+ "FINGERPRINT_FAILED"
121
+ );
122
+ }
123
+ }
124
+ /**
125
+ * Create HCS-17 state hash message
126
+ */
127
+ createStateHashMessage(stateHash, accountId, topicIds, memo) {
128
+ return {
129
+ p: "hcs-17",
130
+ op: "state_hash",
131
+ state_hash: stateHash,
132
+ topics: topicIds,
133
+ account_id: accountId,
134
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135
+ m: memo
136
+ };
137
+ }
138
+ /**
139
+ * Verify state hash by recalculating
140
+ */
141
+ async verifyStateHash(input, expectedHash) {
142
+ try {
143
+ let calculatedHash;
144
+ if ("publicKey" in input) {
145
+ const result = this.calculateAccountStateHash(input);
146
+ calculatedHash = result.stateHash;
147
+ } else {
148
+ const result = this.calculateCompositeStateHash(input);
149
+ calculatedHash = result.stateHash;
150
+ }
151
+ const isValid = calculatedHash === expectedHash;
152
+ const accountId = "accountId" in input ? input.accountId : input.compositeAccountId;
153
+ this.logger.debug("State hash verification", {
154
+ accountId,
155
+ isValid,
156
+ expected: expectedHash,
157
+ calculated: calculatedHash
158
+ });
159
+ return isValid;
160
+ } catch (error) {
161
+ this.logger.error("Failed to verify state hash", error);
162
+ return false;
163
+ }
164
+ }
165
+ /**
166
+ * Get latest running hashes for topics (mock implementation)
167
+ * In production, this would query the actual Hedera network
168
+ */
169
+ async getTopicRunningHashes(topicIds) {
170
+ return topicIds.map((topicId) => ({
171
+ topicId,
172
+ latestRunningHash: createHash("sha256").update(`mock-hash-${topicId}-${Date.now()}`).digest("hex").substring(0, 48)
173
+ }));
174
+ }
175
+ /**
176
+ * Calculate and publish state hash to a topic
177
+ */
178
+ async publishStateHash(stateHash, accountId, topicIds, publishTopicId, client) {
179
+ try {
180
+ const message = this.createStateHashMessage(
181
+ stateHash,
182
+ accountId,
183
+ topicIds,
184
+ "State synchronization"
185
+ );
186
+ const { TopicMessageSubmitTransaction } = await import("@hashgraph/sdk");
187
+ const transaction = new TopicMessageSubmitTransaction().setTopicId(publishTopicId).setMessage(JSON.stringify(message));
188
+ const response = await transaction.execute(client);
189
+ await response.getReceipt(client);
190
+ this.logger.info("State hash published", {
191
+ accountId,
192
+ topicId: publishTopicId,
193
+ stateHash
194
+ });
195
+ } catch (error) {
196
+ this.logger.error("Failed to publish state hash", error);
197
+ throw new StateHashError(
198
+ "Failed to publish state hash",
199
+ "PUBLISH_FAILED"
200
+ );
201
+ }
6
202
  }
7
203
  }
8
204
  export {
9
- StateHashError
205
+ StateHashCalculator
10
206
  };
11
207
  //# sourceMappingURL=standards-sdk.es31.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es31.js","sources":["../../src/hcs-17/types.ts"],"sourcesContent":["import { PublicKey } from '@hashgraph/sdk';\n\n/**\n * HCS-17 Topic state information\n */\nexport interface TopicState {\n topicId: string;\n latestRunningHash: string;\n}\n\n/**\n * HCS-17 Account state hash input\n */\nexport interface AccountStateInput {\n accountId: string;\n publicKey: PublicKey | string;\n topics: TopicState[];\n}\n\n/**\n * HCS-17 Composite state hash input for Flora/Bloom\n */\nexport interface CompositeStateInput {\n compositeAccountId: string;\n compositePublicKeyFingerprint: string;\n memberStates: Array<{\n accountId: string;\n stateHash: string;\n }>;\n compositeTopics: TopicState[];\n}\n\n/**\n * HCS-17 State hash message format\n */\nexport interface StateHashMessage {\n p: 'hcs-17';\n op: 'state_hash';\n state_hash: string;\n topics: string[];\n account_id: string;\n timestamp?: string;\n m?: string;\n}\n\n/**\n * HCS-17 State hash result\n */\nexport interface StateHashResult {\n stateHash: string;\n accountId: string;\n timestamp: Date;\n topicCount: number;\n}\n\n/**\n * HCS-17 Composite state hash result\n */\nexport interface CompositeStateHashResult extends StateHashResult {\n memberCount: number;\n compositeTopicCount: number;\n}\n\n/**\n * HCS-17 errors\n */\nexport class StateHashError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = 'StateHashError';\n }\n}\n"],"names":[],"mappings":"AAkEO,MAAM,uBAAuB,MAAM;AAAA,EACxC,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG,SAAA,OAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;"}
1
+ {"version":3,"file":"standards-sdk.es31.js","sources":["../../src/hcs-17/state-hash-calculator.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { PublicKey, KeyList, Key } from '@hashgraph/sdk';\nimport { Logger } from '../utils/logger';\nimport {\n AccountStateInput,\n CompositeStateInput,\n StateHashResult,\n CompositeStateHashResult,\n StateHashMessage,\n TopicState,\n StateHashError,\n} from './types';\n\n/**\n * HCS-17 State Hash Calculator\n * Calculates state hashes for accounts and composite accounts (Flora/Bloom)\n */\nexport class StateHashCalculator {\n private readonly logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger || new Logger({ module: 'StateHashCalculator' });\n }\n\n /**\n * Calculate state hash for a single account\n * StateHash = SHA384(topicId_1 || latestRunningHash_1 || ... || topicId_n || latestRunningHash_n || account_publicKey)\n */\n calculateAccountStateHash(input: AccountStateInput): StateHashResult {\n try {\n this.logger.debug('Calculating account state hash', {\n accountId: input.accountId,\n topicCount: input.topics.length,\n });\n\n const sortedTopics = [...input.topics].sort((a, b) =>\n a.topicId.localeCompare(b.topicId),\n );\n\n let concatenated = '';\n for (const topic of sortedTopics) {\n concatenated += topic.topicId + topic.latestRunningHash;\n }\n\n const publicKeyString =\n typeof input.publicKey === 'string'\n ? input.publicKey\n : input.publicKey.toString();\n concatenated += publicKeyString;\n const hash = createHash('sha384');\n hash.update(concatenated);\n const stateHash = hash.digest('hex');\n\n this.logger.debug('Account state hash calculated', {\n accountId: input.accountId,\n stateHash,\n });\n\n return {\n stateHash,\n accountId: input.accountId,\n timestamp: new Date(),\n topicCount: input.topics.length,\n };\n } catch (error) {\n this.logger.error('Failed to calculate account state hash', error);\n throw new StateHashError(\n 'Failed to calculate account state hash',\n 'CALCULATION_FAILED',\n );\n }\n }\n\n /**\n * Calculate composite state hash for Flora/Bloom\n * CompositeStateHash = SHA384(\n * Σ_sorted(accountId_i || StateHash_i) ||\n * Σ_sorted(topicId_j || runningHash_j) ||\n * composite_publicKeyFingerprint\n * )\n */\n calculateCompositeStateHash(\n input: CompositeStateInput,\n ): CompositeStateHashResult {\n try {\n this.logger.debug('Calculating composite state hash', {\n compositeAccountId: input.compositeAccountId,\n memberCount: input.memberStates.length,\n topicCount: input.compositeTopics.length,\n });\n\n const sortedMembers = [...input.memberStates].sort((a, b) =>\n a.accountId.localeCompare(b.accountId),\n );\n\n const sortedTopics = [...input.compositeTopics].sort((a, b) =>\n a.topicId.localeCompare(b.topicId),\n );\n\n let concatenated = '';\n for (const member of sortedMembers) {\n concatenated += member.accountId + member.stateHash;\n }\n\n for (const topic of sortedTopics) {\n concatenated += topic.topicId + topic.latestRunningHash;\n }\n\n concatenated += input.compositePublicKeyFingerprint;\n const hash = createHash('sha384');\n hash.update(concatenated);\n const stateHash = hash.digest('hex');\n\n this.logger.debug('Composite state hash calculated', {\n compositeAccountId: input.compositeAccountId,\n stateHash,\n });\n\n return {\n stateHash,\n accountId: input.compositeAccountId,\n timestamp: new Date(),\n topicCount: input.compositeTopics.length,\n memberCount: input.memberStates.length,\n compositeTopicCount: input.compositeTopics.length,\n };\n } catch (error) {\n this.logger.error('Failed to calculate composite state hash', error);\n throw new StateHashError(\n 'Failed to calculate composite state hash',\n 'CALCULATION_FAILED',\n );\n }\n }\n\n /**\n * Calculate deterministic public key fingerprint for KeyList/Threshold keys\n * Used for Flora/Bloom accounts\n */\n calculateKeyFingerprint(keys: PublicKey[], threshold: number): string {\n try {\n const sortedKeys = [...keys].sort((a, b) =>\n a.toString().localeCompare(b.toString()),\n );\n\n const keyData = {\n threshold,\n keys: sortedKeys.map(k => k.toString()),\n };\n const hash = createHash('sha384');\n hash.update(JSON.stringify(keyData));\n return hash.digest('hex');\n } catch (error) {\n this.logger.error('Failed to calculate key fingerprint', error);\n throw new StateHashError(\n 'Failed to calculate key fingerprint',\n 'FINGERPRINT_FAILED',\n );\n }\n }\n\n /**\n * Create HCS-17 state hash message\n */\n createStateHashMessage(\n stateHash: string,\n accountId: string,\n topicIds: string[],\n memo?: string,\n ): StateHashMessage {\n return {\n p: 'hcs-17',\n op: 'state_hash',\n state_hash: stateHash,\n topics: topicIds,\n account_id: accountId,\n timestamp: new Date().toISOString(),\n m: memo,\n };\n }\n\n /**\n * Verify state hash by recalculating\n */\n async verifyStateHash(\n input: AccountStateInput | CompositeStateInput,\n expectedHash: string,\n ): Promise<boolean> {\n try {\n let calculatedHash: string;\n\n if ('publicKey' in input) {\n const result = this.calculateAccountStateHash(input);\n calculatedHash = result.stateHash;\n } else {\n const result = this.calculateCompositeStateHash(input);\n calculatedHash = result.stateHash;\n }\n\n const isValid = calculatedHash === expectedHash;\n\n const accountId =\n 'accountId' in input ? input.accountId : input.compositeAccountId;\n this.logger.debug('State hash verification', {\n accountId,\n isValid,\n expected: expectedHash,\n calculated: calculatedHash,\n });\n\n return isValid;\n } catch (error) {\n this.logger.error('Failed to verify state hash', error);\n return false;\n }\n }\n\n /**\n * Get latest running hashes for topics (mock implementation)\n * In production, this would query the actual Hedera network\n */\n async getTopicRunningHashes(topicIds: string[]): Promise<TopicState[]> {\n return topicIds.map(topicId => ({\n topicId,\n latestRunningHash: createHash('sha256')\n .update(`mock-hash-${topicId}-${Date.now()}`)\n .digest('hex')\n .substring(0, 48),\n }));\n }\n\n /**\n * Calculate and publish state hash to a topic\n */\n async publishStateHash(\n stateHash: string,\n accountId: string,\n topicIds: string[],\n publishTopicId: string,\n client: any,\n ): Promise<void> {\n try {\n const message = this.createStateHashMessage(\n stateHash,\n accountId,\n topicIds,\n 'State synchronization',\n );\n\n const { TopicMessageSubmitTransaction } = await import('@hashgraph/sdk');\n\n const transaction = new TopicMessageSubmitTransaction()\n .setTopicId(publishTopicId)\n .setMessage(JSON.stringify(message));\n\n const response = await transaction.execute(client);\n await response.getReceipt(client);\n\n this.logger.info('State hash published', {\n accountId,\n topicId: publishTopicId,\n stateHash,\n });\n } catch (error) {\n this.logger.error('Failed to publish state hash', error);\n throw new StateHashError(\n 'Failed to publish state hash',\n 'PUBLISH_FAILED',\n );\n }\n }\n}\n"],"names":[],"mappings":"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"}