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