@alephium/web3 0.5.0-rc.15 → 0.5.0-rc.17

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/src/api/index.ts CHANGED
@@ -16,154 +16,8 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { Api as NodeApi } from './api-alephium'
20
- import { Api as ExplorerApi } from './api-explorer'
21
-
22
- export interface ApiRequestArguments {
23
- path: string
24
- method: string
25
- params: any[]
26
- }
27
- export type ApiRequestHandler = (args: ApiRequestArguments) => Promise<any>
28
-
29
- function forwardRequests(api: Record<string, any>, handler: ApiRequestHandler): void {
30
- // Update class properties to forward requests
31
- for (const [path, pathObject] of Object.entries(api)) {
32
- for (const method of Object.keys(pathObject)) {
33
- pathObject[`${method}`] = async (...params: any): Promise<any> => {
34
- return handler({ path, method, params })
35
- }
36
- }
37
- }
38
- }
39
-
40
- async function request(provider: Record<string, any>, args: ApiRequestArguments): Promise<any> {
41
- const call = provider[`${args.path}`][`${args.method}`] as (...any) => Promise<any>
42
- return call(...args.params)
43
- }
44
-
45
- function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
46
- const nodeApi = new NodeApi<string>({
47
- baseUrl: baseUrl,
48
- baseApiParams: { secure: true },
49
- securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
50
- })
51
- nodeApi.setSecurityData(apiKey ?? null)
52
- return nodeApi
53
- }
54
-
55
- export class NodeProvider {
56
- readonly wallets: NodeApi<string>['wallets']
57
- readonly infos: NodeApi<string>['infos']
58
- readonly blockflow: NodeApi<string>['blockflow']
59
- readonly addresses: NodeApi<string>['addresses']
60
- readonly transactions: NodeApi<string>['transactions']
61
- readonly mempool: NodeApi<string>['mempool']
62
- readonly contracts: NodeApi<string>['contracts']
63
- readonly multisig: NodeApi<string>['multisig']
64
- readonly utils: NodeApi<string>['utils']
65
- readonly miners: NodeApi<string>['miners']
66
- readonly events: NodeApi<string>['events']
67
-
68
- constructor(baseUrl: string, apiKey?: string)
69
- constructor(provider: NodeProvider)
70
- constructor(handler: ApiRequestHandler)
71
- constructor(param0: string | NodeProvider | ApiRequestHandler, apiKey?: string) {
72
- let nodeApi: NodeProvider
73
- if (typeof param0 === 'string') {
74
- nodeApi = initializeNodeApi(param0, apiKey)
75
- } else if (typeof param0 === 'function') {
76
- nodeApi = new NodeProvider('https://1.2.3.4:0')
77
- forwardRequests(nodeApi, param0 as ApiRequestHandler)
78
- } else {
79
- nodeApi = param0 as NodeProvider
80
- }
81
-
82
- this.wallets = { ...nodeApi.wallets }
83
- this.infos = { ...nodeApi.infos }
84
- this.blockflow = { ...nodeApi.blockflow }
85
- this.addresses = { ...nodeApi.addresses }
86
- this.transactions = { ...nodeApi.transactions }
87
- this.mempool = { ...nodeApi.mempool }
88
- this.contracts = { ...nodeApi.contracts }
89
- this.multisig = { ...nodeApi.multisig }
90
- this.utils = { ...nodeApi.utils }
91
- this.miners = { ...nodeApi.miners }
92
- this.events = { ...nodeApi.events }
93
- }
94
-
95
- request = (args: ApiRequestArguments): Promise<any> => {
96
- return request(this, args)
97
- }
98
-
99
- // This can prevent the proxied node provider from being modified
100
- static Proxy(nodeProvider: NodeProvider): NodeProvider {
101
- return new NodeProvider(nodeProvider)
102
- }
103
-
104
- static Remote(handler: ApiRequestHandler): NodeProvider {
105
- return new NodeProvider(handler)
106
- }
107
- }
108
-
109
- function initializeExplorerApi(baseUrl: string, apiKey?: string): ExplorerApi<string> {
110
- const explorerApi = new ExplorerApi<string>({
111
- baseUrl: baseUrl,
112
- baseApiParams: { secure: true },
113
- securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
114
- })
115
- explorerApi.setSecurityData(apiKey ?? null)
116
- return explorerApi
117
- }
118
-
119
- export class ExplorerProvider {
120
- readonly blocks = ExplorerApi['blocks']
121
- readonly transactions = ExplorerApi['transactions']
122
- readonly addresses = ExplorerApi['addresses']
123
- readonly infos = ExplorerApi['infos']
124
- readonly unconfirmedTransactions = ExplorerApi['unconfirmedTransactions']
125
- readonly tokens = ExplorerApi['tokens']
126
- readonly charts = ExplorerApi['charts']
127
- readonly utils = ExplorerApi['utils']
128
-
129
- constructor(baseUrl: string, apiKey?: string)
130
- constructor(provider: ExplorerProvider)
131
- constructor(handler: ApiRequestHandler)
132
- constructor(param0: string | ExplorerProvider | ApiRequestHandler, apiKey?: string) {
133
- let explorerApi: ExplorerProvider
134
- if (typeof param0 === 'string') {
135
- explorerApi = initializeExplorerApi(param0, apiKey)
136
- } else if (typeof param0 === 'function') {
137
- explorerApi = new ExplorerProvider('https://1.2.3.4:0')
138
- forwardRequests(explorerApi, param0 as ApiRequestHandler)
139
- } else {
140
- explorerApi = param0 as ExplorerProvider
141
- }
142
-
143
- this.blocks = { ...explorerApi.blocks }
144
- this.transactions = { ...explorerApi.transactions }
145
- this.addresses = { ...explorerApi.addresses }
146
- this.infos = { ...explorerApi.infos }
147
- this.unconfirmedTransactions = { ...explorerApi.unconfirmedTransactions }
148
- this.tokens = { ...explorerApi.tokens }
149
- this.charts = { ...explorerApi.charts }
150
- this.utils = { ...explorerApi.utils }
151
- }
152
-
153
- request = (args: ApiRequestArguments): Promise<any> => {
154
- return request(this, args)
155
- }
156
-
157
- // This can prevent the proxied explorer provider from being modified
158
- static Proxy(explorerProvider: ExplorerProvider): ExplorerProvider {
159
- return new ExplorerProvider(explorerProvider)
160
- }
161
-
162
- static Remote(handler: ApiRequestHandler): ExplorerProvider {
163
- return new ExplorerProvider(handler)
164
- }
165
- }
166
-
19
+ export * from './node-provider'
20
+ export * from './explorer-provider'
167
21
  export * as node from './api-alephium'
