@stellar-expert/tx-meta-effects-parser 5.0.0-beta10
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/.eslintrc.js +8 -0
- package/.npmignore +6 -0
- package/LICENSE +21 -0
- package/README.MD +1145 -0
- package/babel.config.js +3 -0
- package/jest.config.js +6 -0
- package/package.json +21 -0
- package/src/analyzer-primitives.js +150 -0
- package/src/asset-supply-processor.js +130 -0
- package/src/contract-preimage-encoder.js +43 -0
- package/src/effect-types.js +97 -0
- package/src/effect.js +24 -0
- package/src/errors.js +13 -0
- package/src/events-analyzer.js +308 -0
- package/src/index.js +161 -0
- package/src/ledger-entry-changes-parser.js +333 -0
- package/src/signer-changes-analyzer.js +147 -0
- package/src/tx-effects-analyzer.js +826 -0
- package/src/tx-meta-changes-parser.js +35 -0
- package/src/tx-result-parser.js +127 -0
- package/src/tx-xdr-parser-utils.js +276 -0
package/babel.config.js
ADDED
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stellar-expert/tx-meta-effects-parser",
|
|
3
|
+
"version": "5.0.0-beta10",
|
|
4
|
+
"description": "Low-level effects parser for Stellar transaction results and meta XDR",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest"
|
|
8
|
+
},
|
|
9
|
+
"author": "team@stellar.expert",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"@stellar/stellar-base": "^10.0.1"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@babel/core": "^7.22.9",
|
|
16
|
+
"@babel/preset-env": "^7.22.9",
|
|
17
|
+
"@stellar-expert/eslint-config-js": "^1.1.0",
|
|
18
|
+
"babel-jest": "^29.6.1",
|
|
19
|
+
"jest": "^29.6.1"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const {StrKey} = require('@stellar/stellar-base')
|
|
2
|
+
const effectTypes = require('./effect-types')
|
|
3
|
+
const {UnexpectedTxMetaChangeError} = require('./errors')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns true for AlphaNum4/12 assets adn false otherwise
|
|
7
|
+
* @param {String} asset
|
|
8
|
+
*/
|
|
9
|
+
function isAsset(asset) {
|
|
10
|
+
return asset.includes('-') //lazy check for {code}-{issuer}-{type} format
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert value in stroops (Int64 amount) to the normal string representation
|
|
16
|
+
* @param {String|Number|BigInt} valueInStroops
|
|
17
|
+
* @return {String}
|
|
18
|
+
*/
|
|
19
|
+
function fromStroops(valueInStroops) {
|
|
20
|
+
try {
|
|
21
|
+
let parsed = typeof valueInStroops === 'bigint' ?
|
|
22
|
+
valueInStroops :
|
|
23
|
+
BigInt(valueInStroops.toString())
|
|
24
|
+
let negative = false
|
|
25
|
+
if (parsed < 0n) {
|
|
26
|
+
negative = true
|
|
27
|
+
parsed *= -1n
|
|
28
|
+
}
|
|
29
|
+
const int = parsed / 10000000n
|
|
30
|
+
const fract = parsed % 10000000n
|
|
31
|
+
let res = int.toString()
|
|
32
|
+
if (fract) {
|
|
33
|
+
res += '.' + fract.toString().padStart(7, '0')
|
|
34
|
+
}
|
|
35
|
+
if (negative) {
|
|
36
|
+
res = '-' + res
|
|
37
|
+
}
|
|
38
|
+
return trimZeros(res)
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return '0'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convert arbitrary stringified amount to int64 representation
|
|
47
|
+
* @param {String|Number} value
|
|
48
|
+
* @return {BigInt}
|
|
49
|
+
*/
|
|
50
|
+
function toStroops(value) {
|
|
51
|
+
if (!value)
|
|
52
|
+
return 0n
|
|
53
|
+
if (typeof value === 'number') {
|
|
54
|
+
value = value.toFixed(7)
|
|
55
|
+
}
|
|
56
|
+
if (typeof value !== 'string' || !/^-?[\d.,]+$/.test(value))
|
|
57
|
+
return 0n //invalid format
|
|
58
|
+
try {
|
|
59
|
+
let [int, decimal = '0'] = value.split('.', 2)
|
|
60
|
+
let negative = false
|
|
61
|
+
if (int.startsWith('-')) {
|
|
62
|
+
negative = true
|
|
63
|
+
int = int.slice(1)
|
|
64
|
+
}
|
|
65
|
+
let res = BigInt(int) * 10000000n + BigInt(decimal.slice(0, 7).padEnd(7, '0'))
|
|
66
|
+
if (negative) {
|
|
67
|
+
res *= -1n
|
|
68
|
+
if (res < -0x8000000000000000n) //overflow
|
|
69
|
+
return 0n
|
|
70
|
+
} else if (res > 0xFFFFFFFFFFFFFFFFn) //overflow
|
|
71
|
+
return 0n
|
|
72
|
+
return res
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return 0n
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Trim trailing fractional zeros from a string amount representation
|
|
80
|
+
* @param {String} value
|
|
81
|
+
* @return {String}
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
function trimZeros(value) {
|
|
85
|
+
const [int, fract] = value.split('.')
|
|
86
|
+
if (!fract)
|
|
87
|
+
return int
|
|
88
|
+
const trimmed = fract.replace(/0+$/, '')
|
|
89
|
+
if (!trimmed.length)
|
|
90
|
+
return int
|
|
91
|
+
return int + '.' + trimmed
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Replace multiplexed addresses with base G addresses
|
|
96
|
+
* @param {String} address
|
|
97
|
+
* @return {String}
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
function normalizeAddress(address) {
|
|
101
|
+
const prefix = address[0]
|
|
102
|
+
if (prefix === 'G')
|
|
103
|
+
return address //lazy check for ed25519 G address
|
|
104
|
+
if (prefix !== 'M')
|
|
105
|
+
throw new TypeError('Expected ED25519 or Muxed address')
|
|
106
|
+
const rawBytes = StrKey.decodeMed25519PublicKey(address)
|
|
107
|
+
return StrKey.encodeEd25519PublicKey(rawBytes.subarray(0, 32))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {String} action
|
|
112
|
+
* @param {String} type
|
|
113
|
+
* @return {String}
|
|
114
|
+
*/
|
|
115
|
+
function encodeSponsorshipEffectName(action, type) {
|
|
116
|
+
let actionKey
|
|
117
|
+
switch (action) {
|
|
118
|
+
case 'created':
|
|
119
|
+
actionKey = 'Created'
|
|
120
|
+
break
|
|
121
|
+
case 'updated':
|
|
122
|
+
actionKey = 'Updated'
|
|
123
|
+
break
|
|
124
|
+
case 'removed':
|
|
125
|
+
actionKey = 'Removed'
|
|
126
|
+
break
|
|
127
|
+
default:
|
|
128
|
+
throw new UnexpectedTxMetaChangeError({action, type})
|
|
129
|
+
}
|
|
130
|
+
return effectTypes[`${type}Sponsorship${actionKey}`]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if asset issuer is a source account
|
|
135
|
+
* @param {String} account
|
|
136
|
+
* @param {String} asset
|
|
137
|
+
* @return {Boolean}
|
|
138
|
+
*/
|
|
139
|
+
function isIssuer(account, asset) {
|
|
140
|
+
return asset.includes(account)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = {
|
|
144
|
+
fromStroops,
|
|
145
|
+
toStroops,
|
|
146
|
+
normalizeAddress,
|
|
147
|
+
encodeSponsorshipEffectName,
|
|
148
|
+
isIssuer,
|
|
149
|
+
isAsset
|
|
150
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const effectTypes = require('./effect-types')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Effect supply computation processor
|
|
5
|
+
*/
|
|
6
|
+
class AssetSupplyProcessor {
|
|
7
|
+
constructor(effects) {
|
|
8
|
+
this.assetTransfers = {}
|
|
9
|
+
this.processXlmBalances = effects.some(e => e.type === 'contractInvoked')
|
|
10
|
+
for (const effect of effects) {
|
|
11
|
+
this.processEffect(effect)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {Object.<String,BigInt>}
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
assetTransfers
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {Boolean}
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
processXlmBalances = false
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Process generated operation effect
|
|
29
|
+
* @param {{}} effect
|
|
30
|
+
*/
|
|
31
|
+
processEffect(effect) {
|
|
32
|
+
switch (effect.type) {
|
|
33
|
+
case effectTypes.accountCredited:
|
|
34
|
+
case effectTypes.claimableBalanceCreated:
|
|
35
|
+
case effectTypes.assetBurned:
|
|
36
|
+
//increase supply
|
|
37
|
+
this.increase(effect.asset, effect.amount)
|
|
38
|
+
break
|
|
39
|
+
case effectTypes.accountDebited:
|
|
40
|
+
case effectTypes.claimableBalanceRemoved:
|
|
41
|
+
case effectTypes.assetMinted:
|
|
42
|
+
//decrease supply
|
|
43
|
+
this.decrease(effect.asset, effect.amount)
|
|
44
|
+
break
|
|
45
|
+
case effectTypes.liquidityPoolDeposited:
|
|
46
|
+
//increase supply for every deposited asset (if liquidity provider is an issuer)
|
|
47
|
+
for (const {asset, amount} of effect.assets) {
|
|
48
|
+
this.increase(asset, amount)
|
|
49
|
+
}
|
|
50
|
+
break
|
|
51
|
+
case effectTypes.liquidityPoolWithdrew:
|
|
52
|
+
//decrease supply for every deposited asset (if liquidity provider is an issuer)
|
|
53
|
+
for (const {asset, amount} of effect.assets) {
|
|
54
|
+
this.decrease(asset, amount)
|
|
55
|
+
}
|
|
56
|
+
break
|
|
57
|
+
case effectTypes.trade:
|
|
58
|
+
if (effect.pool) {
|
|
59
|
+
for (let i = 0; i < effect.asset.length; i++) {
|
|
60
|
+
if (i === 0) { //increase supply if the issuer is seller
|
|
61
|
+
this.decrease(effect.asset[i], effect.amount[i])
|
|
62
|
+
} else {
|
|
63
|
+
this.increase(effect.asset[i], effect.amount[i])
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
break
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Calculate differences and generate minted/burned effects if needed
|
|
73
|
+
* @return {{}[]}
|
|
74
|
+
*/
|
|
75
|
+
resolve() {
|
|
76
|
+
const res = []
|
|
77
|
+
for (const [asset, amount] of Object.entries(this.assetTransfers)) {
|
|
78
|
+
if (amount === 0n)
|
|
79
|
+
continue
|
|
80
|
+
const effect = {
|
|
81
|
+
type: effectTypes.assetMinted,
|
|
82
|
+
asset
|
|
83
|
+
}
|
|
84
|
+
if (amount > 0n) {
|
|
85
|
+
effect.type = effectTypes.assetMinted
|
|
86
|
+
effect.amount = amount.toString()
|
|
87
|
+
}
|
|
88
|
+
if (amount < 0n) {
|
|
89
|
+
effect.type = effectTypes.assetBurned
|
|
90
|
+
effect.amount = (-amount).toString()
|
|
91
|
+
}
|
|
92
|
+
res.push(effect)
|
|
93
|
+
}
|
|
94
|
+
return res
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {String} asset
|
|
99
|
+
* @param {String} amount
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
increase(asset, amount) {
|
|
103
|
+
if (!this.shouldProcessAsset(asset))
|
|
104
|
+
return
|
|
105
|
+
this.assetTransfers[asset] = (this.assetTransfers[asset] || 0n) + BigInt(amount)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {String} asset
|
|
110
|
+
* @param {String} amount
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
decrease(asset, amount) {
|
|
114
|
+
if (!this.shouldProcessAsset(asset))
|
|
115
|
+
return
|
|
116
|
+
this.assetTransfers[asset] = (this.assetTransfers[asset] || 0n) - BigInt(amount)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {String} asset
|
|
121
|
+
* @return {Boolean}
|
|
122
|
+
*/
|
|
123
|
+
shouldProcessAsset(asset) {
|
|
124
|
+
if (asset === 'XLM') //return true if we process XLM balance changes
|
|
125
|
+
return this.processXlmBalances
|
|
126
|
+
return asset.includes('-') || (asset.length === 56 && asset.startsWith('C')) //lazy checks for alphanum4/12 assets and contracts
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = AssetSupplyProcessor
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const {Asset, StrKey, hash, xdr} = require('@stellar/stellar-base')
|
|
2
|
+
|
|
3
|
+
const passphraseMapping = {}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolve network id hash from a passphrase (with pre-caching)
|
|
7
|
+
* @param {String} networkPassphrase
|
|
8
|
+
* @return {Buffer}
|
|
9
|
+
*/
|
|
10
|
+
function getNetworkIdHash(networkPassphrase) {
|
|
11
|
+
let networkId = passphraseMapping[networkPassphrase]
|
|
12
|
+
if (!networkId) {
|
|
13
|
+
networkId = passphraseMapping[networkPassphrase] = hash(Buffer.from(networkPassphrase))
|
|
14
|
+
}
|
|
15
|
+
return networkId
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Derive ContractId from a wrapped Stellar classic asset
|
|
20
|
+
* @param {Asset} asset
|
|
21
|
+
* @param {String} networkPassphrase
|
|
22
|
+
* @return {String}
|
|
23
|
+
*/
|
|
24
|
+
function contractIdFromAsset(asset, networkPassphrase) {
|
|
25
|
+
return contractIdFromPreimage(xdr.ContractIdPreimage.contractIdPreimageFromAsset(asset.toXDRObject()), networkPassphrase)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Derive ContractId from a hash preimage
|
|
30
|
+
* @param {ContractIdPreimage} contractIdPreimage
|
|
31
|
+
* @param {String} networkPassphrase
|
|
32
|
+
* @return {String}
|
|
33
|
+
*/
|
|
34
|
+
function contractIdFromPreimage(contractIdPreimage, networkPassphrase) {
|
|
35
|
+
const hashPreimage = new xdr.HashIdPreimageContractId({
|
|
36
|
+
networkId: getNetworkIdHash(networkPassphrase),
|
|
37
|
+
contractIdPreimage
|
|
38
|
+
})
|
|
39
|
+
const envelopePreimage = xdr.HashIdPreimage.envelopeTypeContractId(hashPreimage)
|
|
40
|
+
return StrKey.encodeContract(hash(envelopePreimage.toXDR()))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = {contractIdFromAsset, contractIdFromPreimage}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All supported effects types
|
|
3
|
+
* @readonly
|
|
4
|
+
*/
|
|
5
|
+
const effectTypes = {
|
|
6
|
+
feeCharged: 'feeCharged',
|
|
7
|
+
|
|
8
|
+
accountCreated: 'accountCreated',
|
|
9
|
+
accountRemoved: 'accountRemoved',
|
|
10
|
+
|
|
11
|
+
accountDebited: 'accountDebited',
|
|
12
|
+
accountCredited: 'accountCredited',
|
|
13
|
+
|
|
14
|
+
accountHomeDomainUpdated: 'accountHomeDomainUpdated',
|
|
15
|
+
accountThresholdsUpdated: 'accountThresholdsUpdated',
|
|
16
|
+
accountFlagsUpdated: 'accountFlagsUpdated',
|
|
17
|
+
accountInflationDestinationUpdated: 'accountInflationDestinationUpdated',
|
|
18
|
+
|
|
19
|
+
accountSignerUpdated: 'accountSignerUpdated',
|
|
20
|
+
accountSignerRemoved: 'accountSignerRemoved',
|
|
21
|
+
accountSignerCreated: 'accountSignerCreated',
|
|
22
|
+
|
|
23
|
+
trustlineCreated: 'trustlineCreated',
|
|
24
|
+
trustlineUpdated: 'trustlineUpdated',
|
|
25
|
+
trustlineRemoved: 'trustlineRemoved',
|
|
26
|
+
trustlineAuthorizationUpdated: 'trustlineAuthorizationUpdated',
|
|
27
|
+
|
|
28
|
+
assetMinted: 'assetMinted',
|
|
29
|
+
assetBurned: 'assetBurned',
|
|
30
|
+
|
|
31
|
+
liquidityPoolCreated: 'liquidityPoolCreated',
|
|
32
|
+
liquidityPoolUpdated: 'liquidityPoolUpdated',
|
|
33
|
+
liquidityPoolRemoved: 'liquidityPoolRemoved',
|
|
34
|
+
|
|
35
|
+
offerCreated: 'offerCreated',
|
|
36
|
+
offerUpdated: 'offerUpdated',
|
|
37
|
+
offerRemoved: 'offerRemoved',
|
|
38
|
+
|
|
39
|
+
trade: 'trade',
|
|
40
|
+
|
|
41
|
+
inflation: 'inflation',
|
|
42
|
+
|
|
43
|
+
sequenceBumped: 'sequenceBumped',
|
|
44
|
+
|
|
45
|
+
dataEntryCreated: 'dataEntryCreated',
|
|
46
|
+
dataEntryUpdated: 'dataEntryUpdated',
|
|
47
|
+
dataEntryRemoved: 'dataEntryRemoved',
|
|
48
|
+
|
|
49
|
+
claimableBalanceCreated: 'claimableBalanceCreated',
|
|
50
|
+
claimableBalanceRemoved: 'claimableBalanceRemoved',
|
|
51
|
+
|
|
52
|
+
liquidityPoolDeposited: 'liquidityPoolDeposited',
|
|
53
|
+
liquidityPoolWithdrew: 'liquidityPoolWithdrew',
|
|
54
|
+
|
|
55
|
+
accountSponsorshipCreated: 'accountSponsorshipCreated',
|
|
56
|
+
accountSponsorshipUpdated: 'accountSponsorshipUpdated',
|
|
57
|
+
accountSponsorshipRemoved: 'accountSponsorshipRemoved',
|
|
58
|
+
|
|
59
|
+
trustlineSponsorshipCreated: 'trustlineSponsorshipCreated',
|
|
60
|
+
trustlineSponsorshipUpdated: 'trustlineSponsorshipUpdated',
|
|
61
|
+
trustlineSponsorshipRemoved: 'trustlineSponsorshipRemoved',
|
|
62
|
+
|
|
63
|
+
offerSponsorshipCreated: 'offerSponsorshipCreated',
|
|
64
|
+
offerSponsorshipUpdated: 'offerSponsorshipUpdated',
|
|
65
|
+
offerSponsorshipRemoved: 'offerSponsorshipRemoved',
|
|
66
|
+
|
|
67
|
+
dataSponsorshipCreated: 'dataSponsorshipCreated',
|
|
68
|
+
dataSponsorshipUpdated: 'dataSponsorshipUpdated',
|
|
69
|
+
dataSponsorshipRemoved: 'dataSponsorshipRemoved',
|
|
70
|
+
|
|
71
|
+
claimableBalanceSponsorshipCreated: 'claimableBalanceSponsorshipCreated',
|
|
72
|
+
claimableBalanceSponsorshipUpdated: 'claimableBalanceSponsorshipUpdated',
|
|
73
|
+
claimableBalanceSponsorshipRemoved: 'claimableBalanceSponsorshipRemoved',
|
|
74
|
+
|
|
75
|
+
liquidityPoolSponsorshipCreated: 'liquidityPoolSponsorshipCreated',
|
|
76
|
+
liquidityPoolSponsorshipUpdated: 'liquidityPoolSponsorshipUpdated',
|
|
77
|
+
liquidityPoolSponsorshipRemoved: 'liquidityPoolSponsorshipRemoved',
|
|
78
|
+
|
|
79
|
+
signerSponsorshipCreated: 'signerSponsorshipCreated',
|
|
80
|
+
signerSponsorshipUpdated: 'signerSponsorshipUpdated',
|
|
81
|
+
signerSponsorshipRemoved: 'signerSponsorshipRemoved',
|
|
82
|
+
|
|
83
|
+
contractCodeUploaded: 'contractCodeUploaded',
|
|
84
|
+
|
|
85
|
+
contractCreated: 'contractCreated',
|
|
86
|
+
contractUpdated: 'contractUpdated',
|
|
87
|
+
|
|
88
|
+
contractInvoked: 'contractInvoked',
|
|
89
|
+
|
|
90
|
+
contractDataCreated: 'contractDataCreated',
|
|
91
|
+
contractDataUpdated: 'contractDataUpdated',
|
|
92
|
+
contractDataRemoved: 'contractDataRemoved',
|
|
93
|
+
|
|
94
|
+
contractEvent: 'contractEvent'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = effectTypes
|
package/src/effect.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Effect {
|
|
2
|
+
constructor(type, source) {
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @type {String}
|
|
7
|
+
* @readonly
|
|
8
|
+
*/
|
|
9
|
+
type
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @type {String}
|
|
13
|
+
* @readonly
|
|
14
|
+
*/
|
|
15
|
+
source
|
|
16
|
+
|
|
17
|
+
toString() {
|
|
18
|
+
return this.toJSON()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
toJSON() {
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/errors.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class TxMetaEffectParserError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super('Transaction metadata processing error. ' + message)
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class UnexpectedTxMetaChangeError extends TxMetaEffectParserError {
|
|
8
|
+
constructor({type, action}) {
|
|
9
|
+
super(`Unexpected meta changes: "${type}" "${action}"`)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {UnexpectedTxMetaChangeError, TxMetaEffectParserError}
|