@stellar-expert/tx-meta-effects-parser 8.3.3 → 8.4.0

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.
@@ -1,352 +1,352 @@
1
- const {
2
- xdr,
3
- StrKey,
4
- LiquidityPoolId,
5
- scValToBigInt,
6
- encodeMuxedAccount,
7
- encodeMuxedAccountToAddress
8
- } = require('@stellar/stellar-base')
9
- const {TxMetaEffectParserError} = require('../errors')
10
- const effectTypes = require('../effect-types')
11
-
12
- /**
13
- * Parse account address from XDR representation
14
- * @param accountId
15
- * @return {String}
16
- */
17
- function xdrParseAccountAddress(accountId) {
18
- if (!accountId)
19
- return undefined
20
- if (accountId.arm) {
21
- switch (accountId.arm()) {
22
- case 'ed25519':
23
- return StrKey.encodeEd25519PublicKey(accountId.ed25519())
24
- case 'med25519':
25
- return {
26
- primary: StrKey.encodeEd25519PublicKey(accountId.value().ed25519()),
27
- muxedId: accountId.value().id().toString()
28
- }
29
- default:
30
- throw new TxMetaEffectParserError(`Unsupported account type: ${accountId.arm()}`)
31
- }
32
- }
33
- if (accountId instanceof Uint8Array) {
34
- return StrKey.encodeEd25519PublicKey(accountId)
35
- }
36
- throw new TypeError(`Failed to identify and parse account address: ${accountId}`)
37
- }
38
-
39
- /**
40
- * Parse muxed account address from ScAddress XDR representation
41
- * @param {{}} value
42
- * @return {string}
43
- */
44
- function xdrParseMuxedScAddress(value) {
45
- const {ed25519, id} = value._attributes
46
- const muxed = encodeMuxedAccount(StrKey.encodeEd25519PublicKey(ed25519), id._value.toString())
47
- return encodeMuxedAccountToAddress(muxed)
48
- }
49
-
50
- /**
51
- * Parse Contract ID from raw bytes
52
- * @param {Buffer} rawContractId
53
- * @return {String}
54
- */
55
- function xdrParseContractAddress(rawContractId) {
56
- return StrKey.encodeContract(rawContractId)
57
- }
58
-
59
- /**
60
- * Parse XDR price representation
61
- * @param {{n: Function, d: Function}} price
62
- * @return {Number}
63
- */
64
- function xdrParsePrice(price) {
65
- return price.n() / price.d()
66
- }
67
-
68
- /**
69
- * @param {string} address
70
- * @return {string}
71
- */
72
- function retrieveBaseMuxedAddress(address) {
73
- const rawBytes = StrKey.decodeMed25519PublicKey(address)
74
- return StrKey.encodeEd25519PublicKey(rawBytes.subarray(0, 32))
75
- }
76
-
77
- /**
78
- * Parse account signer key XDR
79
- * @param {xdr.SignerKey} signer
80
- * @return {String}
81
- */
82
- function xdrParseSignerKey(signer) {
83
- const type = signer.arm()
84
- switch (type) {
85
- case 'ed25519':
86
- return StrKey.encodeEd25519PublicKey(signer.ed25519())
87
- case 'preAuthTx':
88
- return StrKey.encodePreAuthTx(signer.preAuthTx())
89
- case 'hashX':
90
- return StrKey.encodeSha256Hash(signer.hashX())
91
- case 'ed25519SignedPayload':
92
- let key = signer.ed25519SignedPayload()
93
- if (key._attributes){
94
- key = key._attributes.ed25519
95
- }
96
- return StrKey.encodeSignedPayload(key) //TODO: check
97
- }
98
- throw new TxMetaEffectParserError(`Unsupported signer type: "${type}"`)
99
- }
100
-
101
-
102
- /**
103
- * @typedef {Object} ParsedOffer
104
- * @property {String} account
105
- * @property {Array<String>} asset
106
- * @property {Array<String>} amount
107
- * @property {String} offerId?
108
- * @property {Buffer} poolId?
109
- */
110
-
111
- /**
112
- * Parse maker offer descriptor from raw XDR.
113
- * @param {Object} offerXdr
114
- * @return {ParsedOffer}
115
- */
116
- function xdrParseTradeAtom(offerXdr) {
117
- return {
118
- offerId: offerXdr.offerId().toString(),
119
- account: xdrParseAccountAddress(offerXdr.sellerId()),
120
- asset: [xdrParseAsset(offerXdr.selling()).toString(), xdrParseAsset(offerXdr.buying()).toString()],
121
- //offer amount is always stored in terms of a selling asset, even for buy offers
122
- amount: (offerXdr.amount() || offerXdr.buyAmount()).toString(),
123
- //flags: offerXdr.flags()
124
- price: xdrParsePrice(offerXdr.price())
125
- }
126
- }
127
-
128
- /**
129
- * Parse claimed offer atom from raw XDR.
130
- * @param {xdr.ClaimAtom} claimedAtom
131
- * @return {ParsedOffer}
132
- */
133
- function xdrParseClaimedOffer(claimedAtom) {
134
- const atomType = claimedAtom.arm()
135
- let res
136
- switch (atomType) {
137
- case 'v0':
138
- claimedAtom = claimedAtom.v0()
139
- res = {
140
- account: xdrParseAccountAddress(claimedAtom.sellerEd25519()),
141
- offerId: claimedAtom.offerId().toString()
142
- }
143
- break
144
- case 'orderBook':
145
- claimedAtom = claimedAtom.orderBook()
146
- res = {
147
- account: xdrParseAccountAddress(claimedAtom.sellerId()),
148
- offerId: claimedAtom.offerId().toString()
149
- }
150
- break
151
- case 'liquidityPool':
152
- claimedAtom = claimedAtom.liquidityPool()
153
- res = {
154
- poolId: claimedAtom.liquidityPoolId()
155
- }
156
- break
157
- default:
158
- throw new TxMetaEffectParserError(`Unsupported claimed atom type: ` + atomType)
159
- }
160
- return {
161
- asset: [
162
- xdrParseAsset(claimedAtom.assetSold()),
163
- xdrParseAsset(claimedAtom.assetBought())
164
- ],
165
- amount: [
166
- claimedAtom.amountSold().toString(),
167
- claimedAtom.amountBought().toString()
168
- ],
169
- ...res
170
- }
171
- }
172
-
173
- function xdrParseClaimantPredicate(predicate) {
174
- if (!predicate) return {}
175
- const type = predicate.switch().name
176
- const value = predicate.value()
177
- switch (type) {
178
- case 'claimPredicateUnconditional':
179
- return {}
180
- case 'claimPredicateAnd':
181
- return {and: value.map(p => xdrParseClaimantPredicate(p))}
182
- case 'claimPredicateOr':
183
- return {or: value.map(p => xdrParseClaimantPredicate(p))}
184
- case 'claimPredicateNot':
185
- return {not: xdrParseClaimantPredicate(value)}
186
- case 'claimPredicateBeforeAbsoluteTime':
187
- return {absBefore: value.toString()}
188
- case 'claimPredicateBeforeRelativeTime':
189
- return {relBefore: value.toString()}
190
- default:
191
- throw new TxMetaEffectParserError(`Unknown claim condition predicate: ${type}`)
192
- }
193
- }
194
-
195
- function xdrParseClaimant(claimant) {
196
- const value = claimant.value()
197
- return {
198
- destination: xdrParseAccountAddress(value.destination()),
199
- predicate: xdrParseClaimantPredicate(value.predicate())
200
- }
201
- }
202
-
203
- function xdrParseAsset(src) {
204
- if (!src)
205
- return undefined
206
-
207
- if (src.arm) { //XDR
208
- switch (src.switch().name) {
209
- case 'assetTypeNative':
210
- return 'XLM'
211
- case 'assetTypePoolShare': {
212
- const poolId = src.value()
213
- if (poolId.length)
214
- return poolId.toString('hex')
215
- if (poolId.constantProduct)
216
- return LiquidityPoolId.fromOperation(poolId).getLiquidityPoolId()
217
- throw new TxMetaEffectParserError('Unsupported liquidity pool asset id format')
218
- }
219
- default: {
220
- const value = src.value()
221
- return `${value.assetCode().toString().replace(/\0+$/, '')}-${StrKey.encodeEd25519PublicKey(value.issuer().ed25519())}-${src.arm() === 'alphaNum4' ? 1 : 2}`
222
- }
223
- }
224
- }
225
-
226
- if (typeof src === 'string') {
227
- if (src === 'XLM' || src === 'native')
228
- return 'XLM'//already parsed value
229
- if (src.includes(':')) {
230
- const [code, issuer] = src.split(':')
231
- return `${code.replace(/\0+$/, '')}-${issuer}-${code.length > 4 ? 2 : 1}`
232
- }
233
- if (src.includes('-'))
234
- return src //already parsed
235
- if (src.length === 64)
236
- return src //pool id
237
- }
238
- if (src.type === 0 && !src.code || src.code === 'XLM' && !src.issuer)
239
- return 'XLM'
240
- if (src.code && src.issuer)
241
- return `${src.code}-${src.issuer}-${src.type || (src.code.length > 4 ? 2 : 1)}`
242
- }
243
-
244
- function xdrParseScVal(value, treatBytesAsContractId = false) {
245
- if (typeof value === 'string') {
246
- value = xdr.ScVal.fromXDR(value, 'base64')
247
- }
248
- switch (value._arm) {
249
- case 'vec':
250
- return value._value.map(xdrParseScVal)
251
- case 'map':
252
- const res = {}
253
- for (const entry of value._value) {
254
- res[xdrParseScVal(entry.key())] = xdrParseScVal(entry.val())
255
- }
256
- return res
257
- case 'i256':
258
- case 'u256':
259
- case 'i128':
260
- case 'u128':
261
- case 'i64':
262
- case 'u64':
263
- return scValToBigInt(value).toString()
264
- case 'timepoint':
265
- case 'duration':
266
- return value._value._value.toString()
267
- case 'address':
268
- switch (value._value._arm) {
269
- case 'accountId':
270
- return xdrParseAccountAddress(value._value.value())
271
- case 'contractId':
272
- return xdrParseContractAddress(value._value.value())
273
- case 'muxedAccount':
274
- return xdrParseMuxedScAddress(value._value.value())
275
- }
276
- throw new TxMetaEffectParserError('Not supported XDR primitive type: ' + value._value._arm.toString())
277
- case 'bytes':
278
- return treatBytesAsContractId ? xdrParseContractAddress(value.value()) : value._value.toString('base64')
279
- case 'i32':
280
- case 'u32':
281
- case 'b':
282
- return value._value
283
- case 'str':
284
- case 'sym':
285
- return value._value.toString()
286
- case 'nonceKey':
287
- return value._value.nonce()._value.toString()
288
- case 'instance':
289
- return value._value.executable.wasmHash().toString('base64')
290
- case 'error':
291
- return value.toXDR('base64')
292
- case 'contractId':
293
- return xdrParseContractAddress(value._value)
294
- default:
295
- switch (value._switch.name) {
296
- case 'scvVoid':
297
- return undefined
298
- case 'scvContractInstance':
299
- return '<ContractInstance>'
300
- case 'scvLedgerKeyContractInstance':
301
- return '<LedgerKeyContractInstance>'
302
- case 'scvLedgerKeyNonce':
303
- return '<LedgerKeyNonce>'
304
- }
305
- throw new TxMetaEffectParserError('Not supported XDR primitive type: ' + value.toXDR ? value.toXDR() : value.toString())
306
- }
307
- }
308
-
309
- function xdrParseSacBalanceChange(changeEventType, key, value) {
310
- const parsedKey = xdr.ScVal.fromXDR(key, 'base64')
311
- if (parsedKey._arm !== 'vec')
312
- return null
313
- const keyParts = parsedKey._value
314
- if (!(keyParts instanceof Array) || keyParts.length !== 2)
315
- return null
316
- if (keyParts[0]._arm !== 'sym' || keyParts[1]._arm !== 'address' || keyParts[0]._value.toString() !== 'Balance')
317
- return null
318
- const res = {
319
- address: xdrParseScVal(keyParts[1]),
320
- balance: changeEventType===effectTypes.contractDataRemoved?
321
- '0':
322
- retrieveBalanceFromStateData(value)
323
- }
324
- if (res.balance === undefined)
325
- return null
326
- return res
327
- }
328
-
329
- function retrieveBalanceFromStateData(value) {
330
- const xdrVal = xdr.ScVal.fromXDR(value, 'base64')
331
- if (xdrVal._arm !== 'map')
332
- return undefined
333
- const parsedValue = xdrParseScVal(xdrVal)
334
- if (typeof parsedValue.amount !== 'string')
335
- return undefined
336
- return parsedValue.amount
337
- }
338
-
339
- module.exports = {
340
- xdrParseAsset,
341
- xdrParseAccountAddress,
342
- xdrParseContractAddress,
343
- xdrParseMuxedScAddress,
344
- xdrParseClaimant,
345
- xdrParseClaimedOffer,
346
- xdrParseTradeAtom,
347
- xdrParseSignerKey,
348
- xdrParsePrice,
349
- xdrParseScVal,
350
- xdrParseSacBalanceChange,
351
- retrieveBaseMuxedAddress
352
- }
1
+ const {
2
+ xdr,
3
+ StrKey,
4
+ LiquidityPoolId,
5
+ scValToBigInt,
6
+ encodeMuxedAccount,
7
+ encodeMuxedAccountToAddress
8
+ } = require('@stellar/stellar-base')
9
+ const {TxMetaEffectParserError} = require('../errors')
10
+ const effectTypes = require('../effect-types')
11
+
12
+ /**
13
+ * Parse account address from XDR representation
14
+ * @param accountId
15
+ * @return {String}
16
+ */
17
+ function xdrParseAccountAddress(accountId) {
18
+ if (!accountId)
19
+ return undefined
20
+ if (accountId.arm) {
21
+ switch (accountId.arm()) {
22
+ case 'ed25519':
23
+ return StrKey.encodeEd25519PublicKey(accountId.ed25519())
24
+ case 'med25519':
25
+ return {
26
+ primary: StrKey.encodeEd25519PublicKey(accountId.value().ed25519()),
27
+ muxedId: accountId.value().id().toString()
28
+ }
29
+ default:
30
+ throw new TxMetaEffectParserError(`Unsupported account type: ${accountId.arm()}`)
31
+ }
32
+ }
33
+ if (accountId instanceof Uint8Array) {
34
+ return StrKey.encodeEd25519PublicKey(accountId)
35
+ }
36
+ throw new TypeError(`Failed to identify and parse account address: ${accountId}`)
37
+ }
38
+
39
+ /**
40
+ * Parse muxed account address from ScAddress XDR representation
41
+ * @param {{}} value
42
+ * @return {string}
43
+ */
44
+ function xdrParseMuxedScAddress(value) {
45
+ const {ed25519, id} = value._attributes
46
+ const muxed = encodeMuxedAccount(StrKey.encodeEd25519PublicKey(ed25519), id._value.toString())
47
+ return encodeMuxedAccountToAddress(muxed)
48
+ }
49
+
50
+ /**
51
+ * Parse Contract ID from raw bytes
52
+ * @param {Buffer} rawContractId
53
+ * @return {String}
54
+ */
55
+ function xdrParseContractAddress(rawContractId) {
56
+ return StrKey.encodeContract(rawContractId)
57
+ }
58
+
59
+ /**
60
+ * Parse XDR price representation
61
+ * @param {{n: Function, d: Function}} price
62
+ * @return {Number}
63
+ */
64
+ function xdrParsePrice(price) {
65
+ return price.n() / price.d()
66
+ }
67
+
68
+ /**
69
+ * @param {string} address
70
+ * @return {string}
71
+ */
72
+ function retrieveBaseMuxedAddress(address) {
73
+ const rawBytes = StrKey.decodeMed25519PublicKey(address)
74
+ return StrKey.encodeEd25519PublicKey(rawBytes.subarray(0, 32))
75
+ }
76
+
77
+ /**
78
+ * Parse account signer key XDR
79
+ * @param {xdr.SignerKey} signer
80
+ * @return {String}
81
+ */
82
+ function xdrParseSignerKey(signer) {
83
+ const type = signer.arm()
84
+ switch (type) {
85
+ case 'ed25519':
86
+ return StrKey.encodeEd25519PublicKey(signer.ed25519())
87
+ case 'preAuthTx':
88
+ return StrKey.encodePreAuthTx(signer.preAuthTx())
89
+ case 'hashX':
90
+ return StrKey.encodeSha256Hash(signer.hashX())
91
+ case 'ed25519SignedPayload':
92
+ let key = signer.ed25519SignedPayload()
93
+ if (key._attributes){
94
+ key = key._attributes.ed25519
95
+ }
96
+ return StrKey.encodeSignedPayload(key) //TODO: check
97
+ }
98
+ throw new TxMetaEffectParserError(`Unsupported signer type: "${type}"`)
99
+ }
100
+
101
+
102
+ /**
103
+ * @typedef {Object} ParsedOffer
104
+ * @property {String} account
105
+ * @property {Array<String>} asset
106
+ * @property {Array<String>} amount
107
+ * @property {String} offerId?
108
+ * @property {Buffer} poolId?
109
+ */
110
+
111
+ /**
112
+ * Parse maker offer descriptor from raw XDR.
113
+ * @param {Object} offerXdr
114
+ * @return {ParsedOffer}
115
+ */
116
+ function xdrParseTradeAtom(offerXdr) {
117
+ return {
118
+ offerId: offerXdr.offerId().toString(),
119
+ account: xdrParseAccountAddress(offerXdr.sellerId()),
120
+ asset: [xdrParseAsset(offerXdr.selling()).toString(), xdrParseAsset(offerXdr.buying()).toString()],
121
+ //offer amount is always stored in terms of a selling asset, even for buy offers
122
+ amount: (offerXdr.amount() || offerXdr.buyAmount()).toString(),
123
+ //flags: offerXdr.flags()
124
+ price: xdrParsePrice(offerXdr.price())
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Parse claimed offer atom from raw XDR.
130
+ * @param {xdr.ClaimAtom} claimedAtom
131
+ * @return {ParsedOffer}
132
+ */
133
+ function xdrParseClaimedOffer(claimedAtom) {
134
+ const atomType = claimedAtom.arm()
135
+ let res
136
+ switch (atomType) {
137
+ case 'v0':
138
+ claimedAtom = claimedAtom.v0()
139
+ res = {
140
+ account: xdrParseAccountAddress(claimedAtom.sellerEd25519()),
141
+ offerId: claimedAtom.offerId().toString()
142
+ }
143
+ break
144
+ case 'orderBook':
145
+ claimedAtom = claimedAtom.orderBook()
146
+ res = {
147
+ account: xdrParseAccountAddress(claimedAtom.sellerId()),
148
+ offerId: claimedAtom.offerId().toString()
149
+ }
150
+ break
151
+ case 'liquidityPool':
152
+ claimedAtom = claimedAtom.liquidityPool()
153
+ res = {
154
+ poolId: claimedAtom.liquidityPoolId()
155
+ }
156
+ break
157
+ default:
158
+ throw new TxMetaEffectParserError(`Unsupported claimed atom type: ` + atomType)
159
+ }
160
+ return {
161
+ asset: [
162
+ xdrParseAsset(claimedAtom.assetSold()),
163
+ xdrParseAsset(claimedAtom.assetBought())
164
+ ],
165
+ amount: [
166
+ claimedAtom.amountSold().toString(),
167
+ claimedAtom.amountBought().toString()
168
+ ],
169
+ ...res
170
+ }
171
+ }
172
+
173
+ function xdrParseClaimantPredicate(predicate) {
174
+ if (!predicate) return {}
175
+ const type = predicate.switch().name
176
+ const value = predicate.value()
177
+ switch (type) {
178
+ case 'claimPredicateUnconditional':
179
+ return {}
180
+ case 'claimPredicateAnd':
181
+ return {and: value.map(p => xdrParseClaimantPredicate(p))}
182
+ case 'claimPredicateOr':
183
+ return {or: value.map(p => xdrParseClaimantPredicate(p))}
184
+ case 'claimPredicateNot':
185
+ return {not: xdrParseClaimantPredicate(value)}
186
+ case 'claimPredicateBeforeAbsoluteTime':
187
+ return {absBefore: value.toString()}
188
+ case 'claimPredicateBeforeRelativeTime':
189
+ return {relBefore: value.toString()}
190
+ default:
191
+ throw new TxMetaEffectParserError(`Unknown claim condition predicate: ${type}`)
192
+ }
193
+ }
194
+
195
+ function xdrParseClaimant(claimant) {
196
+ const value = claimant.value()
197
+ return {
198
+ destination: xdrParseAccountAddress(value.destination()),
199
+ predicate: xdrParseClaimantPredicate(value.predicate())
200
+ }
201
+ }
202
+
203
+ function xdrParseAsset(src) {
204
+ if (!src)
205
+ return undefined
206
+
207
+ if (src.arm) { //XDR
208
+ switch (src.switch().name) {
209
+ case 'assetTypeNative':
210
+ return 'XLM'
211
+ case 'assetTypePoolShare': {
212
+ const poolId = src.value()
213
+ if (poolId.length)
214
+ return poolId.toString('hex')
215
+ if (poolId.constantProduct)
216
+ return LiquidityPoolId.fromOperation(poolId).getLiquidityPoolId()
217
+ throw new TxMetaEffectParserError('Unsupported liquidity pool asset id format')
218
+ }
219
+ default: {
220
+ const value = src.value()
221
+ return `${value.assetCode().toString().replace(/\0+$/, '')}-${StrKey.encodeEd25519PublicKey(value.issuer().ed25519())}-${src.arm() === 'alphaNum4' ? 1 : 2}`
222
+ }
223
+ }
224
+ }
225
+
226
+ if (typeof src === 'string') {
227
+ if (src === 'XLM' || src === 'native')
228
+ return 'XLM'//already parsed value
229
+ if (src.includes(':')) {
230
+ const [code, issuer] = src.split(':')
231
+ return `${code.replace(/\0+$/, '')}-${issuer}-${code.length > 4 ? 2 : 1}`
232
+ }
233
+ if (src.includes('-'))
234
+ return src //already parsed
235
+ if (src.length === 64)
236
+ return src //pool id
237
+ }
238
+ if (src.type === 0 && !src.code || src.code === 'XLM' && !src.issuer)
239
+ return 'XLM'
240
+ if (src.code && src.issuer)
241
+ return `${src.code}-${src.issuer}-${src.type || (src.code.length > 4 ? 2 : 1)}`
242
+ }
243
+
244
+ function xdrParseScVal(value, treatBytesAsContractId = false) {
245
+ if (typeof value === 'string') {
246
+ value = xdr.ScVal.fromXDR(value, 'base64')
247
+ }
248
+ switch (value._arm) {
249
+ case 'vec':
250
+ return value._value.map(xdrParseScVal)
251
+ case 'map':
252
+ const res = {}
253
+ for (const entry of value._value) {
254
+ res[xdrParseScVal(entry.key())] = xdrParseScVal(entry.val())
255
+ }
256
+ return res
257
+ case 'i256':
258
+ case 'u256':
259
+ case 'i128':
260
+ case 'u128':
261
+ case 'i64':
262
+ case 'u64':
263
+ return scValToBigInt(value).toString()
264
+ case 'timepoint':
265
+ case 'duration':
266
+ return value._value._value.toString()
267
+ case 'address':
268
+ switch (value._value._arm) {
269
+ case 'accountId':
270
+ return xdrParseAccountAddress(value._value.value())
271
+ case 'contractId':
272
+ return xdrParseContractAddress(value._value.value())
273
+ case 'muxedAccount':
274
+ return xdrParseMuxedScAddress(value._value.value())
275
+ }
276
+ throw new TxMetaEffectParserError('Not supported XDR primitive type: ' + value._value._arm.toString())
277
+ case 'bytes':
278
+ return treatBytesAsContractId ? xdrParseContractAddress(value.value()) : value._value.toString('base64')
279
+ case 'i32':
280
+ case 'u32':
281
+ case 'b':
282
+ return value._value
283
+ case 'str':
284
+ case 'sym':
285
+ return value._value.toString()
286
+ case 'nonceKey':
287
+ return value._value.nonce()._value.toString()
288
+ case 'instance':
289
+ return value._value.executable.wasmHash().toString('base64')
290
+ case 'error':
291
+ return value.toXDR('base64')
292
+ case 'contractId':
293
+ return xdrParseContractAddress(value._value)
294
+ default:
295
+ switch (value._switch.name) {
296
+ case 'scvVoid':
297
+ return undefined
298
+ case 'scvContractInstance':
299
+ return '<ContractInstance>'
300
+ case 'scvLedgerKeyContractInstance':
301
+ return '<LedgerKeyContractInstance>'
302
+ case 'scvLedgerKeyNonce':
303
+ return '<LedgerKeyNonce>'
304
+ }
305
+ throw new TxMetaEffectParserError('Not supported XDR primitive type: ' + value.toXDR ? value.toXDR() : value.toString())
306
+ }
307
+ }
308
+
309
+ function xdrParseSacBalanceChange(changeEventType, key, value) {
310
+ const parsedKey = xdr.ScVal.fromXDR(key, 'base64')
311
+ if (parsedKey._arm !== 'vec')
312
+ return null
313
+ const keyParts = parsedKey._value
314
+ if (!(keyParts instanceof Array) || keyParts.length !== 2)
315
+ return null
316
+ if (keyParts[0]._arm !== 'sym' || keyParts[1]._arm !== 'address' || keyParts[0]._value.toString() !== 'Balance')
317
+ return null
318
+ const res = {
319
+ address: xdrParseScVal(keyParts[1]),
320
+ balance: changeEventType===effectTypes.contractDataRemoved?
321
+ '0':
322
+ retrieveBalanceFromStateData(value)
323
+ }
324
+ if (res.balance === undefined)
325
+ return null
326
+ return res
327
+ }
328
+
329
+ function retrieveBalanceFromStateData(value) {
330
+ const xdrVal = xdr.ScVal.fromXDR(value, 'base64')
331
+ if (xdrVal._arm !== 'map')
332
+ return undefined
333
+ const parsedValue = xdrParseScVal(xdrVal)
334
+ if (typeof parsedValue.amount !== 'string')
335
+ return undefined
336
+ return parsedValue.amount
337
+ }
338
+
339
+ module.exports = {
340
+ xdrParseAsset,
341
+ xdrParseAccountAddress,
342
+ xdrParseContractAddress,
343
+ xdrParseMuxedScAddress,
344
+ xdrParseClaimant,
345
+ xdrParseClaimedOffer,
346
+ xdrParseTradeAtom,
347
+ xdrParseSignerKey,
348
+ xdrParsePrice,
349
+ xdrParseScVal,
350
+ xdrParseSacBalanceChange,
351
+ retrieveBaseMuxedAddress
352
+ }