@stellar-expert/ui-framework 1.16.8 → 1.19.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.
- package/README.md +1168 -3
- package/account/account-address.js +127 -127
- package/account/available-balance.js +22 -22
- package/account/identicon.js +90 -90
- package/account/signer-key.js +65 -64
- package/api/explorer-api-hooks.js +209 -202
- package/api/explorer-api-paginated-list-hooks.js +441 -440
- package/api/explorer-batch-info-loader.js +111 -85
- package/api/explorer-tx-api.js +28 -28
- package/api/ledger-stream.js +15 -0
- package/asset/amount.js +56 -56
- package/asset/asset-icon.js +41 -41
- package/asset/asset-issuer.js +21 -21
- package/asset/asset-link.js +107 -107
- package/asset/asset-list-hooks.js +59 -59
- package/asset/asset-meta-hooks.js +88 -88
- package/asset/asset-selector.js +72 -71
- package/claimable-balance/claimable-balance-claimants.js +23 -18
- package/contract/contract-api.js +15 -0
- package/contract/invocation-info-view.js +10 -2
- package/contract/sc-val.js +131 -107
- package/controls/button-group.js +25 -19
- package/controls/button.js +93 -78
- package/controls/code-block.js +42 -34
- package/controls/dropdown.js +318 -287
- package/controls/external-link.js +10 -4
- package/controls/info-tooltip.js +23 -16
- package/controls/slider.js +29 -19
- package/controls/tabs.js +94 -94
- package/controls/tooltip.js +244 -240
- package/controls/update-highlighter.js +32 -27
- package/date/date-selector.js +56 -54
- package/date/elapsed-time.js +28 -21
- package/dex/price-dynamic.js +53 -44
- package/directory/directory-hooks.js +109 -97
- package/effect/effect-description.js +346 -344
- package/errors/error-boundary.js +110 -97
- package/filter/editors/account-filter-view.js +20 -0
- package/filter/editors/asset-filter-view.js +9 -0
- package/filter/editors/timestamp-filter-view.js +34 -0
- package/filter/editors/type-filter-view.js +148 -0
- package/filter/filter-editors.js +102 -0
- package/filter/filter-view.js +218 -0
- package/filter/filter.scss +57 -0
- package/horizon/horizon-account-helpers.js +104 -104
- package/horizon/horizon-ledger-helpers.js +35 -35
- package/horizon/horizon-trades-helper.js +88 -88
- package/horizon/horizon-transaction-helpers.js +36 -36
- package/index.d.ts +1271 -0
- package/index.js +95 -93
- package/interaction/accordion.js +43 -35
- package/interaction/autofocus.js +13 -9
- package/interaction/block-select.js +64 -53
- package/interaction/copy-to-clipboard.js +25 -18
- package/interaction/inline-progress.js +20 -15
- package/interaction/qr-code.js +34 -34
- package/interaction/responsive.js +20 -20
- package/interaction/spoiler.js +52 -39
- package/interaction/theme-selector.js +13 -10
- package/ledger/ledger-entry-href-formatter.js +27 -26
- package/ledger/ledger-entry-link.js +93 -58
- package/ledger/ledger-info-parser.js +46 -18
- package/meta/page-meta-tags.js +243 -238
- package/module/dynamic-module.js +47 -47
- package/package.json +71 -40
- package/state/on-screen-hooks.js +22 -22
- package/state/page-visibility-helpers.js +29 -16
- package/state/page-visibility-hooks.js +13 -11
- package/state/screen-orientation-hooks.js +19 -15
- package/state/state-hooks.js +76 -76
- package/state/stellar-network-hooks.js +56 -44
- package/state/theme.js +29 -28
- package/stellar/key-type.js +92 -91
- package/stellar/ledger-generic-id.js +39 -39
- package/stellar/signature-hint-utils.js +65 -65
- package/toast/toast-notifications-block.js +59 -59
- package/tx/op-description-view.js +945 -942
- package/tx/op-icon.js +98 -98
- package/tx/parser/op-balance-changes.js +66 -66
- package/tx/parser/op-descriptor.js +51 -48
- package/tx/parser/tx-details-parser.js +81 -81
- package/tx/parser/tx-matcher.js +371 -371
- package/tx/parser/type-filter-matcher.js +126 -126
- package/tx/tx-list-hooks.js +32 -18
- package/tx/tx-operations-list.js +117 -116
package/tx/op-icon.js
CHANGED
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import cn from 'classnames'
|
|
3
|
-
|
|
4
|
-
const opIconMapping = {
|
|
5
|
-
feeCharge: 'send-circle',
|
|
6
|
-
createAccount: 'hexagon-add',
|
|
7
|
-
payment: 'send-circle',
|
|
8
|
-
paymentReceive: 'receive-circle',
|
|
9
|
-
pathPaymentStrictReceive: 'swap',
|
|
10
|
-
manageSellOffer: 'dex-offer',
|
|
11
|
-
createPassiveSellOffer: 'dex-offer',
|
|
12
|
-
setOptions: 'hexagon-set-options',
|
|
13
|
-
changeTrust: 'trustlines',
|
|
14
|
-
changeTrustAdd: 'create-trustline',
|
|
15
|
-
changeTrustRemove: 'remove-trustline',
|
|
16
|
-
changeTrustUpdate: 'trustline-flags',
|
|
17
|
-
allowTrust: 'trustline-flags',
|
|
18
|
-
accountMerge: 'hexagon-remove',
|
|
19
|
-
accountMergeReceive: 'receive-circle',
|
|
20
|
-
inflation: 'hexagon-inflation',
|
|
21
|
-
manageData: 'grid',
|
|
22
|
-
manageDataAdd: 'grid-add',
|
|
23
|
-
manageDataRemove: 'grid-remove',
|
|
24
|
-
bumpSequence: 'upload',
|
|
25
|
-
manageBuyOffer: 'dex-offer',
|
|
26
|
-
pathPaymentStrictSend: 'swap',
|
|
27
|
-
createClaimableBalance: 'shutdown-circle',
|
|
28
|
-
claimClaimableBalance: 'icon-ok',
|
|
29
|
-
claimClaimableBalanceReceive: 'receive-circle',
|
|
30
|
-
beginSponsoringFutureReserves: 'sponsor',
|
|
31
|
-
endSponsoringFutureReserves: 'sponsor',
|
|
32
|
-
revoke: 'revoke',
|
|
33
|
-
revokeAccountSponsorship: 'revoke',
|
|
34
|
-
revokeTrustlineSponsorship: 'revoke',
|
|
35
|
-
revokeOfferSponsorship: 'revoke',
|
|
36
|
-
revokeDataSponsorship: 'revoke',
|
|
37
|
-
revokeClaimableBalanceSponsorship: 'revoke',
|
|
38
|
-
revokeLiquidityPoolSponsorship: 'revoke',
|
|
39
|
-
revokeSignerSponsorship: 'revoke',
|
|
40
|
-
clawback: 'clawback',
|
|
41
|
-
clawbackReceive: 'send-circle',
|
|
42
|
-
clawbackClaimableBalance: 'icon-ok',
|
|
43
|
-
setTrustLineFlags: 'trustline-flags',
|
|
44
|
-
liquidityPoolDeposit: 'droplet',
|
|
45
|
-
liquidityPoolWithdraw: 'droplet-half',
|
|
46
|
-
invokeHostFunction: 'flash',
|
|
47
|
-
extendFootprintTtl: 'upload',
|
|
48
|
-
restoreFootprint: 'upload'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Transaction operation icon
|
|
53
|
-
* @param {OperationDescriptor|'feeCharge'} op - Operation descriptor
|
|
54
|
-
* @param {
|
|
55
|
-
* @constructor
|
|
56
|
-
*/
|
|
57
|
-
export const OpIcon = React.memo(function OpIcon({op, failed = false}) {
|
|
58
|
-
let type
|
|
59
|
-
let title
|
|
60
|
-
if (op === 'feeCharge') {
|
|
61
|
-
type = 'feeCharge'
|
|
62
|
-
title = 'Transaction fees charge'
|
|
63
|
-
} else {
|
|
64
|
-
const {operation} = op
|
|
65
|
-
title = type = operation.type
|
|
66
|
-
title = title[0].toUpperCase() + title.substring(1) + ' operation'
|
|
67
|
-
switch (type) {
|
|
68
|
-
case 'payment':
|
|
69
|
-
case 'accountMerge':
|
|
70
|
-
case 'claimClaimableBalance':
|
|
71
|
-
case 'clawback':
|
|
72
|
-
if (!op.context?.account?.includes(operation.source)) {
|
|
73
|
-
type += 'Receive'
|
|
74
|
-
}
|
|
75
|
-
break
|
|
76
|
-
case 'manageData':
|
|
77
|
-
if (operation.effects.some(e => e.type === 'dataEntryCreated')) {
|
|
78
|
-
type += 'Add'
|
|
79
|
-
} else if (operation.effects.some(e => e.type === 'dataEntryRemoved')) {
|
|
80
|
-
type += 'Remove'
|
|
81
|
-
}
|
|
82
|
-
break
|
|
83
|
-
case 'changeTrust':
|
|
84
|
-
if (operation.limit > 0) {
|
|
85
|
-
type += 'Add'
|
|
86
|
-
} else {
|
|
87
|
-
type += 'Remove'
|
|
88
|
-
}
|
|
89
|
-
break
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (failed) {
|
|
93
|
-
title += ' - Transaction failed'
|
|
94
|
-
}
|
|
95
|
-
const icon = opIconMapping[type]
|
|
96
|
-
return <div className={cn('op-icon', {failed})} title={title}>
|
|
97
|
-
<i className={`icon-${icon}`}/>
|
|
98
|
-
</div>
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import cn from 'classnames'
|
|
3
|
+
|
|
4
|
+
const opIconMapping = {
|
|
5
|
+
feeCharge: 'send-circle',
|
|
6
|
+
createAccount: 'hexagon-add',
|
|
7
|
+
payment: 'send-circle',
|
|
8
|
+
paymentReceive: 'receive-circle',
|
|
9
|
+
pathPaymentStrictReceive: 'swap',
|
|
10
|
+
manageSellOffer: 'dex-offer',
|
|
11
|
+
createPassiveSellOffer: 'dex-offer',
|
|
12
|
+
setOptions: 'hexagon-set-options',
|
|
13
|
+
changeTrust: 'trustlines',
|
|
14
|
+
changeTrustAdd: 'create-trustline',
|
|
15
|
+
changeTrustRemove: 'remove-trustline',
|
|
16
|
+
changeTrustUpdate: 'trustline-flags',
|
|
17
|
+
allowTrust: 'trustline-flags',
|
|
18
|
+
accountMerge: 'hexagon-remove',
|
|
19
|
+
accountMergeReceive: 'receive-circle',
|
|
20
|
+
inflation: 'hexagon-inflation',
|
|
21
|
+
manageData: 'grid',
|
|
22
|
+
manageDataAdd: 'grid-add',
|
|
23
|
+
manageDataRemove: 'grid-remove',
|
|
24
|
+
bumpSequence: 'upload',
|
|
25
|
+
manageBuyOffer: 'dex-offer',
|
|
26
|
+
pathPaymentStrictSend: 'swap',
|
|
27
|
+
createClaimableBalance: 'shutdown-circle',
|
|
28
|
+
claimClaimableBalance: 'icon-ok',
|
|
29
|
+
claimClaimableBalanceReceive: 'receive-circle',
|
|
30
|
+
beginSponsoringFutureReserves: 'sponsor',
|
|
31
|
+
endSponsoringFutureReserves: 'sponsor',
|
|
32
|
+
revoke: 'revoke',
|
|
33
|
+
revokeAccountSponsorship: 'revoke',
|
|
34
|
+
revokeTrustlineSponsorship: 'revoke',
|
|
35
|
+
revokeOfferSponsorship: 'revoke',
|
|
36
|
+
revokeDataSponsorship: 'revoke',
|
|
37
|
+
revokeClaimableBalanceSponsorship: 'revoke',
|
|
38
|
+
revokeLiquidityPoolSponsorship: 'revoke',
|
|
39
|
+
revokeSignerSponsorship: 'revoke',
|
|
40
|
+
clawback: 'clawback',
|
|
41
|
+
clawbackReceive: 'send-circle',
|
|
42
|
+
clawbackClaimableBalance: 'icon-ok',
|
|
43
|
+
setTrustLineFlags: 'trustline-flags',
|
|
44
|
+
liquidityPoolDeposit: 'droplet',
|
|
45
|
+
liquidityPoolWithdraw: 'droplet-half',
|
|
46
|
+
invokeHostFunction: 'flash',
|
|
47
|
+
extendFootprintTtl: 'upload',
|
|
48
|
+
restoreFootprint: 'upload'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Transaction operation icon
|
|
53
|
+
* @param {OperationDescriptor|'feeCharge'} op - Operation descriptor
|
|
54
|
+
* @param {boolean} failed - Whether the transaction failed during execution
|
|
55
|
+
* @constructor
|
|
56
|
+
*/
|
|
57
|
+
export const OpIcon = React.memo(function OpIcon({op, failed = false}) {
|
|
58
|
+
let type
|
|
59
|
+
let title
|
|
60
|
+
if (op === 'feeCharge') {
|
|
61
|
+
type = 'feeCharge'
|
|
62
|
+
title = 'Transaction fees charge'
|
|
63
|
+
} else {
|
|
64
|
+
const {operation} = op
|
|
65
|
+
title = type = operation.type
|
|
66
|
+
title = title[0].toUpperCase() + title.substring(1) + ' operation'
|
|
67
|
+
switch (type) {
|
|
68
|
+
case 'payment':
|
|
69
|
+
case 'accountMerge':
|
|
70
|
+
case 'claimClaimableBalance':
|
|
71
|
+
case 'clawback':
|
|
72
|
+
if (!op.context?.account?.includes(operation.source)) {
|
|
73
|
+
type += 'Receive'
|
|
74
|
+
}
|
|
75
|
+
break
|
|
76
|
+
case 'manageData':
|
|
77
|
+
if (operation.effects.some(e => e.type === 'dataEntryCreated')) {
|
|
78
|
+
type += 'Add'
|
|
79
|
+
} else if (operation.effects.some(e => e.type === 'dataEntryRemoved')) {
|
|
80
|
+
type += 'Remove'
|
|
81
|
+
}
|
|
82
|
+
break
|
|
83
|
+
case 'changeTrust':
|
|
84
|
+
if (operation.limit > 0) {
|
|
85
|
+
type += 'Add'
|
|
86
|
+
} else {
|
|
87
|
+
type += 'Remove'
|
|
88
|
+
}
|
|
89
|
+
break
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (failed) {
|
|
93
|
+
title += ' - Transaction failed'
|
|
94
|
+
}
|
|
95
|
+
const icon = opIconMapping[type]
|
|
96
|
+
return <div className={cn('op-icon', {failed})} title={title}>
|
|
97
|
+
<i className={`icon-${icon}`}/>
|
|
98
|
+
</div>
|
|
99
99
|
})
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
const manageOfferOpTypes = ['manageSellOffer', 'manageBuyOffer', 'createPassiveSellOffer']
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Calculate operation resulting balance changes
|
|
5
|
-
* @param {{}} op - Operation descriptor
|
|
6
|
-
* @return {{amount:
|
|
7
|
-
*/
|
|
8
|
-
export function retrieveOpBalanceChanges(op) {
|
|
9
|
-
const account = op.tx?.context?.account
|
|
10
|
-
if (typeof account !== 'string')
|
|
11
|
-
return []
|
|
12
|
-
const {effects} = op.operation
|
|
13
|
-
const changes = effects.filter(e => e.source === account && (e.type === 'accountDebited' || e.type === 'accountCredited'))
|
|
14
|
-
if (changes.length) {
|
|
15
|
-
changes.sort((a, b) => a.type - b.type)
|
|
16
|
-
return changes
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/*if (manageOfferOpTypes.includes(op.operation.type)) {
|
|
20
|
-
const debitedAmounts = []
|
|
21
|
-
const creditedAmounts = []
|
|
22
|
-
let sourceAsset
|
|
23
|
-
let destAsset
|
|
24
|
-
|
|
25
|
-
for (let e of effects) {
|
|
26
|
-
if (![e.seller, e.source].includes(op.context) || e.type !== 'trade')
|
|
27
|
-
continue
|
|
28
|
-
let {amount} = e
|
|
29
|
-
sourceAsset = e.asset[1]
|
|
30
|
-
destAsset = e.asset[0]
|
|
31
|
-
if (e.seller === op.context) {
|
|
32
|
-
amount = amount.slice().reverse()
|
|
33
|
-
sourceAsset = e.asset[1]
|
|
34
|
-
destAsset = e.asset[0]
|
|
35
|
-
}
|
|
36
|
-
debitedAmounts.push(amount[1])
|
|
37
|
-
creditedAmounts.push(amount[0])
|
|
38
|
-
}
|
|
39
|
-
const res = []
|
|
40
|
-
if (debitedAmounts.length) {
|
|
41
|
-
res.push({
|
|
42
|
-
type: 'accountDebited',
|
|
43
|
-
source: op.context,
|
|
44
|
-
asset: sourceAsset,
|
|
45
|
-
amount: sumAmounts(debitedAmounts)
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (creditedAmounts.length) {
|
|
50
|
-
res.push({
|
|
51
|
-
type: 'accountCredited',
|
|
52
|
-
source: op.context,
|
|
53
|
-
asset: destAsset,
|
|
54
|
-
amount: sumAmounts(creditedAmounts)
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
return res
|
|
58
|
-
}*/
|
|
59
|
-
return []
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/*
|
|
63
|
-
|
|
64
|
-
function sumAmounts(amounts) {
|
|
65
|
-
return amounts.reduce((prev, v) => prev.add(v), new Bignumber(0))
|
|
66
|
-
}*/
|
|
1
|
+
const manageOfferOpTypes = ['manageSellOffer', 'manageBuyOffer', 'createPassiveSellOffer']
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calculate operation resulting balance changes
|
|
5
|
+
* @param {{}} op - Operation descriptor
|
|
6
|
+
* @return {{amount: string, source: string, type: string, asset: string}[]}
|
|
7
|
+
*/
|
|
8
|
+
export function retrieveOpBalanceChanges(op) {
|
|
9
|
+
const account = op.tx?.context?.account
|
|
10
|
+
if (typeof account !== 'string')
|
|
11
|
+
return []
|
|
12
|
+
const {effects} = op.operation
|
|
13
|
+
const changes = effects.filter(e => e.source === account && (e.type === 'accountDebited' || e.type === 'accountCredited'))
|
|
14
|
+
if (changes.length) {
|
|
15
|
+
changes.sort((a, b) => a.type - b.type)
|
|
16
|
+
return changes
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/*if (manageOfferOpTypes.includes(op.operation.type)) {
|
|
20
|
+
const debitedAmounts = []
|
|
21
|
+
const creditedAmounts = []
|
|
22
|
+
let sourceAsset
|
|
23
|
+
let destAsset
|
|
24
|
+
|
|
25
|
+
for (let e of effects) {
|
|
26
|
+
if (![e.seller, e.source].includes(op.context) || e.type !== 'trade')
|
|
27
|
+
continue
|
|
28
|
+
let {amount} = e
|
|
29
|
+
sourceAsset = e.asset[1]
|
|
30
|
+
destAsset = e.asset[0]
|
|
31
|
+
if (e.seller === op.context) {
|
|
32
|
+
amount = amount.slice().reverse()
|
|
33
|
+
sourceAsset = e.asset[1]
|
|
34
|
+
destAsset = e.asset[0]
|
|
35
|
+
}
|
|
36
|
+
debitedAmounts.push(amount[1])
|
|
37
|
+
creditedAmounts.push(amount[0])
|
|
38
|
+
}
|
|
39
|
+
const res = []
|
|
40
|
+
if (debitedAmounts.length) {
|
|
41
|
+
res.push({
|
|
42
|
+
type: 'accountDebited',
|
|
43
|
+
source: op.context,
|
|
44
|
+
asset: sourceAsset,
|
|
45
|
+
amount: sumAmounts(debitedAmounts)
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (creditedAmounts.length) {
|
|
50
|
+
res.push({
|
|
51
|
+
type: 'accountCredited',
|
|
52
|
+
source: op.context,
|
|
53
|
+
asset: destAsset,
|
|
54
|
+
amount: sumAmounts(creditedAmounts)
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
return res
|
|
58
|
+
}*/
|
|
59
|
+
return []
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
|
|
64
|
+
function sumAmounts(amounts) {
|
|
65
|
+
return amounts.reduce((prev, v) => prev.add(v), new Bignumber(0))
|
|
66
|
+
}*/
|
|
@@ -1,49 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
*
|
|
33
|
-
* @param {
|
|
34
|
-
* @
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Operation rendering context
|
|
3
|
+
*/
|
|
4
|
+
export default class OperationDescriptor {
|
|
5
|
+
/**
|
|
6
|
+
* @type {BaseOperation} - Operation properties
|
|
7
|
+
* @readonly
|
|
8
|
+
*/
|
|
9
|
+
operation
|
|
10
|
+
/**
|
|
11
|
+
* @type {string} - Parent transaction hash
|
|
12
|
+
* @readonly
|
|
13
|
+
*/
|
|
14
|
+
txHash
|
|
15
|
+
/**
|
|
16
|
+
* @type {number} - Application order
|
|
17
|
+
* @readonly
|
|
18
|
+
*/
|
|
19
|
+
order
|
|
20
|
+
/**
|
|
21
|
+
* @type {boolean} - True for unsubmitted|unsuccessful transactions
|
|
22
|
+
* @readonly
|
|
23
|
+
*/
|
|
24
|
+
isEphemeral
|
|
25
|
+
/**
|
|
26
|
+
* @type {boolean} - Whether the enclosing transaction has been successfully executed
|
|
27
|
+
* @readonly
|
|
28
|
+
*/
|
|
29
|
+
successful
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Prepare descriptors for transaction operations
|
|
33
|
+
* @param {BaseOperation[]} operations
|
|
34
|
+
* @param {string} txHash
|
|
35
|
+
* @param {boolean} isEphemeral
|
|
36
|
+
* @param {boolean} successful
|
|
37
|
+
* @return {OperationDescriptor[]}
|
|
38
|
+
*/
|
|
39
|
+
static parseOperations(operations, txHash, isEphemeral, successful) {
|
|
40
|
+
return operations.map((operation, i) => {
|
|
41
|
+
const op = new OperationDescriptor()
|
|
42
|
+
Object.assign(op, {
|
|
43
|
+
txHash,
|
|
44
|
+
order: i,
|
|
45
|
+
operation,
|
|
46
|
+
isEphemeral,
|
|
47
|
+
successful
|
|
48
|
+
})
|
|
49
|
+
return op
|
|
50
|
+
})
|
|
51
|
+
}
|
|
49
52
|
}
|
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import {parseTxOperationsMeta} from '@stellar-expert/tx-meta-effects-parser'
|
|
2
|
-
import OperationDescriptor from './op-descriptor'
|
|
3
|
-
import TxMatcher from './tx-matcher'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {Object} ParsedTxDetails - Parsed transaction
|
|
7
|
-
* @property {OperationDescriptor[]} operations - Parsed operation descriptors
|
|
8
|
-
* @property {Transaction|FeeBumpTransaction} tx - Parsed transaction
|
|
9
|
-
* @property {
|
|
10
|
-
* @property {
|
|
11
|
-
* @property {
|
|
12
|
-
* @property {
|
|
13
|
-
* @property {
|
|
14
|
-
* @property {
|
|
15
|
-
* @property {{}[]} [effects] - Transaction-level effects (including fee charges)
|
|
16
|
-
* @property {
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @typedef {Object} TxFiltersContext
|
|
21
|
-
* @property {
|
|
22
|
-
* @property {
|
|
23
|
-
* @property {
|
|
24
|
-
* @property {
|
|
25
|
-
* @property {String[]} [asset]
|
|
26
|
-
* @property {String[]} [src_asset]
|
|
27
|
-
* @property {String[]} [dest_asset]
|
|
28
|
-
* @property {String[]} [offer]
|
|
29
|
-
* @property {String[]} [pool]
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Parse tx details from raw envelope, result, and meta
|
|
34
|
-
* @param {String} network - Network passphrase or identifier
|
|
35
|
-
* @param {String} tx - Base64-encoded tx envelope xdr
|
|
36
|
-
* @param {String} [result] - Base64-encoded tx envelope result
|
|
37
|
-
* @param {String} [meta] - Base64-encoded tx envelope meta
|
|
38
|
-
* @param {String} [id] - Unique transaction id
|
|
39
|
-
* @param {TxFiltersContext} [context] - Filters applied to transactions search
|
|
40
|
-
* @param {String} [createdAt] - Ledger execution timestamp
|
|
41
|
-
* @param {
|
|
42
|
-
* @param {
|
|
43
|
-
* @return {ParsedTxDetails}
|
|
44
|
-
*/
|
|
45
|
-
export function parseTxDetails({network, txEnvelope, result, meta, id, context, createdAt, skipUnrelated, protocol}) {
|
|
46
|
-
const parsedTx = parseTxOperationsMeta({network, tx: txEnvelope, meta, result, protocol, processSystemEvents: true, processFailedOpEffects: true, mapSac: true})
|
|
47
|
-
const {tx, effects, operations, isEphemeral, failed} = parsedTx
|
|
48
|
-
const txHash = tx.hash().toString('hex')
|
|
49
|
-
const txMatcher = new TxMatcher(context, skipUnrelated)
|
|
50
|
-
let parsedOps = OperationDescriptor.parseOperations(operations, txHash, isEphemeral, !isEphemeral && !failed)
|
|
51
|
-
//filter out irrelevant operations
|
|
52
|
-
const matchedOps = parsedOps.filter(od => txMatcher.matchOperation(od))
|
|
53
|
-
//display only relevant operations or all of them if no relevant operations found
|
|
54
|
-
if (matchedOps.length) {
|
|
55
|
-
parsedOps = matchedOps
|
|
56
|
-
}
|
|
57
|
-
const res = {
|
|
58
|
-
operations: parsedOps,
|
|
59
|
-
tx,
|
|
60
|
-
txHash,
|
|
61
|
-
context,
|
|
62
|
-
isEphemeral,
|
|
63
|
-
unmatched: !parsedOps.length
|
|
64
|
-
}
|
|
65
|
-
if (!isEphemeral) {
|
|
66
|
-
res.effects = effects
|
|
67
|
-
}
|
|
68
|
-
if (createdAt) {
|
|
69
|
-
res.createdAt = createdAt
|
|
70
|
-
}
|
|
71
|
-
if (!isEphemeral) {
|
|
72
|
-
res.successful = !failed
|
|
73
|
-
}
|
|
74
|
-
if (id !== undefined) {
|
|
75
|
-
res.id = id
|
|
76
|
-
}
|
|
77
|
-
for (let op of parsedOps) {
|
|
78
|
-
op.tx = res
|
|
79
|
-
}
|
|
80
|
-
return res
|
|
81
|
-
}
|
|
1
|
+
import {parseTxOperationsMeta} from '@stellar-expert/tx-meta-effects-parser'
|
|
2
|
+
import OperationDescriptor from './op-descriptor'
|
|
3
|
+
import TxMatcher from './tx-matcher'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} ParsedTxDetails - Parsed transaction
|
|
7
|
+
* @property {OperationDescriptor[]} operations - Parsed operation descriptors
|
|
8
|
+
* @property {Transaction|FeeBumpTransaction} tx - Parsed transaction
|
|
9
|
+
* @property {string} txHash - Transaction hash
|
|
10
|
+
* @property {string} context - Account address, asset name, offer id
|
|
11
|
+
* @property {string} contextType - Resolved context type
|
|
12
|
+
* @property {boolean} isEphemeral - True if transaction has not been submitted or rejected
|
|
13
|
+
* @property {boolean} unmatched - Whether transaction matches context and filter
|
|
14
|
+
* @property {boolean} [successful] - Whether the transaction has been executed successfully or failed during execution
|
|
15
|
+
* @property {{}[]} [effects] - Transaction-level effects (including fee charges)
|
|
16
|
+
* @property {string} [createdAt] - Ledger application timestamp
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} TxFiltersContext
|
|
21
|
+
* @property {string[]} [type]
|
|
22
|
+
* @property {string[]} [account]
|
|
23
|
+
* @property {string[]} [source]
|
|
24
|
+
* @property {string[]} [destination]
|
|
25
|
+
* @property {String[]} [asset]
|
|
26
|
+
* @property {String[]} [src_asset]
|
|
27
|
+
* @property {String[]} [dest_asset]
|
|
28
|
+
* @property {String[]} [offer]
|
|
29
|
+
* @property {String[]} [pool]
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse tx details from raw envelope, result, and meta
|
|
34
|
+
* @param {String} network - Network passphrase or identifier
|
|
35
|
+
* @param {String} tx - Base64-encoded tx envelope xdr
|
|
36
|
+
* @param {String} [result] - Base64-encoded tx envelope result
|
|
37
|
+
* @param {String} [meta] - Base64-encoded tx envelope meta
|
|
38
|
+
* @param {String} [id] - Unique transaction id
|
|
39
|
+
* @param {TxFiltersContext} [context] - Filters applied to transactions search
|
|
40
|
+
* @param {String} [createdAt] - Ledger execution timestamp
|
|
41
|
+
* @param {boolean} [skipUnrelated] - Ledger execution timestamp
|
|
42
|
+
* @param {number} [protocol] – Specific Stellar protocol version for the executed transaction
|
|
43
|
+
* @return {ParsedTxDetails}
|
|
44
|
+
*/
|
|
45
|
+
export function parseTxDetails({network, txEnvelope, result, meta, id, context, createdAt, skipUnrelated, protocol}) {
|
|
46
|
+
const parsedTx = parseTxOperationsMeta({network, tx: txEnvelope, meta, result, protocol, processSystemEvents: true, processFailedOpEffects: true, mapSac: true})
|
|
47
|
+
const {tx, effects, operations, isEphemeral, failed} = parsedTx
|
|
48
|
+
const txHash = tx.hash().toString('hex')
|
|
49
|
+
const txMatcher = new TxMatcher(context, skipUnrelated)
|
|
50
|
+
let parsedOps = OperationDescriptor.parseOperations(operations, txHash, isEphemeral, !isEphemeral && !failed)
|
|
51
|
+
//filter out irrelevant operations
|
|
52
|
+
const matchedOps = parsedOps.filter(od => txMatcher.matchOperation(od))
|
|
53
|
+
//display only relevant operations or all of them if no relevant operations found
|
|
54
|
+
if (matchedOps.length) {
|
|
55
|
+
parsedOps = matchedOps
|
|
56
|
+
}
|
|
57
|
+
const res = {
|
|
58
|
+
operations: parsedOps,
|
|
59
|
+
tx,
|
|
60
|
+
txHash,
|
|
61
|
+
context,
|
|
62
|
+
isEphemeral,
|
|
63
|
+
unmatched: !parsedOps.length
|
|
64
|
+
}
|
|
65
|
+
if (!isEphemeral) {
|
|
66
|
+
res.effects = effects
|
|
67
|
+
}
|
|
68
|
+
if (createdAt) {
|
|
69
|
+
res.createdAt = createdAt
|
|
70
|
+
}
|
|
71
|
+
if (!isEphemeral) {
|
|
72
|
+
res.successful = !failed
|
|
73
|
+
}
|
|
74
|
+
if (id !== undefined) {
|
|
75
|
+
res.id = id
|
|
76
|
+
}
|
|
77
|
+
for (let op of parsedOps) {
|
|
78
|
+
op.tx = res
|
|
79
|
+
}
|
|
80
|
+
return res
|
|
81
|
+
}
|