168
22
  export * as explorer from './api-explorer'
169
23
  export * from './types'
@@ -0,0 +1,84 @@
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
+ import { ApiRequestArguments, ApiRequestHandler, forwardRequests, request } from './types'
20
+ import { Api as NodeApi } from './api-alephium'
21
+
22
+ function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
23
+ const nodeApi = new NodeApi<string>({
24
+ baseUrl: baseUrl,
25
+ baseApiParams: { secure: true },
26
+ securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
27
+ })
28
+ nodeApi.setSecurityData(apiKey ?? null)
29
+ return nodeApi
30
+ }
31
+
32
+ export class NodeProvider {
33
+ readonly wallets: NodeApi<string>['wallets']
34
+ readonly infos: NodeApi<string>['infos']
35
+ readonly blockflow: NodeApi<string>['blockflow']
36
+ readonly addresses: NodeApi<string>['addresses']
37
+ readonly transactions: NodeApi<string>['transactions']
38
+ readonly mempool: NodeApi<string>['mempool']
39
+ readonly contracts: NodeApi<string>['contracts']
40
+ readonly multisig: NodeApi<string>['multisig']
41
+ readonly utils: NodeApi<string>['utils']
42
+ readonly miners: NodeApi<string>['miners']
43
+ readonly events: NodeApi<string>['events']
44
+
45
+ constructor(baseUrl: string, apiKey?: string)
46
+ constructor(provider: NodeProvider)
47
+ constructor(handler: ApiRequestHandler)
48
+ constructor(param0: string | NodeProvider | ApiRequestHandler, apiKey?: string) {
49
+ let nodeApi: NodeProvider
50
+ if (typeof param0 === 'string') {
51
+ nodeApi = initializeNodeApi(param0, apiKey)
52
+ } else if (typeof param0 === 'function') {
53
+ nodeApi = new NodeProvider('https://1.2.3.4:0')
54
+ forwardRequests(nodeApi, param0 as ApiRequestHandler)
55
+ } else {
56
+ nodeApi = param0 as NodeProvider
57
+ }
58
+
59
+ this.wallets = { ...nodeApi.wallets }
60
+ this.infos = { ...nodeApi.infos }
61
+ this.blockflow = { ...nodeApi.blockflow }
62
+ this.addresses = { ...nodeApi.addresses }
63
+ this.transactions = { ...nodeApi.transactions }
64
+ this.mempool = { ...nodeApi.mempool }
65
+ this.contracts = { ...nodeApi.contracts }
66
+ this.multisig = { ...nodeApi.multisig }
67
+ this.utils = { ...nodeApi.utils }
68
+ this.miners = { ...nodeApi.miners }
69
+ this.events = { ...nodeApi.events }
70
+ }
71
+
72
+ request = (args: ApiRequestArguments): Promise<any> => {
73
+ return request(this, args)
74
+ }
75
+
76
+ // This can prevent the proxied node provider from being modified
77
+ static Proxy(nodeProvider: NodeProvider): NodeProvider {
78
+ return new NodeProvider(nodeProvider)
79
+ }
80
+
81
+ static Remote(handler: ApiRequestHandler): NodeProvider {
82
+ return new NodeProvider(handler)
83
+ }
84
+ }
package/src/api/types.ts CHANGED
@@ -245,3 +245,26 @@ export function typeLength(tpe: string): number {
245
245
  const [, dims] = decodeArrayType(tpe)
246
246
  return dims.reduce((a, b) => a * b)
247
247
  }
