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