@alephium/web3 0.5.0-rc.14 → 0.5.0-rc.16
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/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-explorer.d.ts +67 -46
- package/dist/src/api/api-explorer.js +12 -12
- package/dist/src/api/index.d.ts +1 -1
- package/dist/src/api/index.js +2 -2
- package/dist/src/signer/types.d.ts +2 -1
- package/dist/src/utils/number.d.ts +14 -0
- package/dist/src/utils/number.fixture.d.ts +7 -0
- package/dist/src/utils/number.fixture.js +162 -0
- package/dist/src/utils/number.js +130 -0
- package/package.json +5 -4
- package/src/api/api-explorer.ts +78 -50
- package/src/api/index.ts +2 -2
- package/src/signer/types.ts +4 -1
- package/src/utils/number.fixture.ts +159 -0
- package/src/utils/number.ts +144 -0
package/src/api/api-explorer.ts
CHANGED
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
* ---------------------------------------------------------------
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
export interface AcceptedTransaction {
|
|
13
|
+
/** @format 32-byte-hash */
|
|
14
|
+
hash: string
|
|
15
|
+
/** @format block-hash */
|
|
16
|
+
blockHash: string
|
|
17
|
+
/** @format int64 */
|
|
18
|
+
timestamp: number
|
|
19
|
+
inputs?: Input[]
|
|
20
|
+
outputs?: Output[]
|
|
21
|
+
/** @format int32 */
|
|
22
|
+
gasAmount: number
|
|
23
|
+
/** @format uint256 */
|
|
24
|
+
gasPrice: string
|
|
25
|
+
coinbase: boolean
|
|
26
|
+
type: string
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
export interface AddressBalance {
|
|
13
30
|
/** @format uint256 */
|
|
14
31
|
balance: string
|
|
@@ -32,6 +49,7 @@ export interface AssetOutput {
|
|
|
32
49
|
key: string
|
|
33
50
|
/** @format uint256 */
|
|
34
51
|
attoAlphAmount: string
|
|
52
|
+
/** @format address */
|
|
35
53
|
address: string
|
|
36
54
|
tokens?: Token[]
|
|
37
55
|
/** @format int64 */
|
|
@@ -65,23 +83,6 @@ export interface BlockEntryLite {
|
|
|
65
83
|
hashRate: string
|
|
66
84
|
}
|
|
67
85
|
|
|
68
|
-
export interface ConfirmedTransaction {
|
|
69
|
-
/** @format 32-byte-hash */
|
|
70
|
-
hash: string
|
|
71
|
-
/** @format block-hash */
|
|
72
|
-
blockHash: string
|
|
73
|
-
/** @format int64 */
|
|
74
|
-
timestamp: number
|
|
75
|
-
inputs?: Input[]
|
|
76
|
-
outputs?: Output[]
|
|
77
|
-
/** @format int32 */
|
|
78
|
-
gasAmount: number
|
|
79
|
-
/** @format uint256 */
|
|
80
|
-
gasPrice: string
|
|
81
|
-
coinbase: boolean
|
|
82
|
-
type: string
|
|
83
|
-
}
|
|
84
|
-
|
|
85
86
|
export interface ContractOutput {
|
|
86
87
|
/** @format int32 */
|
|
87
88
|
hint: number
|
|
@@ -89,6 +90,7 @@ export interface ContractOutput {
|
|
|
89
90
|
key: string
|
|
90
91
|
/** @format uint256 */
|
|
91
92
|
attoAlphAmount: string
|
|
93
|
+
/** @format address */
|
|
92
94
|
address: string
|
|
93
95
|
tokens?: Token[]
|
|
94
96
|
/** @format 32-byte-hash */
|
|
@@ -101,7 +103,9 @@ export interface Event {
|
|
|
101
103
|
blockHash: string
|
|
102
104
|
/** @format 32-byte-hash */
|
|
103
105
|
txHash: string
|
|
106
|
+
/** @format address */
|
|
104
107
|
contractAddress: string
|
|
108
|
+
/** @format address */
|
|
105
109
|
inputAddress?: string
|
|
106
110
|
/** @format int32 */
|
|
107
111
|
eventIndex: number
|
|
@@ -126,6 +130,7 @@ export interface Input {
|
|
|
126
130
|
unlockScript?: string
|
|
127
131
|
/** @format 32-byte-hash */
|
|
128
132
|
txHashRef?: string
|
|
133
|
+
/** @format address */
|
|
129
134
|
address?: string
|
|
130
135
|
/** @format uint256 */
|
|
131
136
|
attoAlphAmount?: string
|
|
@@ -152,6 +157,23 @@ export interface LogbackValue {
|
|
|
152
157
|
level: string
|
|
153
158
|
}
|
|
154
159
|
|
|
160
|
+
export interface MempoolTransaction {
|
|
161
|
+
/** @format 32-byte-hash */
|
|
162
|
+
hash: string
|
|
163
|
+
/** @format int32 */
|
|
164
|
+
chainFrom: number
|
|
165
|
+
/** @format int32 */
|
|
166
|
+
chainTo: number
|
|
167
|
+
inputs?: Input[]
|
|
168
|
+
outputs?: Output[]
|
|
169
|
+
/** @format int32 */
|
|
170
|
+
gasAmount: number
|
|
171
|
+
/** @format uint256 */
|
|
172
|
+
gasPrice: string
|
|
173
|
+
/** @format int64 */
|
|
174
|
+
lastSeen: number
|
|
175
|
+
}
|
|
176
|
+
|
|
155
177
|
export interface NotFound {
|
|
156
178
|
detail: string
|
|
157
179
|
resource: string
|
|
@@ -166,6 +188,24 @@ export interface OutputRef {
|
|
|
166
188
|
key: string
|
|
167
189
|
}
|
|
168
190
|
|
|
191
|
+
export interface PendingTransaction {
|
|
192
|
+
/** @format 32-byte-hash */
|
|
193
|
+
hash: string
|
|
194
|
+
/** @format int32 */
|
|
195
|
+
chainFrom: number
|
|
196
|
+
/** @format int32 */
|
|
197
|
+
chainTo: number
|
|
198
|
+
inputs?: Input[]
|
|
199
|
+
outputs?: Output[]
|
|
200
|
+
/** @format int32 */
|
|
201
|
+
gasAmount: number
|
|
202
|
+
/** @format uint256 */
|
|
203
|
+
gasPrice: string
|
|
204
|
+
/** @format int64 */
|
|
205
|
+
lastSeen: number
|
|
206
|
+
type: string
|
|
207
|
+
}
|
|
208
|
+
|
|
169
209
|
export interface PerChainCount {
|
|
170
210
|
/** @format int32 */
|
|
171
211
|
chainFrom: number
|
|
@@ -252,30 +292,12 @@ export interface Transaction {
|
|
|
252
292
|
coinbase: boolean
|
|
253
293
|
}
|
|
254
294
|
|
|
255
|
-
export type TransactionLike =
|
|
295
|
+
export type TransactionLike = AcceptedTransaction | PendingTransaction
|
|
256
296
|
|
|
257
297
|
export interface Unauthorized {
|
|
258
298
|
detail: string
|
|
259
299
|
}
|
|
260
300
|
|
|
261
|
-
export interface UnconfirmedTransaction {
|
|
262
|
-
/** @format 32-byte-hash */
|
|
263
|
-
hash: string
|
|
264
|
-
/** @format int32 */
|
|
265
|
-
chainFrom: number
|
|
266
|
-
/** @format int32 */
|
|
267
|
-
chainTo: number
|
|
268
|
-
inputs?: Input[]
|
|
269
|
-
outputs?: Output[]
|
|
270
|
-
/** @format int32 */
|
|
271
|
-
gasAmount: number
|
|
272
|
-
/** @format uint256 */
|
|
273
|
-
gasPrice: string
|
|
274
|
-
/** @format int64 */
|
|
275
|
-
lastSeen: number
|
|
276
|
-
type: string
|
|
277
|
-
}
|
|
278
|
-
|
|
279
301
|
export type Val = ValAddress | ValArray | ValBool | ValByteVec | ValI256 | ValU256
|
|
280
302
|
|
|
281
303
|
export interface ValAddress {
|
|
@@ -769,15 +791,18 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
769
791
|
}).then(convertHttpResponse),
|
|
770
792
|
|
|
771
793
|
/**
|
|
772
|
-
* @description List
|
|
794
|
+
* @description List mempool transactions of a given address
|
|
773
795
|
*
|
|
774
796
|
* @tags Addresses
|
|
775
|
-
* @name
|
|
776
|
-
* @request GET:/addresses/{address}/
|
|
797
|
+
* @name GetAddressesAddressMempoolTransactions
|
|
798
|
+
* @request GET:/addresses/{address}/mempool/transactions
|
|
777
799
|
*/
|
|
778
|
-
|
|
779
|
-
this.request<
|
|
780
|
-
|
|
800
|
+
getAddressesAddressMempoolTransactions: (address: string, params: RequestParams = {}) =>
|
|
801
|
+
this.request<
|
|
802
|
+
MempoolTransaction[],
|
|
803
|
+
BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
|
|
804
|
+
>({
|
|
805
|
+
path: `/addresses/${address}/mempool/transactions`,
|
|
781
806
|
method: 'GET',
|
|
782
807
|
format: 'json',
|
|
783
808
|
...params
|
|
@@ -1059,15 +1084,15 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1059
1084
|
}
|
|
1060
1085
|
).then(convertHttpResponse)
|
|
1061
1086
|
}
|
|
1062
|
-
|
|
1087
|
+
mempool = {
|
|
1063
1088
|
/**
|
|
1064
|
-
* @description list
|
|
1089
|
+
* @description list mempool transactions
|
|
1065
1090
|
*
|
|
1066
|
-
* @tags
|
|
1067
|
-
* @name
|
|
1068
|
-
* @request GET:/
|
|
1091
|
+
* @tags Mempool
|
|
1092
|
+
* @name GetMempoolTransactions
|
|
1093
|
+
* @request GET:/mempool/transactions
|
|
1069
1094
|
*/
|
|
1070
|
-
|
|
1095
|
+
getMempoolTransactions: (
|
|
1071
1096
|
query?: {
|
|
1072
1097
|
/**
|
|
1073
1098
|
* Page number
|
|
@@ -1084,8 +1109,11 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1084
1109
|
},
|
|
1085
1110
|
params: RequestParams = {}
|
|
1086
1111
|
) =>
|
|
1087
|
-
this.request<
|
|
1088
|
-
|
|
1112
|
+
this.request<
|
|
1113
|
+
MempoolTransaction[],
|
|
1114
|
+
BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
|
|
1115
|
+
>({
|
|
1116
|
+
path: `/mempool/transactions`,
|
|
1089
1117
|
method: 'GET',
|
|
1090
1118
|
query: query,
|
|
1091
1119
|
format: 'json',
|
package/src/api/index.ts
CHANGED
|
@@ -121,7 +121,7 @@ export class ExplorerProvider {
|
|
|
121
121
|
readonly transactions = ExplorerApi['transactions']
|
|
122
122
|
readonly addresses = ExplorerApi['addresses']
|
|
123
123
|
readonly infos = ExplorerApi['infos']
|
|
124
|
-
readonly
|
|
124
|
+
readonly mempool = ExplorerApi['mempool']
|
|
125
125
|
readonly tokens = ExplorerApi['tokens']
|
|
126
126
|
readonly charts = ExplorerApi['charts']
|
|
127
127
|
readonly utils = ExplorerApi['utils']
|
|
@@ -144,7 +144,7 @@ export class ExplorerProvider {
|
|
|
144
144
|
this.transactions = { ...explorerApi.transactions }
|
|
145
145
|
this.addresses = { ...explorerApi.addresses }
|
|
146
146
|
this.infos = { ...explorerApi.infos }
|
|
147
|
-
this.
|
|
147
|
+
this.mempool = { ...explorerApi.mempool }
|
|
148
148
|
this.tokens = { ...explorerApi.tokens }
|
|
149
149
|
this.charts = { ...explorerApi.charts }
|
|
150
150
|
this.utils = { ...explorerApi.utils }
|
package/src/signer/types.ts
CHANGED
|
@@ -166,6 +166,9 @@ export interface SubmissionResult {
|
|
|
166
166
|
export interface EnableOptionsBase {
|
|
167
167
|
// chainGroup - specify whether to use addresses from a specific group
|
|
168
168
|
chainGroup?: number
|
|
169
|
+
// keyType - specify which type of signing algorithm to use
|
|
170
|
+
keyType?: KeyType
|
|
171
|
+
|
|
169
172
|
networkId: string
|
|
170
|
-
onDisconnected: () => Promise<void>
|
|
173
|
+
onDisconnected: () => Promise<void> | void
|
|
171
174
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
export const tests = [
|
|
19
|
+
{
|
|
20
|
+
raw: 123456n,
|
|
21
|
+
decimal: 5,
|
|
22
|
+
exact: '1.23456',
|
|
23
|
+
alphFormat: '1.23',
|
|
24
|
+
tokenFormat: '1.2346'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
raw: 12345612n,
|
|
28
|
+
decimal: 2,
|
|
29
|
+
exact: '123,456.12',
|
|
30
|
+
alphFormat: '123,456.12',
|
|
31
|
+
tokenFormat: '123,456.12'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
raw: 123456123456n,
|
|
35
|
+
decimal: 6,
|
|
36
|
+
exact: '123,456.123456',
|
|
37
|
+
alphFormat: '123,456.12',
|
|
38
|
+
tokenFormat: '123,456.1235'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
raw: 12n,
|
|
42
|
+
decimal: 2,
|
|
43
|
+
exact: '0.12',
|
|
44
|
+
alphFormat: '0.12',
|
|
45
|
+
tokenFormat: '0.12'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
raw: 123456n,
|
|
49
|
+
decimal: 6,
|
|
50
|
+
exact: '0.123456',
|
|
51
|
+
alphFormat: '0.12',
|
|
52
|
+
tokenFormat: '0.1235'
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
raw: 123456n,
|
|
56
|
+
decimal: 7,
|
|
57
|
+
exact: '0.0123456',
|
|
58
|
+
alphFormat: '0.012',
|
|
59
|
+
tokenFormat: '0.0123'
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
raw: 123456n,
|
|
63
|
+
decimal: 8,
|
|
64
|
+
exact: '0.00123456',
|
|
65
|
+
alphFormat: '0.0012',
|
|
66
|
+
tokenFormat: '0.0012'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
raw: 123456n,
|
|
70
|
+
decimal: 9,
|
|
71
|
+
exact: '0.000123456',
|
|
72
|
+
alphFormat: '0.00012',
|
|
73
|
+
tokenFormat: '0.00012'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
raw: 123456n,
|
|
77
|
+
decimal: 11,
|
|
78
|
+
exact: '0.00000123456',
|
|
79
|
+
alphFormat: '0.0000012',
|
|
80
|
+
tokenFormat: '0.0000012'
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
raw: -123456n,
|
|
84
|
+
decimal: 11,
|
|
85
|
+
exact: '-0.00000123456',
|
|
86
|
+
alphFormat: '-0.0000012',
|
|
87
|
+
tokenFormat: '-0.0000012'
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
raw: 8923088n,
|
|
91
|
+
decimal: 10,
|
|
92
|
+
exact: '0.0008923088',
|
|
93
|
+
alphFormat: '0.00089',
|
|
94
|
+
tokenFormat: '0.00089'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
raw: 885n,
|
|
98
|
+
decimal: 6,
|
|
99
|
+
exact: '0.000885',
|
|
100
|
+
alphFormat: '0.00089',
|
|
101
|
+
tokenFormat: '0.00089'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
raw: 100000000000n,
|
|
105
|
+
decimal: 18,
|
|
106
|
+
exact: '0.0000001',
|
|
107
|
+
alphFormat: '0.0000001',
|
|
108
|
+
tokenFormat: '0.0000001'
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
raw: 1504000000000000000n,
|
|
112
|
+
decimal: 18,
|
|
113
|
+
exact: '1.504',
|
|
114
|
+
alphFormat: '1.50',
|
|
115
|
+
tokenFormat: '1.504'
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
raw: 1505000000000000000n,
|
|
119
|
+
decimal: 18,
|
|
120
|
+
exact: '1.505',
|
|
121
|
+
alphFormat: '1.51',
|
|
122
|
+
tokenFormat: '1.505'
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
raw: 1500050000000000000n,
|
|
126
|
+
decimal: 18,
|
|
127
|
+
exact: '1.50005',
|
|
128
|
+
alphFormat: '1.50',
|
|
129
|
+
tokenFormat: '1.5001'
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
raw: 100n,
|
|
133
|
+
decimal: 0,
|
|
134
|
+
exact: '100',
|
|
135
|
+
alphFormat: '100.00',
|
|
136
|
+
tokenFormat: '100.0'
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
raw: 123456789n,
|
|
140
|
+
decimal: 0,
|
|
141
|
+
exact: '123,456,789',
|
|
142
|
+
alphFormat: '123,456,789.00',
|
|
143
|
+
tokenFormat: '123,456,789.0'
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
raw: -123456789n,
|
|
147
|
+
decimal: 0,
|
|
148
|
+
exact: '-123,456,789',
|
|
149
|
+
alphFormat: '-123,456,789.00',
|
|
150
|
+
tokenFormat: '-123,456,789.0'
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
raw: 0n,
|
|
154
|
+
decimal: 0,
|
|
155
|
+
exact: '0',
|
|
156
|
+
alphFormat: '0.00',
|
|
157
|
+
tokenFormat: '0.0'
|
|
158
|
+
}
|
|
159
|
+
]
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Credits:
|
|
20
|
+
// 1. https://github.com/argentlabs/argent-x/blob/e63affa7f28b27333dca4081a3dcd375bb2da40b/packages/extension/src/shared/utils/number.ts
|
|
21
|
+
// 2. https://github.com/ethers-io/ethers.js/blob/724881f34d428406488a1c9f9dbebe54b6edecda/src.ts/utils/fixednumber.ts
|
|
22
|
+
|
|
23
|
+
import BigNumber from 'bignumber.js'
|
|
24
|
+
|
|
25
|
+
export const isNumeric = (numToCheck: any): boolean => !isNaN(parseFloat(numToCheck)) && isFinite(numToCheck)
|
|
26
|
+
|
|
27
|
+
export interface IPrettifyNumberConfig {
|
|
28
|
+
minDecimalPlaces: number
|
|
29
|
+
maxDecimalPlaces: number
|
|
30
|
+
/** significant digits to show in decimals while respecting decimal places */
|
|
31
|
+
minDecimalSignificantDigits: number
|
|
32
|
+
/** special case for zero, e.g. we may want to display $0.00 or 0.0 ALPH */
|
|
33
|
+
decimalPlacesWhenZero: number
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const prettifyNumberConfig: Record<string, IPrettifyNumberConfig> = {
|
|
37
|
+
ALPH: {
|
|
38
|
+
minDecimalPlaces: 2,
|
|
39
|
+
maxDecimalPlaces: 10,
|
|
40
|
+
minDecimalSignificantDigits: 2,
|
|
41
|
+
decimalPlacesWhenZero: 2
|
|
42
|
+
},
|
|
43
|
+
TOKEN: {
|
|
44
|
+
minDecimalPlaces: 4,
|
|
45
|
+
maxDecimalPlaces: 16,
|
|
46
|
+
minDecimalSignificantDigits: 2,
|
|
47
|
+
decimalPlacesWhenZero: 1
|
|
48
|
+
},
|
|
49
|
+
Exact: {
|
|
50
|
+
minDecimalPlaces: 18,
|
|
51
|
+
maxDecimalPlaces: 18,
|
|
52
|
+
minDecimalSignificantDigits: 0,
|
|
53
|
+
decimalPlacesWhenZero: 0
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function prettifyAttoAlphAmount(amount: bigint): string | null {
|
|
58
|
+
return prettifyNumber(amount, 18, prettifyNumberConfig.ALPH)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function prettifyTokenAmount(amount: bigint, decimals: number): string | null {
|
|
62
|
+
return prettifyNumber(amount, decimals, prettifyNumberConfig.TOKEN)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function prettifyExactAmount(amount: bigint, decimals: number): string | null {
|
|
66
|
+
return prettifyNumber(amount, decimals, prettifyNumberConfig.Exact)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function prettifyNumber(amount: bigint, decimals: number, config: IPrettifyNumberConfig): string | null {
|
|
70
|
+
const number = toFixedNumber(amount, decimals)
|
|
71
|
+
|
|
72
|
+
if (!isNumeric(number)) {
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const numberBN = new BigNumber(number)
|
|
77
|
+
|
|
78
|
+
let untrimmed: string
|
|
79
|
+
if (numberBN.gte(1)) {
|
|
80
|
+
/** simplest case, formatting to minDecimalPlaces will look good */
|
|
81
|
+
untrimmed = numberBN.toFormat(config.minDecimalPlaces)
|
|
82
|
+
} else {
|
|
83
|
+
/** now need to interrogate the appearance of decimal number < 1 */
|
|
84
|
+
/** longest case - max decimal places e.g. 0.0008923088123 -> 0.0008923088 */
|
|
85
|
+
const maxDecimalPlacesString = numberBN.toFormat(config.maxDecimalPlaces)
|
|
86
|
+
/** count the zeros, which will then allow us to know the final length with desired significant digits */
|
|
87
|
+
const decimalPart = maxDecimalPlacesString.split('.')[1]
|
|
88
|
+
const zeroMatches = decimalPart?.match(/^0+/)
|
|
89
|
+
const leadingZerosInDecimalPart = zeroMatches && zeroMatches.length ? zeroMatches[0].length : 0
|
|
90
|
+
/** now we can re-format with leadingZerosInDecimalPart + maxDecimalSignificanDigits to give us the pretty version */
|
|
91
|
+
/** e.g. 0.0008923088123 -> 0.00089 */
|
|
92
|
+
const prettyDecimalPlaces = Math.max(
|
|
93
|
+
leadingZerosInDecimalPart + config.minDecimalSignificantDigits,
|
|
94
|
+
config.minDecimalPlaces
|
|
95
|
+
)
|
|
96
|
+
untrimmed = numberBN.toFormat(prettyDecimalPlaces)
|
|
97
|
+
}
|
|
98
|
+
/** the untrimmed string may have trailing zeros, e.g. 0.0890 */
|
|
99
|
+
/** trim to a minimum specified by the config, e.g. we may want to display $0.00 or 0.0 ETH */
|
|
100
|
+
let trimmed = untrimmed.replace(/0+$/, '')
|
|
101
|
+
const minLength = 1 + untrimmed.indexOf('.') + config.decimalPlacesWhenZero
|
|
102
|
+
if (trimmed.length < minLength) {
|
|
103
|
+
trimmed = untrimmed.substring(0, minLength)
|
|
104
|
+
}
|
|
105
|
+
if (trimmed[trimmed.length - 1] === '.') {
|
|
106
|
+
trimmed = trimmed.slice(0, -1)
|
|
107
|
+
}
|
|
108
|
+
return trimmed
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const BN_N1 = BigInt(-1)
|
|
112
|
+
const BN_0 = BigInt(0)
|
|
113
|
+
|
|
114
|
+
// Constant to pull zeros from for multipliers
|
|
115
|
+
const Zeros = '0000'
|
|
116
|
+
|
|
117
|
+
function toFixedNumber(val: bigint, decimals: number): string {
|
|
118
|
+
let negative = ''
|
|
119
|
+
if (val < BN_0) {
|
|
120
|
+
negative = '-'
|
|
121
|
+
val *= BN_N1
|
|
122
|
+
}
|
|
123
|
+
let str = val.toString()
|
|
124
|
+
// No decimal point for whole values
|
|
125
|
+
if (decimals === 0) {
|
|
126
|
+
return negative + str
|
|
127
|
+
}
|
|
128
|
+
// Pad out to the whole component (including a whole digit)
|
|
129
|
+
while (str.length <= decimals) {
|
|
130
|
+
str = Zeros + str
|
|
131
|
+
}
|
|
132
|
+
// Insert the decimal point
|
|
133
|
+
const index = str.length - decimals
|
|
134
|
+
str = str.substring(0, index) + '.' + str.substring(index)
|
|
135
|
+
// Trim the whole component (leaving at least one 0)
|
|
136
|
+
while (str[0] === '0' && str[1] !== '.') {
|
|
137
|
+
str = str.substring(1)
|
|
138
|
+
}
|
|
139
|
+
// Trim the decimal component (leaving at least one 0)
|
|
140
|
+
while (str[str.length - 1] === '0' && str[str.length - 2] !== '.') {
|
|
141
|
+
str = str.substring(0, str.length - 1)
|
|
142
|
+
}
|
|
143
|
+
return negative + str
|
|
144
|
+
}
|