@alephium/web3 0.30.2 → 0.31.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/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +39 -25
- package/dist/src/api/api-alephium.js +49 -34
- package/dist/src/api/node-provider.js +1 -2
- package/dist/src/contract/contract.d.ts +1 -0
- package/dist/src/contract/contract.js +42 -8
- package/dist/src/utils/address.d.ts +20 -1
- package/dist/src/utils/address.js +168 -14
- package/dist/src/utils/error.d.ts +15 -0
- package/dist/src/utils/error.js +66 -0
- package/dist/src/utils/utils.d.ts +0 -19
- package/dist/src/utils/utils.js +1 -152
- package/package.json +2 -2
- package/src/api/api-alephium.ts +64 -44
- package/src/api/node-provider.ts +1 -2
- package/src/contract/contract.ts +62 -10
- package/src/utils/address.ts +167 -12
- package/src/utils/error.ts +77 -0
- package/src/utils/utils.ts +0 -155
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
class CompilationError {
|
|
20
|
+
constructor(
|
|
21
|
+
public lineStart: number,
|
|
22
|
+
public column: number,
|
|
23
|
+
public errorType: string,
|
|
24
|
+
public line: number,
|
|
25
|
+
public codeLine: string,
|
|
26
|
+
public errorIndicator: string,
|
|
27
|
+
public message: string,
|
|
28
|
+
public additionalLine1?: string,
|
|
29
|
+
public additionalLine2?: string
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
reformat(line: number, file: string): string {
|
|
33
|
+
const spaces = `${line}`.replace(/\d/g, ' ')
|
|
34
|
+
const newError = `${file} (${line}:${this.column}): ${this.errorType}
|
|
35
|
+
${line} |${this.codeLine}
|
|
36
|
+
${spaces} |${this.errorIndicator}
|
|
37
|
+
${spaces} |${this.message}`
|
|
38
|
+
|
|
39
|
+
if (this.additionalLine1 && this.additionalLine2) {
|
|
40
|
+
return `${newError}\n${spaces} |${this.additionalLine1}\n${spaces} |${this.additionalLine2}`
|
|
41
|
+
} else {
|
|
42
|
+
return newError
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const errorRegex = /error \((\d+):(\d+)\):\s*(.*)\n\s*(\d+)\s*\|(.*)\n.*\|(.*)\n\s*\|(.*)(?:\n\s*\|(.*)\n\s*\|(.*))?/
|
|
48
|
+
|
|
49
|
+
export function parseError(error: string): CompilationError | undefined {
|
|
50
|
+
const match = error.match(errorRegex)
|
|
51
|
+
|
|
52
|
+
if (match) {
|
|
53
|
+
const lineStart = parseInt(match[1])
|
|
54
|
+
const column = parseInt(match[2])
|
|
55
|
+
const errorType = match[3]
|
|
56
|
+
const line = parseInt(match[4])
|
|
57
|
+
const codeLine = match[5]
|
|
58
|
+
const errorIndicator = match[6]
|
|
59
|
+
const message = match[7]
|
|
60
|
+
const additionalLine1 = match[8]
|
|
61
|
+
const additionalLine2 = match[9]
|
|
62
|
+
|
|
63
|
+
return new CompilationError(
|
|
64
|
+
lineStart,
|
|
65
|
+
column,
|
|
66
|
+
errorType,
|
|
67
|
+
line,
|
|
68
|
+
codeLine,
|
|
69
|
+
errorIndicator,
|
|
70
|
+
message,
|
|
71
|
+
additionalLine1,
|
|
72
|
+
additionalLine2
|
|
73
|
+
)
|
|
74
|
+
} else {
|
|
75
|
+
undefined
|
|
76
|
+
}
|
|
77
|
+
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -18,12 +18,10 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
18
18
|
|
|
19
19
|
import { ec as EC, SignatureInput } from 'elliptic'
|
|
20
20
|
import BN from 'bn.js'
|
|
21
|
-
import blake from 'blakejs'
|
|
22
21
|
import bs58 from './bs58'
|
|
23
22
|
import { Buffer } from 'buffer/'
|
|
24
23
|
|
|
25
24
|
import { TOTAL_NUMBER_OF_GROUPS, TOTAL_NUMBER_OF_CHAINS } from '../constants'
|
|
26
|
-
import djb2 from './djb2'
|
|
27
25
|
import { KeyType } from '../signer'
|
|
28
26
|
import { HexString } from '../contract'
|
|
29
27
|
|
|
@@ -63,14 +61,6 @@ export function signatureDecode(ec: EC, signature: string): SignatureInput {
|
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
export function xorByte(intValue: number): number {
|
|
67
|
-
const byte0 = (intValue >> 24) & 0xff
|
|
68
|
-
const byte1 = (intValue >> 16) & 0xff
|
|
69
|
-
const byte2 = (intValue >> 8) & 0xff
|
|
70
|
-
const byte3 = intValue & 0xff
|
|
71
|
-
return (byte0 ^ byte1 ^ byte2 ^ byte3) & 0xff
|
|
72
|
-
}
|
|
73
|
-
|
|
74
64
|
export function isHexString(input: string): boolean {
|
|
75
65
|
return input.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(input)
|
|
76
66
|
}
|
|
@@ -84,85 +74,6 @@ export function toNonNegativeBigInt(input: string): bigint | undefined {
|
|
|
84
74
|
}
|
|
85
75
|
}
|
|
86
76
|
|
|
87
|
-
export enum AddressType {
|
|
88
|
-
P2PKH = 0x00,
|
|
89
|
-
P2MPKH = 0x01,
|
|
90
|
-
P2SH = 0x02,
|
|
91
|
-
P2C = 0x03
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function groupOfAddress(address: string): number {
|
|
95
|
-
const decoded = bs58.decode(address)
|
|
96
|
-
|
|
97
|
-
if (decoded.length == 0) throw new Error('Address string is empty')
|
|
98
|
-
const addressType = decoded[0]
|
|
99
|
-
const addressBody = decoded.slice(1)
|
|
100
|
-
|
|
101
|
-
if (addressType == AddressType.P2PKH) {
|
|
102
|
-
return groupOfP2pkhAddress(addressBody)
|
|
103
|
-
} else if (addressType == AddressType.P2MPKH) {
|
|
104
|
-
return groupOfP2mpkhAddress(addressBody)
|
|
105
|
-
} else if (addressType == AddressType.P2SH) {
|
|
106
|
-
return groupOfP2shAddress(addressBody)
|
|
107
|
-
} else {
|
|
108
|
-
// Contract Address
|
|
109
|
-
const id = contractIdFromAddress(address)
|
|
110
|
-
return id[`${id.length - 1}`]
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function groupOfAddressBytes(bytes: Uint8Array): number {
|
|
115
|
-
const hint = djb2(bytes) | 1
|
|
116
|
-
const hash = xorByte(hint)
|
|
117
|
-
const group = hash % TOTAL_NUMBER_OF_GROUPS
|
|
118
|
-
return group
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Pay to public key hash address
|
|
122
|
-
function groupOfP2pkhAddress(address: Uint8Array): number {
|
|
123
|
-
if (address.length != 32) {
|
|
124
|
-
throw new Error(`Invalid p2pkh address length: ${address.length}`)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return groupOfAddressBytes(address)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Pay to multiple public key hash address
|
|
131
|
-
function groupOfP2mpkhAddress(address: Uint8Array): number {
|
|
132
|
-
if ((address.length - 2) % 32 != 0) {
|
|
133
|
-
throw new Error(`Invalid p2mpkh address length: ${address.length}`)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return groupOfAddressBytes(address.slice(1, 33))
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Pay to script hash address
|
|
140
|
-
function groupOfP2shAddress(address: Uint8Array): number {
|
|
141
|
-
return groupOfAddressBytes(address)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function contractIdFromAddress(address: string): Uint8Array {
|
|
145
|
-
return idFromAddress(address)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function tokenIdFromAddress(address: string): Uint8Array {
|
|
149
|
-
return idFromAddress(address)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function idFromAddress(address: string): Uint8Array {
|
|
153
|
-
const decoded = bs58.decode(address)
|
|
154
|
-
|
|
155
|
-
if (decoded.length == 0) throw new Error('Address string is empty')
|
|
156
|
-
const addressType = decoded[0]
|
|
157
|
-
const addressBody = decoded.slice(1)
|
|
158
|
-
|
|
159
|
-
if (addressType == AddressType.P2C) {
|
|
160
|
-
return addressBody
|
|
161
|
-
} else {
|
|
162
|
-
throw new Error(`Invalid contract address type: ${addressType}`)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
77
|
export function hexToBinUnsafe(hex: string): Uint8Array {
|
|
167
78
|
return Buffer.from(hex, 'hex')
|
|
168
79
|
}
|
|
@@ -171,72 +82,6 @@ export function binToHex(bin: Uint8Array): string {
|
|
|
171
82
|
return Buffer.from(bin).toString('hex')
|
|
172
83
|
}
|
|
173
84
|
|
|
174
|
-
export function groupOfPrivateKey(privateKey: string, keyType?: KeyType): number {
|
|
175
|
-
return groupOfAddress(addressFromPublicKey(publicKeyFromPrivateKey(privateKey, keyType), keyType))
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function publicKeyFromPrivateKey(privateKey: string, _keyType?: KeyType): string {
|
|
179
|
-
const keyType = _keyType ?? 'default'
|
|
180
|
-
|
|
181
|
-
if (keyType === 'default') {
|
|
182
|
-
const key = ec.keyFromPrivate(privateKey)
|
|
183
|
-
return key.getPublic(true, 'hex')
|
|
184
|
-
} else {
|
|
185
|
-
return ec.g.mul(new BN(privateKey, 16)).encode('hex', true).slice(2)
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function addressFromPublicKey(publicKey: string, _keyType?: KeyType): string {
|
|
190
|
-
const keyType = _keyType ?? 'default'
|
|
191
|
-
|
|
192
|
-
if (keyType === 'default') {
|
|
193
|
-
const addressType = Buffer.from([AddressType.P2PKH])
|
|
194
|
-
const hash = Buffer.from(blake.blake2b(Buffer.from(publicKey, 'hex'), undefined, 32))
|
|
195
|
-
const bytes = Buffer.concat([addressType, hash])
|
|
196
|
-
return bs58.encode(bytes)
|
|
197
|
-
} else {
|
|
198
|
-
const lockupScript = Buffer.from(`0101000000000458144020${publicKey}8685`, 'hex')
|
|
199
|
-
return addressFromScript(lockupScript)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function addressFromScript(script: Uint8Array): string {
|
|
204
|
-
const scriptHash = blake.blake2b(script, undefined, 32)
|
|
205
|
-
const addressType = Buffer.from([AddressType.P2SH])
|
|
206
|
-
return bs58.encode(Buffer.concat([addressType, scriptHash]))
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export function addressFromContractId(contractId: string): string {
|
|
210
|
-
const addressType = Buffer.from([AddressType.P2C])
|
|
211
|
-
const hash = Buffer.from(hexToBinUnsafe(contractId))
|
|
212
|
-
const bytes = Buffer.concat([addressType, hash])
|
|
213
|
-
return bs58.encode(bytes)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
export function addressFromTokenId(tokenId: string): string {
|
|
217
|
-
const contractId = tokenId // contract ID is the same as token ID
|
|
218
|
-
return addressFromContractId(contractId)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export function contractIdFromTx(txId: string, outputIndex: number): string {
|
|
222
|
-
const txIdBin = hexToBinUnsafe(txId)
|
|
223
|
-
const data = Buffer.concat([txIdBin, Buffer.from([outputIndex])])
|
|
224
|
-
const hash = blake.blake2b(data, undefined, 32)
|
|
225
|
-
return binToHex(hash)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export function subContractId(parentContractId: string, pathInHex: string, group: number): string {
|
|
229
|
-
if (group < 0 || group >= TOTAL_NUMBER_OF_GROUPS) {
|
|
230
|
-
throw new Error(`Invalid group ${group}`)
|
|
231
|
-
}
|
|
232
|
-
const data = Buffer.concat([hexToBinUnsafe(parentContractId), hexToBinUnsafe(pathInHex)])
|
|
233
|
-
const bytes = Buffer.concat([
|
|
234
|
-
blake.blake2b(blake.blake2b(data, undefined, 32), undefined, 32).slice(0, -1),
|
|
235
|
-
Buffer.from([group])
|
|
236
|
-
])
|
|
237
|
-
return binToHex(bytes)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
85
|
export function blockChainIndex(blockHash: HexString): { fromGroup: number; toGroup: number } {
|
|
241
86
|
if (blockHash.length != 64) {
|
|
242
87
|
throw Error(`Invalid block hash: ${blockHash}`)
|