248
+
249
+ export interface ApiRequestArguments {
250
+ path: string
251
+ method: string
252
+ params: any[]
253
+ }
254
+ export type ApiRequestHandler = (args: ApiRequestArguments) => Promise<any>
255
+
256
+ export function forwardRequests(api: Record<string, any>, handler: ApiRequestHandler): void {
257
+ // Update class properties to forward requests
258
+ for (const [path, pathObject] of Object.entries(api)) {
259
+ for (const method of Object.keys(pathObject)) {
260
+ pathObject[`${method}`] = async (...params: any): Promise<any> => {
261
+ return handler({ path, method, params })
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ export async function request(provider: Record<string, any>, args: ApiRequestArguments): Promise<any> {
268
+ const call = provider[`${args.path}`][`${args.method}`] as (...any) => Promise<any>
269
+ return call(...args.params)
270
+ }
@@ -22,3 +22,4 @@ export * from './djb2'
22
22
  export * from './utils'
23
23
  export * from './subscription'
24
24
  export * from './sign'
25
+ export * from './number'
@@ -0,0 +1,187 @@
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
+ ]
160
+
161
+ export const tests1 = [
162
+ {
163
+ raw: '0',
164
+ decimals: 18,
165
+ amount: 0n
166
+ },
167
+ {
168
+ raw: '1.23',
169
+ decimals: 2,
170
+ amount: 123n
171
+ },
172
+ {
173
+ raw: '1',
174
+ decimals: 5,
175
+ amount: 100000n
176
+ },
177
+ {
178
+ raw: '1',
179
+ decimals: 18,
180
+ amount: 1000000000000000000n
181
+ },
182
+ {
183
+ raw: '1.23456789',
184
+ decimals: 18,
185
+ amount: 1234567890000000000n
186
+ }
187
+ ]
@@ -0,0 +1,157 @@
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 | undefined {
58
+ return prettifyNumber(amount, 18, prettifyNumberConfig.ALPH)
59
+ }
60
+
61
+ export function prettifyTokenAmount(amount: bigint, decimals: number): string | undefined {
62
+ return prettifyNumber(amount, decimals, prettifyNumberConfig.TOKEN)
63
+ }
64
+
65
+ export function prettifyExactAmount(amount: bigint, decimals: number): string | undefined {
66
+ return prettifyNumber(amount, decimals, prettifyNumberConfig.Exact)
67
+ }
68
+
69
+ export function prettifyNumber(amount: bigint, decimals: number, config: IPrettifyNumberConfig): string | undefined {
70
+ const number = toFixedNumber(amount, decimals)
71
+
72
+ if (!isNumeric(number)) {
73
+ return undefined
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
+ }
145
+
146
+ export function convertAmountWithDecimals(amount: string | number, decimals: number): bigint | undefined {
147
+ try {
148
+ const result = new BigNumber(amount).multipliedBy(Math.pow(10, decimals))
149
+ return BigInt(result.toFormat(0, { groupSeparator: '' }))
150
+ } catch (e) {
151
+ return undefined
152
+ }
153
+ }
154
+
155
+ export function convertAlphAmount(amount: string | number): bigint | undefined {
156
+ return convertAmountWithDecimals(amount, 18)
157
+ }