@stellar-expert/tx-meta-effects-parser 6.0.3 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stellar-expert/tx-meta-effects-parser",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Low-level effects parser for Stellar transaction results and meta XDR",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"author": "team@stellar.expert",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"peerDependencies": {
|
|
12
|
-
"@stellar/stellar-base": "^12.1.
|
|
12
|
+
"@stellar/stellar-base": "^12.1.1"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@babel/core": "^7.22.9",
|
|
@@ -61,13 +61,13 @@ class EventsAnalyzer {
|
|
|
61
61
|
* @private
|
|
62
62
|
*/
|
|
63
63
|
analyzeDiagnosticEvents() {
|
|
64
|
-
const {diagnosticEvents, processSystemEvents} = this.effectsAnalyzer
|
|
64
|
+
const {diagnosticEvents, processSystemEvents, processMetrics, processFailedOpEffects} = this.effectsAnalyzer
|
|
65
65
|
if (!diagnosticEvents)
|
|
66
66
|
return
|
|
67
67
|
const opContractId = this.effectsAnalyzer.retrieveOpContractId()
|
|
68
68
|
//diagnostic events
|
|
69
69
|
for (const evt of diagnosticEvents) {
|
|
70
|
-
if (!processSystemEvents && !(evt.inSuccessfulContractCall()
|
|
70
|
+
if (!processSystemEvents && !(processFailedOpEffects || evt.inSuccessfulContractCall()))
|
|
71
71
|
continue //throw new UnexpectedTxMetaChangeError({type: 'diagnostic_event', action: 'failed'})
|
|
72
72
|
//parse event
|
|
73
73
|
const event = evt.event()
|
|
@@ -75,7 +75,7 @@ class EventsAnalyzer {
|
|
|
75
75
|
if (contractId && typeof contractId !== 'string') {
|
|
76
76
|
contractId = StrKey.encodeContract(contractId)
|
|
77
77
|
}
|
|
78
|
-
this.processDiagnosticEvent(event.body
|
|
78
|
+
this.processDiagnosticEvent(event._attributes.body._value, event._attributes.type.value, contractId, processMetrics)
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -83,9 +83,10 @@ class EventsAnalyzer {
|
|
|
83
83
|
* @param {xdr.ContractEventV0} body
|
|
84
84
|
* @param {Number} type
|
|
85
85
|
* @param {String} contract
|
|
86
|
+
* @param {Boolean} processMetrics
|
|
86
87
|
* @private
|
|
87
88
|
*/
|
|
88
|
-
processDiagnosticEvent(body, type, contract) {
|
|
89
|
+
processDiagnosticEvent(body, type, contract, processMetrics) {
|
|
89
90
|
const topics = body.topics()
|
|
90
91
|
if (!topics?.length)
|
|
91
92
|
return
|
|
@@ -121,16 +122,22 @@ class EventsAnalyzer {
|
|
|
121
122
|
case 'error':
|
|
122
123
|
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
123
124
|
return // skip non-diagnostic events
|
|
125
|
+
let code = topics[1].value().value()
|
|
126
|
+
if (code.name) {
|
|
127
|
+
code = code.name
|
|
128
|
+
}
|
|
124
129
|
this.effectsAnalyzer.addEffect({
|
|
125
130
|
type: effectTypes.contractError,
|
|
126
131
|
contract,
|
|
127
|
-
code
|
|
132
|
+
code,
|
|
128
133
|
details: processEventBodyValue(body.data())
|
|
129
134
|
})
|
|
130
135
|
break
|
|
131
136
|
case 'core_metrics':
|
|
132
137
|
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
133
138
|
return // skip non-diagnostic events
|
|
139
|
+
if (!processMetrics)
|
|
140
|
+
return
|
|
134
141
|
this.effectsAnalyzer.addMetric(contract, xdrParseScVal(topics[1]), parseInt(processEventBodyValue(body.data())))
|
|
135
142
|
break
|
|
136
143
|
//handle standard token contract events
|
package/src/effects-analyzer.js
CHANGED
|
@@ -11,7 +11,18 @@ const {UnexpectedTxMetaChangeError, TxMetaEffectParserError} = require('./errors
|
|
|
11
11
|
const {generateContractCodeEntryHash} = require('./parser/ledger-key')
|
|
12
12
|
|
|
13
13
|
class EffectsAnalyzer {
|
|
14
|
-
constructor({
|
|
14
|
+
constructor({
|
|
15
|
+
operation,
|
|
16
|
+
meta,
|
|
17
|
+
result,
|
|
18
|
+
network,
|
|
19
|
+
events,
|
|
20
|
+
diagnosticEvents,
|
|
21
|
+
mapSac,
|
|
22
|
+
processSystemEvents,
|
|
23
|
+
processFailedOpEffects,
|
|
24
|
+
processMetrics
|
|
25
|
+
}) {
|
|
15
26
|
//set execution context
|
|
16
27
|
if (!operation.source)
|
|
17
28
|
throw new TxMetaEffectParserError('Operation source is not explicitly defined')
|
|
@@ -22,6 +33,7 @@ class EffectsAnalyzer {
|
|
|
22
33
|
this.source = this.operation.source
|
|
23
34
|
this.events = events
|
|
24
35
|
this.processFailedOpEffects = processFailedOpEffects
|
|
36
|
+
this.processMetrics = processMetrics
|
|
25
37
|
if (diagnosticEvents?.length) {
|
|
26
38
|
this.diagnosticEvents = diagnosticEvents
|
|
27
39
|
if (processSystemEvents) {
|
|
@@ -84,6 +96,11 @@ class EffectsAnalyzer {
|
|
|
84
96
|
* @readonly
|
|
85
97
|
*/
|
|
86
98
|
processSystemEvents = false
|
|
99
|
+
/**
|
|
100
|
+
* @type {Boolean}
|
|
101
|
+
* @readonly
|
|
102
|
+
*/
|
|
103
|
+
processMetrics = true
|
|
87
104
|
/**
|
|
88
105
|
* @type {{}}
|
|
89
106
|
* @private
|
|
@@ -106,6 +123,10 @@ class EffectsAnalyzer {
|
|
|
106
123
|
this.processSponsorshipEffects()
|
|
107
124
|
//calculate minted/burned assets
|
|
108
125
|
new AssetSupplyAnalyzer(this).analyze()
|
|
126
|
+
//add Soroban op metrics if available
|
|
127
|
+
if (this.metrics) {
|
|
128
|
+
this.addEffect(this.metrics)
|
|
129
|
+
}
|
|
109
130
|
return this.effects
|
|
110
131
|
}
|
|
111
132
|
|
|
@@ -180,7 +201,6 @@ class EffectsAnalyzer {
|
|
|
180
201
|
type: effectTypes.contractMetrics,
|
|
181
202
|
contract
|
|
182
203
|
}
|
|
183
|
-
this.addEffect(metrics)
|
|
184
204
|
}
|
|
185
205
|
metrics[metric] = value
|
|
186
206
|
}
|
package/src/index.js
CHANGED
|
@@ -19,16 +19,29 @@ const effectTypes = require('./effect-types')
|
|
|
19
19
|
* @param {Boolean} [mapSac] - Whether to create a map SAC->Asset
|
|
20
20
|
* @param {Boolean} [processSystemEvents] - Emit effects for contract errors and resource stats
|
|
21
21
|
* @param {Boolean} [processFailedOpEffects] - Whether to generate operation effects for failed/rejected transactions
|
|
22
|
+
* @param {Boolean} [processMetrics] - Process invocation metrics emitted by Soroban
|
|
22
23
|
* @param {Number} [protocol] - Specific Stellar protocol version for the executed transaction
|
|
23
24
|
* @return {ParsedTxOperationsMetadata}
|
|
24
25
|
*/
|
|
25
|
-
function parseTxOperationsMeta({
|
|
26
|
+
function parseTxOperationsMeta({
|
|
27
|
+
network,
|
|
28
|
+
tx,
|
|
29
|
+
result,
|
|
30
|
+
meta,
|
|
31
|
+
mapSac = false,
|
|
32
|
+
processSystemEvents = false,
|
|
33
|
+
processFailedOpEffects = false,
|
|
34
|
+
processMetrics,
|
|
35
|
+
protocol
|
|
36
|
+
}) {
|
|
26
37
|
if (!network)
|
|
27
38
|
throw new TypeError(`Network passphrase argument is required.`)
|
|
28
39
|
if (typeof network !== 'string')
|
|
29
40
|
throw new TypeError(`Invalid network passphrase: "${network}".`)
|
|
30
41
|
if (!tx)
|
|
31
42
|
throw new TypeError(`Transaction envelope argument is required.`)
|
|
43
|
+
if (processMetrics !== false)
|
|
44
|
+
processMetrics = true
|
|
32
45
|
const isEphemeral = !meta
|
|
33
46
|
//parse tx, result, and meta xdr
|
|
34
47
|
try {
|
|
@@ -132,10 +145,12 @@ function parseTxOperationsMeta({network, tx, result, meta, mapSac = false, proce
|
|
|
132
145
|
const operation = parsedTx.operations[i]
|
|
133
146
|
if (success || processFailedOpEffects) {
|
|
134
147
|
const params = {
|
|
148
|
+
network,
|
|
135
149
|
operation,
|
|
136
150
|
meta: opMeta[i]?.changes() || [],
|
|
137
|
-
result: opResults[i],
|
|
138
|
-
processFailedOpEffects
|
|
151
|
+
result: opResults[i],
|
|
152
|
+
processFailedOpEffects,
|
|
153
|
+
processMetrics
|
|
139
154
|
}
|
|
140
155
|
const isSorobanInvocation = operation.type === 'invokeHostFunction'
|
|
141
156
|
//only for Soroban contract invocation
|
|
@@ -280,8 +280,16 @@ function xdrParseScVal(value, treatBytesAsContractId = false) {
|
|
|
280
280
|
case 'contractId':
|
|
281
281
|
return xdrParseContractAddress(value._value)
|
|
282
282
|
default:
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
switch (value._switch.name) {
|
|
284
|
+
case 'scvVoid':
|
|
285
|
+
return undefined
|
|
286
|
+
case 'scvContractInstance':
|
|
287
|
+
return '<ContractInstance>'
|
|
288
|
+
case 'scvLedgerKeyContractInstance':
|
|
289
|
+
return '<LedgerKeyContractInstance>'
|
|
290
|
+
case 'scvLedgerKeyNonce':
|
|
291
|
+
return '<LedgerKeyNonce>'
|
|
292
|
+
}
|
|
285
293
|
throw new TxMetaEffectParserError('Not supported XDR primitive type: ' + value.toXDR ? value.toXDR() : value.toString())
|
|
286
294
|
}
|
|
287
295
|
}
|