@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.
- package/dist/cjs/hcs-10/base-client.d.ts +1 -1
- package/dist/cjs/hcs-10/base-client.d.ts.map +1 -1
- package/dist/cjs/hcs-10/sdk.d.ts +1 -1
- package/dist/cjs/hcs-10/sdk.d.ts.map +1 -1
- package/dist/cjs/hcs-11/agent-builder.d.ts +2 -0
- package/dist/cjs/hcs-11/agent-builder.d.ts.map +1 -1
- package/dist/cjs/hcs-11/client.d.ts +2 -0
- package/dist/cjs/hcs-11/client.d.ts.map +1 -1
- package/dist/cjs/hcs-11/types.d.ts +4 -2
- package/dist/cjs/hcs-11/types.d.ts.map +1 -1
- package/dist/cjs/hcs-15/index.d.ts +3 -0
- package/dist/cjs/hcs-15/index.d.ts.map +1 -0
- package/dist/cjs/hcs-15/petal-manager.d.ts +27 -0
- package/dist/cjs/hcs-15/petal-manager.d.ts.map +1 -0
- package/dist/cjs/hcs-15/types.d.ts +41 -0
- package/dist/cjs/hcs-15/types.d.ts.map +1 -0
- package/dist/cjs/hcs-16/flora-account-manager.d.ts.map +1 -1
- package/dist/cjs/hcs-16/types.d.ts +3 -5
- package/dist/cjs/hcs-16/types.d.ts.map +1 -1
- package/dist/cjs/hcs-18/discovery.d.ts +1 -0
- package/dist/cjs/hcs-18/discovery.d.ts.map +1 -1
- package/dist/cjs/hcs-18/types.d.ts +1 -0
- package/dist/cjs/hcs-18/types.d.ts.map +1 -1
- package/dist/cjs/hcs-20/sdk.d.ts.map +1 -1
- package/dist/cjs/hcs-7/evm-bridge.d.ts.map +1 -1
- package/dist/cjs/hcs-7/redis-cache.d.ts.map +1 -1
- package/dist/cjs/hcs-7/wasm-bridge.d.ts.map +1 -1
- package/dist/cjs/{index-xZmk-HBD.cjs → index-CJsmyij2.cjs} +12 -12
- package/dist/cjs/index-CJsmyij2.cjs.map +1 -0
- package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs → index-CyAbgH2f-Dn5WQtPx.cjs} +2 -2
- package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs.map → index-CyAbgH2f-Dn5WQtPx.cjs.map} +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/services/types.d.ts +1 -1
- package/dist/cjs/services/types.d.ts.map +1 -1
- package/dist/cjs/standards-sdk.cjs +1 -1
- package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs.map → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs.map → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs.map → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs.map → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs.map} +1 -1
- package/dist/cjs/utils/logger.d.ts.map +1 -1
- package/dist/es/hcs-10/base-client.d.ts +1 -1
- package/dist/es/hcs-10/base-client.d.ts.map +1 -1
- package/dist/es/hcs-10/sdk.d.ts +1 -1
- package/dist/es/hcs-10/sdk.d.ts.map +1 -1
- package/dist/es/hcs-11/agent-builder.d.ts +2 -0
- package/dist/es/hcs-11/agent-builder.d.ts.map +1 -1
- package/dist/es/hcs-11/client.d.ts +2 -0
- package/dist/es/hcs-11/client.d.ts.map +1 -1
- package/dist/es/hcs-11/types.d.ts +4 -2
- package/dist/es/hcs-11/types.d.ts.map +1 -1
- package/dist/es/hcs-15/index.d.ts +3 -0
- package/dist/es/hcs-15/index.d.ts.map +1 -0
- package/dist/es/hcs-15/petal-manager.d.ts +27 -0
- package/dist/es/hcs-15/petal-manager.d.ts.map +1 -0
- package/dist/es/hcs-15/types.d.ts +41 -0
- package/dist/es/hcs-15/types.d.ts.map +1 -0
- package/dist/es/hcs-16/flora-account-manager.d.ts.map +1 -1
- package/dist/es/hcs-16/types.d.ts +3 -5
- package/dist/es/hcs-16/types.d.ts.map +1 -1
- package/dist/es/hcs-18/discovery.d.ts +1 -0
- package/dist/es/hcs-18/discovery.d.ts.map +1 -1
- package/dist/es/hcs-18/types.d.ts +1 -0
- package/dist/es/hcs-18/types.d.ts.map +1 -1
- package/dist/es/hcs-20/sdk.d.ts.map +1 -1
- package/dist/es/hcs-7/evm-bridge.d.ts.map +1 -1
- package/dist/es/hcs-7/redis-cache.d.ts.map +1 -1
- package/dist/es/hcs-7/wasm-bridge.d.ts.map +1 -1
- package/dist/es/index.d.ts +1 -1
- package/dist/es/services/types.d.ts +1 -1
- package/dist/es/services/types.d.ts.map +1 -1
- package/dist/es/standards-sdk.es.js +19 -22
- package/dist/es/standards-sdk.es.js.map +1 -1
- package/dist/es/standards-sdk.es10.js +1 -1
- package/dist/es/standards-sdk.es11.js +10 -2
- package/dist/es/standards-sdk.es11.js.map +1 -1
- package/dist/es/standards-sdk.es12.js +1 -1
- package/dist/es/standards-sdk.es13.js +1 -1
- package/dist/es/standards-sdk.es13.js.map +1 -1
- package/dist/es/standards-sdk.es14.js +1 -1
- package/dist/es/standards-sdk.es15.js +39 -9
- package/dist/es/standards-sdk.es15.js.map +1 -1
- package/dist/es/standards-sdk.es16.js +1 -0
- package/dist/es/standards-sdk.es16.js.map +1 -1
- package/dist/es/standards-sdk.es18.js +1 -1
- package/dist/es/standards-sdk.es19.js +1 -1
- package/dist/es/standards-sdk.es2.js +1 -1
- package/dist/es/standards-sdk.es20.js +2 -2
- package/dist/es/standards-sdk.es23.js +2 -2
- package/dist/es/standards-sdk.es25.js +4 -2
- package/dist/es/standards-sdk.es25.js.map +1 -1
- package/dist/es/standards-sdk.es26.js +2 -2
- package/dist/es/standards-sdk.es27.js +152 -6
- package/dist/es/standards-sdk.es27.js.map +1 -1
- package/dist/es/standards-sdk.es28.js +26 -189
- package/dist/es/standards-sdk.es28.js.map +1 -1
- package/dist/es/standards-sdk.es29.js +446 -26
- package/dist/es/standards-sdk.es29.js.map +1 -1
- package/dist/es/standards-sdk.es3.js +1 -1
- package/dist/es/standards-sdk.es3.js.map +1 -1
- package/dist/es/standards-sdk.es30.js +6 -342
- package/dist/es/standards-sdk.es30.js.map +1 -1
- package/dist/es/standards-sdk.es31.js +202 -6
- package/dist/es/standards-sdk.es31.js.map +1 -1
- package/dist/es/standards-sdk.es32.js +34 -202
- package/dist/es/standards-sdk.es32.js.map +1 -1
- package/dist/es/standards-sdk.es33.js +529 -34
- package/dist/es/standards-sdk.es33.js.map +1 -1
- package/dist/es/standards-sdk.es34.js +87 -501
- package/dist/es/standards-sdk.es34.js.map +1 -1
- package/dist/es/standards-sdk.es35.js +19 -98
- package/dist/es/standards-sdk.es35.js.map +1 -1
- package/dist/es/standards-sdk.es36.js +156 -18
- package/dist/es/standards-sdk.es36.js.map +1 -1
- package/dist/es/standards-sdk.es37.js +146 -150
- package/dist/es/standards-sdk.es37.js.map +1 -1
- package/dist/es/standards-sdk.es38.js +561 -134
- package/dist/es/standards-sdk.es38.js.map +1 -1
- package/dist/es/standards-sdk.es39.js +562 -543
- package/dist/es/standards-sdk.es39.js.map +1 -1
- package/dist/es/standards-sdk.es4.js +6 -4
- package/dist/es/standards-sdk.es4.js.map +1 -1
- package/dist/es/standards-sdk.es40.js +4 -601
- package/dist/es/standards-sdk.es40.js.map +1 -1
- package/dist/es/standards-sdk.es41.js +415 -4
- package/dist/es/standards-sdk.es41.js.map +1 -1
- package/dist/es/standards-sdk.es42.js +1536 -389
- package/dist/es/standards-sdk.es42.js.map +1 -1
- package/dist/es/standards-sdk.es43.js +133 -1541
- package/dist/es/standards-sdk.es43.js.map +1 -1
- package/dist/es/standards-sdk.es44.js +7 -155
- package/dist/es/standards-sdk.es44.js.map +1 -1
- package/dist/es/standards-sdk.es45.js +2 -7
- package/dist/es/standards-sdk.es45.js.map +1 -1
- package/dist/es/standards-sdk.es46.js +5 -5
- package/dist/es/standards-sdk.es48.js +1 -1
- package/dist/es/standards-sdk.es49.js +1 -1
- package/dist/es/standards-sdk.es5.js +4 -6
- package/dist/es/standards-sdk.es5.js.map +1 -1
- package/dist/es/standards-sdk.es50.js +1 -1
- package/dist/es/standards-sdk.es51.js +1 -1
- package/dist/es/standards-sdk.es52.js +1 -1
- package/dist/es/standards-sdk.es54.js +7135 -2
- package/dist/es/standards-sdk.es54.js.map +1 -1
- package/dist/es/standards-sdk.es55.js +7134 -41
- package/dist/es/standards-sdk.es55.js.map +1 -1
- package/dist/es/standards-sdk.es56.js +37 -37
- package/dist/es/standards-sdk.es56.js.map +1 -1
- package/dist/es/standards-sdk.es57.js +37 -37
- package/dist/es/standards-sdk.es57.js.map +1 -1
- package/dist/es/standards-sdk.es58.js +78 -72
- package/dist/es/standards-sdk.es58.js.map +1 -1
- package/dist/es/standards-sdk.es59.js +41 -7134
- package/dist/es/standards-sdk.es59.js.map +1 -1
- package/dist/es/standards-sdk.es6.js.map +1 -1
- package/dist/es/standards-sdk.es7.js +28 -22
- package/dist/es/standards-sdk.es7.js.map +1 -1
- package/dist/es/standards-sdk.es8.js +5 -5
- package/dist/es/utils/logger.d.ts.map +1 -1
- package/package.json +37 -35
- package/dist/cjs/hcs-21/index.d.ts +0 -4
- package/dist/cjs/hcs-21/index.d.ts.map +0 -1
- package/dist/cjs/hcs-21/petal-account-manager.d.ts +0 -52
- package/dist/cjs/hcs-21/petal-account-manager.d.ts.map +0 -1
- package/dist/cjs/hcs-21/types.d.ts +0 -44
- package/dist/cjs/hcs-21/types.d.ts.map +0 -1
- package/dist/cjs/index-xZmk-HBD.cjs.map +0 -1
- package/dist/es/hcs-21/index.d.ts +0 -4
- package/dist/es/hcs-21/index.d.ts.map +0 -1
- package/dist/es/hcs-21/petal-account-manager.d.ts +0 -52
- package/dist/es/hcs-21/petal-account-manager.d.ts.map +0 -1
- package/dist/es/hcs-21/types.d.ts +0 -44
- package/dist/es/hcs-21/types.d.ts.map +0 -1
- package/dist/es/standards-sdk.es60.js +0 -7144
- package/dist/es/standards-sdk.es60.js.map +0 -1
|
@@ -1,31 +1,451 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
import { KeyList, PublicKey, AccountCreateTransaction, Hbar, AccountInfoQuery, TopicCreateTransaction, CustomFixedFee, AccountId, TopicMessageSubmitTransaction, TokenId } from "@hashgraph/sdk";
|
|
2
|
+
import { Logger } from "./standards-sdk.es34.js";
|
|
3
|
+
import { FloraError, FloraTopicType, FloraOperation } from "./standards-sdk.es28.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) => {
|
|
20
|
+
if (typeof m.publicKey === "string") {
|
|
21
|
+
return PublicKey.fromString(m.publicKey);
|
|
22
|
+
}
|
|
23
|
+
return m.publicKey;
|
|
24
|
+
}).filter((key) => key !== void 0),
|
|
25
|
+
config.threshold
|
|
26
|
+
);
|
|
27
|
+
this.logger.debug("Creating Flora with KeyList:", {
|
|
28
|
+
threshold: config.threshold,
|
|
29
|
+
members: config.members.length,
|
|
30
|
+
publicKeys: config.members.map((m) => m.publicKey.toString())
|
|
31
|
+
});
|
|
32
|
+
const transaction = new AccountCreateTransaction().setKey(keyList).setInitialBalance(new Hbar(config.initialBalance || 1)).setMaxAutomaticTokenAssociations(
|
|
33
|
+
config.maxAutomaticTokenAssociations || -1
|
|
34
|
+
);
|
|
35
|
+
const response = await transaction.execute(this.client);
|
|
36
|
+
const receipt = await response.getReceipt(this.client);
|
|
37
|
+
if (!receipt.accountId) {
|
|
38
|
+
throw new Error("Failed to create Flora account");
|
|
39
|
+
}
|
|
40
|
+
const floraAccountId = receipt.accountId;
|
|
41
|
+
this.logger.info("Flora account created successfully:", floraAccountId.toString());
|
|
42
|
+
this.logger.info("Creating Flora topics...");
|
|
43
|
+
let topics;
|
|
44
|
+
try {
|
|
45
|
+
topics = await this.createFloraTopics(
|
|
46
|
+
floraAccountId,
|
|
47
|
+
keyList,
|
|
48
|
+
config
|
|
49
|
+
);
|
|
50
|
+
this.logger.info("Flora topics created successfully");
|
|
51
|
+
} catch (topicError) {
|
|
52
|
+
this.logger.error("Failed to create Flora topics:", {
|
|
53
|
+
error: topicError.message || "Unknown topic error",
|
|
54
|
+
status: topicError.status,
|
|
55
|
+
code: topicError.code,
|
|
56
|
+
name: topicError.name,
|
|
57
|
+
stack: topicError.stack
|
|
58
|
+
});
|
|
59
|
+
throw topicError;
|
|
60
|
+
}
|
|
61
|
+
this.logger.info("Creating Flora profile...");
|
|
62
|
+
await this.createFloraProfile(floraAccountId, topics, config);
|
|
63
|
+
this.logger.info("Flora profile created successfully");
|
|
64
|
+
this.logger.info("Flora created successfully", {
|
|
65
|
+
floraAccountId: floraAccountId.toString(),
|
|
66
|
+
topics: {
|
|
67
|
+
communication: topics.communication.toString(),
|
|
68
|
+
transaction: topics.transaction.toString(),
|
|
69
|
+
state: topics.state.toString()
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
floraAccountId,
|
|
74
|
+
topics,
|
|
75
|
+
keyList,
|
|
76
|
+
transactionId: ""
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
this.logger.error("Failed to create Flora", error);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build KeyList from member public keys
|
|
85
|
+
*/
|
|
86
|
+
async buildKeyList(members, threshold) {
|
|
87
|
+
const keyList = new KeyList();
|
|
88
|
+
keyList.setThreshold(threshold);
|
|
89
|
+
for (const member of members) {
|
|
90
|
+
if (member.publicKey) {
|
|
91
|
+
if (typeof member.publicKey === "string") {
|
|
92
|
+
keyList.push(PublicKey.fromString(member.publicKey));
|
|
93
|
+
} else {
|
|
94
|
+
keyList.push(member.publicKey);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
const accountInfo = await new AccountInfoQuery().setAccountId(member.accountId).execute(this.client);
|
|
98
|
+
keyList.push(accountInfo.key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return keyList;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create the Flora account with threshold key
|
|
105
|
+
*/
|
|
106
|
+
async createFloraAccount(keyList, config) {
|
|
107
|
+
const transaction = new AccountCreateTransaction().setKey(keyList).setInitialBalance(new Hbar(config.initialBalance || 20)).setMaxAutomaticTokenAssociations(
|
|
108
|
+
config.maxAutomaticTokenAssociations || -1
|
|
109
|
+
);
|
|
110
|
+
const response = await transaction.execute(this.client);
|
|
111
|
+
const receipt = await response.getReceipt(this.client);
|
|
112
|
+
if (!receipt.accountId) {
|
|
113
|
+
throw new FloraError(
|
|
114
|
+
"Failed to create Flora account",
|
|
115
|
+
"ACCOUNT_CREATION_FAILED"
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
return receipt.accountId;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create the three required Flora topics with HCS-16 memo format
|
|
122
|
+
*/
|
|
123
|
+
async createFloraTopics(floraAccountId, adminKey, config) {
|
|
124
|
+
const operatorSubmitKey = this.client.operatorPublicKey;
|
|
125
|
+
if (!operatorSubmitKey) {
|
|
126
|
+
throw new FloraError(
|
|
127
|
+
"Operator public key required for topic submission",
|
|
128
|
+
"MISSING_OPERATOR_KEY"
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
this.logger.debug("About to create COMMUNICATION topic...");
|
|
132
|
+
const communication = await this.createTopic(
|
|
133
|
+
floraAccountId,
|
|
134
|
+
FloraTopicType.COMMUNICATION,
|
|
135
|
+
adminKey,
|
|
136
|
+
operatorSubmitKey,
|
|
137
|
+
config.customFees
|
|
138
|
+
);
|
|
139
|
+
this.logger.debug("COMMUNICATION topic created, creating TRANSACTION topic...");
|
|
140
|
+
const transaction = await this.createTopic(
|
|
141
|
+
floraAccountId,
|
|
142
|
+
FloraTopicType.TRANSACTION,
|
|
143
|
+
adminKey,
|
|
144
|
+
operatorSubmitKey,
|
|
145
|
+
config.customFees
|
|
146
|
+
);
|
|
147
|
+
this.logger.debug("TRANSACTION topic created, creating STATE topic...");
|
|
148
|
+
const state = await this.createTopic(
|
|
149
|
+
floraAccountId,
|
|
150
|
+
FloraTopicType.STATE,
|
|
151
|
+
adminKey,
|
|
152
|
+
operatorSubmitKey,
|
|
153
|
+
config.customFees
|
|
154
|
+
);
|
|
155
|
+
this.logger.debug("All Flora topics created successfully");
|
|
156
|
+
return { communication, transaction, state };
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Create a single topic with HCS-16 memo format
|
|
160
|
+
*/
|
|
161
|
+
async createTopic(floraAccountId, topicType, adminKey, submitKey, customFees) {
|
|
162
|
+
const memo = `hcs-16:${floraAccountId}:${topicType}`;
|
|
163
|
+
this.logger.debug(`Creating ${FloraTopicType[topicType]} topic with memo: ${memo}`);
|
|
164
|
+
this.logger.debug("Topic creation details:", {
|
|
165
|
+
operatorId: this.client.operatorAccountId?.toString(),
|
|
166
|
+
operatorIdType: typeof this.client.operatorAccountId,
|
|
167
|
+
hasOperatorPublicKey: !!this.client.operatorPublicKey
|
|
168
|
+
});
|
|
169
|
+
const operatorAccountId = this.client.operatorAccountId;
|
|
170
|
+
if (!operatorAccountId) {
|
|
171
|
+
throw new FloraError("No operator account ID configured", "MISSING_OPERATOR_ACCOUNT");
|
|
172
|
+
}
|
|
173
|
+
const transaction = new TopicCreateTransaction().setTopicMemo(memo).setSubmitKey(submitKey);
|
|
174
|
+
transaction.setAutoRenewAccountId(operatorAccountId.toString());
|
|
175
|
+
if (customFees && customFees.length > 0) {
|
|
176
|
+
const fees = customFees.map(
|
|
177
|
+
(fee) => new CustomFixedFee().setAmount(fee.amount).setFeeCollectorAccountId(
|
|
178
|
+
AccountId.fromString(fee.feeCollectorAccountId)
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
transaction.setCustomFees(fees);
|
|
182
|
+
}
|
|
183
|
+
this.logger.debug(`About to execute topic creation for ${FloraTopicType[topicType]}`);
|
|
184
|
+
let response;
|
|
185
|
+
try {
|
|
186
|
+
this.logger.debug(`Executing topic creation transaction for ${FloraTopicType[topicType]}`);
|
|
187
|
+
response = await transaction.execute(this.client);
|
|
188
|
+
this.logger.debug(`Transaction executed successfully for ${FloraTopicType[topicType]}, response:`, typeof response);
|
|
189
|
+
} catch (executeError) {
|
|
190
|
+
this.logger.error(`Transaction execution failed for ${FloraTopicType[topicType]}:`, {
|
|
191
|
+
error: executeError.message || "Unknown execute error",
|
|
192
|
+
status: executeError.status,
|
|
193
|
+
code: executeError.code,
|
|
194
|
+
name: executeError.name,
|
|
195
|
+
stack: executeError.stack
|
|
196
|
+
});
|
|
197
|
+
throw executeError;
|
|
198
|
+
}
|
|
199
|
+
let receipt;
|
|
200
|
+
try {
|
|
201
|
+
this.logger.debug(`Getting receipt for ${FloraTopicType[topicType]}`);
|
|
202
|
+
receipt = await response.getReceipt(this.client);
|
|
203
|
+
this.logger.debug(`Receipt obtained for ${FloraTopicType[topicType]}`);
|
|
204
|
+
} catch (receiptError) {
|
|
205
|
+
this.logger.error(`Receipt retrieval failed for ${FloraTopicType[topicType]}:`, {
|
|
206
|
+
error: receiptError.message || "Unknown receipt error",
|
|
207
|
+
status: receiptError.status,
|
|
208
|
+
code: receiptError.code,
|
|
209
|
+
name: receiptError.name,
|
|
210
|
+
stack: receiptError.stack
|
|
211
|
+
});
|
|
212
|
+
throw receiptError;
|
|
213
|
+
}
|
|
214
|
+
if (!receipt.topicId) {
|
|
215
|
+
throw new FloraError(
|
|
216
|
+
`Failed to create ${FloraTopicType[topicType]} topic - no topicId in receipt`,
|
|
217
|
+
"TOPIC_CREATION_FAILED"
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
this.logger.debug(`${FloraTopicType[topicType]} topic created: ${receipt.topicId}`);
|
|
221
|
+
return receipt.topicId;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Create and store Flora profile using HCS-11
|
|
225
|
+
*/
|
|
226
|
+
async createFloraProfile(floraAccountId, topics, config) {
|
|
227
|
+
this.logger.info("Creating Flora profile using HCS-11");
|
|
228
|
+
const operatorMember = config.members[0];
|
|
229
|
+
if (!operatorMember.privateKey) {
|
|
230
|
+
throw new FloraError(
|
|
231
|
+
"First member must have private key to create profile",
|
|
232
|
+
"MISSING_PRIVATE_KEY"
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
const hcs11Client = new HCS11Client({
|
|
236
|
+
network: this.network,
|
|
237
|
+
auth: {
|
|
238
|
+
operatorId: operatorMember.accountId,
|
|
239
|
+
privateKey: operatorMember.privateKey
|
|
240
|
+
},
|
|
241
|
+
keyType: "ecdsa"
|
|
242
|
+
});
|
|
243
|
+
const profileMembers = config.members.map((member) => ({
|
|
244
|
+
accountId: member.accountId,
|
|
245
|
+
publicKey: member.publicKey?.toString(),
|
|
246
|
+
// Serialize PublicKey to string
|
|
247
|
+
weight: member.weight
|
|
248
|
+
// Note: privateKey is intentionally excluded from the profile
|
|
249
|
+
}));
|
|
250
|
+
const floraBuilder = new FloraBuilder().setDisplayName(config.displayName).setMembers(profileMembers).setThreshold(config.threshold).setTopics({
|
|
251
|
+
communication: topics.communication.toString(),
|
|
252
|
+
transaction: topics.transaction.toString(),
|
|
253
|
+
state: topics.state.toString()
|
|
254
|
+
}).setPolicies(config.policies);
|
|
255
|
+
if (config.bio) {
|
|
256
|
+
floraBuilder.setBio(config.bio);
|
|
257
|
+
}
|
|
258
|
+
if (config.metadata) {
|
|
259
|
+
floraBuilder.setMetadata(config.metadata);
|
|
260
|
+
}
|
|
261
|
+
const profile = floraBuilder.build();
|
|
262
|
+
this.logger.debug("Attempting Flora profile inscription with config:", {
|
|
263
|
+
operatorId: operatorMember.accountId,
|
|
264
|
+
hasPrivateKey: !!operatorMember.privateKey,
|
|
265
|
+
floraAccountId: floraAccountId.toString(),
|
|
266
|
+
network: this.network
|
|
267
|
+
});
|
|
268
|
+
this.logger.debug("Built Flora profile for validation:", {
|
|
269
|
+
profile: JSON.stringify(profile, null, 2)
|
|
270
|
+
});
|
|
271
|
+
let inscriptionResult;
|
|
272
|
+
try {
|
|
273
|
+
inscriptionResult = await hcs11Client.createAndInscribeProfile(
|
|
274
|
+
profile,
|
|
275
|
+
true
|
|
276
|
+
);
|
|
277
|
+
} catch (inscriptionError) {
|
|
278
|
+
this.logger.error("HCS-11 inscription error:", {
|
|
279
|
+
error: inscriptionError.message || "Unknown inscription error",
|
|
280
|
+
status: inscriptionError.status,
|
|
281
|
+
code: inscriptionError.code,
|
|
282
|
+
name: inscriptionError.name,
|
|
283
|
+
stack: inscriptionError.stack
|
|
284
|
+
});
|
|
285
|
+
throw new FloraError(
|
|
286
|
+
`HCS-11 inscription failed: ${inscriptionError.message}`,
|
|
287
|
+
"PROFILE_INSCRIPTION_FAILED"
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
if (!inscriptionResult.success) {
|
|
291
|
+
this.logger.error("Flora profile inscription failed:", {
|
|
292
|
+
error: inscriptionResult.error,
|
|
293
|
+
result: inscriptionResult
|
|
294
|
+
});
|
|
295
|
+
throw new FloraError(
|
|
296
|
+
`Failed to inscribe Flora profile: ${inscriptionResult.error}`,
|
|
297
|
+
"PROFILE_INSCRIPTION_FAILED"
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
this.logger.info("Flora profile inscribed successfully", {
|
|
301
|
+
profileTopicId: inscriptionResult.profileTopicId,
|
|
302
|
+
transactionId: inscriptionResult.transactionId
|
|
303
|
+
});
|
|
304
|
+
return inscriptionResult.profileTopicId;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Send a message to a Flora topic
|
|
308
|
+
*/
|
|
309
|
+
async sendFloraMessage(topicId, message) {
|
|
310
|
+
try {
|
|
311
|
+
message.p = "hcs-16";
|
|
312
|
+
const transaction = new TopicMessageSubmitTransaction().setTopicId(topicId).setMessage(JSON.stringify(message));
|
|
313
|
+
const response = await transaction.execute(this.client);
|
|
314
|
+
await response.getReceipt(this.client);
|
|
315
|
+
this.logger.debug("Flora message sent", {
|
|
316
|
+
topicId: topicId.toString(),
|
|
317
|
+
operation: message.op
|
|
318
|
+
});
|
|
319
|
+
} catch (error) {
|
|
320
|
+
this.logger.error("Failed to send Flora message", error);
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Send flora_created notification to all members
|
|
326
|
+
*/
|
|
327
|
+
async notifyFloraCreated(result, memberTopics) {
|
|
328
|
+
const message = {
|
|
329
|
+
p: "hcs-16",
|
|
330
|
+
op: FloraOperation.FLORA_CREATED,
|
|
331
|
+
operator_id: `${this.client.operatorAccountId}@${result.floraAccountId}`,
|
|
332
|
+
flora_account_id: result.floraAccountId.toString(),
|
|
333
|
+
topics: {
|
|
334
|
+
communication: result.topics.communication.toString(),
|
|
335
|
+
transaction: result.topics.transaction.toString(),
|
|
336
|
+
state: result.topics.state.toString()
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
await Promise.all(
|
|
340
|
+
memberTopics.map((topicId) => this.sendFloraMessage(topicId, message))
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Parse HCS-16 topic memo
|
|
345
|
+
*/
|
|
346
|
+
parseTopicMemo(memo) {
|
|
347
|
+
const match = memo.match(/^hcs-16:([0-9.]+):(\d)$/);
|
|
348
|
+
if (!match) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
protocol: "hcs-16",
|
|
353
|
+
floraAccountId: match[1],
|
|
354
|
+
topicType: parseInt(match[2])
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Create a proposal for a scheduled transaction
|
|
359
|
+
*/
|
|
360
|
+
async createTransactionProposal(transactionTopicId, scheduledTxId, description, operatorAccountId, floraAccountId) {
|
|
361
|
+
const message = {
|
|
362
|
+
p: "hcs-16",
|
|
363
|
+
op: FloraOperation.TX_PROPOSAL,
|
|
364
|
+
operator_id: `${operatorAccountId}@${floraAccountId}`,
|
|
365
|
+
scheduled_tx_id: scheduledTxId,
|
|
366
|
+
description,
|
|
367
|
+
m: description
|
|
368
|
+
};
|
|
369
|
+
await this.sendFloraMessage(transactionTopicId, message);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Submit a state update to the state topic
|
|
373
|
+
*/
|
|
374
|
+
async submitStateUpdate(stateTopicId, stateHash, operatorAccountId, floraAccountId, epoch) {
|
|
375
|
+
const message = {
|
|
376
|
+
p: "hcs-16",
|
|
377
|
+
op: FloraOperation.STATE_UPDATE,
|
|
378
|
+
operator_id: `${operatorAccountId}@${floraAccountId}`,
|
|
379
|
+
hash: stateHash,
|
|
380
|
+
epoch,
|
|
381
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
382
|
+
};
|
|
383
|
+
await this.sendFloraMessage(stateTopicId, message);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Create a generic HCS-16 transaction topic with HIP-991 support
|
|
387
|
+
* This can be used for any HCS-16 compliant topic, not just Flora accounts
|
|
388
|
+
*/
|
|
389
|
+
async createTransactionTopic(config) {
|
|
390
|
+
const transaction = new TopicCreateTransaction().setTopicMemo(config.memo);
|
|
391
|
+
if (config.adminKey) {
|
|
392
|
+
transaction.setAdminKey(config.adminKey);
|
|
393
|
+
}
|
|
394
|
+
if (config.submitKey) {
|
|
395
|
+
transaction.setSubmitKey(config.submitKey);
|
|
396
|
+
}
|
|
397
|
+
if (config.feeScheduleKey) {
|
|
398
|
+
transaction.setFeeScheduleKey(config.feeScheduleKey);
|
|
399
|
+
}
|
|
400
|
+
if (config.customFees && config.customFees.length > 0) {
|
|
401
|
+
const fees = config.customFees.map((fee) => {
|
|
402
|
+
const customFee = new CustomFixedFee().setAmount(fee.amount).setFeeCollectorAccountId(
|
|
403
|
+
AccountId.fromString(fee.feeCollectorAccountId)
|
|
404
|
+
);
|
|
405
|
+
if (fee.denominatingTokenId) {
|
|
406
|
+
customFee.setDenominatingTokenId(
|
|
407
|
+
TokenId.fromString(fee.denominatingTokenId)
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
return customFee;
|
|
411
|
+
});
|
|
412
|
+
transaction.setCustomFees(fees);
|
|
413
|
+
}
|
|
414
|
+
if (config.feeExemptKeys && config.feeExemptKeys.length > 0) {
|
|
415
|
+
transaction.setFeeExemptKeyList(config.feeExemptKeys);
|
|
416
|
+
}
|
|
417
|
+
const response = await transaction.execute(this.client);
|
|
418
|
+
const receipt = await response.getReceipt(this.client);
|
|
419
|
+
if (!receipt.topicId) {
|
|
420
|
+
throw new FloraError(
|
|
421
|
+
"Failed to create transaction topic",
|
|
422
|
+
"TOPIC_CREATION_FAILED"
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
this.logger.info("Created HCS-16 transaction topic", {
|
|
426
|
+
topicId: receipt.topicId.toString(),
|
|
427
|
+
memo: config.memo,
|
|
428
|
+
hasFees: !!config.customFees
|
|
429
|
+
});
|
|
430
|
+
return receipt.topicId;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Submit HCS-16 compliant credit purchase message
|
|
434
|
+
*/
|
|
435
|
+
async submitCreditPurchase(topicId, purchaser, amount, floraAccountId) {
|
|
436
|
+
const message = {
|
|
437
|
+
p: "hcs-16",
|
|
438
|
+
op: FloraOperation.CREDIT_PURCHASE,
|
|
439
|
+
operator_id: floraAccountId ? `${purchaser}@${floraAccountId}` : purchaser,
|
|
440
|
+
amount,
|
|
441
|
+
purchaser,
|
|
442
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
443
|
+
m: `Purchase ${amount} credits`
|
|
444
|
+
};
|
|
445
|
+
await this.sendFloraMessage(topicId, message);
|
|
24
446
|
}
|
|
25
447
|
}
|
|
26
448
|
export {
|
|
27
|
-
|
|
28
|
-
FloraOperation,
|
|
29
|
-
FloraTopicType
|
|
449
|
+
FloraAccountManager
|
|
30
450
|
};
|
|
31
451
|
//# sourceMappingURL=standards-sdk.es29.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-sdk.es29.js","sources":["../../src/hcs-16/types.ts"],"sourcesContent":["import {\n AccountId,\n TopicId,\n PublicKey,\n Key,\n PrivateKey,\n KeyList,\n TokenId,\n} from '@hashgraph/sdk';\n\n/**\n * HCS-16 Topic type enums\n */\nexport enum FloraTopicType {\n COMMUNICATION = 0,\n TRANSACTION = 1,\n STATE = 2,\n}\n\n/**\n * HCS-16 Flora member\n */\nexport interface FloraMember {\n accountId: string;\n publicKey?: PublicKey;\n privateKey?: string;\n weight?: number;\n}\n\n/**\n * HCS-16 Flora topics\n */\nexport interface FloraTopics {\n communication: TopicId;\n transaction: TopicId;\n state: TopicId;\n custom?: Array<{\n name: string;\n topicId: string;\n description?: string;\n }>;\n}\n\n/**\n * HCS-16 Flora configuration\n */\nexport interface FloraConfig {\n displayName: string;\n bio?: string;\n members: FloraMember[];\n threshold: number;\n initialBalance?: number;\n maxAutomaticTokenAssociations?: number;\n policies?: {\n membershipChange?: string;\n scheduleTxApproval?: string;\n };\n customFees?: {\n amount: number;\n feeCollectorAccountId: string;\n }[];\n metadata?: Record<string, any>;\n}\n\n/**\n * HCS-16 Flora creation result\n */\nexport interface FloraCreationResult {\n floraAccountId: AccountId;\n topics: FloraTopics;\n keyList: Key;\n transactionId: string;\n}\n\n/**\n * HCS-16 Message protocol operations\n */\nexport enum FloraOperation {\n FLORA_CREATE_REQUEST = 'flora_create_request',\n FLORA_CREATE_ACCEPTED = 'flora_create_accepted',\n FLORA_CREATED = 'flora_created',\n TX_PROPOSAL = 'tx_proposal',\n STATE_UPDATE = 'state_update',\n FLORA_JOIN_REQUEST = 'flora_join_request',\n FLORA_JOIN_VOTE = 'flora_join_vote',\n FLORA_JOIN_ACCEPTED = 'flora_join_accepted',\n CREDIT_PURCHASE = 'credit_purchase',\n}\n\n/**\n * HCS-16 Message envelope\n */\nexport interface FloraMessage {\n p: 'hcs-16';\n op: FloraOperation;\n operator_id: string;\n m?: string;\n [key: string]: unknown;\n}\n\n/**\n * HCS-16 Flora profile (extends HCS-11)\n */\nexport interface FloraProfile {\n version: string;\n type: 3;\n display_name: string;\n members: FloraMember[];\n threshold: number;\n topics: {\n communication: string;\n transaction: string;\n state: string;\n custom?: Array<{\n name: string;\n topicId: string;\n description?: string;\n }>;\n };\n alias?: string;\n bio?: string;\n socials?: Array<{ platform: string; handle: string }>;\n profileImage?: string;\n properties?: Record<string, unknown>;\n inboundTopicId: string;\n outboundTopicId: string;\n policies?: Record<string, string>;\n metadata?: Record<string, any>;\n}\n\n/**\n * HCS-16 errors\n */\nexport class FloraError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = 'FloraError';\n }\n}\n\n/**\n * Flora state update message\n */\nexport interface FloraStateUpdate {\n p: 'hcs-16';\n op: 'state_update';\n operator_id: string;\n hash: string;\n epoch?: number;\n members?: string[];\n timestamp: string;\n}\n\n/**\n * HIP-991 Custom fee configuration for transaction topics\n */\nexport interface TransactionTopicFee {\n amount: number;\n feeCollectorAccountId: string;\n denominatingTokenId?: string;\n}\n\n/**\n * Configuration for creating HCS-16 transaction topics with HIP-991 support\n */\nexport interface TransactionTopicConfig {\n memo: string;\n adminKey?: PrivateKey | KeyList;\n submitKey?: PrivateKey | KeyList;\n feeScheduleKey?: PrivateKey | KeyList;\n customFees?: TransactionTopicFee[];\n feeExemptKeys?: Key[];\n}\n\n/**\n * HCS-16 Credit purchase message\n */\nexport interface CreditPurchaseMessage extends FloraMessage {\n p: 'hcs-16';\n op: FloraOperation.CREDIT_PURCHASE;\n amount: number;\n purchaser: string;\n timestamp: string;\n}\n"],"names":["FloraTopicType","FloraOperation"],"mappings":"AAaO,IAAK,mCAAAA,oBAAL;AACLA,kBAAAA,gBAAA,mBAAgB,CAAA,IAAhB;AACAA,kBAAAA,gBAAA,iBAAc,CAAA,IAAd;AACAA,kBAAAA,gBAAA,WAAQ,CAAA,IAAR;AAHU,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAgEL,IAAK,mCAAAC,oBAAL;AACLA,kBAAA,sBAAA,IAAuB;AACvBA,kBAAA,uBAAA,IAAwB;AACxBA,kBAAA,eAAA,IAAgB;AAChBA,kBAAA,aAAA,IAAc;AACdA,kBAAA,cAAA,IAAe;AACfA,kBAAA,oBAAA,IAAqB;AACrBA,kBAAA,iBAAA,IAAkB;AAClBA,kBAAA,qBAAA,IAAsB;AACtBA,kBAAA,iBAAA,IAAkB;AATR,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAwDL,MAAM,mBAAmB,MAAM;AAAA,EACpC,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG,SAAA,OAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;"}
|
|
1
|
+
{"version":3,"file":"standards-sdk.es29.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 => {\n if (typeof m.publicKey === 'string') {\n return PublicKey.fromString(m.publicKey);\n }\n return m.publicKey;\n }).filter(key => key !== undefined),\n config.threshold,\n );\n \n this.logger.debug('Creating Flora with KeyList:', {\n threshold: config.threshold,\n members: config.members.length,\n publicKeys: config.members.map(m => m.publicKey.toString()),\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 this.logger.info('Flora account created successfully:', floraAccountId.toString());\n\n this.logger.info('Creating Flora topics...');\n let topics;\n try {\n topics = await this.createFloraTopics(\n floraAccountId,\n keyList,\n config,\n );\n this.logger.info('Flora topics created successfully');\n } catch (topicError: any) {\n this.logger.error('Failed to create Flora topics:', {\n error: topicError.message || 'Unknown topic error',\n status: topicError.status,\n code: topicError.code,\n name: topicError.name,\n stack: topicError.stack,\n });\n throw topicError;\n }\n\n this.logger.info('Creating Flora profile...');\n await this.createFloraProfile(floraAccountId, topics, config);\n this.logger.info('Flora profile created successfully');\n\n this.logger.info('Flora created successfully', {\n floraAccountId: floraAccountId.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,\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 if (typeof member.publicKey === 'string') {\n keyList.push(PublicKey.fromString(member.publicKey));\n } else {\n keyList.push(member.publicKey);\n }\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 // Use operator's public key for submitKey (simplified approach)\n const operatorSubmitKey = this.client.operatorPublicKey;\n if (!operatorSubmitKey) {\n throw new FloraError(\n 'Operator public key required for topic submission',\n 'MISSING_OPERATOR_KEY',\n );\n }\n\n // Create topics sequentially to better handle errors\n this.logger.debug('About to create COMMUNICATION topic...');\n const communication = await this.createTopic(\n floraAccountId,\n FloraTopicType.COMMUNICATION,\n adminKey,\n operatorSubmitKey,\n config.customFees,\n );\n this.logger.debug('COMMUNICATION topic created, creating TRANSACTION topic...');\n \n const transaction = await this.createTopic(\n floraAccountId,\n FloraTopicType.TRANSACTION,\n adminKey,\n operatorSubmitKey,\n config.customFees,\n );\n this.logger.debug('TRANSACTION topic created, creating STATE topic...');\n \n const state = await this.createTopic(\n floraAccountId,\n FloraTopicType.STATE,\n adminKey,\n operatorSubmitKey,\n config.customFees,\n );\n this.logger.debug('All Flora topics created successfully');\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: PublicKey,\n customFees?: Array<{ amount: number; feeCollectorAccountId: string }>,\n ): Promise<TopicId> {\n const memo = `hcs-16:${floraAccountId}:${topicType}`;\n \n this.logger.debug(`Creating ${FloraTopicType[topicType]} topic with memo: ${memo}`);\n this.logger.debug('Topic creation details:', {\n operatorId: this.client.operatorAccountId?.toString(),\n operatorIdType: typeof this.client.operatorAccountId,\n hasOperatorPublicKey: !!this.client.operatorPublicKey,\n });\n\n // Ensure operatorAccountId is properly handled\n const operatorAccountId = this.client.operatorAccountId;\n if (!operatorAccountId) {\n throw new FloraError('No operator account ID configured', 'MISSING_OPERATOR_ACCOUNT');\n }\n\n const transaction = new TopicCreateTransaction()\n .setTopicMemo(memo)\n .setSubmitKey(submitKey);\n \n // Convert AccountId to string for setAutoRenewAccountId\n transaction.setAutoRenewAccountId(operatorAccountId.toString());\n \n // Note: adminKey temporarily removed to allow operator to create topics\n // In practice, adminKey would be set to the threshold key, but this requires\n // threshold signatures for topic creation which is complex to implement\n // .setAdminKey(adminKey)\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 this.logger.debug(`About to execute topic creation for ${FloraTopicType[topicType]}`);\n \n let response;\n try {\n this.logger.debug(`Executing topic creation transaction for ${FloraTopicType[topicType]}`);\n response = await transaction.execute(this.client);\n this.logger.debug(`Transaction executed successfully for ${FloraTopicType[topicType]}, response:`, typeof response);\n } catch (executeError: any) {\n this.logger.error(`Transaction execution failed for ${FloraTopicType[topicType]}:`, {\n error: executeError.message || 'Unknown execute error',\n status: executeError.status,\n code: executeError.code,\n name: executeError.name,\n stack: executeError.stack,\n });\n throw executeError;\n }\n\n let receipt;\n try {\n this.logger.debug(`Getting receipt for ${FloraTopicType[topicType]}`);\n receipt = await response.getReceipt(this.client);\n this.logger.debug(`Receipt obtained for ${FloraTopicType[topicType]}`);\n } catch (receiptError: any) {\n this.logger.error(`Receipt retrieval failed for ${FloraTopicType[topicType]}:`, {\n error: receiptError.message || 'Unknown receipt error',\n status: receiptError.status,\n code: receiptError.code,\n name: receiptError.name,\n stack: receiptError.stack,\n });\n throw receiptError;\n }\n\n if (!receipt.topicId) {\n throw new FloraError(\n `Failed to create ${FloraTopicType[topicType]} topic - no topicId in receipt`,\n 'TOPIC_CREATION_FAILED',\n );\n }\n\n this.logger.debug(`${FloraTopicType[topicType]} topic created: ${receipt.topicId}`);\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 // Use the first member's account as operator (they have the signing key)\n // The Flora profile will still be associated with the Flora account via the profile content\n const hcs11Client = new HCS11Client({\n network: this.network,\n auth: {\n operatorId: operatorMember.accountId,\n privateKey: operatorMember.privateKey,\n },\n keyType: 'ecdsa',\n });\n\n // Convert members to profile-safe format (no private keys, serialized public keys)\n const profileMembers = config.members.map(member => ({\n accountId: member.accountId,\n publicKey: member.publicKey?.toString(), // Serialize PublicKey to string\n weight: member.weight,\n // Note: privateKey is intentionally excluded from the profile\n }));\n\n const floraBuilder = new FloraBuilder()\n .setDisplayName(config.displayName)\n .setMembers(profileMembers)\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 this.logger.debug('Attempting Flora profile inscription with config:', {\n operatorId: operatorMember.accountId,\n hasPrivateKey: !!operatorMember.privateKey,\n floraAccountId: floraAccountId.toString(),\n network: this.network,\n });\n\n this.logger.debug('Built Flora profile for validation:', {\n profile: JSON.stringify(profile, null, 2),\n });\n\n let inscriptionResult;\n try {\n inscriptionResult = await hcs11Client.createAndInscribeProfile(\n profile,\n true,\n );\n } catch (inscriptionError: any) {\n this.logger.error('HCS-11 inscription error:', {\n error: inscriptionError.message || 'Unknown inscription error',\n status: inscriptionError.status,\n code: inscriptionError.code,\n name: inscriptionError.name,\n stack: inscriptionError.stack,\n });\n throw new FloraError(\n `HCS-11 inscription failed: ${inscriptionError.message}`,\n 'PROFILE_INSCRIPTION_FAILED',\n );\n }\n\n if (!inscriptionResult.success) {\n this.logger.error('Flora profile inscription failed:', {\n error: inscriptionResult.error,\n result: inscriptionResult,\n });\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-sdk.es3.js","sources":["../../src/hcs-7/wasm-bridge.ts"],"sourcesContent":["\nimport { Logger } from '../utils/logger';\n\nexport interface BaseMessage {\n p: string;\n op: string;\n m: string;\n t?: string;\n t_id?: string;\n d?: Record<string, unknown>;\n}\n\nexport interface EVMConfig extends BaseMessage {\n c: {\n contractAddress: string;\n abi: {\n inputs: Array<{\n name: string;\n type: string;\n }>;\n name: string;\n outputs: Array<{\n name: string;\n type: string;\n }>;\n stateMutability: string;\n type: string;\n };\n };\n}\n\nexport interface WASMConfig extends BaseMessage {\n c: {\n wasmTopicId: string;\n inputType: {\n stateData: Record<string, string>;\n };\n outputType: {\n type: string;\n format: string;\n };\n };\n}\n\nexport interface WasmExports extends WebAssembly.Exports {\n __wbindgen_add_to_stack_pointer: (a: number) => number;\n __wbindgen_malloc: (a: number, b: number) => number;\n __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;\n __wbindgen_free: (a: number, b: number, c: number) => void;\n memory: WebAssembly.Memory;\n process_state: (state_json: string, messages_json: string) => string;\n get_params: () => string;\n [key: string]: any;\n}\n\nexport class WasmBridge {\n wasm: WasmExports | null = null;\n private WASM_VECTOR_LEN: number = 0;\n private cachedUint8Memory: Uint8Array | null = null;\n private cachedDataViewMemory: DataView | null = null;\n private readonly textEncoder: TextEncoder;\n private readonly textDecoder: TextDecoder;\n private logger: Logger;\n\n constructor() {\n this.textEncoder = new TextEncoder();\n this.textDecoder = new TextDecoder('utf-8', {\n ignoreBOM: true,\n fatal: true,\n });\n this.textDecoder.decode();\n this.logger = Logger.getInstance({ module: 'WasmBridge' });\n }\n\n setLogLevel(level: 'debug' | 'info' | 'warn' | 'error'): void {\n this.logger.setLogLevel(level);\n }\n\n get wasmInstance(): WasmExports {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n return this.wasm;\n }\n\n private getUint8Memory(): Uint8Array {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n if (\n this.cachedUint8Memory === null ||\n this.cachedUint8Memory.byteLength === 0\n ) {\n this.cachedUint8Memory = new Uint8Array(this.wasm.memory.buffer);\n }\n return this.cachedUint8Memory;\n }\n\n private getDataViewMemory(): DataView {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n if (\n this.cachedDataViewMemory === null ||\n this.cachedDataViewMemory.buffer !== this.wasm.memory.buffer\n ) {\n this.cachedDataViewMemory = new DataView(this.wasm.memory.buffer);\n }\n return this.cachedDataViewMemory;\n }\n\n private encodeString(\n arg: string,\n view: Uint8Array,\n ): { read: number; written: number } {\n if (arg.length === 0) {\n return { read: 0, written: 0 };\n }\n\n const buf = this.textEncoder.encode(arg);\n view.set(buf);\n return { read: arg.length, written: buf.length };\n }\n\n private passStringToWasm(\n arg: string,\n malloc: (a: number, b: number) => number,\n realloc?: (a: number, b: number, c: number, d: number) => number,\n ): number {\n if (realloc === undefined) {\n const buf = this.textEncoder.encode(arg);\n const ptr = malloc(buf.length, 1);\n const view = this.getUint8Memory();\n view.set(buf, ptr);\n this.WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = this.textEncoder.encode(arg).length;\n let ptr = malloc(len, 1);\n\n const mem = this.getUint8Memory();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7f) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(\n ptr,\n len,\n (len = offset + this.textEncoder.encode(arg).length * 3),\n 1,\n );\n const view = this.getUint8Memory().subarray(ptr + offset, ptr + len);\n const ret = this.encodeString(arg, view);\n\n offset += ret.written;\n }\n\n this.WASM_VECTOR_LEN = offset;\n return ptr;\n }\n\n private getStringFromWasm(ptr: number, len: number): string {\n ptr = ptr >>> 0;\n return this.textDecoder.decode(\n this.getUint8Memory().subarray(ptr, ptr + len),\n );\n }\n\n createWasmFunction(\n wasmFn: (...args: any[]) => any,\n ): (...args: string[]) => string {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n\n return (...args: string[]): string => {\n const retptr = this.wasm!.__wbindgen_add_to_stack_pointer(-16);\n let deferred: [number, number] = [0, 0];\n\n try {\n const ptrLenPairs = args.map(arg => {\n const ptr = this.passStringToWasm(\n arg,\n this.wasm!.__wbindgen_malloc,\n this.wasm!.__wbindgen_realloc,\n );\n return [ptr, this.WASM_VECTOR_LEN];\n });\n\n const wasmArgs = [retptr, ...ptrLenPairs.flat()];\n\n wasmFn.apply(this.wasm, wasmArgs);\n\n const r0 = this.getDataViewMemory().getInt32(retptr + 4 * 0, true);\n const r1 = this.getDataViewMemory().getInt32(retptr + 4 * 1, true);\n deferred = [r0, r1];\n\n return this.getStringFromWasm(r0, r1);\n } finally {\n this.wasm!.__wbindgen_add_to_stack_pointer(16);\n this.wasm!.__wbindgen_free(deferred[0], deferred[1], 1);\n }\n };\n }\n\n async initWasm(wasmBytes: BufferSource): Promise<WasmExports> {\n const bridge = this;\n const imports = {\n __wbindgen_placeholder__: {\n __wbindgen_throw: function (ptr: number, len: number) {\n const message = bridge.getStringFromWasm(ptr, len);\n bridge.logger.error(`WASM error: ${message}`);\n throw new Error(message);\n },\n },\n };\n\n try {\n this.logger.debug('Compiling WASM module');\n const wasmModule = await WebAssembly.compile(wasmBytes);\n this.logger.debug('Instantiating WASM module');\n const wasmInstance = await WebAssembly.instantiate(wasmModule, imports);\n this.wasm = wasmInstance.exports as WasmExports;\n this.logger.info('WASM module initialized successfully');\n return this.wasm;\n } catch (error) {\n this.logger.error('Failed to initialize WASM module', error);\n throw error;\n }\n }\n\n createStateData(wasmConfig: WASMConfig, stateData: Record<string, any> = {}) {\n let dynamicStateData: Record<string, any> = {};\n\n if (wasmConfig?.c?.inputType?.stateData) {\n\n if (\n stateData.latestRoundData &&\n Object.keys(wasmConfig.c.inputType.stateData).every(\n key => key in stateData.latestRoundData,\n )\n ) {\n\n dynamicStateData.latestRoundData = {};\n Object.entries(wasmConfig.c.inputType.stateData).forEach(([key, _]) => {\n dynamicStateData.latestRoundData[key] = String(\n stateData.latestRoundData[key],\n );\n });\n } else {\n\n Object.entries(wasmConfig.c.inputType.stateData).forEach(\n ([key, type]) => {\n const result = stateData[key];\n if (\n result &&\n typeof result === 'object' &&\n 'values' in result &&\n result.values.length > 0\n ) {\n dynamicStateData[key] = String(result.values[0]);\n } else {\n dynamicStateData[key] = this.getDefaultValueForType(\n type as string,\n );\n }\n },\n );\n }\n }\n return dynamicStateData;\n }\n\n private getDefaultValueForType(type: string): string {\n if (\n type.startsWith('uint') ||\n type.startsWith('int') ||\n type === 'number'\n ) {\n return '0';\n } else if (type === 'bool') {\n return 'false';\n } else {\n return '';\n }\n }\n\n executeWasm(stateData: Record<string, any>, messages: BaseMessage[]) {\n if (!this.wasm) {\n this.logger.error('WASM not initialized');\n throw new Error('WASM not initialized');\n }\n\n try {\n this.logger.debug('Executing WASM with stateData', stateData);\n const fn = this.createWasmFunction(this.wasmInstance.process_state);\n return fn(JSON.stringify(stateData), JSON.stringify(messages));\n } catch (error) {\n this.logger.error('Error executing WASM', error);\n throw error;\n }\n }\n\n getParams(): string {\n const fn = this.createWasmFunction(this.wasmInstance.get_params);\n return fn();\n }\n}\n"],"names":["ptr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"standards-sdk.es3.js","sources":["../../src/hcs-7/wasm-bridge.ts"],"sourcesContent":["// TextEncoder and TextDecoder are available globally in modern browsers\n// and in Node.js without explicit import\nimport { Logger } from '../utils/logger';\n\nexport interface BaseMessage {\n p: string;\n op: string;\n m: string;\n t?: string;\n t_id?: string;\n d?: Record<string, unknown>;\n}\n\nexport interface EVMConfig extends BaseMessage {\n c: {\n contractAddress: string;\n abi: {\n inputs: Array<{\n name: string;\n type: string;\n }>;\n name: string;\n outputs: Array<{\n name: string;\n type: string;\n }>;\n stateMutability: string;\n type: string;\n };\n };\n}\n\nexport interface WASMConfig extends BaseMessage {\n c: {\n wasmTopicId: string;\n inputType: {\n stateData: Record<string, string>;\n };\n outputType: {\n type: string;\n format: string;\n };\n };\n}\n\nexport interface WasmExports extends WebAssembly.Exports {\n __wbindgen_add_to_stack_pointer: (a: number) => number;\n __wbindgen_malloc: (a: number, b: number) => number;\n __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;\n __wbindgen_free: (a: number, b: number, c: number) => void;\n memory: WebAssembly.Memory;\n process_state: (state_json: string, messages_json: string) => string;\n get_params: () => string;\n [key: string]: any;\n}\n\nexport class WasmBridge {\n wasm: WasmExports | null = null;\n private WASM_VECTOR_LEN: number = 0;\n private cachedUint8Memory: Uint8Array | null = null;\n private cachedDataViewMemory: DataView | null = null;\n private readonly textEncoder: TextEncoder;\n private readonly textDecoder: TextDecoder;\n private logger: Logger;\n\n constructor() {\n this.textEncoder = new TextEncoder();\n this.textDecoder = new TextDecoder('utf-8', {\n ignoreBOM: true,\n fatal: true,\n });\n this.textDecoder.decode();\n this.logger = Logger.getInstance({ module: 'WasmBridge' });\n }\n\n setLogLevel(level: 'debug' | 'info' | 'warn' | 'error'): void {\n this.logger.setLogLevel(level);\n }\n\n get wasmInstance(): WasmExports {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n return this.wasm;\n }\n\n private getUint8Memory(): Uint8Array {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n if (\n this.cachedUint8Memory === null ||\n this.cachedUint8Memory.byteLength === 0\n ) {\n this.cachedUint8Memory = new Uint8Array(this.wasm.memory.buffer);\n }\n return this.cachedUint8Memory;\n }\n\n private getDataViewMemory(): DataView {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n if (\n this.cachedDataViewMemory === null ||\n this.cachedDataViewMemory.buffer !== this.wasm.memory.buffer\n ) {\n this.cachedDataViewMemory = new DataView(this.wasm.memory.buffer);\n }\n return this.cachedDataViewMemory;\n }\n\n private encodeString(\n arg: string,\n view: Uint8Array,\n ): { read: number; written: number } {\n if (arg.length === 0) {\n return { read: 0, written: 0 };\n }\n\n const buf = this.textEncoder.encode(arg);\n view.set(buf);\n return { read: arg.length, written: buf.length };\n }\n\n private passStringToWasm(\n arg: string,\n malloc: (a: number, b: number) => number,\n realloc?: (a: number, b: number, c: number, d: number) => number,\n ): number {\n if (realloc === undefined) {\n const buf = this.textEncoder.encode(arg);\n const ptr = malloc(buf.length, 1);\n const view = this.getUint8Memory();\n view.set(buf, ptr);\n this.WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = this.textEncoder.encode(arg).length;\n let ptr = malloc(len, 1);\n\n const mem = this.getUint8Memory();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7f) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(\n ptr,\n len,\n (len = offset + this.textEncoder.encode(arg).length * 3),\n 1,\n );\n const view = this.getUint8Memory().subarray(ptr + offset, ptr + len);\n const ret = this.encodeString(arg, view);\n\n offset += ret.written;\n }\n\n this.WASM_VECTOR_LEN = offset;\n return ptr;\n }\n\n private getStringFromWasm(ptr: number, len: number): string {\n ptr = ptr >>> 0;\n return this.textDecoder.decode(\n this.getUint8Memory().subarray(ptr, ptr + len),\n );\n }\n\n createWasmFunction(\n wasmFn: (...args: any[]) => any,\n ): (...args: string[]) => string {\n if (!this.wasm) {\n throw new Error('WASM not initialized');\n }\n\n return (...args: string[]): string => {\n const retptr = this.wasm!.__wbindgen_add_to_stack_pointer(-16);\n let deferred: [number, number] = [0, 0];\n\n try {\n const ptrLenPairs = args.map(arg => {\n const ptr = this.passStringToWasm(\n arg,\n this.wasm!.__wbindgen_malloc,\n this.wasm!.__wbindgen_realloc,\n );\n return [ptr, this.WASM_VECTOR_LEN];\n });\n\n const wasmArgs = [retptr, ...ptrLenPairs.flat()];\n\n wasmFn.apply(this.wasm, wasmArgs);\n\n const r0 = this.getDataViewMemory().getInt32(retptr + 4 * 0, true);\n const r1 = this.getDataViewMemory().getInt32(retptr + 4 * 1, true);\n deferred = [r0, r1];\n\n return this.getStringFromWasm(r0, r1);\n } finally {\n this.wasm!.__wbindgen_add_to_stack_pointer(16);\n this.wasm!.__wbindgen_free(deferred[0], deferred[1], 1);\n }\n };\n }\n\n async initWasm(wasmBytes: BufferSource): Promise<WasmExports> {\n const bridge = this;\n const imports = {\n __wbindgen_placeholder__: {\n __wbindgen_throw: function (ptr: number, len: number) {\n const message = bridge.getStringFromWasm(ptr, len);\n bridge.logger.error(`WASM error: ${message}`);\n throw new Error(message);\n },\n },\n };\n\n try {\n this.logger.debug('Compiling WASM module');\n const wasmModule = await WebAssembly.compile(wasmBytes);\n this.logger.debug('Instantiating WASM module');\n const wasmInstance = await WebAssembly.instantiate(wasmModule, imports);\n this.wasm = wasmInstance.exports as WasmExports;\n this.logger.info('WASM module initialized successfully');\n return this.wasm;\n } catch (error) {\n this.logger.error('Failed to initialize WASM module', error);\n throw error;\n }\n }\n\n createStateData(wasmConfig: WASMConfig, stateData: Record<string, any> = {}) {\n let dynamicStateData: Record<string, any> = {};\n\n if (wasmConfig?.c?.inputType?.stateData) {\n // Special case: if we have latestRoundData with all the fields we need\n if (\n stateData.latestRoundData &&\n Object.keys(wasmConfig.c.inputType.stateData).every(\n key => key in stateData.latestRoundData,\n )\n ) {\n // Return the nested structure for Chainlink\n dynamicStateData.latestRoundData = {};\n Object.entries(wasmConfig.c.inputType.stateData).forEach(([key, _]) => {\n dynamicStateData.latestRoundData[key] = String(\n stateData.latestRoundData[key],\n );\n });\n } else {\n // Handle flat structure (launchpage case)\n Object.entries(wasmConfig.c.inputType.stateData).forEach(\n ([key, type]) => {\n const result = stateData[key];\n if (\n result &&\n typeof result === 'object' &&\n 'values' in result &&\n result.values.length > 0\n ) {\n dynamicStateData[key] = String(result.values[0]);\n } else {\n dynamicStateData[key] = this.getDefaultValueForType(\n type as string,\n );\n }\n },\n );\n }\n }\n return dynamicStateData;\n }\n\n private getDefaultValueForType(type: string): string {\n if (\n type.startsWith('uint') ||\n type.startsWith('int') ||\n type === 'number'\n ) {\n return '0';\n } else if (type === 'bool') {\n return 'false';\n } else {\n return '';\n }\n }\n\n executeWasm(stateData: Record<string, any>, messages: BaseMessage[]) {\n if (!this.wasm) {\n this.logger.error('WASM not initialized');\n throw new Error('WASM not initialized');\n }\n\n try {\n this.logger.debug('Executing WASM with stateData', stateData);\n const fn = this.createWasmFunction(this.wasmInstance.process_state);\n return fn(JSON.stringify(stateData), JSON.stringify(messages));\n } catch (error) {\n this.logger.error('Error executing WASM', error);\n throw error;\n }\n }\n\n getParams(): string {\n const fn = this.createWasmFunction(this.wasmInstance.get_params);\n return fn();\n }\n}\n"],"names":["ptr"],"mappings":"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"}
|