@stellar-expert/tx-meta-effects-parser 5.5.4 → 5.6.1

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.4",
3
+ "version": "5.6.1",
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.1"
12
+ "@stellar/stellar-base": "^12.1.0"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@babel/core": "^7.22.9",
@@ -155,30 +155,27 @@ class EventsAnalyzer {
155
155
  classicAsset = null //not an SAC event
156
156
  }
157
157
  }
158
- if (classicAsset && (classicAsset.includes(from) || classicAsset.includes(to))) { //SAC transfer by asset issuer
159
- if (classicAsset.includes(from)) {
160
- this.effectsAnalyzer.mint(contract, amount)
161
- this.effectsAnalyzer.credit(amount, isContractAddress(to) ? contract : classicAsset, to)
162
- }
163
- if (classicAsset.includes(to)) {
164
- this.effectsAnalyzer.debit(amount, isContractAddress(from) ? contract : classicAsset, from)
165
- this.effectsAnalyzer.burn(contract, amount)
158
+ if (classicAsset) {
159
+ if (classicAsset.includes(from)) { //SAC transfer by asset issuer
160
+ this.effectsAnalyzer.mint(classicAsset, amount)
161
+ this.effectsAnalyzer.credit(amount, classicAsset, to)
162
+ return
166
163
  }
167
- } else { //other cases
168
- if (classicAsset && !isContractAddress(from)) { //classic asset bridged to Soroban
164
+ if (classicAsset.includes(to)) { //SAC transfer by asset issuer
165
+ this.effectsAnalyzer.debit(amount, classicAsset, from)
169
166
  this.effectsAnalyzer.burn(classicAsset, amount)
170
- this.effectsAnalyzer.mint(contract, amount)
171
- } else {
172
- this.effectsAnalyzer.debit(amount, contract, from)
167
+ return
173
168
  }
174
- if (classicAsset && !isContractAddress(to)) { //classic asset bridged from Soroban
175
- this.effectsAnalyzer.burn(contract, amount)
176
- this.effectsAnalyzer.mint(classicAsset, amount)
177
- } else {
178
- this.effectsAnalyzer.credit(amount, contract, to)
169
+ if (isContractAddress(from)) {
170
+ this.effectsAnalyzer.debit(amount, classicAsset, from)
179
171
  }
172
+ if (isContractAddress(to)) {
173
+ this.effectsAnalyzer.credit(amount, classicAsset, to)
174
+ }
175
+ } else { //other cases
176
+ this.effectsAnalyzer.debit(amount, this.effectsAnalyzer.resolveAsset(contract), from)
177
+ this.effectsAnalyzer.credit(amount, this.effectsAnalyzer.resolveAsset(contract), to)
180
178
  }
181
-
182
179
  }
183
180
  break
184
181
  case 'mint': {
@@ -188,15 +185,14 @@ class EventsAnalyzer {
188
185
  const amount = processEventBodyValue(body.data())
189
186
  if (!this.matchInvocationEffect(e => e.function === 'mint' && matchArrays([to, amount], e.args)))
190
187
  return
191
- this.effectsAnalyzer.addEffect({
192
- type: effectTypes.assetMinted,
193
- asset: contract,
194
- amount
195
- })
196
- this.effectsAnalyzer.credit(amount, contract, to)
197
188
  if (topics.length > 3) {
198
189
  mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[3])))
199
190
  }
191
+ const asset = this.effectsAnalyzer.resolveAsset(contract)
192
+ this.effectsAnalyzer.mint(asset, amount)
193
+ if (isContractAddress(asset) || isContractAddress(to)) {
194
+ this.effectsAnalyzer.credit(amount, asset, to)
195
+ }
200
196
  }
201
197
  break
202
198
  case 'burn': {
@@ -209,12 +205,14 @@ class EventsAnalyzer {
209
205
  (e.function === 'burn_from' && matchArrays([undefined, from, amount], e.args))
210
206
  ))
211
207
  return
212
-
213
- this.effectsAnalyzer.debit(amount, contract, from)
214
- this.effectsAnalyzer.burn(contract, amount)
215
208
  if (topics.length > 2) {
216
209
  mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[2])))
217
210
  }
211
+ const asset = this.effectsAnalyzer.resolveAsset(contract)
212
+ if (isContractAddress(asset) || isContractAddress(from)) {
213
+ this.effectsAnalyzer.debit(amount, asset, from)
214
+ }
215
+ this.effectsAnalyzer.burn(asset, amount)
218
216
  }
219
217
  break
