@hashgraphonline/standards-sdk 0.0.174 → 0.0.176
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/{index-xQfUfn20.cjs → index-DBI7RYzm.cjs} +19 -19
- package/dist/cjs/{index-xQfUfn20.cjs.map → index-DBI7RYzm.cjs.map} +1 -1
- package/dist/cjs/{index-DNOBUKZd-g0uNa1rQ.cjs → index-DNOBUKZd-PuaZE8zI.cjs} +2 -2
- package/dist/cjs/{index-DNOBUKZd-g0uNa1rQ.cjs.map → index-DNOBUKZd-PuaZE8zI.cjs.map} +1 -1
- package/dist/cjs/standards-sdk.cjs +1 -1
- package/dist/cjs/{standards-sdk.es47-LpJXpYet-fj1bqMZs.cjs → standards-sdk.es47-LpJXpYet-Dn0a_M7H.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es47-LpJXpYet-fj1bqMZs.cjs.map → standards-sdk.es47-LpJXpYet-Dn0a_M7H.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es48-PT6ZHlCU-vkSluOOc.cjs → standards-sdk.es48-PT6ZHlCU-CpnblkfW.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es48-PT6ZHlCU-vkSluOOc.cjs.map → standards-sdk.es48-PT6ZHlCU-CpnblkfW.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es49-BoFc-ELK-DC0zfqT0.cjs → standards-sdk.es49-BoFc-ELK-AFqdqMBQ.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es49-BoFc-ELK-DC0zfqT0.cjs.map → standards-sdk.es49-BoFc-ELK-AFqdqMBQ.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es50-miBtNmtl-B2MpsQnf.cjs → standards-sdk.es50-miBtNmtl-BXhMfUtd.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es50-miBtNmtl-B2MpsQnf.cjs.map → standards-sdk.es50-miBtNmtl-BXhMfUtd.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es51-rS2UvvV5-CRkd1bF-.cjs → standards-sdk.es51-rS2UvvV5-Bh2x7xrp.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es51-rS2UvvV5-CRkd1bF-.cjs.map → standards-sdk.es51-rS2UvvV5-Bh2x7xrp.cjs.map} +1 -1
- package/dist/cjs/{standards-sdk.es52-D-lvSMBY-DdUJIqZX.cjs → standards-sdk.es52-D-lvSMBY-DvI5ClIb.cjs} +2 -2
- package/dist/cjs/{standards-sdk.es52-D-lvSMBY-DdUJIqZX.cjs.map → standards-sdk.es52-D-lvSMBY-DvI5ClIb.cjs.map} +1 -1
- package/dist/cjs/utils/parsers/crypto-parser.d.ts +37 -0
- package/dist/cjs/utils/parsers/crypto-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/file-parser.d.ts +46 -0
- package/dist/cjs/utils/parsers/file-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/hcs-parser.d.ts +10 -0
- package/dist/cjs/utils/parsers/hcs-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/hts-parser.d.ts +23 -5
- package/dist/cjs/utils/parsers/hts-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/parser-utils.d.ts +11 -0
- package/dist/cjs/utils/parsers/parser-utils.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/schedule-parser.d.ts +56 -11
- package/dist/cjs/utils/parsers/schedule-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/scs-parser.d.ts +51 -0
- package/dist/cjs/utils/parsers/scs-parser.d.ts.map +1 -1
- package/dist/cjs/utils/parsers/util-parser.d.ts +72 -1
- package/dist/cjs/utils/parsers/util-parser.d.ts.map +1 -1
- package/dist/cjs/utils/transaction-parser-types.d.ts +60 -0
- package/dist/cjs/utils/transaction-parser-types.d.ts.map +1 -1
- package/dist/cjs/utils/transaction-parser.d.ts +16 -14
- package/dist/cjs/utils/transaction-parser.d.ts.map +1 -1
- package/dist/es/standards-sdk.es35.js +388 -387
- package/dist/es/standards-sdk.es35.js.map +1 -1
- package/dist/es/standards-sdk.es36.js.map +1 -1
- package/dist/es/standards-sdk.es39.js +385 -18
- package/dist/es/standards-sdk.es39.js.map +1 -1
- package/dist/es/standards-sdk.es40.js +209 -86
- package/dist/es/standards-sdk.es40.js.map +1 -1
- package/dist/es/standards-sdk.es50.js +55 -0
- package/dist/es/standards-sdk.es50.js.map +1 -1
- package/dist/es/standards-sdk.es51.js +249 -1
- package/dist/es/standards-sdk.es51.js.map +1 -1
- package/dist/es/standards-sdk.es52.js +90 -0
- package/dist/es/standards-sdk.es52.js.map +1 -1
- package/dist/es/standards-sdk.es53.js +268 -9
- package/dist/es/standards-sdk.es53.js.map +1 -1
- package/dist/es/standards-sdk.es54.js +306 -0
- package/dist/es/standards-sdk.es54.js.map +1 -1
- package/dist/es/standards-sdk.es55.js +32 -0
- package/dist/es/standards-sdk.es55.js.map +1 -1
- package/dist/es/utils/parsers/crypto-parser.d.ts +37 -0
- package/dist/es/utils/parsers/crypto-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/file-parser.d.ts +46 -0
- package/dist/es/utils/parsers/file-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/hcs-parser.d.ts +10 -0
- package/dist/es/utils/parsers/hcs-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/hts-parser.d.ts +23 -5
- package/dist/es/utils/parsers/hts-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/parser-utils.d.ts +11 -0
- package/dist/es/utils/parsers/parser-utils.d.ts.map +1 -1
- package/dist/es/utils/parsers/schedule-parser.d.ts +56 -11
- package/dist/es/utils/parsers/schedule-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/scs-parser.d.ts +51 -0
- package/dist/es/utils/parsers/scs-parser.d.ts.map +1 -1
- package/dist/es/utils/parsers/util-parser.d.ts +72 -1
- package/dist/es/utils/parsers/util-parser.d.ts.map +1 -1
- package/dist/es/utils/transaction-parser-types.d.ts +60 -0
- package/dist/es/utils/transaction-parser-types.d.ts.map +1 -1
- package/dist/es/utils/transaction-parser.d.ts +16 -14
- package/dist/es/utils/transaction-parser.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/utils/__tests__/hts-parser.test.d.ts +0 -2
- package/dist/cjs/utils/__tests__/hts-parser.test.d.ts.map +0 -1
- package/dist/cjs/utils/__tests__/schedule-parser.test.d.ts +0 -2
- package/dist/cjs/utils/__tests__/schedule-parser.test.d.ts.map +0 -1
- package/dist/cjs/utils/__tests__/token-create-parsing.test.d.ts +0 -2
- package/dist/cjs/utils/__tests__/token-create-parsing.test.d.ts.map +0 -1
- package/dist/cjs/utils/__tests__/transaction-parser.test.d.ts +0 -2
- package/dist/cjs/utils/__tests__/transaction-parser.test.d.ts.map +0 -1
- package/dist/es/utils/__tests__/hts-parser.test.d.ts +0 -2
- package/dist/es/utils/__tests__/hts-parser.test.d.ts.map +0 -1
- package/dist/es/utils/__tests__/schedule-parser.test.d.ts +0 -2
- package/dist/es/utils/__tests__/schedule-parser.test.d.ts.map +0 -1
- package/dist/es/utils/__tests__/token-create-parsing.test.d.ts +0 -2
- package/dist/es/utils/__tests__/token-create-parsing.test.d.ts.map +0 -1
- package/dist/es/utils/__tests__/transaction-parser.test.d.ts +0 -2
- package/dist/es/utils/__tests__/transaction-parser.test.d.ts.map +0 -1
|
@@ -86,91 +86,100 @@ class TransactionParser {
|
|
|
86
86
|
return fallbackResult;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* Parse a Transaction object directly
|
|
90
|
-
* This method
|
|
89
|
+
* Parse a Transaction object directly using unified delegation approach
|
|
90
|
+
* This method delegates to specialized parsers for clean separation of concerns
|
|
91
91
|
*
|
|
92
92
|
* @param transaction - The Transaction object to parse
|
|
93
|
+
* @param originalBytes - The original transaction bytes (optional, for protobuf parsing)
|
|
93
94
|
* @param options - Parsing options
|
|
94
95
|
* @returns Parsed transaction data
|
|
95
96
|
*/
|
|
96
|
-
static parseTransactionObject(transaction, options = {}) {
|
|
97
|
+
static parseTransactionObject(transaction, originalBytes, options = {}) {
|
|
97
98
|
try {
|
|
98
99
|
const metadata = this.extractTransactionMetadata(transaction);
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
100
|
+
const htsResult = HTSParser.parseFromTransactionObject(transaction);
|
|
101
|
+
const cryptoResult = CryptoParser.parseFromTransactionObject(transaction);
|
|
102
|
+
const hcsResult = HCSParser.parseFromTransactionObject(transaction);
|
|
103
|
+
const fileResult = FileParser.parseFromTransactionObject(transaction);
|
|
104
|
+
const scsResult = SCSParser.parseFromTransactionObject(transaction);
|
|
105
|
+
const scheduleResult = ScheduleParser.parseFromTransactionObject(transaction);
|
|
106
|
+
const utilResult = UtilParser.parseFromTransactionObject(transaction);
|
|
107
|
+
const results = [
|
|
108
|
+
htsResult,
|
|
109
|
+
cryptoResult,
|
|
110
|
+
hcsResult,
|
|
111
|
+
fileResult,
|
|
112
|
+
scsResult,
|
|
113
|
+
scheduleResult,
|
|
114
|
+
utilResult
|
|
115
|
+
];
|
|
116
|
+
const primaryResult = results.find((result2) => result2.type && result2.type !== "UNKNOWN") || {};
|
|
117
|
+
let finalType = "UNKNOWN";
|
|
118
|
+
let finalHumanReadableType = "Unknown Transaction";
|
|
119
|
+
let parsedTokenCreation;
|
|
120
|
+
let protoParsingResult = {};
|
|
121
|
+
if (originalBytes || transaction.toBytes) {
|
|
122
|
+
try {
|
|
123
|
+
const bytesToParse = originalBytes || transaction.toBytes();
|
|
124
|
+
const decoded = proto.TransactionList.decode(bytesToParse);
|
|
125
|
+
if (decoded.transactionList && decoded.transactionList.length > 0) {
|
|
126
|
+
const tx = decoded.transactionList[0];
|
|
127
|
+
if (tx.bodyBytes && tx.bodyBytes.length > 0) {
|
|
128
|
+
const txBody = proto.TransactionBody.decode(tx.bodyBytes);
|
|
129
|
+
const typeResult = this.detectTransactionTypeFromBody(txBody);
|
|
130
|
+
finalType = typeResult.type;
|
|
131
|
+
finalHumanReadableType = typeResult.humanReadableType;
|
|
132
|
+
protoParsingResult = this.parseTransactionBodyDetails(
|
|
133
|
+
txBody,
|
|
134
|
+
finalType
|
|
135
|
+
);
|
|
136
|
+
if (protoParsingResult.tokenCreation) {
|
|
137
|
+
parsedTokenCreation = protoParsingResult.tokenCreation;
|
|
138
|
+
}
|
|
139
|
+
} else if (tx.signedTransactionBytes && tx.signedTransactionBytes.length > 0) {
|
|
140
|
+
const signedTx = proto.SignedTransaction.decode(
|
|
141
|
+
tx.signedTransactionBytes
|
|
142
|
+
);
|
|
143
|
+
if (signedTx.bodyBytes) {
|
|
144
|
+
const txBody = proto.TransactionBody.decode(signedTx.bodyBytes);
|
|
145
|
+
const typeResult = this.detectTransactionTypeFromBody(txBody);
|
|
146
|
+
finalType = typeResult.type;
|
|
147
|
+
finalHumanReadableType = typeResult.humanReadableType;
|
|
148
|
+
protoParsingResult = this.parseTransactionBodyDetails(
|
|
149
|
+
txBody,
|
|
150
|
+
finalType
|
|
151
|
+
);
|
|
152
|
+
if (protoParsingResult.tokenCreation) {
|
|
153
|
+
parsedTokenCreation = protoParsingResult.tokenCreation;
|
|
154
|
+
}
|
|
147
155
|
}
|
|
148
156
|
}
|
|
149
157
|
}
|
|
158
|
+
} catch (protoError) {
|
|
150
159
|
}
|
|
151
|
-
} catch (protoError) {
|
|
152
|
-
console.warn("Failed to parse transaction protobuf:", protoError);
|
|
153
160
|
}
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
if (finalType === "UNKNOWN" && primaryResult.type) {
|
|
162
|
+
finalType = primaryResult.type;
|
|
163
|
+
finalHumanReadableType = primaryResult.humanReadableType || finalHumanReadableType;
|
|
157
164
|
}
|
|
158
165
|
const result = {
|
|
159
|
-
type,
|
|
160
|
-
humanReadableType,
|
|
166
|
+
type: finalType,
|
|
167
|
+
humanReadableType: finalHumanReadableType,
|
|
168
|
+
transfers: [],
|
|
169
|
+
tokenTransfers: [],
|
|
161
170
|
...metadata,
|
|
162
|
-
...
|
|
163
|
-
...scheduleData,
|
|
171
|
+
...primaryResult,
|
|
164
172
|
raw: options.includeRaw ? transaction._transactionBody || {} : void 0
|
|
165
173
|
};
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
result.
|
|
174
|
+
this.mergeProtoParsingResults(
|
|
175
|
+
result,
|
|
176
|
+
protoParsingResult,
|
|
177
|
+
htsResult,
|
|
178
|
+
transaction,
|
|
179
|
+
originalBytes
|
|
180
|
+
);
|
|
181
|
+
result.transfers = cryptoResult.transfers || result.transfers || [];
|
|
182
|
+
result.tokenTransfers = cryptoResult.tokenTransfers || result.tokenTransfers || [];
|
|
174
183
|
return result;
|
|
175
184
|
} catch (error) {
|
|
176
185
|
return {
|
|
@@ -370,6 +379,109 @@ class TransactionParser {
|
|
|
370
379
|
};
|
|
371
380
|
}
|
|
372
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Detect transaction type and human-readable type from transaction body protobuf
|
|
384
|
+
* Centralized method to eliminate duplication across parsing methods
|
|
385
|
+
*/
|
|
386
|
+
static detectTransactionTypeFromBody(txBody) {
|
|
387
|
+
if (txBody.tokenCreation) {
|
|
388
|
+
return { type: "TOKENCREATE", humanReadableType: "Token Creation" };
|
|
389
|
+
} else if (txBody.tokenAirdrop) {
|
|
390
|
+
return { type: "TOKENAIRDROP", humanReadableType: "Token Airdrop" };
|
|
391
|
+
} else if (txBody.cryptoTransfer) {
|
|
392
|
+
return { type: "CRYPTOTRANSFER", humanReadableType: "Crypto Transfer" };
|
|
393
|
+
} else if (txBody.consensusSubmitMessage) {
|
|
394
|
+
return {
|
|
395
|
+
type: "CONSENSUSSUBMITMESSAGE",
|
|
396
|
+
humanReadableType: "Submit Message"
|
|
397
|
+
};
|
|
398
|
+
} else if (txBody.contractCall) {
|
|
399
|
+
return { type: "CONTRACTCALL", humanReadableType: "Contract Call" };
|
|
400
|
+
} else if (txBody.cryptoCreateAccount) {
|
|
401
|
+
return { type: "ACCOUNTCREATE", humanReadableType: "Account Creation" };
|
|
402
|
+
} else if (txBody.cryptoUpdateAccount) {
|
|
403
|
+
return { type: "ACCOUNTUPDATE", humanReadableType: "Account Update" };
|
|
404
|
+
} else if (txBody.cryptoDelete) {
|
|
405
|
+
return { type: "ACCOUNTDELETE", humanReadableType: "Account Deletion" };
|
|
406
|
+
} else if (txBody.cryptoApproveAllowance) {
|
|
407
|
+
return {
|
|
408
|
+
type: "APPROVEALLOWANCE",
|
|
409
|
+
humanReadableType: "Approve Allowance"
|
|
410
|
+
};
|
|
411
|
+
} else if (txBody.cryptoDeleteAllowance) {
|
|
412
|
+
return { type: "DELETEALLOWANCE", humanReadableType: "Delete Allowance" };
|
|
413
|
+
} else if (txBody.tokenMint) {
|
|
414
|
+
return { type: "TOKENMINT", humanReadableType: "Token Mint" };
|
|
415
|
+
} else if (txBody.tokenBurn) {
|
|
416
|
+
return { type: "TOKENBURN", humanReadableType: "Token Burn" };
|
|
417
|
+
} else if (txBody.tokenUpdate) {
|
|
418
|
+
return { type: "TOKENUPDATE", humanReadableType: "Token Update" };
|
|
419
|
+
} else if (txBody.tokenDeletion) {
|
|
420
|
+
return { type: "TOKENDELETE", humanReadableType: "Token Deletion" };
|
|
421
|
+
} else if (txBody.tokenAssociate) {
|
|
422
|
+
return { type: "TOKENASSOCIATE", humanReadableType: "Token Association" };
|
|
423
|
+
} else if (txBody.tokenDissociate) {
|
|
424
|
+
return {
|
|
425
|
+
type: "TOKENDISSOCIATE",
|
|
426
|
+
humanReadableType: "Token Dissociation"
|
|
427
|
+
};
|
|
428
|
+
} else if (txBody.tokenFreeze) {
|
|
429
|
+
return { type: "TOKENFREEZE", humanReadableType: "Token Freeze" };
|
|
430
|
+
} else if (txBody.tokenUnfreeze) {
|
|
431
|
+
return { type: "TOKENUNFREEZE", humanReadableType: "Token Unfreeze" };
|
|
432
|
+
} else if (txBody.tokenGrantKyc) {
|
|
433
|
+
return { type: "TOKENGRANTKYC", humanReadableType: "Token Grant KYC" };
|
|
434
|
+
} else if (txBody.tokenRevokeKyc) {
|
|
435
|
+
return { type: "TOKENREVOKEKYC", humanReadableType: "Token Revoke KYC" };
|
|
436
|
+
} else if (txBody.tokenWipe) {
|
|
437
|
+
return { type: "TOKENWIPE", humanReadableType: "Token Wipe" };
|
|
438
|
+
} else if (txBody.tokenPause) {
|
|
439
|
+
return { type: "TOKENPAUSE", humanReadableType: "Token Pause" };
|
|
440
|
+
} else if (txBody.tokenUnpause) {
|
|
441
|
+
return { type: "TOKENUNPAUSE", humanReadableType: "Token Unpause" };
|
|
442
|
+
} else if (txBody.tokenFeeScheduleUpdate) {
|
|
443
|
+
return {
|
|
444
|
+
type: "TOKENFEESCHEDULEUPDATE",
|
|
445
|
+
humanReadableType: "Token Fee Schedule Update"
|
|
446
|
+
};
|
|
447
|
+
} else if (txBody.fileCreate) {
|
|
448
|
+
return { type: "FILECREATE", humanReadableType: "File Creation" };
|
|
449
|
+
} else if (txBody.fileUpdate) {
|
|
450
|
+
return { type: "FILEUPDATE", humanReadableType: "File Update" };
|
|
451
|
+
} else if (txBody.fileDelete) {
|
|
452
|
+
return { type: "FILEDELETE", humanReadableType: "File Deletion" };
|
|
453
|
+
} else if (txBody.fileAppend) {
|
|
454
|
+
return { type: "FILEAPPEND", humanReadableType: "File Append" };
|
|
455
|
+
} else if (txBody.consensusCreateTopic) {
|
|
456
|
+
return { type: "TOPICCREATE", humanReadableType: "Topic Creation" };
|
|
457
|
+
} else if (txBody.consensusUpdateTopic) {
|
|
458
|
+
return { type: "TOPICUPDATE", humanReadableType: "Topic Update" };
|
|
459
|
+
} else if (txBody.consensusDeleteTopic) {
|
|
460
|
+
return { type: "TOPICDELETE", humanReadableType: "Topic Deletion" };
|
|
461
|
+
} else if (txBody.contractCreateInstance) {
|
|
462
|
+
return { type: "CONTRACTCREATE", humanReadableType: "Contract Creation" };
|
|
463
|
+
} else if (txBody.contractUpdateInstance) {
|
|
464
|
+
return { type: "CONTRACTUPDATE", humanReadableType: "Contract Update" };
|
|
465
|
+
} else if (txBody.contractDeleteInstance) {
|
|
466
|
+
return { type: "CONTRACTDELETE", humanReadableType: "Contract Deletion" };
|
|
467
|
+
} else if (txBody.scheduleCreate) {
|
|
468
|
+
return { type: "SCHEDULECREATE", humanReadableType: "Schedule Creation" };
|
|
469
|
+
} else if (txBody.scheduleSign) {
|
|
470
|
+
return { type: "SCHEDULESIGN", humanReadableType: "Schedule Sign" };
|
|
471
|
+
} else if (txBody.scheduleDelete) {
|
|
472
|
+
return { type: "SCHEDULEDELETE", humanReadableType: "Schedule Deletion" };
|
|
473
|
+
} else if (txBody.utilPrng) {
|
|
474
|
+
return { type: "PRNG", humanReadableType: "Pseudo Random Number" };
|
|
475
|
+
} else if (txBody.freeze) {
|
|
476
|
+
return { type: "FREEZE", humanReadableType: "Network Freeze" };
|
|
477
|
+
} else if (txBody.systemDelete) {
|
|
478
|
+
return { type: "SYSTEMDELETE", humanReadableType: "System Delete" };
|
|
479
|
+
} else if (txBody.systemUndelete) {
|
|
480
|
+
return { type: "SYSTEMUNDELETE", humanReadableType: "System Undelete" };
|
|
481
|
+
} else {
|
|
482
|
+
return { type: "UNKNOWN", humanReadableType: "Unknown Transaction" };
|
|
483
|
+
}
|
|
484
|
+
}
|
|
373
485
|
/**
|
|
374
486
|
* Parse details from a complete schedule response
|
|
375
487
|
* @param scheduleResponse - The schedule response to parse
|
|
@@ -400,79 +512,42 @@ class TransactionParser {
|
|
|
400
512
|
* @returns The type of the transaction
|
|
401
513
|
*/
|
|
402
514
|
static getTransactionType(txBody) {
|
|
403
|
-
|
|
404
|
-
if (txBody.
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
transactionType = "contractDelete";
|
|
440
|
-
} else if (txBody.tokenCreation) {
|
|
441
|
-
transactionType = "tokenCreate";
|
|
442
|
-
} else if (txBody.tokenUpdate) {
|
|
443
|
-
transactionType = "tokenUpdate";
|
|
444
|
-
} else if (txBody.tokenDeletion) {
|
|
445
|
-
transactionType = "tokenDelete";
|
|
446
|
-
} else if (txBody.tokenAssociate) {
|
|
447
|
-
transactionType = "tokenAssociate";
|
|
448
|
-
} else if (txBody.tokenDissociate) {
|
|
449
|
-
transactionType = "tokenDissociate";
|
|
450
|
-
} else if (txBody.tokenMint) {
|
|
451
|
-
transactionType = "tokenMint";
|
|
452
|
-
} else if (txBody.tokenBurn) {
|
|
453
|
-
transactionType = "tokenBurn";
|
|
454
|
-
} else if (txBody.tokenFeeScheduleUpdate) {
|
|
455
|
-
transactionType = "tokenFeeScheduleUpdate";
|
|
456
|
-
} else if (txBody.tokenFreeze) {
|
|
457
|
-
transactionType = "tokenFreeze";
|
|
458
|
-
} else if (txBody.tokenUnfreeze) {
|
|
459
|
-
transactionType = "tokenUnfreeze";
|
|
460
|
-
} else if (txBody.tokenGrantKyc) {
|
|
461
|
-
transactionType = "tokenGrantKyc";
|
|
462
|
-
} else if (txBody.tokenRevokeKyc) {
|
|
463
|
-
transactionType = "tokenRevokeKyc";
|
|
464
|
-
} else if (txBody.tokenPause) {
|
|
465
|
-
transactionType = "tokenPause";
|
|
466
|
-
} else if (txBody.tokenUnpause) {
|
|
467
|
-
transactionType = "tokenUnpause";
|
|
468
|
-
} else if (txBody.tokenWipe) {
|
|
469
|
-
transactionType = "tokenWipe";
|
|
470
|
-
} else if (txBody.tokenAirdrop) {
|
|
471
|
-
transactionType = "tokenAirdrop";
|
|
472
|
-
} else if (txBody.utilPrng) {
|
|
473
|
-
transactionType = "utilPrng";
|
|
474
|
-
}
|
|
475
|
-
return transactionType;
|
|
515
|
+
if (txBody.tokenCreation) return "tokenCreate";
|
|
516
|
+
if (txBody.tokenAirdrop) return "tokenAirdrop";
|
|
517
|
+
if (txBody.cryptoTransfer) return "cryptoTransfer";
|
|
518
|
+
if (txBody.consensusSubmitMessage) return "consensusSubmitMessage";
|
|
519
|
+
if (txBody.contractCall) return "contractCall";
|
|
520
|
+
if (txBody.cryptoCreateAccount) return "cryptoCreateAccount";
|
|
521
|
+
if (txBody.cryptoUpdateAccount) return "cryptoUpdateAccount";
|
|
522
|
+
if (txBody.cryptoApproveAllowance) return "cryptoApproveAllowance";
|
|
523
|
+
if (txBody.cryptoDeleteAllowance) return "cryptoDeleteAllowance";
|
|
524
|
+
if (txBody.cryptoDelete) return "cryptoDelete";
|
|
525
|
+
if (txBody.consensusCreateTopic) return "consensusCreateTopic";
|
|
526
|
+
if (txBody.consensusUpdateTopic) return "consensusUpdateTopic";
|
|
527
|
+
if (txBody.consensusDeleteTopic) return "consensusDeleteTopic";
|
|
528
|
+
if (txBody.fileCreate) return "fileCreate";
|
|
529
|
+
if (txBody.fileAppend) return "fileAppend";
|
|
530
|
+
if (txBody.fileUpdate) return "fileUpdate";
|
|
531
|
+
if (txBody.fileDelete) return "fileDelete";
|
|
532
|
+
if (txBody.contractCreateInstance) return "contractCreate";
|
|
533
|
+
if (txBody.contractUpdateInstance) return "contractUpdate";
|
|
534
|
+
if (txBody.contractDeleteInstance) return "contractDelete";
|
|
535
|
+
if (txBody.tokenUpdate) return "tokenUpdate";
|
|
536
|
+
if (txBody.tokenDeletion) return "tokenDelete";
|
|
537
|
+
if (txBody.tokenAssociate) return "tokenAssociate";
|
|
538
|
+
if (txBody.tokenDissociate) return "tokenDissociate";
|
|
539
|
+
if (txBody.tokenMint) return "tokenMint";
|
|
540
|
+
if (txBody.tokenBurn) return "tokenBurn";
|
|
541
|
+
if (txBody.tokenFeeScheduleUpdate) return "tokenFeeScheduleUpdate";
|
|
542
|
+
if (txBody.tokenFreeze) return "tokenFreeze";
|
|
543
|
+
if (txBody.tokenUnfreeze) return "tokenUnfreeze";
|
|
544
|
+
if (txBody.tokenGrantKyc) return "tokenGrantKyc";
|
|
545
|
+
if (txBody.tokenRevokeKyc) return "tokenRevokeKyc";
|
|
546
|
+
if (txBody.tokenPause) return "tokenPause";
|
|
547
|
+
if (txBody.tokenUnpause) return "tokenUnpause";
|
|
548
|
+
if (txBody.tokenWipe) return "tokenWipe";
|
|
549
|
+
if (txBody.utilPrng) return "utilPrng";
|
|
550
|
+
return "unknown";
|
|
476
551
|
}
|
|
477
552
|
/**
|
|
478
553
|
* Convert technical transaction type to human-readable format
|
|
@@ -868,148 +943,129 @@ class TransactionParser {
|
|
|
868
943
|
return this.decodeTransactionBytes(transactionBytes);
|
|
869
944
|
}
|
|
870
945
|
/**
|
|
871
|
-
* Parse transaction bytes into structured data
|
|
946
|
+
* Parse transaction bytes into structured data using thin orchestration
|
|
947
|
+
* Delegates to specialized parsers for clean separation of concerns
|
|
872
948
|
*/
|
|
873
949
|
static async parseTransaction(transactionBytes, options = {}) {
|
|
874
950
|
try {
|
|
875
951
|
const bytes = this.decodeTransactionBytes(transactionBytes);
|
|
876
952
|
const transaction = Transaction.fromBytes(bytes);
|
|
877
953
|
const metadata = this.extractTransactionMetadataEnhanced(transaction);
|
|
878
|
-
const
|
|
879
|
-
const
|
|
880
|
-
const
|
|
881
|
-
const
|
|
882
|
-
const
|
|
883
|
-
const scheduleResult = ScheduleParser.
|
|
954
|
+
const htsResult = HTSParser.parseFromTransactionObject(transaction);
|
|
955
|
+
const cryptoResult = CryptoParser.parseFromTransactionObject(transaction);
|
|
956
|
+
const hcsResult = HCSParser.parseFromTransactionObject(transaction);
|
|
957
|
+
const fileResult = FileParser.parseFromTransactionObject(transaction);
|
|
958
|
+
const scsResult = SCSParser.parseFromTransactionObject(transaction);
|
|
959
|
+
const scheduleResult = ScheduleParser.parseFromTransactionObject(transaction);
|
|
960
|
+
const utilResult = UtilParser.parseFromTransactionObject(transaction);
|
|
961
|
+
const results = [
|
|
962
|
+
htsResult,
|
|
963
|
+
cryptoResult,
|
|
964
|
+
hcsResult,
|
|
965
|
+
fileResult,
|
|
966
|
+
scsResult,
|
|
967
|
+
scheduleResult,
|
|
968
|
+
utilResult
|
|
969
|
+
];
|
|
970
|
+
const primaryResult = results.find((result2) => result2.type && result2.type !== "UNKNOWN") || {};
|
|
884
971
|
let transactionType = "UNKNOWN";
|
|
885
972
|
let humanReadableType = "Unknown Transaction";
|
|
973
|
+
let parsedTokenCreation;
|
|
886
974
|
try {
|
|
887
|
-
const
|
|
888
|
-
const decoded = proto.TransactionList.decode(transactionBytes2);
|
|
975
|
+
const decoded = proto.TransactionList.decode(bytes);
|
|
889
976
|
if (decoded.transactionList && decoded.transactionList.length > 0) {
|
|
890
977
|
const tx = decoded.transactionList[0];
|
|
891
|
-
if (tx.
|
|
978
|
+
if (tx.bodyBytes && tx.bodyBytes.length > 0) {
|
|
979
|
+
const txBody = proto.TransactionBody.decode(tx.bodyBytes);
|
|
980
|
+
const typeResult = this.detectTransactionTypeFromBody(txBody);
|
|
981
|
+
transactionType = typeResult.type;
|
|
982
|
+
humanReadableType = typeResult.humanReadableType;
|
|
983
|
+
const protoParsingResult = this.parseTransactionBodyDetails(
|
|
984
|
+
txBody,
|
|
985
|
+
transactionType
|
|
986
|
+
);
|
|
987
|
+
if (protoParsingResult.tokenCreation) {
|
|
988
|
+
parsedTokenCreation = protoParsingResult.tokenCreation;
|
|
989
|
+
}
|
|
990
|
+
} else if (tx.signedTransactionBytes && tx.signedTransactionBytes.length > 0) {
|
|
892
991
|
const signedTx = proto.SignedTransaction.decode(
|
|
893
992
|
tx.signedTransactionBytes
|
|
894
993
|
);
|
|
895
994
|
if (signedTx.bodyBytes) {
|
|
896
995
|
const txBody = proto.TransactionBody.decode(signedTx.bodyBytes);
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
} else if (txBody.consensusSubmitMessage) {
|
|
907
|
-
transactionType = "CONSENSUSSUBMITMESSAGE";
|
|
908
|
-
humanReadableType = "Submit Message";
|
|
909
|
-
} else if (txBody.contractCall) {
|
|
910
|
-
transactionType = "CONTRACTCALL";
|
|
911
|
-
humanReadableType = "Contract Call";
|
|
912
|
-
} else if (txBody.cryptoCreateAccount) {
|
|
913
|
-
transactionType = "ACCOUNTCREATE";
|
|
914
|
-
humanReadableType = "Account Creation";
|
|
915
|
-
} else if (txBody.tokenMint) {
|
|
916
|
-
transactionType = "TOKENMINT";
|
|
917
|
-
humanReadableType = "Token Mint";
|
|
918
|
-
} else if (txBody.tokenBurn) {
|
|
919
|
-
transactionType = "TOKENBURN";
|
|
920
|
-
humanReadableType = "Token Burn";
|
|
921
|
-
} else if (txBody.tokenAssociate) {
|
|
922
|
-
transactionType = "TOKENASSOCIATE";
|
|
923
|
-
humanReadableType = "Token Association";
|
|
924
|
-
} else if (txBody.fileCreate) {
|
|
925
|
-
transactionType = "FILECREATE";
|
|
926
|
-
humanReadableType = "File Creation";
|
|
927
|
-
} else if (txBody.consensusCreateTopic) {
|
|
928
|
-
transactionType = "TOPICCREATE";
|
|
929
|
-
humanReadableType = "Topic Creation";
|
|
996
|
+
const typeResult = this.detectTransactionTypeFromBody(txBody);
|
|
997
|
+
transactionType = typeResult.type;
|
|
998
|
+
humanReadableType = typeResult.humanReadableType;
|
|
999
|
+
const protoParsingResult = this.parseTransactionBodyDetails(
|
|
1000
|
+
txBody,
|
|
1001
|
+
transactionType
|
|
1002
|
+
);
|
|
1003
|
+
if (protoParsingResult.tokenCreation) {
|
|
1004
|
+
parsedTokenCreation = protoParsingResult.tokenCreation;
|
|
930
1005
|
}
|
|
931
1006
|
}
|
|
932
1007
|
}
|
|
933
1008
|
}
|
|
934
1009
|
} catch (protoError) {
|
|
935
|
-
console.warn("Failed to parse transaction protobuf:", protoError);
|
|
936
|
-
}
|
|
937
|
-
if (transactionType === "UNKNOWN") {
|
|
938
|
-
transactionType = htsResult.type || scheduleResult.type || "UNKNOWN";
|
|
939
|
-
humanReadableType = htsResult.humanReadableType || scheduleResult.humanReadableType || "Unknown Transaction";
|
|
940
|
-
if (!transactionType || transactionType === "UNKNOWN") {
|
|
941
|
-
if (tokenCreation) {
|
|
942
|
-
transactionType = "TOKENCREATE";
|
|
943
|
-
humanReadableType = "Token Creation";
|
|
944
|
-
} else if (tokenAirdrop) {
|
|
945
|
-
transactionType = "TOKENAIRDROP";
|
|
946
|
-
humanReadableType = "Token Airdrop";
|
|
947
|
-
} else if (hbarTransfers.length > 0) {
|
|
948
|
-
transactionType = "CRYPTOTRANSFER";
|
|
949
|
-
humanReadableType = "HBAR Transfer";
|
|
950
|
-
} else if (tokenTransfers.length > 0) {
|
|
951
|
-
transactionType = "TOKENTRANSFER";
|
|
952
|
-
humanReadableType = "Token Transfer";
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
1010
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}));
|
|
961
|
-
const convertedTokenTransfers = tokenTransfers.flatMap(
|
|
962
|
-
(tokenGroup) => tokenGroup.transfers.map((transfer) => ({
|
|
963
|
-
tokenId: tokenGroup.tokenId,
|
|
964
|
-
accountId: transfer.accountId,
|
|
965
|
-
amount: transfer.amount
|
|
966
|
-
}))
|
|
967
|
-
);
|
|
1011
|
+
if (transactionType === "UNKNOWN" && primaryResult.type) {
|
|
1012
|
+
transactionType = primaryResult.type;
|
|
1013
|
+
humanReadableType = primaryResult.humanReadableType || "Unknown Transaction";
|
|
1014
|
+
}
|
|
968
1015
|
const result = {
|
|
969
1016
|
type: transactionType,
|
|
970
1017
|
humanReadableType,
|
|
971
|
-
transfers:
|
|
972
|
-
tokenTransfers:
|
|
1018
|
+
transfers: cryptoResult.transfers || [],
|
|
1019
|
+
tokenTransfers: cryptoResult.tokenTransfers || [],
|
|
973
1020
|
details: {
|
|
974
|
-
...metadata
|
|
975
|
-
transferCount: hbarTransfers.length + tokenTransfers.length
|
|
1021
|
+
...metadata
|
|
976
1022
|
},
|
|
977
|
-
memo: metadata.memo,
|
|
978
|
-
transactionId: metadata.transactionId,
|
|
979
|
-
nodeAccountIds: metadata.nodeAccountIds,
|
|
980
|
-
maxTransactionFee: metadata.maxTransactionFee,
|
|
981
|
-
validStart: metadata.validStart,
|
|
982
|
-
validDuration: metadata.validDuration,
|
|
1023
|
+
memo: typeof metadata.memo === "string" ? metadata.memo : void 0,
|
|
1024
|
+
transactionId: typeof metadata.transactionId === "string" ? metadata.transactionId : void 0,
|
|
1025
|
+
nodeAccountIds: Array.isArray(metadata.nodeAccountIds) ? metadata.nodeAccountIds : [],
|
|
1026
|
+
maxTransactionFee: typeof metadata.maxTransactionFee === "string" ? metadata.maxTransactionFee : void 0,
|
|
1027
|
+
validStart: typeof metadata.validStart === "string" ? metadata.validStart : void 0,
|
|
1028
|
+
validDuration: typeof metadata.validDuration === "string" ? metadata.validDuration : void 0,
|
|
1029
|
+
...primaryResult,
|
|
983
1030
|
raw: options.includeRaw ? {} : void 0
|
|
984
1031
|
};
|
|
985
|
-
if (
|
|
986
|
-
|
|
987
|
-
} else if (htsResult.type && transactionType !== "UNKNOWN") {
|
|
988
|
-
const {
|
|
989
|
-
type: htsType,
|
|
990
|
-
humanReadableType: htsHumanType,
|
|
991
|
-
...htsData
|
|
992
|
-
} = htsResult;
|
|
993
|
-
Object.assign(result, htsData);
|
|
994
|
-
}
|
|
995
|
-
if (scheduleResult.type && transactionType === "UNKNOWN") {
|
|
996
|
-
Object.assign(result, scheduleResult);
|
|
997
|
-
} else if (scheduleResult.type && transactionType !== "UNKNOWN") {
|
|
998
|
-
const {
|
|
999
|
-
type: scheduleType,
|
|
1000
|
-
humanReadableType: scheduleHumanType,
|
|
1001
|
-
...scheduleData
|
|
1002
|
-
} = scheduleResult;
|
|
1003
|
-
Object.assign(result, scheduleData);
|
|
1004
|
-
}
|
|
1005
|
-
if (transactionType === "TOKENCREATE" || tokenCreation) {
|
|
1006
|
-
const tokenCreationData = tokenCreation || this.extractTokenCreation(transaction);
|
|
1032
|
+
if (transactionType === "TOKENCREATE") {
|
|
1033
|
+
const tokenCreationData = parsedTokenCreation || htsResult.tokenCreation || HTSParser.extractTokenCreationFromTransaction(transaction);
|
|
1007
1034
|
if (tokenCreationData) {
|
|
1008
1035
|
result.tokenCreation = tokenCreationData;
|
|
1009
1036
|
}
|
|
1010
1037
|
}
|
|
1011
|
-
if (tokenAirdrop && !result.tokenAirdrop) {
|
|
1012
|
-
result.tokenAirdrop = tokenAirdrop;
|
|
1038
|
+
if (htsResult.tokenAirdrop && !result.tokenAirdrop) {
|
|
1039
|
+
result.tokenAirdrop = htsResult.tokenAirdrop;
|
|
1040
|
+
}
|
|
1041
|
+
if (transactionType === "TOKENAIRDROP" && !result.tokenAirdrop) {
|
|
1042
|
+
try {
|
|
1043
|
+
const buffer = Buffer.from(transactionBytes, "base64");
|
|
1044
|
+
const decoded = proto.TransactionList.decode(buffer);
|
|
1045
|
+
if (decoded.transactionList && decoded.transactionList.length > 0) {
|
|
1046
|
+
const tx = decoded.transactionList[0];
|
|
1047
|
+
let txBody = null;
|
|
1048
|
+
if (tx.bodyBytes && tx.bodyBytes.length > 0) {
|
|
1049
|
+
txBody = proto.TransactionBody.decode(tx.bodyBytes);
|
|
1050
|
+
} else if (tx.signedTransactionBytes && tx.signedTransactionBytes.length > 0) {
|
|
1051
|
+
const signedTx = proto.SignedTransaction.decode(
|
|
1052
|
+
tx.signedTransactionBytes
|
|
1053
|
+
);
|
|
1054
|
+
if (signedTx.bodyBytes) {
|
|
1055
|
+
txBody = proto.TransactionBody.decode(signedTx.bodyBytes);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
if (txBody && txBody.tokenAirdrop) {
|
|
1059
|
+
const parsedAirdrop = HTSParser.parseTokenAirdropFromProto(
|
|
1060
|
+
txBody.tokenAirdrop
|
|
1061
|
+
);
|
|
1062
|
+
if (parsedAirdrop) {
|
|
1063
|
+
result.tokenAirdrop = parsedAirdrop;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
} catch (error) {
|
|
1068
|
+
}
|
|
1013
1069
|
}
|
|
1014
1070
|
return result;
|
|
1015
1071
|
} catch (error) {
|
|
@@ -1079,154 +1135,99 @@ class TransactionParser {
|
|
|
1079
1135
|
};
|
|
1080
1136
|
}
|
|
1081
1137
|
/**
|
|
1082
|
-
* Parse transaction
|
|
1138
|
+
* Parse transaction body details for all supported transaction types
|
|
1139
|
+
* This is the DRY, unified approach that delegates to appropriate parsers
|
|
1083
1140
|
*/
|
|
1084
|
-
static
|
|
1141
|
+
static parseTransactionBodyDetails(txBody, transactionType) {
|
|
1085
1142
|
const result = {};
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
if (
|
|
1091
|
-
result.
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1143
|
+
if (txBody.tokenCreation && transactionType === "TOKENCREATE") {
|
|
1144
|
+
result.tokenCreation = HTSParser.parseTokenCreate(txBody.tokenCreation);
|
|
1145
|
+
} else if (txBody.tokenMint && transactionType === "TOKENMINT") {
|
|
1146
|
+
result.tokenMint = HTSParser.parseTokenMint(txBody.tokenMint);
|
|
1147
|
+
} else if (txBody.tokenBurn && transactionType === "TOKENBURN") {
|
|
1148
|
+
result.tokenBurn = HTSParser.parseTokenBurn(txBody.tokenBurn);
|
|
1149
|
+
} else if (txBody.tokenUpdate && transactionType === "TOKENUPDATE") {
|
|
1150
|
+
result.tokenUpdate = HTSParser.parseTokenUpdate(txBody.tokenUpdate);
|
|
1151
|
+
} else if (txBody.tokenDeletion && transactionType === "TOKENDELETE") {
|
|
1152
|
+
result.tokenDelete = HTSParser.parseTokenDelete(txBody.tokenDeletion);
|
|
1153
|
+
} else if (txBody.tokenAssociate && transactionType === "TOKENASSOCIATE") {
|
|
1154
|
+
result.tokenAssociate = HTSParser.parseTokenAssociate(
|
|
1155
|
+
txBody.tokenAssociate
|
|
1156
|
+
);
|
|
1157
|
+
} else if (txBody.tokenDissociate && transactionType === "TOKENDISSOCIATE") {
|
|
1158
|
+
result.tokenDissociate = HTSParser.parseTokenDissociate(
|
|
1159
|
+
txBody.tokenDissociate
|
|
1160
|
+
);
|
|
1161
|
+
} else if (txBody.tokenFreeze && transactionType === "TOKENFREEZE") {
|
|
1162
|
+
result.tokenFreeze = HTSParser.parseTokenFreeze(txBody.tokenFreeze);
|
|
1163
|
+
} else if (txBody.tokenUnfreeze && transactionType === "TOKENUNFREEZE") {
|
|
1164
|
+
result.tokenUnfreeze = HTSParser.parseTokenUnfreeze(txBody.tokenUnfreeze);
|
|
1165
|
+
} else if (txBody.tokenGrantKyc && transactionType === "TOKENGRANTKYC") {
|
|
1166
|
+
result.tokenGrantKyc = HTSParser.parseTokenGrantKyc(txBody.tokenGrantKyc);
|
|
1167
|
+
} else if (txBody.tokenRevokeKyc && transactionType === "TOKENREVOKEKYC") {
|
|
1168
|
+
result.tokenRevokeKyc = HTSParser.parseTokenRevokeKyc(
|
|
1169
|
+
txBody.tokenRevokeKyc
|
|
1170
|
+
);
|
|
1171
|
+
} else if (txBody.tokenPause && transactionType === "TOKENPAUSE") {
|
|
1172
|
+
result.tokenPause = HTSParser.parseTokenPause(txBody.tokenPause);
|
|
1173
|
+
} else if (txBody.tokenUnpause && transactionType === "TOKENUNPAUSE") {
|
|
1174
|
+
result.tokenUnpause = HTSParser.parseTokenUnpause(txBody.tokenUnpause);
|
|
1175
|
+
} else if (txBody.tokenWipe && transactionType === "TOKENWIPEACCOUNT") {
|
|
1176
|
+
result.tokenWipeAccount = HTSParser.parseTokenWipeAccount(
|
|
1177
|
+
txBody.tokenWipe
|
|
1178
|
+
);
|
|
1179
|
+
} else if (txBody.tokenFeeScheduleUpdate && transactionType === "TOKENFEESCHEDULEUPDATE") {
|
|
1180
|
+
result.tokenFeeScheduleUpdate = HTSParser.parseTokenFeeScheduleUpdate(
|
|
1181
|
+
txBody.tokenFeeScheduleUpdate
|
|
1182
|
+
);
|
|
1183
|
+
} else if (txBody.tokenAirdrop && transactionType === "TOKENAIRDROP") {
|
|
1184
|
+
result.tokenAirdrop = HTSParser.parseTokenAirdropFromProto(
|
|
1185
|
+
txBody.tokenAirdrop
|
|
1104
1186
|
);
|
|
1105
1187
|
}
|
|
1106
1188
|
return result;
|
|
1107
1189
|
}
|
|
1108
1190
|
/**
|
|
1109
|
-
*
|
|
1110
|
-
*/
|
|
1111
|
-
static extractHbarTransfersFromTransaction(transaction) {
|
|
1112
|
-
const transfers = [];
|
|
1113
|
-
try {
|
|
1114
|
-
const hbarTransfers = transaction._hbarTransfers;
|
|
1115
|
-
if (Array.isArray(hbarTransfers)) {
|
|
1116
|
-
hbarTransfers.forEach((transfer) => {
|
|
1117
|
-
if (transfer.accountId && transfer.amount) {
|
|
1118
|
-
const amountInTinybars = transfer.amount.toTinybars();
|
|
1119
|
-
const amountInHbar = Number(amountInTinybars) / 1e8;
|
|
1120
|
-
transfers.push({
|
|
1121
|
-
accountId: transfer.accountId.toString(),
|
|
1122
|
-
amount: amountInHbar
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
});
|
|
1126
|
-
}
|
|
1127
|
-
} catch (error) {
|
|
1128
|
-
}
|
|
1129
|
-
return transfers;
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Extract token transfers from Transaction object
|
|
1191
|
+
* Merge protobuf parsing results with parser results using unified prioritization
|
|
1133
1192
|
*/
|
|
1134
|
-
static
|
|
1135
|
-
const
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const signedTx = proto.SignedTransaction.decode(
|
|
1165
|
-
tx.signedTransactionBytes
|
|
1166
|
-
);
|
|
1167
|
-
if (signedTx.bodyBytes) {
|
|
1168
|
-
const txBody = proto.TransactionBody.decode(signedTx.bodyBytes);
|
|
1169
|
-
if (txBody.tokenCreation) {
|
|
1170
|
-
const tokenCreation = txBody.tokenCreation;
|
|
1171
|
-
return {
|
|
1172
|
-
tokenName: tokenCreation.name || "Unknown Token",
|
|
1173
|
-
tokenSymbol: tokenCreation.symbol || "UNKNOWN",
|
|
1174
|
-
initialSupply: tokenCreation.initialSupply?.toString() || "0",
|
|
1175
|
-
decimals: Number(tokenCreation.decimals || 0),
|
|
1176
|
-
maxSupply: tokenCreation.maxSupply?.toString(),
|
|
1177
|
-
tokenType: tokenCreation.tokenType || "FUNGIBLE_COMMON",
|
|
1178
|
-
supplyType: tokenCreation.supplyType || "INFINITE",
|
|
1179
|
-
tokenMemo: tokenCreation.memo || "",
|
|
1180
|
-
treasuryAccountId: tokenCreation.treasury?.toString() || "Unknown"
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1193
|
+
static mergeProtoParsingResults(result, protoResult, htsResult, transaction, originalBytes) {
|
|
1194
|
+
const transactionFields = [
|
|
1195
|
+
"tokenCreation",
|
|
1196
|
+
"tokenMint",
|
|
1197
|
+
"tokenBurn",
|
|
1198
|
+
"tokenUpdate",
|
|
1199
|
+
"tokenDelete",
|
|
1200
|
+
"tokenAssociate",
|
|
1201
|
+
"tokenDissociate",
|
|
1202
|
+
"tokenFreeze",
|
|
1203
|
+
"tokenUnfreeze",
|
|
1204
|
+
"tokenGrantKyc",
|
|
1205
|
+
"tokenRevokeKyc",
|
|
1206
|
+
"tokenPause",
|
|
1207
|
+
"tokenUnpause",
|
|
1208
|
+
"tokenWipeAccount",
|
|
1209
|
+
"tokenFeeScheduleUpdate",
|
|
1210
|
+
"tokenAirdrop"
|
|
1211
|
+
];
|
|
1212
|
+
transactionFields.forEach((field) => {
|
|
1213
|
+
const protoValue = protoResult[field];
|
|
1214
|
+
const htsValue = htsResult[field];
|
|
1215
|
+
if (protoValue !== void 0) {
|
|
1216
|
+
result[field] = protoValue;
|
|
1217
|
+
} else if (htsValue !== void 0) {
|
|
1218
|
+
result[field] = htsValue;
|
|
1219
|
+
} else if (field === "tokenCreation" && result.type === "TOKENCREATE") {
|
|
1220
|
+
const extracted = HTSParser.extractTokenCreationFromTransaction(transaction);
|
|
1221
|
+
if (extracted) {
|
|
1222
|
+
result[field] = extracted;
|
|
1184
1223
|
}
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
console.warn("Failed to extract token creation data:", error);
|
|
1190
|
-
}
|
|
1191
|
-
return null;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
static extractTokenAirdrop(transaction) {
|
|
1195
|
-
try {
|
|
1196
|
-
const transactionBytes = transaction.toBytes();
|
|
1197
|
-
const decoded = proto.TransactionList.decode(transactionBytes);
|
|
1198
|
-
if (decoded.transactionList && decoded.transactionList.length > 0) {
|
|
1199
|
-
const tx = decoded.transactionList[0];
|
|
1200
|
-
if (tx.signedTransactionBytes) {
|
|
1201
|
-
const signedTx = proto.SignedTransaction.decode(
|
|
1202
|
-
tx.signedTransactionBytes
|
|
1203
|
-
);
|
|
1204
|
-
if (signedTx.bodyBytes) {
|
|
1205
|
-
const txBody = proto.TransactionBody.decode(signedTx.bodyBytes);
|
|
1206
|
-
if (txBody.tokenAirdrop) {
|
|
1207
|
-
const airdrop = txBody.tokenAirdrop;
|
|
1208
|
-
const tokenTransfers = airdrop.tokenTransfers || [];
|
|
1209
|
-
return {
|
|
1210
|
-
tokenTransfers: tokenTransfers.map(
|
|
1211
|
-
(transfer) => ({
|
|
1212
|
-
tokenId: transfer.token?.toString() || "Unknown",
|
|
1213
|
-
transfers: (transfer.transfers || []).map(
|
|
1214
|
-
(t) => ({
|
|
1215
|
-
accountId: t.accountID?.toString() || "Unknown",
|
|
1216
|
-
amount: t.amount?.toString() || "0"
|
|
1217
|
-
})
|
|
1218
|
-
)
|
|
1219
|
-
})
|
|
1220
|
-
)
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
+
} else if (field === "tokenAirdrop" && result.type === "TOKENAIRDROP") {
|
|
1225
|
+
const extracted = HTSParser.extractTokenAirdropFromTransaction(transaction);
|
|
1226
|
+
if (extracted) {
|
|
1227
|
+
result[field] = extracted;
|
|
1224
1228
|
}
|
|
1225
1229
|
}
|
|
1226
|
-
|
|
1227
|
-
} catch (error) {
|
|
1228
|
-
return null;
|
|
1229
|
-
}
|
|
1230
|
+
});
|
|
1230
1231
|
}
|
|
1231
1232
|
/**
|
|
1232
1233
|
* Create fallback result when all parsing methods fail
|