@alephium/web3 0.5.0-rc.2 → 0.5.0-rc.20
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.LICENSE.txt +2 -0
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +113 -26
- package/dist/src/api/api-alephium.js +62 -18
- package/dist/src/api/api-explorer.d.ts +222 -52
- package/dist/src/api/api-explorer.js +17 -15
- package/dist/src/api/explorer-provider.d.ts +18 -0
- package/dist/src/api/explorer-provider.js +65 -0
- package/dist/src/api/index.d.ts +2 -41
- package/dist/src/api/index.js +6 -116
- package/dist/src/api/node-provider.d.ts +21 -0
- package/dist/src/api/node-provider.js +68 -0
- package/dist/src/api/types.d.ts +10 -2
- package/dist/src/api/types.js +23 -3
- package/dist/src/contract/contract.d.ts +15 -7
- package/dist/src/contract/contract.js +62 -42
- package/dist/src/signer/signer.d.ts +25 -30
- package/dist/src/signer/signer.js +57 -30
- package/dist/src/signer/tx-builder.d.ts +2 -7
- package/dist/src/signer/tx-builder.js +10 -7
- package/dist/src/signer/types.d.ts +12 -16
- package/dist/src/transaction/sign-verify.d.ts +3 -2
- package/dist/src/transaction/sign-verify.js +4 -14
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/index.js +2 -0
- package/dist/src/utils/number.d.ts +17 -0
- package/dist/src/utils/number.fixture.d.ts +12 -0
- package/dist/src/utils/number.fixture.js +189 -0
- package/dist/src/utils/number.js +144 -0
- package/dist/src/utils/sign.d.ts +3 -0
- package/dist/src/utils/sign.js +89 -0
- package/dist/src/utils/utils.d.ts +4 -3
- package/dist/src/utils/utils.js +25 -10
- package/package.json +7 -5
- package/src/api/api-alephium.ts +260 -207
- package/src/api/api-explorer.ts +327 -126
- package/src/api/explorer-provider.ts +78 -0
- package/src/api/index.ts +2 -146
- package/src/api/node-provider.ts +84 -0
- package/src/api/types.ts +36 -3
- package/src/contract/contract.ts +80 -49
- package/src/signer/signer.ts +87 -66
- package/src/signer/tx-builder.ts +13 -7
- package/src/signer/types.ts +22 -11
- package/src/transaction/sign-verify.ts +10 -15
- package/src/utils/index.ts +2 -0
- package/src/utils/number.fixture.ts +187 -0
- package/src/utils/number.ts +158 -0
- package/src/utils/sign.ts +66 -0
- package/src/utils/utils.ts +26 -10
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
import { Number256 } from '..'
|
|
25
|
+
|
|
26
|
+
export const isNumeric = (numToCheck: any): boolean => !isNaN(parseFloat(numToCheck)) && isFinite(numToCheck)
|
|
27
|
+
|
|
28
|
+
export interface IPrettifyNumberConfig {
|
|
29
|
+
minDecimalPlaces: number
|
|
30
|
+
maxDecimalPlaces: number
|
|
31
|
+
/** significant digits to show in decimals while respecting decimal places */
|
|
32
|
+
minDecimalSignificantDigits: number
|
|
33
|
+
/** special case for zero, e.g. we may want to display $0.00 or 0.0 ALPH */
|
|
34
|
+
decimalPlacesWhenZero: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const prettifyNumberConfig: Record<string, IPrettifyNumberConfig> = {
|
|
38
|
+
ALPH: {
|
|
39
|
+
minDecimalPlaces: 2,
|
|
40
|
+
maxDecimalPlaces: 10,
|
|
41
|
+
minDecimalSignificantDigits: 2,
|
|
42
|
+
decimalPlacesWhenZero: 2
|
|
43
|
+
},
|
|
44
|
+
TOKEN: {
|
|
45
|
+
minDecimalPlaces: 4,
|
|
46
|
+
maxDecimalPlaces: 16,
|
|
47
|
+
minDecimalSignificantDigits: 2,
|
|
48
|
+
decimalPlacesWhenZero: 1
|
|
49
|
+
},
|
|
50
|
+
Exact: {
|
|
51
|
+
minDecimalPlaces: 18,
|
|
52
|
+
maxDecimalPlaces: 18,
|
|
53
|
+
minDecimalSignificantDigits: 0,
|
|
54
|
+
decimalPlacesWhenZero: 0
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function prettifyAttoAlphAmount(amount: Number256): string | undefined {
|
|
59
|
+
return prettifyNumber(amount, 18, prettifyNumberConfig.ALPH)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function prettifyTokenAmount(amount: Number256, decimals: number): string | undefined {
|
|
63
|
+
return prettifyNumber(amount, decimals, prettifyNumberConfig.TOKEN)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function prettifyExactAmount(amount: Number256, decimals: number): string | undefined {
|
|
67
|
+
return prettifyNumber(amount, decimals, prettifyNumberConfig.Exact)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function prettifyNumber(amount: Number256, decimals: number, config: IPrettifyNumberConfig): string | undefined {
|
|
71
|
+
const number = typeof amount === 'string' ? amount : toFixedNumber(amount, decimals)
|
|
72
|
+
|
|
73
|
+
if (!isNumeric(number)) {
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const numberBN = new BigNumber(number)
|
|
78
|
+
|
|
79
|
+
let untrimmed: string
|
|
80
|
+
if (numberBN.gte(1)) {
|
|
81
|
+
/** simplest case, formatting to minDecimalPlaces will look good */
|
|
82
|
+
untrimmed = numberBN.toFormat(config.minDecimalPlaces)
|
|
83
|
+
} else {
|
|
84
|
+
/** now need to interrogate the appearance of decimal number < 1 */
|
|
85
|
+
/** longest case - max decimal places e.g. 0.0008923088123 -> 0.0008923088 */
|
|
86
|
+
const maxDecimalPlacesString = numberBN.toFormat(config.maxDecimalPlaces)
|
|
87
|
+
/** count the zeros, which will then allow us to know the final length with desired significant digits */
|
|
88
|
+
const decimalPart = maxDecimalPlacesString.split('.')[1]
|
|
89
|
+
const zeroMatches = decimalPart?.match(/^0+/)
|
|
90
|
+
const leadingZerosInDecimalPart = zeroMatches && zeroMatches.length ? zeroMatches[0].length : 0
|
|
91
|
+
/** now we can re-format with leadingZerosInDecimalPart + maxDecimalSignificanDigits to give us the pretty version */
|
|
92
|
+
/** e.g. 0.0008923088123 -> 0.00089 */
|
|
93
|
+
const prettyDecimalPlaces = Math.max(
|
|
94
|
+
leadingZerosInDecimalPart + config.minDecimalSignificantDigits,
|
|
95
|
+
config.minDecimalPlaces
|
|
96
|
+
)
|
|
97
|
+
untrimmed = numberBN.toFormat(prettyDecimalPlaces)
|
|
98
|
+
}
|
|
99
|
+
/** the untrimmed string may have trailing zeros, e.g. 0.0890 */
|
|
100
|
+
/** trim to a minimum specified by the config, e.g. we may want to display $0.00 or 0.0 ETH */
|
|
101
|
+
let trimmed = untrimmed.replace(/0+$/, '')
|
|
102
|
+
const minLength = 1 + untrimmed.indexOf('.') + config.decimalPlacesWhenZero
|
|
103
|
+
if (trimmed.length < minLength) {
|
|
104
|
+
trimmed = untrimmed.substring(0, minLength)
|
|
105
|
+
}
|
|
106
|
+
if (trimmed[trimmed.length - 1] === '.') {
|
|
107
|
+
trimmed = trimmed.slice(0, -1)
|
|
108
|
+
}
|
|
109
|
+
return trimmed
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const BN_N1 = BigInt(-1)
|
|
113
|
+
const BN_0 = BigInt(0)
|
|
114
|
+
|
|
115
|
+
// Constant to pull zeros from for multipliers
|
|
116
|
+
const Zeros = '0000'
|
|
117
|
+
|
|
118
|
+
function toFixedNumber(val: bigint, decimals: number): string {
|
|
119
|
+
let negative = ''
|
|
120
|
+
if (val < BN_0) {
|
|
121
|
+
negative = '-'
|
|
122
|
+
val *= BN_N1
|
|
123
|
+
}
|
|
124
|
+
let str = val.toString()
|
|
125
|
+
// No decimal point for whole values
|
|
126
|
+
if (decimals === 0) {
|
|
127
|
+
return negative + str
|
|
128
|
+
}
|
|
129
|
+
// Pad out to the whole component (including a whole digit)
|
|
130
|
+
while (str.length <= decimals) {
|
|
131
|
+
str = Zeros + str
|
|
132
|
+
}
|
|
133
|
+
// Insert the decimal point
|
|
134
|
+
const index = str.length - decimals
|
|
135
|
+
str = str.substring(0, index) + '.' + str.substring(index)
|
|
136
|
+
// Trim the whole component (leaving at least one 0)
|
|
137
|
+
while (str[0] === '0' && str[1] !== '.') {
|
|
138
|
+
str = str.substring(1)
|
|
139
|
+
}
|
|
140
|
+
// Trim the decimal component (leaving at least one 0)
|
|
141
|
+
while (str[str.length - 1] === '0' && str[str.length - 2] !== '.') {
|
|
142
|
+
str = str.substring(0, str.length - 1)
|
|
143
|
+
}
|
|
144
|
+
return negative + str
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function convertAmountWithDecimals(amount: string | number, decimals: number): bigint | undefined {
|
|
148
|
+
try {
|
|
149
|
+
const result = new BigNumber(amount).multipliedBy(Math.pow(10, decimals))
|
|
150
|
+
return BigInt(result.toFormat(0, { groupSeparator: '' }))
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return undefined
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function convertAlphAmount(amount: string | number): bigint | undefined {
|
|
157
|
+
return convertAmountWithDecimals(amount, 18)
|
|
158
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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 { ec as EC } from 'elliptic'
|
|
20
|
+
import { binToHex, encodeSignature, hexToBinUnsafe, signatureDecode } from '..'
|
|
21
|
+
import { KeyType } from '../signer'
|
|
22
|
+
import * as necc from '@noble/secp256k1'
|
|
23
|
+
import { createHash, createHmac } from 'crypto'
|
|
24
|
+
|
|
25
|
+
const ec = new EC('secp256k1')
|
|
26
|
+
|
|
27
|
+
necc.utils.sha256Sync = (...messages: Uint8Array[]): Uint8Array => {
|
|
28
|
+
const sha256 = createHash('sha256')
|
|
29
|
+
for (const message of messages) sha256.update(message)
|
|
30
|
+
return sha256.digest()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
necc.utils.hmacSha256Sync = (key: Uint8Array, ...messages: Uint8Array[]): Uint8Array => {
|
|
34
|
+
const hash = createHmac('sha256', Buffer.from(key))
|
|
35
|
+
messages.forEach((m) => hash.update(m))
|
|
36
|
+
return Uint8Array.from(hash.digest())
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// hash has to be 32 bytes
|
|
40
|
+
export function sign(hash: string, privateKey: string, _keyType?: KeyType): string {
|
|
41
|
+
const keyType = _keyType ?? 'default'
|
|
42
|
+
|
|
43
|
+
if (keyType === 'default') {
|
|
44
|
+
const key = ec.keyFromPrivate(privateKey)
|
|
45
|
+
const signature = key.sign(hash)
|
|
46
|
+
return encodeSignature(signature)
|
|
47
|
+
} else {
|
|
48
|
+
const signature = necc.schnorr.signSync(hexToBinUnsafe(hash), hexToBinUnsafe(privateKey))
|
|
49
|
+
return binToHex(signature)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function verifySignature(hash: string, publicKey: string, signature: string, _keyType?: KeyType): boolean {
|
|
54
|
+
const keyType = _keyType ?? 'default'
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
if (keyType === 'default') {
|
|
58
|
+
const key = ec.keyFromPublic(publicKey, 'hex')
|
|
59
|
+
return key.verify(hash, signatureDecode(ec, signature))
|
|
60
|
+
} else {
|
|
61
|
+
return necc.schnorr.verifySync(hexToBinUnsafe(signature), hexToBinUnsafe(hash), hexToBinUnsafe(publicKey))
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { Buffer } from 'buffer/'
|
|
|
24
24
|
|
|
25
25
|
import { TOTAL_NUMBER_OF_GROUPS } from '../constants'
|
|
26
26
|
import djb2 from './djb2'
|
|
27
|
+
import { KeyType } from '../signer'
|
|
27
28
|
|
|
28
29
|
const ec = new EC('secp256k1')
|
|
29
30
|
|
|
@@ -157,20 +158,35 @@ export function binToHex(bin: Uint8Array): string {
|
|
|
157
158
|
return Buffer.from(bin).toString('hex')
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
export function groupOfPrivateKey(privateKey: string): number {
|
|
161
|
-
return groupOfAddress(addressFromPublicKey(publicKeyFromPrivateKey(privateKey)))
|
|
161
|
+
export function groupOfPrivateKey(privateKey: string, keyType?: KeyType): number {
|
|
162
|
+
return groupOfAddress(addressFromPublicKey(publicKeyFromPrivateKey(privateKey, keyType), keyType))
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
export function publicKeyFromPrivateKey(privateKey: string): string {
|
|
165
|
-
const
|
|
166
|
-
|
|
165
|
+
export function publicKeyFromPrivateKey(privateKey: string, _keyType?: KeyType): string {
|
|
166
|
+
const keyType = _keyType ?? 'default'
|
|
167
|
+
|
|
168
|
+
if (keyType === 'default') {
|
|
169
|
+
const key = ec.keyFromPrivate(privateKey)
|
|
170
|
+
return key.getPublic(true, 'hex')
|
|
171
|
+
} else {
|
|
172
|
+
return ec.g.mul(new BN(privateKey, 16)).encode('hex', true).slice(2)
|
|
173
|
+
}
|
|
167
174
|
}
|
|
168
175
|
|
|
169
|
-
export function addressFromPublicKey(publicKey: string): string {
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
export function addressFromPublicKey(publicKey: string, _keyType?: KeyType): string {
|
|
177
|
+
const keyType = _keyType ?? 'default'
|
|
178
|
+
|
|
179
|
+
if (keyType === 'default') {
|
|
180
|
+
const addressType = Buffer.from([AddressType.P2PKH])
|
|
181
|
+
const hash = Buffer.from(blake.blake2b(Buffer.from(publicKey, 'hex'), undefined, 32))
|
|
182
|
+
const bytes = Buffer.concat([addressType, hash])
|
|
183
|
+
return bs58.encode(bytes)
|
|
184
|
+
} else {
|
|
185
|
+
const lockupScript = Buffer.from(`0101000000000458144020${publicKey}8685`, 'hex')
|
|
186
|
+
const lockupScriptHash = blake.blake2b(lockupScript, undefined, 32)
|
|
187
|
+
const addressType = Buffer.from([AddressType.P2SH])
|
|
188
|
+
return bs58.encode(Buffer.concat([addressType, lockupScriptHash]))
|
|
189
|
+
}
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
export function addressFromContractId(contractId: string): string {
|