220
218
  case 'clawback': {
@@ -224,11 +222,14 @@ class EventsAnalyzer {
224
222
  const amount = processEventBodyValue(body.data())
225
223
  if (!this.matchInvocationEffect(e => e.function === 'clawback' && matchArrays([from, amount], e.args)))
226
224
  return
227
- this.effectsAnalyzer.debit(amount, contract, from)
228
- this.effectsAnalyzer.burn(contract, amount)
229
225
  if (topics.length > 3) {
230
226
  mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[3])))
231
227
  }
228
+ const asset = this.effectsAnalyzer.resolveAsset(contract)
229
+ if (isContractAddress(asset)) {
230
+ this.effectsAnalyzer.debit(amount, asset, from)
231
+ }
232
+ this.effectsAnalyzer.burn(asset, amount)
232
233
  }
233
234
  break
234
235
  case 'set_admin': {
@@ -238,10 +239,10 @@ class EventsAnalyzer {
238
239
  const newAdmin = processEventBodyValue(body.data())
239
240
  if (!this.matchInvocationEffect(e => e.function === 'set_admin' && matchArrays([currentAdmin, newAdmin], [this.effectsAnalyzer.source, e.args])))
240
241
  return
241
- this.effectsAnalyzer.setAdmin(contract, newAdmin)
242
242
  if (topics.length > 2) {
243
243
  mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[2])))
244
244
  }
245
+ this.effectsAnalyzer.setAdmin(contract, newAdmin)
245
246
  }
246
247
  break
247
248
  /*case 'approve': { //TODO: think about processing this effect
@@ -15,14 +15,22 @@ function mapSacContract(effectsAnalyzer, contractAddress, classicAsset) {
15
15
  if (!classicAsset)
16
16
  return false
17
17
  const {network, sacMap} = effectsAnalyzer
18
+ if (!sacMap)
19
+ return false
20
+ const prevMapping = sacMap[contractAddress]
21
+ if (prevMapping) {
22
+ return prevMapping === classicAsset
23
+ }
18
24
  //try to load from cache first
19
- const fromCache = sacCache.get(contractAddress + network)
25
+ const fromCache = sacCache.get(classicAsset + network)
20
26
  if (!fromCache) {
21
27
  const encodedContract = contractIdFromAsset(toStellarAsset(classicAsset), network)
22
- sacCache.set(encodedContract + network, classicAsset)
23
- if (encodedContract !== contractAddress)
28
+ sacCache.set(classicAsset + network, contractAddress)
29
+ if (contractAddress === undefined) {
30
+ contractAddress = encodedContract
31
+ } else if (encodedContract !== contractAddress)
24
32
  return false
25
- } else if (classicAsset !== fromCache)
33
+ } else if (contractAddress !== fromCache)
26
34
  return false //check whether validated contract from cache matches the asset
27
35
  if (sacMap) {
28
36
  sacMap[contractAddress] = classicAsset
@@ -7,6 +7,7 @@ const {contractIdFromPreimage} = require('./parser/contract-preimage-encoder')
7
7
  const EventsAnalyzer = require('./aggregation/events-analyzer')
8
8
  const AssetSupplyAnalyzer = require('./aggregation/asset-supply-analyzer')
9
9
  const {UnexpectedTxMetaChangeError, TxMetaEffectParserError} = require('./errors')
10
+ const {mapSacContract} = require('./aggregation/sac-contract-mapper')
10
11
 
11
12
  class EffectsAnalyzer {
12
13
  constructor({operation, meta, result, network, events, diagnosticEvents, mapSac, processSystemEvents}) {
@@ -571,6 +572,9 @@ class EffectsAnalyzer {
571
572
  }
572
573
 
573
574
  processBalanceChange(account, asset, beforeBalance, afterBalance) {
575
+ if (this.isContractCall) { //map contract=>asset proactively
576
+ mapSacContract(this, undefined, asset)
577
+ }
574
578
  const balanceChange = BigInt(afterBalance) - BigInt(beforeBalance)
575
579
  if (balanceChange < 0n) {
576
580
  this.debit((-balanceChange).toString(), asset, account, afterBalance)
@@ -922,6 +926,13 @@ class EffectsAnalyzer {
922
926
  }
923
927
  return null
924
928
  }
929
+
930
+ resolveAsset(assetOrContract) {
931
+ if (!assetOrContract.startsWith('C') || !this.sacMap)
932
+ return assetOrContract
933
+ //try to resolve using SAC map
934
+ return this.sacMap[assetOrContract] || assetOrContract
935
+ }
925
936
  }
926
937
 
927
938
  /**