@stellar-expert/tx-meta-effects-parser 5.5.1 → 5.5.3

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": "5.5.1",
3
+ "version": "5.5.3",
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.0.0"
12
+ "@stellar/stellar-base": "^12.0.1"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@babel/core": "^7.22.9",
@@ -1,6 +1,7 @@
1
1
  const {StrKey} = require('@stellar/stellar-base')
2
2
  const effectTypes = require('../effect-types')
3
3
  const {xdrParseScVal, xdrParseAsset, isContractAddress} = require('../parser/tx-xdr-parser-utils')
4
+ const {contractIdFromPreimage} = require('../parser/contract-preimage-encoder')
4
5
  const {mapSacContract} = require('./sac-contract-mapper')
5
6
 
6
7
  const EVENT_TYPES = {
@@ -64,15 +65,18 @@ class EventsAnalyzer {
64
65
  const {diagnosticEvents, processSystemEvents} = this.effectsAnalyzer
65
66
  if (!diagnosticEvents)
66
67
  return
68
+ const opContractId = retrieveOpContractId(this.effectsAnalyzer.operation, this.effectsAnalyzer.network)
67
69
  //diagnostic events
68
70
  for (const evt of diagnosticEvents) {
69
71
  if (!processSystemEvents && !evt.inSuccessfulContractCall())
70
72
  continue //throw new UnexpectedTxMetaChangeError({type: 'diagnostic_event', action: 'failed'})
71
73
  //parse event
72
74
  const event = evt.event()
73
- const contractId = event.contractId() //contract id attached to the event itself
74
- || this.effectsAnalyzer.operation.func._value.contractAddress()._value //retrieve from the operation
75
- this.processDiagnosticEvent(event.body().value(), event.type().value, contractId ? StrKey.encodeContract(contractId) : null)
75
+ let contractId = event.contractId() || opContractId //contract id may be attached to the event itself, otherwise use contract from operation
76
+ if (contractId && typeof contractId !== 'string') {
77
+ contractId = StrKey.encodeContract(contractId)
78
+ }
79
+ this.processDiagnosticEvent(event.body().value(), event.type().value, contractId)
76
80
  }
77
81
  }
78
82
 
@@ -301,4 +305,18 @@ function processEventBodyValue(value) {
301
305
  return xdrParseScVal(value) //other scValue
302
306
  }
303
307
 
308
+ function retrieveOpContractId(operation, network) {
309
+ const funcValue = operation.func._value._attributes
310
+ if (!funcValue)
311
+ return null //WASM upload
312
+ let address = funcValue.contractAddress?._value
313
+ if (!address) {
314
+ const preimage = funcValue.contractIdPreimage
315
+ if (preimage) {
316
+ address = contractIdFromPreimage(preimage, network)
317
+ }
318
+ }
319
+ return address
320
+ }
321
+
304
322
  module.exports = EventsAnalyzer
@@ -185,6 +185,20 @@ class EffectsAnalyzer {
185
185
  metrics[metric] = value
186
186
  }
187
187
 
188
+ addFeeMetric(metaValue) {
189
+ const sorobanExt = metaValue._attributes.sorobanMeta._attributes.ext._value
190
+ if (sorobanExt) {
191
+ const attrs = sorobanExt._attributes
192
+ const fee = {
193
+ nonrefundable: parseLargeInt(attrs.totalNonRefundableResourceFeeCharged),
194
+ refundable: parseLargeInt(attrs.totalRefundableResourceFeeCharged),
195
+ rent: parseLargeInt(attrs.rentFeeCharged)
196
+ }
197
+ const contract = StrKey.encodeContract(this.operation.func._value.contractAddress()._value)
198
+ this.addMetric(contract, 'fee', fee)
199
+ }
200
+ }
201
+
188
202
  setOptions() {
189
203
  const sourceAccount = normalizeAddress(this.source)
190
204
  const {before, after} = this.changes.find(ch => ch.type === 'account' && ch.before.address === sourceAccount)
@@ -962,4 +976,8 @@ function encodeSponsorshipEffectName(action, type) {
962
976
  return effectTypes[`${type}Sponsorship${actionKey}`]
963
977
  }
964
978
 
979
+ function parseLargeInt(largeInt) {
980
+ return largeInt._value.toString()
981
+ }
982
+
965
983
  module.exports = {EffectsAnalyzer, processFeeChargedEffect}
package/src/index.js CHANGED
@@ -134,19 +134,25 @@ function parseTxOperationsMeta({network, tx, result, meta, mapSac = false, proce
134
134
  meta: opMeta[i]?.changes(),
135
135
  result: opResults[i], network
136
136
  }
137
+ const isSorobanInvocation = operation.type === 'invokeHostFunction'
137
138
  //only for Soroban contract invocation
138
- if (operation.type === 'invokeHostFunction') {
139
- const sorobanMeta = metaValue.sorobanMeta()
139
+ if (isSorobanInvocation) {
140
+ const sorobanMeta = metaValue._attributes.sorobanMeta
140
141
  params.events = sorobanMeta.events()
141
142
  params.diagnosticEvents = sorobanMeta.diagnosticEvents()
142
143
  params.mapSac = mapSac
143
144
  params.processSystemEvents = processSystemEvents
145
+ //process fee stats
146
+
144
147
  }
145
148
  const analyzer = new EffectsAnalyzer(params)
146
149
  operation.effects = analyzer.analyze()
147
150
  if (analyzer.sacMap && !isEmptyObject(analyzer.sacMap)) {
148
151
  operation.sacMap = analyzer.sacMap
149
152
  }
153
+ if (isSorobanInvocation) {
154
+ analyzer.addFeeMetric(metaValue)
155
+ }
150
156
  }
151
157
  }
152
158
  return res