@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.
Files changed (85) hide show
  1. package/README.md +1168 -3
  2. package/account/account-address.js +127 -127
  3. package/account/available-balance.js +22 -22
  4. package/account/identicon.js +90 -90
  5. package/account/signer-key.js +65 -64
  6. package/api/explorer-api-hooks.js +209 -202
  7. package/api/explorer-api-paginated-list-hooks.js +441 -440
  8. package/api/explorer-batch-info-loader.js +111 -85
  9. package/api/explorer-tx-api.js +28 -28
  10. package/api/ledger-stream.js +15 -0
  11. package/asset/amount.js +56 -56
  12. package/asset/asset-icon.js +41 -41
  13. package/asset/asset-issuer.js +21 -21
  14. package/asset/asset-link.js +107 -107
  15. package/asset/asset-list-hooks.js +59 -59
  16. package/asset/asset-meta-hooks.js +88 -88
  17. package/asset/asset-selector.js +72 -71
  18. package/claimable-balance/claimable-balance-claimants.js +23 -18
  19. package/contract/contract-api.js +15 -0
  20. package/contract/invocation-info-view.js +10 -2
  21. package/contract/sc-val.js +131 -107
  22. package/controls/button-group.js +25 -19
  23. package/controls/button.js +93 -78
  24. package/controls/code-block.js +42 -34
  25. package/controls/dropdown.js +318 -287
  26. package/controls/external-link.js +10 -4
  27. package/controls/info-tooltip.js +23 -16
  28. package/controls/slider.js +29 -19
  29. package/controls/tabs.js +94 -94
  30. package/controls/tooltip.js +244 -240
  31. package/controls/update-highlighter.js +32 -27
  32. package/date/date-selector.js +56 -54
  33. package/date/elapsed-time.js +28 -21
  34. package/dex/price-dynamic.js +53 -44
  35. package/directory/directory-hooks.js +109 -97
  36. package/effect/effect-description.js +346 -344
  37. package/errors/error-boundary.js +110 -97
  38. package/filter/editors/account-filter-view.js +20 -0
  39. package/filter/editors/asset-filter-view.js +9 -0
  40. package/filter/editors/timestamp-filter-view.js +34 -0
  41. package/filter/editors/type-filter-view.js +148 -0
  42. package/filter/filter-editors.js +102 -0
  43. package/filter/filter-view.js +218 -0
  44. package/filter/filter.scss +57 -0
  45. package/horizon/horizon-account-helpers.js +104 -104
  46. package/horizon/horizon-ledger-helpers.js +35 -35
  47. package/horizon/horizon-trades-helper.js +88 -88
  48. package/horizon/horizon-transaction-helpers.js +36 -36
  49. package/index.d.ts +1271 -0
  50. package/index.js +95 -93
  51. package/interaction/accordion.js +43 -35
  52. package/interaction/autofocus.js +13 -9
  53. package/interaction/block-select.js +64 -53
  54. package/interaction/copy-to-clipboard.js +25 -18
  55. package/interaction/inline-progress.js +20 -15
  56. package/interaction/qr-code.js +34 -34
  57. package/interaction/responsive.js +20 -20
  58. package/interaction/spoiler.js +52 -39
  59. package/interaction/theme-selector.js +13 -10
  60. package/ledger/ledger-entry-href-formatter.js +27 -26
  61. package/ledger/ledger-entry-link.js +93 -58
  62. package/ledger/ledger-info-parser.js +46 -18
  63. package/meta/page-meta-tags.js +243 -238
  64. package/module/dynamic-module.js +47 -47
  65. package/package.json +71 -40
  66. package/state/on-screen-hooks.js +22 -22
  67. package/state/page-visibility-helpers.js +29 -16
  68. package/state/page-visibility-hooks.js +13 -11
  69. package/state/screen-orientation-hooks.js +19 -15
  70. package/state/state-hooks.js +76 -76
  71. package/state/stellar-network-hooks.js +56 -44
  72. package/state/theme.js +29 -28
  73. package/stellar/key-type.js +92 -91
  74. package/stellar/ledger-generic-id.js +39 -39
  75. package/stellar/signature-hint-utils.js +65 -65
  76. package/toast/toast-notifications-block.js +59 -59
  77. package/tx/op-description-view.js +945 -942
  78. package/tx/op-icon.js +98 -98
  79. package/tx/parser/op-balance-changes.js +66 -66
  80. package/tx/parser/op-descriptor.js +51 -48
  81. package/tx/parser/tx-details-parser.js +81 -81
  82. package/tx/parser/tx-matcher.js +371 -371
  83. package/tx/parser/type-filter-matcher.js +126 -126
  84. package/tx/tx-list-hooks.js +32 -18
  85. package/tx/tx-operations-list.js +117 -116
