@stellar-expert/tx-meta-effects-parser 5.6.1 → 5.6.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.6.1",
3
+ "version": "5.6.3",
4
4
  "description": "Low-level effects parser for Stellar transaction results and meta XDR",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -50,9 +50,9 @@ class AssetSupplyAnalyzer {
50
50
  this.supplyChanges |= 1
51
51
  }
52
52
  }
53
- if ((this.supplyChanges & 3) === 3) { //analyze possible collapsible mints only if both mint and burn effects recorded
53
+ /*if ((this.supplyChanges & 3) === 3) { //analyze possible collapsible mints only if both mint and burn effects recorded
54
54
  new CollapsibleMintsAnalyzer(this.effectsAnalyzer).removeCollapsingMints()
55
- }
55
+ }*/
56
56
  }
57
57
 
58
58
  /**
@@ -181,7 +181,7 @@ class CollapsibleMintsAnalyzer {
181
181
  if (sum > 0n) { //asset minted
182
182
  this.effectsAnalyzer.mint(asset, sum.toString(), true) //insert mint effect
183
183
  } else if (sum < 0n) { //asset burned
184
- this.effectsAnalyzer.burn(asset, sum.toString(), position) //insert burn effect at the position of the last removed effect
184
+ this.effectsAnalyzer.burn(asset, (-sum).toString(), position) //insert burn effect at the position of the last removed effect
185
185
  }
186
186
  //if sum=0 then both effects were annihilated and removed
187
187
  }
@@ -158,13 +158,6 @@ class EventsAnalyzer {
158
158
  if (classicAsset) {
159
159
  if (classicAsset.includes(from)) { //SAC transfer by asset issuer
160
160
  this.effectsAnalyzer.mint(classicAsset, amount)
161
- this.effectsAnalyzer.credit(amount, classicAsset, to)
162
- return
163
- }
164
- if (classicAsset.includes(to)) { //SAC transfer by asset issuer
165
- this.effectsAnalyzer.debit(amount, classicAsset, from)
166
- this.effectsAnalyzer.burn(classicAsset, amount)
167
- return
168
161
  }
169
162
  if (isContractAddress(from)) {
170
163
  this.effectsAnalyzer.debit(amount, classicAsset, from)
@@ -172,6 +165,9 @@ class EventsAnalyzer {
172
165
  if (isContractAddress(to)) {
173
166
  this.effectsAnalyzer.credit(amount, classicAsset, to)
174
167
  }
168
+ if (classicAsset.includes(to)) { //SAC transfer by asset issuer
169
+ this.effectsAnalyzer.burn(classicAsset, amount)
170
+ }
175
171
  } else { //other cases
176
172
  this.effectsAnalyzer.debit(amount, this.effectsAnalyzer.resolveAsset(contract), from)
177
173
  this.effectsAnalyzer.credit(amount, this.effectsAnalyzer.resolveAsset(contract), to)
@@ -132,7 +132,7 @@ class EffectsAnalyzer {
132
132
  type: effectTypes.accountDebited,
133
133
  source,
134
134
  asset,
135
- amount
135
+ amount: validateAmount(amount)
136
136
  }
137
137
  if (balance !== undefined) {
138
138
  effect.balance = balance
@@ -147,7 +147,7 @@ class EffectsAnalyzer {
147
147
  type: effectTypes.accountCredited,
148
148
  source,
149
149
  asset,
150
- amount
150
+ amount: validateAmount(amount)
151
151
  }
152
152
  if (balance !== undefined) {
153
153
  effect.balance = balance
@@ -162,7 +162,7 @@ class EffectsAnalyzer {
162
162
  this.addEffect({
163
163
  type: effectTypes.assetMinted,
164
164
  asset,
165
- amount
165
+ amount: validateAmount(amount)
166
166
  }, position)
167
167
  }
168
168
 
@@ -170,7 +170,7 @@ class EffectsAnalyzer {
170
170
  this.addEffect({
171
171
  type: effectTypes.assetBurned,
172
172
  asset,
173
- amount
173
+ amount: validateAmount(amount)
174
174
  }, position)
175
175
  }
176
176
 
@@ -782,12 +782,21 @@ class EffectsAnalyzer {
782
782
  processContractChanges({action, before, after}) {
783
783
  if (action !== 'created' && action !== 'updated')
784
784
  throw new UnexpectedTxMetaChangeError({type: 'contract', action})
785
- const {kind, contract, hash} = after
785
+ const {kind, contract} = after
786
786
  const effect = {
787
787
  type: effectTypes.contractCreated,
788
788
  contract,
789
- kind,
790
- wasmHash: hash
789
+ kind
790
+ }
791
+ switch (kind) {
792
+ case 'fromAsset':
793
+ effect.asset = after.asset
794
+ break
795
+ case 'wasm':
796
+ effect.wasmHash = after.hash
797
+ break
798
+ default:
799
+ throw new TxMetaEffectParserError('Unexpected contract type: ' + kind)
791
800
  }
792
801
  if (action === 'created') {
793
802
  if (this.effects.some(e => e.contract === contract))
@@ -798,7 +807,7 @@ class EffectsAnalyzer {
798
807
  if (before.storage?.length || after.storage?.length) {
799
808
  this.processInstanceDataChanges(before, after)
800
809
  }
801
- if (before.hash === hash) //skip if hash unchanged
810
+ if (before.hash === after.hash) //skip if hash unchanged
802
811
  return
803
812
  }
804
813
  this.addEffect(effect)
@@ -998,6 +1007,12 @@ function encodeSponsorshipEffectName(action, type) {
998
1007
  return effectTypes[`${type}Sponsorship${actionKey}`]
999
1008
  }
1000
1009
 
1010
+ function validateAmount(amount) {
1011
+ if (amount < 0)
1012
+ throw new TxMetaEffectParserError('Negative balance change amount: ' + amount.toString())
1013
+ return amount
1014
+ }
1015
+
1001
1016
  function parseLargeInt(largeInt) {
1002
1017
  return largeInt._value.toString()
1003
1018
  }
@@ -246,52 +246,20 @@ function parseContractData(value) {
246
246
  entry: 'contract',
247
247
  contract: owner
248
248
  }
249
- const type = valueAttr.instance().executable().switch().name
249
+ const instance = valueAttr.instance()._attributes
250
+ const type = instance.executable._switch.name
250
251
  switch (type) {
251
252
  case 'contractExecutableStellarAsset':
252
- entry.type = 'token'
253
- /**
254
- * data._attributes.val._value._attributes.storage
255
- *
256
- * ScVal: [scvContractInstance]
257
- * instance
258
- * executable: [contractExecutableStellarAsset]
259
- * storage: Array[3]
260
- * [0]
261
- * key: [scvSymbol]
262
- * sym: METADATA
263
- * val: [scvMap]
264
- * map: Array[3]
265
- * [0]
266
- * key: [scvSymbol]
267
- * sym: decimal
268
- * val: [scvU32]
269
- * u32: 7
270
- * [1]
271
- * key: [scvSymbol]
272
- * sym: name
273
- * val: [scvString]
274
- * str: ICGVCWUQXIHO:GBD2ALDOSNTEW2QWQA6RGQXTZVWGFZYTT5DYZDCPPGNOYTXOAQ6RFUAC
275
- * [2]
276
- * key: [scvSymbol]
277
- * sym: symbol
278
- * val: [scvString]
279
- * str: ICGVCWUQXIHO
280
- * [1]
281
- * key: [scvVec]
282
- * vec: Array[1]
283
- * [0]: [scvSymbol]
284
- * sym: Admin
285
- * val: [scvAddress]
286
- * address: [scAddressTypeAccount]
287
- * accountId: [publicKeyTypeEd25519]
288
- * ed25519: GBD2ALDOSNTEW2QWQA6RGQXTZVWGFZYTT5DYZDCPPGNOYTXOAQ6RFUAC
289
- */
290
- return undefined
253
+ entry.kind = 'fromAsset'
254
+ if (!instance.storage.length)
255
+ throw new TxMetaEffectParserError('Unexpected asset initialization metadata')
256
+ const metaArgs = instance.storage[0]._attributes
257
+ if (metaArgs.key._value.toString() !== 'METADATA')
258
+ throw new TxMetaEffectParserError('Unexpected asset initialization metadata')
259
+ entry.asset = xdrParseAsset(metaArgs.val._value[1]._attributes.val._value.toString())
291
260
  break
292
261
  case 'contractExecutableWasm':
293
262
  entry.kind = 'wasm'
294
- const instance = valueAttr.instance()._attributes
295
263
  entry.hash = instance.executable.wasmHash().toString('hex')
296
264
  if (instance.storage?.length) {
297
265
  entry.storage = instance.storage.map(entry => ({