@stellar-expert/tx-meta-effects-parser 7.0.0-rc.7 → 7.0.0-rc.9
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,4 +1,4 @@
|
|
|
1
|
-
const {StrKey} = require('@stellar/stellar-base')
|
|
1
|
+
const {StrKey, encodeMuxedAccount, encodeMuxedAccountToAddress} = require('@stellar/stellar-base')
|
|
2
2
|
const effectTypes = require('../effect-types')
|
|
3
3
|
const {xdrParseScVal, xdrParseAsset, isContractAddress} = require('../parser/tx-xdr-parser-utils')
|
|
4
4
|
const {mapSacContract} = require('./sac-contract-mapper')
|
|
@@ -146,15 +146,19 @@ class EventsAnalyzer {
|
|
|
146
146
|
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']))
|
|
147
147
|
return
|
|
148
148
|
const from = xdrParseScVal(topics[1])
|
|
149
|
-
const
|
|
149
|
+
const receiver = xdrParseScVal(topics[2])
|
|
150
|
+
let to = receiver
|
|
151
|
+
let amount = processEventBodyValue(body.data())
|
|
152
|
+
if (amount?.amount !== undefined) {
|
|
153
|
+
if (amount.to_muxed_id && !to.startsWith('M')) {
|
|
154
|
+
to = encodeMuxedAccountToAddress(encodeMuxedAccount(to, amount.to_muxed_id))
|
|
155
|
+
amount = amount.amount
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (typeof amount!=='string')
|
|
159
|
+
return null
|
|
150
160
|
if (to === from) //self transfer - nothing happens
|
|
151
161
|
return // TODO: need additional checks
|
|
152
|
-
const amount = processEventBodyValue(body.data())
|
|
153
|
-
if (!this.matchInvocationEffect(e =>
|
|
154
|
-
(e.function === 'transfer' && matchArrays([from, to, amount], e.args)) ||
|
|
155
|
-
(e.function === 'transfer_from' && matchArrays([undefined, from, to, amount], e.args))
|
|
156
|
-
))
|
|
157
|
-
return
|
|
158
162
|
let classicAsset
|
|
159
163
|
if (topics.length > 3) {
|
|
160
164
|
classicAsset = xdrParseAsset(xdrParseScVal(topics[3]))
|
|
@@ -172,7 +176,7 @@ class EventsAnalyzer {
|
|
|
172
176
|
if (isContractAddress(to)) {
|
|
173
177
|
this.effectsAnalyzer.credit(amount, classicAsset, to)
|
|
174
178
|
}
|
|
175
|
-
if (classicAsset.includes(
|
|
179
|
+
if (classicAsset.includes(receiver)) { //SAC transfer by asset issuer
|
|
176
180
|
this.effectsAnalyzer.burn(classicAsset, amount)
|
|
177
181
|
}
|
|
178
182
|
} else { //other cases
|
|
@@ -182,14 +186,21 @@ class EventsAnalyzer {
|
|
|
182
186
|
}
|
|
183
187
|
break
|
|
184
188
|
case 'mint': {
|
|
185
|
-
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']))
|
|
189
|
+
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']) && !matchEventTopicsShape(topics, ['address', 'str?']))
|
|
186
190
|
return //throw new Error('Non-standard event')
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
let to = xdrParseScVal(topics[topics[2]?._arm === 'address' ? 2 : 1])
|
|
192
|
+
let amount = processEventBodyValue(body.data())
|
|
193
|
+
if (amount?.amount !== undefined) {
|
|
194
|
+
if (amount.to_muxed_id && !to.startsWith('M')) {
|
|
195
|
+
to = encodeMuxedAccountToAddress(encodeMuxedAccount(to, amount.to_muxed_id))
|
|
196
|
+
amount = amount.amount
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (typeof amount !== 'string')
|
|
200
|
+
return null
|
|
201
|
+
const last = topics[topics.length - 1]
|
|
202
|
+
if (last._arm === 'str') {
|
|
203
|
+
mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(last)))
|
|
193
204
|
}
|
|
194
205
|
const asset = this.effectsAnalyzer.resolveAsset(contract)
|
|
195
206
|
this.effectsAnalyzer.mint(asset, amount)
|
|
@@ -203,13 +214,8 @@ class EventsAnalyzer {
|
|
|
203
214
|
return //throw new Error('Non-standard event')
|
|
204
215
|
const from = xdrParseScVal(topics[1])
|
|
205
216
|
const amount = processEventBodyValue(body.data())
|
|
206
|
-
if (
|
|
207
|
-
return
|
|
208
|
-
if (!this.matchInvocationEffect(e =>
|
|
209
|
-
(e.function === 'burn' && matchArrays([from, amount], e.args)) ||
|
|
210
|
-
(e.function === 'burn_from' && matchArrays([undefined, from, amount], e.args))
|
|
211
|
-
))
|
|
212
|
-
return
|
|
217
|
+
if (typeof amount !== 'string')
|
|
218
|
+
return null
|
|
213
219
|
if (topics.length > 2) {
|
|
214
220
|
mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[2])))
|
|
215
221
|
}
|
|
@@ -221,12 +227,12 @@ class EventsAnalyzer {
|
|
|
221
227
|
}
|
|
222
228
|
break
|
|
223
229
|
case 'clawback': {
|
|
224
|
-
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']))
|
|
230
|
+
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']) && !matchEventTopicsShape(topics, ['address', 'str?']))
|
|
225
231
|
return //throw new Error('Non-standard event')
|
|
226
|
-
const from = xdrParseScVal(topics[2])
|
|
232
|
+
const from = xdrParseScVal(topics[topics[2]?._arm === 'address' ? 2 : 1])
|
|
227
233
|
const amount = processEventBodyValue(body.data())
|
|
228
|
-
if (
|
|
229
|
-
return
|
|
234
|
+
if (typeof amount !== 'string')
|
|
235
|
+
return null
|
|
230
236
|
if (topics.length > 3) {
|
|
231
237
|
mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[3])))
|
|
232
238
|
}
|
|
@@ -240,15 +246,14 @@ class EventsAnalyzer {
|
|
|
240
246
|
return //throw new Error('Non-standard event')
|
|
241
247
|
const currentAdmin = xdrParseScVal(topics[1])
|
|
242
248
|
const newAdmin = processEventBodyValue(body.data())
|
|
243
|
-
if (!this.matchInvocationEffect(e => e.function === 'set_admin' && matchArrays([currentAdmin, newAdmin], [this.effectsAnalyzer.source, e.args])))
|
|
244
|
-
return
|
|
245
249
|
if (topics.length > 2) {
|
|
246
250
|
mapSacContract(this.effectsAnalyzer, contract, xdrParseAsset(xdrParseScVal(topics[2])))
|
|
247
251
|
}
|
|
248
252
|
this.effectsAnalyzer.setAdmin(contract, newAdmin)
|
|
249
253
|
}
|
|
250
254
|
break
|
|
251
|
-
/*case '
|
|
255
|
+
/*case 'set_authorized':*/ //TODO: think about processing this effects
|
|
256
|
+
/*case 'approve': {
|
|
252
257
|
if (!matchEventTopicsShape(topics, ['address', 'address', 'str?']))
|
|
253
258
|
throw new Error('Non-standard event')
|
|
254
259
|
const from = xdrParseScVal(topics[1])
|
|
@@ -260,12 +265,14 @@ class EventsAnalyzer {
|
|
|
260
265
|
break*/
|
|
261
266
|
}
|
|
262
267
|
}
|
|
263
|
-
|
|
264
|
-
matchInvocationEffect(cb) {
|
|
265
|
-
return this.effectsAnalyzer.effects.find(e => e.type === effectTypes.contractInvoked && cb(e))
|
|
266
|
-
}
|
|
267
268
|
}
|
|
268
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Compare types in the topics array with expected values
|
|
272
|
+
* @param {ScVal[]} topics
|
|
273
|
+
* @param {string[]} shape
|
|
274
|
+
* @return {boolean}
|
|
275
|
+
*/
|
|
269
276
|
function matchEventTopicsShape(topics, shape) {
|
|
270
277
|
if (topics.length > shape.length + 1)
|
|
271
278
|
return false
|
|
@@ -287,22 +294,12 @@ function matchEventTopicsShape(topics, shape) {
|
|
|
287
294
|
return true
|
|
288
295
|
}
|
|
289
296
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return false
|
|
295
|
-
for (let i = a.length; i--;) {
|
|
296
|
-
if (a[i] !== undefined && a[i] !== b[i]) //undefined serves as * substitution
|
|
297
|
-
return false
|
|
298
|
-
}
|
|
299
|
-
return true
|
|
300
|
-
}
|
|
301
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Retrieve event body value
|
|
299
|
+
* @param value
|
|
300
|
+
*/
|
|
302
301
|
function processEventBodyValue(value) {
|
|
303
302
|
const innerValue = value.value()
|
|
304
|
-
/*if (innerValue instanceof Array) //handle simple JS arrays
|
|
305
|
-
return innerValue.map(xdrParseScVal)*/
|
|
306
303
|
if (!innerValue) //scVoid
|
|
307
304
|
return null
|
|
308
305
|
return xdrParseScVal(value) //other scValue
|
|
@@ -24,12 +24,16 @@ function mapSacContract(effectsAnalyzer, contractAddress, classicAsset) {
|
|
|
24
24
|
//try to load from cache first
|
|
25
25
|
const fromCache = sacCache.get(classicAsset + network)
|
|
26
26
|
if (!fromCache) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
contractAddress
|
|
31
|
-
|
|
27
|
+
try {
|
|
28
|
+
const encodedContract = contractIdFromAsset(toStellarAsset(classicAsset), network)
|
|
29
|
+
sacCache.set(classicAsset + network, contractAddress)
|
|
30
|
+
if (contractAddress === undefined) {
|
|
31
|
+
contractAddress = encodedContract
|
|
32
|
+
} else if (encodedContract !== contractAddress)
|
|
33
|
+
return false
|
|
34
|
+
} catch (e) {
|
|
32
35
|
return false
|
|
36
|
+
}
|
|
33
37
|
} else if (contractAddress !== fromCache)
|
|
34
38
|
return false //check whether validated contract from cache matches the asset
|
|
35
39
|
if (sacMap) {
|