@stellar-expert/tx-meta-effects-parser 7.0.0-rc.20 → 7.0.0-rc.21

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": "7.0.0-rc.20",
3
+ "version": "7.0.0-rc.21",
4
4
  "description": "Low-level effects parser for Stellar transaction results and meta XDR",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,6 +1,7 @@
1
1
  const {StrKey, encodeMuxedAccount, encodeMuxedAccountToAddress} = require('@stellar/stellar-base')
2
2
  const effectTypes = require('../effect-types')
3
- const {xdrParseScVal, xdrParseAsset, isContractAddress} = require('../parser/tx-xdr-parser-utils')
3
+ const {xdrParseScVal, xdrParseAsset} = require('../parser/tx-xdr-parser-utils')
4
+ const {isContractAddress, validateAmount} = require('../parser/normalization')
4
5
  const {mapSacContract} = require('./sac-contract-mapper')
5
6
 
6
7
  const EVENT_TYPES = {
@@ -155,7 +156,7 @@ class EventsAnalyzer {
155
156
  amount = amount.amount
156
157
  }
157
158
  }
158
- if (typeof amount !== 'string')
159
+ if (validateAmount(amount, false) === null)
159
160
  return null
160
161
  if (to === from) //self transfer - nothing happens
161
162
  return // TODO: need additional checks
@@ -190,8 +191,9 @@ class EventsAnalyzer {
190
191
  amount = amount.amount
191
192
  }
192
193
  }
193
- if (typeof amount !== 'string')
194
+ if (validateAmount(amount, false) === null)
194
195
  return null
196
+ validateAmount(amount)
195
197
  const asset = this.getAssetFromEventTopics(topics, contract)
196
198
  this.effectsAnalyzer.mint(asset, amount)