@@ -1,127 +1,127 @@
1
- import React from 'react'
2
- import cn from 'classnames'
3
- import {shortenString} from '@stellar-expert/formatter'
4
- import {AccountIdenticon} from './identicon'
5
- import {InfoTooltip} from '../controls/info-tooltip'
6
- import {useDirectory} from '../directory/directory-hooks'
7
- import {formatExplorerLink} from '../ledger/ledger-entry-href-formatter'
8
- import {useStellarNetwork} from '../state/stellar-network-hooks'
9
- import {decodeKeyType} from '../stellar/key-type'
10
- import './account-address.scss'
11
-
12
-
13
- function isPublicKeyOrContract(type) {
14
- return type === 'ed25519' || type === 'contract' || type === 'muxed'
15
- }
16
-
17
- function getAccountPredefinedDisplayName(address) {
18
- if (!window.predefinedAccountDisplayNames)
19
- return undefined
20
- return window.predefinedAccountDisplayNames[address]
21
- }
22
-
23
- function AccountDisplayName({type, address, name}) {
24
- const predefined = getAccountPredefinedDisplayName(address)
25
- let directoryInfo = useDirectory(!predefined && !name && isPublicKeyOrContract(type) && address),
26
- warning
27
- if (name === false)
28
- return null
29
- if (predefined)
30
- return `[${predefined}] `
31
- if (directoryInfo) {
32
- name = directoryInfo.name
33
- if (directoryInfo.tags.includes('malicious')) {
34
- warning = <i className="icon icon-warning color-warning"
35
- title="This account was reported for illicit or fraudulent activity. Do not send funds to this address and do not trust any person affiliated with it."/>
36
- }
37
- }
38
- if (!name && !warning) return null
39
- return <>
40
- {name ? `[${name}] ` : ''}
41
- {warning}
42
- </>
43
-
44
- }
45
-
46
- /**
47
- * Explorer link for Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
48
- * @param {String} account - StrKey-encoded Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
49
- * @param {Number|'all'} [chars] - Visible address characters count
50
- * @param {Bool|String} [name] - Explicit account name that overrides the name from Directory; if false, friendly name is ignored
51
- * @param {Bool|String} [link] - Explicit link; if false, the component is rendered without a link
52
- * @param {Boolean} [icon] - Whether to show/hide account identicon
53
- * @param {String} [network] - Stellar network identifier
54
- * @param {*} [prefix] - Link prefix
55
- * @param {*} [suffix] - Link suffix
56
- * @param {{}} [style] - Optional CSS inline style
57
- * @param {String} [className] - Optional CSS class attribute
58
- * @param {...*} [otherProps] - Optional container parameters
59
- * @constructor
60
- */
61
- export const AccountAddress = React.memo(function AccountAddress({
62
- account,
63
- chars = 8,
64
- name,
65
- link,
66
- style,
67
- className,
68
- icon,
69
- prefix,
70
- suffix,
71
- network,
72
- ...otherProps
73
- }) {
74
- useStellarNetwork()
75
- const keyType = decodeKeyType(account)
76
- if (!keyType)
77
- return null //failed to decode address type
78
- let {type, address, muxedId, publicKey, payload} = keyType
79
-
80
- let innerStyle = !style ? undefined : style
81
-
82
- let ed25519Address = address
83
- if (chars && chars !== 'all') {
84
- address = shortenString(account, chars)
85
- }
86
-
87
- const children = <>
88
- {prefix}
89
- {icon !== false && isPublicKeyOrContract(type) && <AccountIdenticon key="identicon" address={ed25519Address}/>}
90
- <AccountDisplayName type={type} address={ed25519Address} name={name}/>
91
- <span className="account-key">{address}</span>
92
- {muxedId !== undefined && <InfoTooltip icon="icon-plus">
93
- Subaccount of a custodial account<br/>
94
- <AccountAddress account={ed25519Address} name={false} chars={12}/>
95
- <div className="dimmed text-tiny micro-space">Multiplexed id: {muxedId.toString()}</div>
96
- </InfoTooltip>}
97
- {payload !== undefined && <InfoTooltip icon="icon-plus">
98
- ED25519 payload signer<br/>
99
- <AccountAddress account={publicKey} name={false} chars={12}/>
100
- <div className="dimmed text-tiny micro-space">Payload: {payload}</div>
101
- </InfoTooltip>}
102
- {suffix}
103
- </>
104
-
105
- const containerProps = {
106
- title: account,
107
- 'aria-label': account,
108
- className: cn('account-address', className),
109
- style: innerStyle,
110
- ...otherProps
111
- }
112
- let renderAs = 'span'
113
-
114
- if (link !== false && isPublicKeyOrContract(type)) {
115
- renderAs = 'a'
116
- if (typeof link === 'string') {
117
- containerProps.href = link
118
- } else {
119
- containerProps.href = formatExplorerLink(type === 'contract' ? 'contract' : 'account', account, network)
120
- if (window.origin !== explorerFrontendOrigin) {
121
- containerProps.target = '_blank'
122
- }
123
- }
124
- }
125
-
126
- return React.createElement(renderAs, containerProps, children)
127
- })
1
+ import React from 'react'
2
+ import cn from 'classnames'
3
+ import {shortenString} from '@stellar-expert/formatter'
4
+ import {AccountIdenticon} from './identicon'
5
+ import {InfoTooltip} from '../controls/info-tooltip'
6
+ import {useDirectory} from '../directory/directory-hooks'
7
+ import {formatExplorerLink} from '../ledger/ledger-entry-href-formatter'
8
+ import {useStellarNetwork} from '../state/stellar-network-hooks'
9
+ import {decodeKeyType} from '../stellar/key-type'
10
+ import './account-address.scss'
11
+
12
+
13
+ function isPublicKeyOrContract(type) {
14
+ return type === 'ed25519' || type === 'contract' || type === 'muxed'
15
+ }
16
+
17
+ function getAccountPredefinedDisplayName(address) {
18
+ if (!window.predefinedAccountDisplayNames)
19
+ return undefined
20
+ return window.predefinedAccountDisplayNames[address]
21
+ }
22
+
23
+ function AccountDisplayName({type, address, name}) {
24
+ const predefined = getAccountPredefinedDisplayName(address)
25
+ let directoryInfo = useDirectory(!predefined && !name && isPublicKeyOrContract(type) && address),
26
+ warning
27
+ if (name === false)
28
+ return null
29
+ if (predefined)
30
+ return `[${predefined}] `
31
+ if (directoryInfo) {
32
+ name = directoryInfo.name
33
+ if (directoryInfo.tags.includes('malicious')) {
34
+ warning = <i className="icon icon-warning color-warning"
35
+ title="This account was reported for illicit or fraudulent activity. Do not send funds to this address and do not trust any person affiliated with it."/>
36
+ }
37
+ }
38
+ if (!name && !warning) return null
39
+ return <>
40
+ {name ? `[${name}] ` : ''}
41
+ {warning}
42
+ </>
43
+
44
+ }
45
+
46
+ /**
47
+ * Explorer link for Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
48
+ * @param {string} account - StrKey-encoded Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
49
+ * @param {number|'all'} [chars] - Visible address characters count
50
+ * @param {boolean|string} [name] - Explicit account name that overrides the name from Directory; if false, friendly name is ignored
51
+ * @param {boolean|string} [link] - Explicit link; if false, the component is rendered without a link
52
+ * @param {boolean} [icon] - Whether to show/hide account identicon
53
+ * @param {string} [network] - Stellar network identifier
54
+ * @param {*} [prefix] - Link prefix
55
+ * @param {*} [suffix] - Link suffix
56
+ * @param {{}} [style] - Optional CSS inline style
57
+ * @param {string} [className] - Optional CSS class attribute
58
+ * @param {...*} [otherProps] - Optional container parameters
59
+ * @constructor
60
+ */
61
+ export const AccountAddress = React.memo(function AccountAddress({
62
+ account,
63
+ chars = 8,
64
+ name,
65
+ link,
66
+ style,
67
+ className,
68
+ icon,
69
+ prefix,
70
+ suffix,
71
+ network,
72
+ ...otherProps
73
+ }) {
74
+ useStellarNetwork()
75
+ const keyType = decodeKeyType(account)
76
+ if (!keyType)
77
+ return null //failed to decode address type
78
+ let {type, address, muxedId, publicKey, payload} = keyType
79
+
80
+ let innerStyle = !style ? undefined : style
81
+
82
+ let ed25519Address = address
83
+ if (chars && chars !== 'all') {
84
+ address = shortenString(account, chars)
85
+ }
86
+
87
+ const children = <>
88
+ {prefix}
89
+ {icon !== false && isPublicKeyOrContract(type) && <AccountIdenticon key="identicon" address={ed25519Address}/>}
90
+ <AccountDisplayName type={type} address={ed25519Address} name={name}/>
91
+ <span className="account-key">{address}</span>
92
+ {muxedId !== undefined && <InfoTooltip icon="icon-plus">
93
+ Subaccount of a custodial account<br/>
94
+ <AccountAddress account={ed25519Address} name={false} chars={12}/>
95
+ <div className="dimmed text-tiny micro-space">Multiplexed id: {muxedId.toString()}</div>
96
+ </InfoTooltip>}
97
+ {payload !== undefined && <InfoTooltip icon="icon-plus">
98
+ ED25519 payload signer<br/>
99
+ <AccountAddress account={publicKey} name={false} chars={12}/>
100
+ <div className="dimmed text-tiny micro-space">Payload: {payload}</div>
101
+ </InfoTooltip>}
102
+ {suffix}
103
+ </>
104
+
105
+ const containerProps = {
106
+ title: account,
107
+ 'aria-label': account,
108
+ className: cn('account-address', className),
109
+ style: innerStyle,
110
+ ...otherProps
111
+ }
112
+ let renderAs = 'span'
113
+
114
+ if (link !== false && isPublicKeyOrContract(type)) {
115
+ renderAs = 'a'
116
+ if (typeof link === 'string') {
117
+ containerProps.href = link
118
+ } else {
119
+ containerProps.href = formatExplorerLink(type === 'contract' ? 'contract' : 'account', account, network)
120
+ if (window.origin !== explorerFrontendOrigin) {
121
+ containerProps.target = '_blank'
122
+ }
123
+ }
124
+ }
125
+
126
+ return React.createElement(renderAs, containerProps, children)
127
+ })
@@ -1,23 +1,23 @@
1
- import {toStroops, fromStroops} from '@stellar-expert/formatter'
2
- import {AssetDescriptor} from '@stellar-expert/asset-descriptor'
3
-
4
- /**
5
- * Calculate available balance for a given account balance trustline
6
- * @param {AccountResponse} account
7
- * @param {Horizon.BalanceLine} balance
8
- * @param {Number} [additionalReserves]
9
- * @param {Number} [decimals=7]
10
- * @return {String}
11
- */
12
- export function calculateAvailableBalance(account, balance, additionalReserves = null, decimals = 7) {
13
- let available = toStroops(balance.balance) - toStroops(balance.selling_liabilities || 0)
14
- if (balance.asset_type === 'native') {
15
- const reserves = 2 + account.subentry_count + account.num_sponsoring - account.num_sponsored
16
- available = available - (BigInt(reserves) * 5000000n)
17
- //TODO: fetch base_reserve from the Horizon
18
- }
19
- if (additionalReserves !== null) {
20
- available = available - toStroops(additionalReserves, decimals)
21
- }
22
- return fromStroops(available, decimals)
1
+ import {toStroops, fromStroops} from '@stellar-expert/formatter'
2
+ import {AssetDescriptor} from '@stellar-expert/asset-descriptor'
3
+
4
+ /**
5
+ * Calculate available balance for a given account balance trustline
6
+ * @param {AccountResponse} account
7
+ * @param {Horizon.BalanceLine} balance
8
+ * @param {number} [additionalReserves]
9
+ * @param {number} [decimals=7]
10
+ * @return {string}
11
+ */
12
+ export function calculateAvailableBalance(account, balance, additionalReserves = null, decimals = 7) {
13
+ let available = toStroops(balance.balance) - toStroops(balance.selling_liabilities || 0)
14
+ if (balance.asset_type === 'native') {
15
+ const reserves = 2 + account.subentry_count + account.num_sponsoring - account.num_sponsored
16
+ available = available - (BigInt(reserves) * 5000000n)
17
+ //TODO: fetch base_reserve from the Horizon
18
+ }
19
+ if (additionalReserves !== null) {
20
+ available = available - toStroops(additionalReserves, decimals)
21
+ }
22
+ return fromStroops(available, decimals)
23
23
  }
@@ -1,91 +1,91 @@
1
- import React from 'react'
2
- import './identicon.scss'
3
-
4
- const RESOLUTION = 7
5
- const SIZE = 448
6
- const base32Alphabet = {}
7
-
8
- //map base32 alphabet
9
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('').map((c, i) => base32Alphabet[c] = i)
10
-
11
- function decodeBase32(input) {
12
- const buf = []
13
- let shift = 8
14
- let carry = 0
15
-
16
- input.toUpperCase().split('').forEach(char => {
17
- const symbol = base32Alphabet[char] & 0xff
18
- shift -= 5
19
- if (shift > 0) {
20
- carry |= symbol << shift
21
- } else if (shift < 0) {
22
- buf.push(carry | (symbol >> -shift))
23
- shift += 8
24
- carry = (symbol << shift) & 0xff
25
- } else {
26
- buf.push(carry | symbol)
27
- shift = 8
28
- carry = 0
29
- }
30
- })
31
-
32
- if (shift !== 8 && carry !== 0) {
33
- buf.push(carry)
34
- shift = 8
35
- carry = 0
36
- }
37
-
38
- return buf
39
- }
40
-
41
- /**
42
- * Draw Stellar address identicon on the given canvas
43
- * @param {String} address - StrKey-encoded account address
44
- * @param {Number} [size] - Identicon painting area size, in pixels (by default 448)
45
- * @return {String}
46
- */
47
- export function drawIdenticon(address, size = SIZE) {
48
- //take 16 meaningful bytes from the raw pub key
49
- const decoded = decodeBase32(address).slice(2, 16)
50
- const width = RESOLUTION
51
- const height = RESOLUTION
52
- const columns = Math.ceil(width / 2)
53
- const cellSize = size / width
54
- const addressBytes = decoded.slice(1)
55
- const fillStyle = `hsl(${360 * decoded[0] / 256 | 0},58%,52%)`
56
- const dots = []
57
- const rsize = ` width="${cellSize}" height="${cellSize}"`
58
- for (let row = 0; row < height; row++) {
59
- for (let column = 0; column < columns; column++) {
60
- const position = column + row * columns
61
- const bitSet = (addressBytes[position / 8 | 0] & (1 << (7 - position % 8))) !== 0
62
- if (bitSet) {
63
- dots.push(`<rect x="${cellSize * column}" y="${cellSize * row}"${rsize}/>`)
64
- dots.push(`<rect x="${cellSize * (width - column - 1)}" y="${cellSize * row}"${rsize}/>`)
65
- }
66
- }
67
- }
68
- return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" fill="${fillStyle}">${dots.join('')}</svg>`
69
- }
70
-
71
- /**
72
- * Renders account-specific identicon
73
- * @param {String} address - StrKey-encoded account address
74
- * @param {Number} size - Identicon size
75
- * @constructor
76
- */
77
- export const AccountIdenticon = React.memo(function AccountIdenticon({address, size}) {
78
- const props = {
79
- className: 'identicon',
80
- src: 'data:image/svg+xml;charset=utf-8,' + drawIdenticon(address),
81
- width: SIZE,
82
- height: SIZE
83
- }
84
- if (size) {
85
- props.style = {
86
- width: size,
87
- height: size
88
- }
89
- }
90
- return <img {...props}/>
1
+ import React from 'react'
2
+ import './identicon.scss'
3
+
4
+ const RESOLUTION = 7
5
+ const SIZE = 448
6
+ const base32Alphabet = {}
7
+
8
+ //map base32 alphabet
9
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('').map((c, i) => base32Alphabet[c] = i)
10
+
11
+ function decodeBase32(input) {
12
+ const buf = []
13
+ let shift = 8
14
+ let carry = 0
15
+
16
+ input.toUpperCase().split('').forEach(char => {
17
+ const symbol = base32Alphabet[char] & 0xff
18
+ shift -= 5
19
+ if (shift > 0) {
20
+ carry |= symbol << shift
21
+ } else if (shift < 0) {
22
+ buf.push(carry | (symbol >> -shift))
23
+ shift += 8
24
+ carry = (symbol << shift) & 0xff
25
+ } else {
26
+ buf.push(carry | symbol)
27
+ shift = 8
28
+ carry = 0
29
+ }
30
+ })
31
+
32
+ if (shift !== 8 && carry !== 0) {
33
+ buf.push(carry)
34
+ shift = 8
35
+ carry = 0
36
+ }
37
+
38
+ return buf
39
+ }
40
+
41
+ /**
42
+ * Draw Stellar address identicon on the given canvas
43
+ * @param {string} address - StrKey-encoded account address
44
+ * @param {number} [size] - Identicon painting area size, in pixels (by default 448)
45
+ * @return {string}
46
+ */
47
+ export function drawIdenticon(address, size = SIZE) {
48
+ //take 16 meaningful bytes from the raw pub key
49
+ const decoded = decodeBase32(address).slice(2, 16)
50
+ const width = RESOLUTION
51
+ const height = RESOLUTION
52
+ const columns = Math.ceil(width / 2)
53
+ const cellSize = size / width
54
+ const addressBytes = decoded.slice(1)
55
+ const fillStyle = `hsl(${360 * decoded[0] / 256 | 0},58%,52%)`
56
+ const dots = []
57
+ const rsize = ` width="${cellSize}" height="${cellSize}"`
58
+ for (let row = 0; row < height; row++) {
59
+ for (let column = 0; column < columns; column++) {
60
+ const position = column + row * columns
61
+ const bitSet = (addressBytes[position / 8 | 0] & (1 << (7 - position % 8))) !== 0
62
+ if (bitSet) {
63
+ dots.push(`<rect x="${cellSize * column}" y="${cellSize * row}"${rsize}/>`)
64
+ dots.push(`<rect x="${cellSize * (width - column - 1)}" y="${cellSize * row}"${rsize}/>`)
65
+ }
66
+ }
67
+ }
68
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" fill="${fillStyle}">${dots.join('')}</svg>`
69
+ }
70
+
71
+ /**
72
+ * Renders account-specific identicon
73
+ * @param {string} address - StrKey-encoded account address
74
+ * @param {number} size - Identicon size
75
+ * @constructor
76
+ */
77
+ export const AccountIdenticon = React.memo(function AccountIdenticon({address, size}) {
78
+ const props = {
79
+ className: 'identicon',
80
+ src: 'data:image/svg+xml;charset=utf-8,' + drawIdenticon(address),
81
+ width: SIZE,
82
+ height: SIZE
83
+ }
84
+ if (size) {
85
+ props.style = {
86
+ width: size,
87
+ height: size
88
+ }
89
+ }
90
+ return <img {...props}/>
91
91
  })
@@ -1,65 +1,66 @@
1
- import React from 'react'
2
- import {StrKey} from '@stellar/stellar-base'
3
- import {AccountAddress} from './account-address'
4
-
5
- /**
6
- * @param {Signer} signer
7
- * @return {{key: String, weight: Number}|null}
8
- * @internal
9
- */
10
- function decodeSigner(signer) {
11
- if (!signer)
12
- return null
13
- let weight
14
- let key
15
- if (typeof signer.arm === 'function') { //raw xdr
16
- const type = signer.arm()
17
- weight = signer.weight()
18
- switch (type) {
19
- case 'ed25519':
20
- key = StrKey.encodeEd25519PublicKey(signer.ed25519())
21
- break
22
- case 'preAuthTx':
23
- key = StrKey.encodePreAuthTx(signer.preAuthTx())
24
- break
25
- case 'hashX':
26
- key = StrKey.encodeSha256Hash(signer.hashX())
27
- break
28
- case 'ed25519SignedPayload':
29
- key = StrKey.encodeSignedPayload(signer.ed25519SignedPayload())
30
- break
31
- }
32
- } else { //parsed
33
- if (signer.ed25519PublicKey) {
34
- key = signer.ed25519PublicKey
35
- } else if (signer.sha256Hash) {
36
- key = StrKey.encodeSha256Hash(signer.sha256Hash)
37
- } else if (signer.preAuthTx) {
38
- key = StrKey.encodePreAuthTx(signer.preAuthTx)
39
- } else if (signer.ed25519SignedPayload) {
40
- key = StrKey.encodeSignedPayload(signer.ed25519SignedPayload)
41
- }
42
- weight = signer.weight
43
- }
44
- if (!key)
45
- throw new Error('Unknown signer type: ' + JSON.stringify(signer))
46
- return {key, weight}
47
- }
48
-
49
- /**
50
- * Account signer key description
51
- * @param {Signer} signer - StrKey-encoded Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
52
- * @param {String} [name] - Explicit account name that overrides the name from Directory; if false, friendly name is ignored
53
- * @param {String} [className] - Optional CSS class attribute
54
- * @param {Boolean} [showWeight] - Whether to display weight attribute
55
- * @constructor
56
- */
57
- export const SignerKey = React.memo(function SignerKey({signer, name, className, showWeight = true}) {
58
- if (!signer)
59
- return null
60
- const {key, weight} = decodeSigner(signer)
61
- return <span className={className}>
62
- <AccountAddress account={key} name={name}/>
63
- {!!showWeight && <span className="dimmed text-tiny">&nbsp;(weight={weight})</span>}
64
- </span>
1
+ import React from 'react'
2
+ import {StrKey} from '@stellar/stellar-base'
3
+ import {AccountAddress} from './account-address'
4
+
5
+ /**
6
+ * Decode a Stellar signer object (XDR or parsed) into a StrKey-encoded key and weight
7
+ * @param {Signer} signer
8
+ * @return {{key: string, weight: number}|null}
9
+ * @internal
10
+ */
11
+ function decodeSigner(signer) {
12
+ if (!signer)
13
+ return null
14
+ let weight
15
+ let key
16
+ if (typeof signer.arm === 'function') { //raw xdr
17
+ const type = signer.arm()
18
+ weight = signer.weight()
19
+ switch (type) {
20
+ case 'ed25519':
21
+ key = StrKey.encodeEd25519PublicKey(signer.ed25519())
22
+ break
23
+ case 'preAuthTx':
24
+ key = StrKey.encodePreAuthTx(signer.preAuthTx())
25
+ break
26
+ case 'hashX':
27
+ key = StrKey.encodeSha256Hash(signer.hashX())
28
+ break
29
+ case 'ed25519SignedPayload':
30
+ key = StrKey.encodeSignedPayload(signer.ed25519SignedPayload())
31
+ break
32
+ }
33
+ } else { //parsed
34
+ if (signer.ed25519PublicKey) {
35
+ key = signer.ed25519PublicKey
36
+ } else if (signer.sha256Hash) {
37
+ key = StrKey.encodeSha256Hash(signer.sha256Hash)
38
+ } else if (signer.preAuthTx) {
39
+ key = StrKey.encodePreAuthTx(signer.preAuthTx)
40
+ } else if (signer.ed25519SignedPayload) {
41
+ key = StrKey.encodeSignedPayload(signer.ed25519SignedPayload)
42
+ }
43
+ weight = signer.weight
44
+ }
45
+ if (!key)
46
+ throw new Error('Unknown signer type: ' + JSON.stringify(signer))
47
+ return {key, weight}
48
+ }
49
+
50
+ /**
51
+ * Account signer key description
52
+ * @param {Signer} signer - StrKey-encoded Account/MuxedAccount/Sha256Hash/PreAuthTx/SignedPayload
53
+ * @param {string} [name] - Explicit account name that overrides the name from Directory; if false, friendly name is ignored
54
+ * @param {string} [className] - Optional CSS class attribute
55
+ * @param {boolean} [showWeight] - Whether to display weight attribute
56
+ * @constructor
57
+ */
58
+ export const SignerKey = React.memo(function SignerKey({signer, name, className, showWeight = true}) {
59
+ if (!signer)
60
+ return null
61
+ const {key, weight} = decodeSigner(signer)
62
+ return <span className={className}>
63
+ <AccountAddress account={key} name={name}/>
64
+ {!!showWeight && <span className="dimmed text-tiny">&nbsp;(weight={weight})</span>}
65
+ </span>
65
66
  })