197
199
  if (isContractAddress(asset) || isContractAddress(to)) {
@@ -204,7 +206,7 @@ class EventsAnalyzer {
204
206
  return //throw new Error('Non-standard event')
205
207
  const from = xdrParseScVal(topics[1])
206
208
  const amount = processEventBodyValue(body.data())
207
- if (typeof amount !== 'string')
209
+ if (validateAmount(amount, false) === null)
208
210
  return null
209
211
  const asset = this.getAssetFromEventTopics(topics, contract)
210
212
  if (isContractAddress(asset) || isContractAddress(from)) {
@@ -218,7 +220,7 @@ class EventsAnalyzer {
218
220
  return //throw new Error('Non-standard event')
219
221
  const from = xdrParseScVal(topics[topics[2]?._arm === 'address' ? 2 : 1])
220
222
  const amount = processEventBodyValue(body.data())
221
- if (typeof amount !== 'string')
223
+ if (validateAmount(amount, false) === null)
222
224
  return null
223
225
  const asset = this.getAssetFromEventTopics(topics, contract)
224
226
  if (StrKey.isValidContract(from)) { //transfer tokens from account only in case of contract assets to avoid double debits
@@ -1,6 +1,6 @@
1
1
  const TtlCache = require('../cache/ttl-cache')
2
- const {toStellarAsset} = require('../parser/tx-xdr-parser-utils')
3
2
  const {contractIdFromAsset} = require('../parser/contract-preimage-encoder')
3
+ const {toStellarAsset} = require('../parser/normalization')
4
4
 
5
5
  const sacCache = new TtlCache()
6
6
 
@@ -17,7 +17,7 @@ function mapSacContract(effectsAnalyzer, contractAddress, classicAsset) {
17
17
  const {network, sacMap} = effectsAnalyzer
18
18
  if (!sacMap)
19
19
  return false
20
- const prevMapping = sacMap[contractAddress]
20
+ const prevMapping = sacMap.get(contractAddress)
21
21
  if (prevMapping) {
22
22
  return prevMapping === classicAsset
23
23
  }
@@ -37,7 +37,7 @@ function mapSacContract(effectsAnalyzer, contractAddress, classicAsset) {
37
37
  } else if (contractAddress !== fromCache)
38
38
  return false //check whether validated contract from cache matches the asset
39
39
  if (sacMap) {
40
- sacMap[contractAddress] = classicAsset
40
+ sacMap.set(contractAddress, classicAsset)
41
41
  }
42
42
  return true
43
43
  }
@@ -1,5 +1,6 @@
1
1
  const {StrKey, hash, xdr, nativeToScVal} = require('@stellar/stellar-base')
2
2
  const effectTypes = require('./effect-types')
3
+ const {validateAmount, normalizeAddress, parseLargeInt} = require('./parser/normalization')
3
4
  const {parseLedgerEntryChanges} = require('./parser/ledger-entry-changes-parser')
4
5
  const {xdrParseAsset, xdrParseAccountAddress, xdrParseScVal} = require('./parser/tx-xdr-parser-utils')
5
6
  const {contractIdFromPreimage} = require('./parser/contract-preimage-encoder')
@@ -42,7 +43,7 @@ class EffectsAnalyzer {
42
43
  }
43
44
  this.network = network
44
45
  if (mapSac) {
45
- this.sacMap = {}
46
+ this.sacMap = new Map()
46
47
  }
47
48
  }
48
49
 
@@ -64,7 +65,7 @@ class EffectsAnalyzer {
64
65
  */
65
66
  network
66
67
  /**
67
- * @type {{}}
68
+ * @type {Map<string,string>}
68
69
  * @readonly
69
70
  */
70
71
  sacMap
@@ -261,7 +262,10 @@ class EffectsAnalyzer {
261
262
  setTrustLineFlags() {
262
263
  if (!this.changes.length)
263
264
  return
264
- const trustAsset = xdrParseAsset(this.operation.asset || {code: this.operation.assetCode, issuer: normalizeAddress(this.source)})
265
+ const trustAsset = xdrParseAsset(this.operation.asset || {
266
+ code: this.operation.assetCode,
267
+ issuer: normalizeAddress(this.source)
268
+ })
265
269
  const change = this.changes.find(ch => ch.type === 'trustline' && ch.before.asset === trustAsset)
266
270
  if (!change)
267
271
  return
@@ -1051,6 +1055,10 @@ class EffectsAnalyzer {
1051
1055
  }
1052
1056
  }
1053
1057
 
1058
+ /**
1059
+ * @return {String|null}
1060
+ * @private
1061
+ */
1054
1062
  retrieveOpContractId() {
1055
1063
  const funcValue = this.operation.func._value._attributes
1056
1064
  if (funcValue) {
@@ -1063,11 +1071,16 @@ class EffectsAnalyzer {
1063
1071
  return null
1064
1072
  }
1065
1073
 
1074
+ /**
1075
+ *
1076
+ * @param assetOrContract
1077
+ * @return {*}
1078
+ */
1066
1079
  resolveAsset(assetOrContract) {
1067
1080
  if (!assetOrContract.startsWith('C') || !this.sacMap)
1068
1081
  return assetOrContract
1069
1082
  //try to resolve using SAC map
1070
- return this.sacMap[assetOrContract] || assetOrContract
1083
+ return this.sacMap.get(assetOrContract) || assetOrContract
1071
1084
  }
1072
1085
  }
1073
1086
 
@@ -1100,17 +1113,6 @@ function processFeeChargedEffect(tx, source, chargedAmount, feeBump = false) {
1100
1113
  return res
1101
1114
  }
1102
1115
 
1103
- function normalizeAddress(address) {
1104
- const prefix = address[0]
1105
- if (prefix === 'G')
1106
- return address
1107
- if (prefix !== 'M')
1108
- throw new TypeError('Expected ED25519 or Muxed address')
1109
- const rawBytes = StrKey.decodeMed25519PublicKey(address)
1110
- return StrKey.encodeEd25519PublicKey(rawBytes.subarray(0, 32))
1111
- }
1112
-
1113
-
1114
1116
  /**
1115
1117
  * @param {String} action
1116
1118
  * @param {String} type
@@ -1137,18 +1139,4 @@ function encodeSponsorshipEffectName(action, type) {
1137
1139
  return effectTypes[`${type}Sponsorship${actionKey}`]
1138
1140
  }
1139
1141
 
1140
- function validateAmount(amount) {
1141
- if (amount < 0)
1142
- throw new TxMetaEffectParserError('Negative balance change amount: ' + amount.toString())
1143
- return amount
1144
- }
1145
-
1146
- /**
1147
- * @param largeInt
1148
- * @return {String}
1149
- */
1150
- function parseLargeInt(largeInt) {
1151
- return largeInt._value.toString()
1152
- }
1153
-
1154
1142
  module.exports = {EffectsAnalyzer, processFeeChargedEffect}
package/src/index.js CHANGED
@@ -177,7 +177,7 @@ function parseTxOperationsMeta({
177
177
  }
178
178
  const analyzer = new EffectsAnalyzer(params)
179
179
  operation.effects = analyzer.analyze()
180
- if (analyzer.sacMap && !isEmptyObject(analyzer.sacMap)) {
180
+ if (analyzer.sacMap && analyzer.sacMap.size > 0) {
181
181
  operation.sacMap = analyzer.sacMap
182
182
  }
183
183
  if (isSorobanInvocation) {
@@ -204,12 +204,6 @@ function ensureXdrInputType(value, xdrType) {
204
204
  return xdrType.fromXDR(value, typeof value === 'string' ? 'base64' : 'raw')
205
205
  }
206
206
 
207
- function isEmptyObject(obj) {
208
- for (const key in obj)
209
- return false
210
- return true
211
- }
212
-
213
207
  /**
214
208
  * @typedef {{}} ParsedTxOperationsMetadata
215
209
  * @property {Transaction|FeeBumpTransaction} tx - Parsed transaction object
@@ -0,0 +1,73 @@
1
+ const {StrKey, Asset} = require('@stellar/stellar-base')
2
+ const {TxMetaEffectParserError} = require('../errors')
3
+
4
+ /**
5
+ * @param {String} address
6
+ * @return {String}
7
+ */
8
+ function normalizeAddress(address) {
9
+ const prefix = address[0]
10
+ if (prefix === 'G')
11
+ return address
12
+ if (prefix !== 'M')
13
+ throw new TypeError('Expected ED25519 or Muxed address')
14
+ const rawBytes = StrKey.decodeMed25519PublicKey(address)
15
+ return StrKey.encodeEd25519PublicKey(rawBytes.subarray(0, 32))
16
+ }
17
+
18
+
19
+ /**
20
+ * @param {String} address
21
+ * @return {Boolean}
22
+ */
23
+ function isContractAddress(address) {
24
+ return address.length === 56 && address[0] === 'C'
25
+ }
26
+
27
+ /**
28
+ * @param {String} asset
29
+ * @return {Asset}
30
+ */
31
+ function toStellarAsset(asset) {
32
+ if (asset === 'XLM')
33
+ return Asset.native()
34
+ if (asset.includes('-')) {
35
+ const [code, issuer] = asset.split('-')
36
+ return new Asset(code, issuer)
37
+ }
38
+ throw new TypeError('Unsupported asset format ' + asset)
39
+ }
40
+
41
+ /**
42
+ * @param {String} amount
43
+ * @param {Boolean} [throwIfInvalid]
44
+ * @return {String|null}
45
+ */
46
+ function validateAmount(amount, throwIfInvalid = true) {
47
+ let parsed
48
+ try {
49
+ if (typeof amount !== 'string')
50
+ throw new TypeError('Invalid amount type')
51
+ parsed = BigInt(amount)
52
+ } catch (e) {
53
+ if (!throwIfInvalid)
54
+ return null
55
+ throw new TxMetaEffectParserError('Invalid amount: ' + amount)
56
+ }
57
+ if (parsed < 0n) {
58
+ if (!throwIfInvalid)
59
+ return null
60
+ throw new TxMetaEffectParserError('Negative effect amount: ' + amount)
61
+ }
62
+ return amount
63
+ }
64
+
65
+ /**
66
+ * @param largeInt
67
+ * @return {String}
68
+ */
69
+ function parseLargeInt(largeInt) {
70
+ return largeInt._value.toString()
71
+ }
72
+
73
+ module.exports = {normalizeAddress, isContractAddress, toStellarAsset, validateAmount, parseLargeInt}
@@ -1,28 +1,6 @@
1
- const {xdr, StrKey, LiquidityPoolId, Asset, scValToBigInt, encodeMuxedAccount, encodeMuxedAccountToAddress} = require('@stellar/stellar-base')
1
+ const {xdr, StrKey, LiquidityPoolId, scValToBigInt, encodeMuxedAccount, encodeMuxedAccountToAddress} = require('@stellar/stellar-base')
2
2
  const {TxMetaEffectParserError} = require('../errors')
3
3
 
4
- /**
5
- * @param {String} address
6
- * @return {Boolean}
7
- */
8
- function isContractAddress(address) {
9
- return address.length === 56 && address[0] === 'C'
10
- }
11
-
12
- /**
13
- * @param {String} assetDescriptor
14
- * @return {Asset}
15
- */
16
- function toStellarAsset(assetDescriptor) {
17
- if (assetDescriptor === 'XLM')
18
- return Asset.native()
19
- if (assetDescriptor.includes('-')) {
20
- const [code, issuer] = assetDescriptor.split('-')
21
- return new Asset(code, issuer)
22
- }
23
- throw new TypeError('Unsupported asset format ' + assetDescriptor)
24
- }
25
-
26
4
  /**
27
5
  * Parse account address from XDR representation
28
6
  * @param accountId
@@ -317,7 +295,5 @@ module.exports = {
317
295
  xdrParseTradeAtom,
318
296
  xdrParseSignerKey,
319
297
  xdrParsePrice,
320
- xdrParseScVal,
321
- isContractAddress,
322
- toStellarAsset
298
+ xdrParseScVal
323
299
  }