@alephium/web3 0.29.3 → 0.30.0-beta.1
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 +1 -1
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/codec/array-codec.d.ts +17 -0
- package/dist/src/codec/array-codec.js +58 -0
- package/dist/src/codec/asset-output-codec.d.ts +27 -0
- package/dist/src/codec/asset-output-codec.js +135 -0
- package/dist/src/codec/bigint-codec.d.ts +5 -0
- package/dist/src/codec/bigint-codec.js +85 -0
- package/dist/src/codec/bytestring-codec.d.ts +16 -0
- package/dist/src/codec/bytestring-codec.js +49 -0
- package/dist/src/codec/codec.d.ts +8 -0
- package/dist/src/codec/codec.js +9 -0
- package/dist/src/codec/compact-int-codec.d.ts +47 -0
- package/dist/src/codec/compact-int-codec.js +287 -0
- package/dist/src/codec/contract-codec.d.ts +22 -0
- package/dist/src/codec/contract-codec.js +62 -0
- package/dist/src/codec/contract-output-codec.d.ts +21 -0
- package/dist/src/codec/contract-output-codec.js +81 -0
- package/dist/src/codec/contract-output-ref-codec.d.ts +15 -0
- package/dist/src/codec/contract-output-ref-codec.js +37 -0
- package/dist/src/codec/either-codec.d.ts +17 -0
- package/dist/src/codec/either-codec.js +66 -0
- package/dist/src/codec/hash.d.ts +4 -0
- package/dist/src/codec/hash.js +40 -0
- package/dist/src/codec/index.d.ts +23 -0
- package/dist/src/codec/index.js +69 -0
- package/dist/src/codec/input-codec.d.ts +22 -0
- package/dist/src/codec/input-codec.js +70 -0
- package/dist/src/codec/instr-codec.d.ts +223 -0
- package/dist/src/codec/instr-codec.js +459 -0
- package/dist/src/codec/lockup-script-codec.d.ts +28 -0
- package/dist/src/codec/lockup-script-codec.js +79 -0
- package/dist/src/codec/long-codec.d.ts +9 -0
- package/dist/src/codec/long-codec.js +55 -0
- package/dist/src/codec/method-codec.d.ts +30 -0
- package/dist/src/codec/method-codec.js +67 -0
- package/dist/src/codec/option-codec.d.ts +15 -0
- package/dist/src/codec/option-codec.js +54 -0
- package/dist/src/codec/output-codec.d.ts +7 -0
- package/dist/src/codec/output-codec.js +26 -0
- package/dist/src/codec/script-codec.d.ts +16 -0
- package/dist/src/codec/script-codec.js +40 -0
- package/dist/src/codec/signature-codec.d.ts +14 -0
- package/dist/src/codec/signature-codec.js +36 -0
- package/dist/src/codec/signed-int-codec.d.ts +9 -0
- package/dist/src/codec/signed-int-codec.js +38 -0
- package/dist/src/codec/token-codec.d.ts +16 -0
- package/dist/src/codec/token-codec.js +45 -0
- package/dist/src/codec/transaction-codec.d.ts +27 -0
- package/dist/src/codec/transaction-codec.js +127 -0
- package/dist/src/codec/unlock-script-codec.d.ts +40 -0
- package/dist/src/codec/unlock-script-codec.js +169 -0
- package/dist/src/codec/unsigned-tx-codec.d.ts +30 -0
- package/dist/src/codec/unsigned-tx-codec.js +102 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +2 -1
- package/package.json +4 -3
- package/src/api/api-alephium.ts +1 -1
- package/src/codec/array-codec.ts +62 -0
- package/src/codec/asset-output-codec.ts +150 -0
- package/src/codec/bigint-codec.ts +91 -0
- package/src/codec/bytestring-codec.ts +55 -0
- package/src/codec/codec.ts +30 -0
- package/src/codec/compact-int-codec.ts +299 -0
- package/src/codec/contract-codec.ts +76 -0
- package/src/codec/contract-output-codec.ts +97 -0
- package/src/codec/contract-output-ref-codec.ts +41 -0
- package/src/codec/either-codec.ts +73 -0
- package/src/codec/hash.ts +34 -0
- package/src/codec/index.ts +41 -0
- package/src/codec/input-codec.ts +80 -0
- package/src/codec/instr-codec.ts +462 -0
- package/src/codec/lockup-script-codec.ts +98 -0
- package/src/codec/long-codec.ts +58 -0
- package/src/codec/method-codec.ts +85 -0
- package/src/codec/option-codec.ts +59 -0
- package/src/codec/output-codec.ts +26 -0
- package/src/codec/script-codec.ts +44 -0
- package/src/codec/signature-codec.ts +39 -0
- package/src/codec/signed-int-codec.ts +36 -0
- package/src/codec/token-codec.ts +49 -0
- package/src/codec/transaction-codec.ts +146 -0
- package/src/codec/unlock-script-codec.ts +193 -0
- package/src/codec/unsigned-tx-codec.ts +123 -0
- package/src/index.ts +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec'
|
|
20
|
+
import { Codec } from './codec'
|
|
21
|
+
|
|
22
|
+
export interface ByteString {
|
|
23
|
+
length: DecodedCompactInt
|
|
24
|
+
value: Buffer
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class ByteStringCodec implements Codec<ByteString> {
|
|
28
|
+
parser = new Parser()
|
|
29
|
+
.nest('length', {
|
|
30
|
+
type: compactUnsignedIntCodec.parser
|
|
31
|
+
})
|
|
32
|
+
.buffer('value', {
|
|
33
|
+
length: function (ctx) {
|
|
34
|
+
return compactUnsignedIntCodec.toU32(this['length']! as any as DecodedCompactInt)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
encode(input: ByteString): Buffer {
|
|
39
|
+
return Buffer.from([...compactUnsignedIntCodec.encode(input.length), ...input.value])
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
decode(input: Buffer): ByteString {
|
|
43
|
+
return this.parser.parse(input)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
encodeBuffer(input: Buffer): Buffer {
|
|
47
|
+
return Buffer.from([...compactUnsignedIntCodec.encodeU32(input.length), ...input])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
decodeBuffer(input: Buffer): Buffer {
|
|
51
|
+
return this.decode(input).value
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const byteStringCodec = new ByteStringCodec()
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
|
|
20
|
+
export interface Codec<T> {
|
|
21
|
+
parser: Parser
|
|
22
|
+
encode(input: T): Buffer
|
|
23
|
+
decode(input: Buffer): T
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function assert(value: boolean, message: string) {
|
|
27
|
+
if (!value) {
|
|
28
|
+
throw new Error(message)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
import { Codec, assert } from './codec'
|
|
20
|
+
import { BigIntCodec } from './bigint-codec'
|
|
21
|
+
import { ArrayCodec } from './array-codec'
|
|
22
|
+
|
|
23
|
+
export class CompactInt {
|
|
24
|
+
static readonly oneBytePrefix = 0x00
|
|
25
|
+
static readonly oneByteNegPrefix = 0xc0
|
|
26
|
+
static readonly twoBytePrefix = 0x40
|
|
27
|
+
static readonly twoByteNegPrefix = 0x80
|
|
28
|
+
static readonly fourBytePrefix = 0x80
|
|
29
|
+
static readonly fourByteNegPrefix = 0x40
|
|
30
|
+
static readonly multiBytePrefix = 0xc0
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const maskRest = 0xc0
|
|
34
|
+
const maskMode = 0x3f
|
|
35
|
+
const maskModeNeg = 0xffffffc0
|
|
36
|
+
const signFlag = 0x20 // 0b00100000
|
|
37
|
+
|
|
38
|
+
export interface DecodedCompactInt {
|
|
39
|
+
mode: number
|
|
40
|
+
rest: Uint8Array
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const compactIntParser = new Parser().uint8('mode').buffer('rest', {
|
|
44
|
+
length: function (ctx) {
|
|
45
|
+
const rawMode = this['mode']
|
|
46
|
+
const mode = rawMode & maskRest
|
|
47
|
+
|
|
48
|
+
switch (mode) {
|
|
49
|
+
case CompactInt.oneBytePrefix:
|
|
50
|
+
return 0
|
|
51
|
+
case CompactInt.twoBytePrefix:
|
|
52
|
+
return 1
|
|
53
|
+
case CompactInt.fourBytePrefix:
|
|
54
|
+
return 3
|
|
55
|
+
default:
|
|
56
|
+
return (rawMode & maskMode) + 4
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
export class CompactUnsignedIntCodec implements Codec<DecodedCompactInt> {
|
|
62
|
+
private oneByteBound = 0x40
|
|
63
|
+
private twoByteBound = this.oneByteBound << 8
|
|
64
|
+
private fourByteBound = this.oneByteBound << (8 * 3)
|
|
65
|
+
|
|
66
|
+
parser = compactIntParser
|
|
67
|
+
|
|
68
|
+
encode(input: DecodedCompactInt): Buffer {
|
|
69
|
+
return Buffer.from([input.mode, ...input.rest])
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
encodeU32(value: number): Buffer {
|
|
73
|
+
if (value < this.oneByteBound) {
|
|
74
|
+
return Buffer.from([(CompactInt.oneBytePrefix + value) & 0xff])
|
|
75
|
+
} else if (value < this.twoByteBound) {
|
|
76
|
+
return Buffer.from([(CompactInt.twoBytePrefix + (value >> 8)) & 0xff, value & 0xff])
|
|
77
|
+
} else if (value < this.fourByteBound) {
|
|
78
|
+
return Buffer.from([
|
|
79
|
+
(CompactInt.fourBytePrefix + (value >> 24)) & 0xff,
|
|
80
|
+
(value >> 16) & 0xff,
|
|
81
|
+
(value >> 8) & 0xff,
|
|
82
|
+
value & 0xff
|
|
83
|
+
])
|
|
84
|
+
} else {
|
|
85
|
+
return Buffer.from([
|
|
86
|
+
CompactInt.multiBytePrefix,
|
|
87
|
+
(value >> 24) & 0xff,
|
|
88
|
+
(value >> 16) & 0xff,
|
|
89
|
+
(value >> 8) & 0xff,
|
|
90
|
+
value & 0xff
|
|
91
|
+
])
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
encodeU256(value: bigint): Buffer {
|
|
96
|
+
assert(value >= 0n, 'Value should be positive')
|
|
97
|
+
|
|
98
|
+
if (value < this.fourByteBound) {
|
|
99
|
+
return this.encodeU32(Number(value))
|
|
100
|
+
} else {
|
|
101
|
+
let bytes = BigIntCodec.encode(value)
|
|
102
|
+
if (bytes[0] === 0) {
|
|
103
|
+
bytes = bytes.slice(1)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
assert(bytes.length <= 32, 'Expect <= 32 bytes for U256')
|
|
107
|
+
|
|
108
|
+
const header = (bytes.length - 4 + CompactInt.multiBytePrefix) & 0xff
|
|
109
|
+
return Buffer.concat([Buffer.from([header]), bytes])
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
decodeU32(input: Buffer): number {
|
|
114
|
+
const decoded = this.decode(input)
|
|
115
|
+
return this.toU32(decoded)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
decodeU256(input: Buffer): bigint {
|
|
119
|
+
const decoded = this.decode(input)
|
|
120
|
+
return this.toU256(decoded)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
decode(input: Buffer): DecodedCompactInt {
|
|
124
|
+
return this.parser.parse(input)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
toU32(value: DecodedCompactInt): number {
|
|
128
|
+
const body = Buffer.from([value.mode, ...value.rest])
|
|
129
|
+
return decodePositiveInt(value.mode, body)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
toU256(value: DecodedCompactInt): bigint {
|
|
133
|
+
const mode = value.mode & maskRest
|
|
134
|
+
if (fixedSize(mode)) {
|
|
135
|
+
return BigInt(this.toU32(value))
|
|
136
|
+
} else {
|
|
137
|
+
assert(value.rest.length <= 32, 'Expect <= 32 bytes for U256')
|
|
138
|
+
return BigIntCodec.decode(Buffer.from(value.rest), false)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const compactUnsignedIntCodec = new CompactUnsignedIntCodec()
|
|
144
|
+
|
|
145
|
+
export class CompactSignedIntCodec implements Codec<DecodedCompactInt> {
|
|
146
|
+
private signFlag = 0x20 // 0b00100000
|
|
147
|
+
private oneByteBound = 0x20 // 0b00100000
|
|
148
|
+
private twoByteBound = this.oneByteBound << 8
|
|
149
|
+
private fourByteBound = this.oneByteBound << (8 * 3)
|
|
150
|
+
|
|
151
|
+
parser = compactIntParser
|
|
152
|
+
|
|
153
|
+
encode(input: DecodedCompactInt): Buffer {
|
|
154
|
+
return Buffer.from([input.mode, ...input.rest])
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
decode(input: Buffer): DecodedCompactInt {
|
|
158
|
+
return this.parser.parse(input)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
decodeI32(input: Buffer): number {
|
|
162
|
+
const decoded = this.decode(input)
|
|
163
|
+
return this.toI32(decoded)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
encodeI32(value: number): Buffer {
|
|
167
|
+
if (value >= 0) {
|
|
168
|
+
if (value < this.oneByteBound) {
|
|
169
|
+
return Buffer.from([(CompactInt.oneBytePrefix + value) & 0xff])
|
|
170
|
+
} else if (value < this.twoByteBound) {
|
|
171
|
+
return Buffer.from([(CompactInt.twoBytePrefix + (value >> 8)) & 0xff, value & 0xff])
|
|
172
|
+
} else if (value < this.fourByteBound) {
|
|
173
|
+
return Buffer.from([
|
|
174
|
+
(CompactInt.fourBytePrefix + (value >> 24)) & 0xff,
|
|
175
|
+
(value >> 16) & 0xff,
|
|
176
|
+
(value >> 8) & 0xff,
|
|
177
|
+
value & 0xff
|
|
178
|
+
])
|
|
179
|
+
} else {
|
|
180
|
+
return Buffer.from([
|
|
181
|
+
CompactInt.multiBytePrefix,
|
|
182
|
+
(value >> 24) & 0xff,
|
|
183
|
+
(value >> 16) & 0xff,
|
|
184
|
+
(value >> 8) & 0xff,
|
|
185
|
+
value & 0xff
|
|
186
|
+
])
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
if (value >= -this.oneByteBound) {
|
|
190
|
+
return Buffer.from([(value ^ CompactInt.oneByteNegPrefix) & 0xff])
|
|
191
|
+
} else if (value >= -this.twoByteBound) {
|
|
192
|
+
return Buffer.from([((value >> 8) ^ CompactInt.twoByteNegPrefix) & 0xff, value & 0xff])
|
|
193
|
+
} else if (value >= -this.fourByteBound) {
|
|
194
|
+
return Buffer.from([
|
|
195
|
+
((value >> 24) ^ CompactInt.fourByteNegPrefix) & 0xff,
|
|
196
|
+
(value >> 16) & 0xff,
|
|
197
|
+
(value >> 8) & 0xff,
|
|
198
|
+
value & 0xff
|
|
199
|
+
])
|
|
200
|
+
} else {
|
|
201
|
+
return Buffer.from([
|
|
202
|
+
CompactInt.multiBytePrefix,
|
|
203
|
+
(value >> 24) & 0xff,
|
|
204
|
+
(value >> 16) & 0xff,
|
|
205
|
+
(value >> 8) & 0xff,
|
|
206
|
+
value & 0xff
|
|
207
|
+
])
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
encodeI256(value: bigint): Buffer {
|
|
213
|
+
if (value >= -0x20000000 && value < 0x20000000) {
|
|
214
|
+
return this.encodeI32(Number(value))
|
|
215
|
+
} else {
|
|
216
|
+
const bytes = BigIntCodec.encode(value)
|
|
217
|
+
const header = (bytes.length - 4 + CompactInt.multiBytePrefix) & 0xff
|
|
218
|
+
return Buffer.concat([Buffer.from([header]), bytes])
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
decodeI256(input: Buffer): bigint {
|
|
223
|
+
const decoded = this.decode(input)
|
|
224
|
+
return this.toI256(decoded)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
toI32(value: DecodedCompactInt): number {
|
|
228
|
+
const body = Buffer.from([value.mode, ...value.rest])
|
|
229
|
+
const mode = value.mode & maskRest
|
|
230
|
+
if (fixedSize(mode)) {
|
|
231
|
+
const isPositive = (value.mode & signFlag) == 0
|
|
232
|
+
if (isPositive) {
|
|
233
|
+
return decodePositiveInt(value.mode, body)
|
|
234
|
+
} else {
|
|
235
|
+
return decodeNegativeInt(value.mode, body)
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
if (body.length === 5) {
|
|
239
|
+
return ((body[1] & 0xff) << 24) | ((body[2] & 0xff) << 16) | ((body[3] & 0xff) << 8) | (body[4] & 0xff)
|
|
240
|
+
} else {
|
|
241
|
+
throw new Error(`Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
toI256(value: DecodedCompactInt): bigint {
|
|
247
|
+
const mode = value.mode & maskRest
|
|
248
|
+
|
|
249
|
+
if (fixedSize(mode)) {
|
|
250
|
+
return BigInt(this.toI32(value))
|
|
251
|
+
} else {
|
|
252
|
+
assert(value.rest.length <= 32, 'Expect <= 32 bytes for I256')
|
|
253
|
+
return BigIntCodec.decode(Buffer.from(value.rest), true)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export const compactSignedIntCodec = new CompactSignedIntCodec()
|
|
259
|
+
|
|
260
|
+
function decodePositiveInt(rawMode: number, body: Buffer): number {
|
|
261
|
+
const mode = rawMode & maskRest
|
|
262
|
+
|
|
263
|
+
switch (mode) {
|
|
264
|
+
case CompactInt.oneBytePrefix:
|
|
265
|
+
return rawMode
|
|
266
|
+
case CompactInt.twoBytePrefix:
|
|
267
|
+
assert(body.length === 2, 'Length should be 2')
|
|
268
|
+
return ((body[0] & maskMode) << 8) | (body[1] & 0xff)
|
|
269
|
+
case CompactInt.fourBytePrefix:
|
|
270
|
+
assert(body.length === 4, 'Length should be 4')
|
|
271
|
+
return ((body[0] & maskMode) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
272
|
+
default:
|
|
273
|
+
if (body.length === 5) {
|
|
274
|
+
return Number(BigInt('0x' + body.slice(1).toString('hex')))
|
|
275
|
+
} else {
|
|
276
|
+
throw new Error(`decodePositiveInt: Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function decodeNegativeInt(rawMode: number, body: Buffer) {
|
|
282
|
+
const mode = rawMode & maskRest
|
|
283
|
+
switch (mode) {
|
|
284
|
+
case CompactInt.oneBytePrefix:
|
|
285
|
+
return rawMode | maskModeNeg
|
|
286
|
+
case CompactInt.twoBytePrefix:
|
|
287
|
+
assert(body.length === 2, 'Length should be 2')
|
|
288
|
+
return ((body[0] | maskModeNeg) << 8) | (body[1] & 0xff)
|
|
289
|
+
case CompactInt.fourBytePrefix:
|
|
290
|
+
assert(body.length === 4, 'Length should be 4')
|
|
291
|
+
return ((body[0] | maskModeNeg) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
292
|
+
default:
|
|
293
|
+
throw new Error(`decodeNegativeInt: Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function fixedSize(mode: number): boolean {
|
|
298
|
+
return mode === CompactInt.oneBytePrefix || mode === CompactInt.twoBytePrefix || mode === CompactInt.fourBytePrefix
|
|
299
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
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 { Parser } from 'binary-parser'
|
|
20
|
+
import { ArrayCodec, DecodedArray } from './array-codec'
|
|
21
|
+
import { Codec } from './codec'
|
|
22
|
+
import { compactSignedIntCodec, compactUnsignedIntCodec, DecodedCompactInt } from './compact-int-codec'
|
|
23
|
+
import { Method, MethodCodec, methodCodec } from './method-codec'
|
|
24
|
+
|
|
25
|
+
const compactSignedIntsCodec = new ArrayCodec(compactSignedIntCodec)
|
|
26
|
+
|
|
27
|
+
export interface HalfDecodedContract {
|
|
28
|
+
fieldLength: DecodedCompactInt
|
|
29
|
+
methodIndexes: DecodedArray<DecodedCompactInt>
|
|
30
|
+
methods: Buffer
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Contract {
|
|
34
|
+
fieldLength: number
|
|
35
|
+
methods: Method[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class ContractCodec implements Codec<HalfDecodedContract> {
|
|
39
|
+
parser = Parser.start()
|
|
40
|
+
.nest('fieldLength', {
|
|
41
|
+
type: compactSignedIntCodec.parser
|
|
42
|
+
})
|
|
43
|
+
.nest('methodIndexes', {
|
|
44
|
+
type: compactSignedIntsCodec.parser
|
|
45
|
+
})
|
|
46
|
+
.buffer('methods', { readUntil: 'eof' })
|
|
47
|
+
|
|
48
|
+
encode(input: HalfDecodedContract): Buffer {
|
|
49
|
+
return Buffer.from([
|
|
50
|
+
...compactSignedIntCodec.encode(input.fieldLength),
|
|
51
|
+
...compactSignedIntsCodec.encode(input.methodIndexes.value),
|
|
52
|
+
...input.methods
|
|
53
|
+
])
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
decode(input: Buffer): HalfDecodedContract {
|
|
57
|
+
return this.parser.parse(input)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
decodeContract(input: Buffer): Contract {
|
|
61
|
+
const halfDecoded = this.decode(input)
|
|
62
|
+
const fieldLength = compactUnsignedIntCodec.toU32(halfDecoded.fieldLength)
|
|
63
|
+
const methodIndexes = halfDecoded.methodIndexes.value.map((v) => compactUnsignedIntCodec.toU32(v))
|
|
64
|
+
const methods: Method[] = []
|
|
65
|
+
for (let i = 0, start = 0; i < methodIndexes.length; i++) {
|
|
66
|
+
const end = methodIndexes[i]
|
|
67
|
+
const method = MethodCodec.toMethod(methodCodec.decode(halfDecoded.methods.slice(start, end)))
|
|
68
|
+
methods.push(method)
|
|
69
|
+
start = end
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { fieldLength, methods }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const contractCodec = new ContractCodec()
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
import { DecodedArray } from './array-codec'
|
|
20
|
+
import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec'
|
|
21
|
+
import { P2C } from './lockup-script-codec'
|
|
22
|
+
import { Codec } from './codec'
|
|
23
|
+
import { Token, tokensCodec } from './token-codec'
|
|
24
|
+
import { ContractOutput as ApiContractOutput } from '../api/api-alephium'
|
|
25
|
+
import { blakeHash, createHint } from './hash'
|
|
26
|
+
import { binToHex, bs58 } from '..'
|
|
27
|
+
import { signedIntCodec } from './signed-int-codec'
|
|
28
|
+
import { LockupScript } from './lockup-script-codec'
|
|
29
|
+
import { lockupScriptCodec } from './lockup-script-codec'
|
|
30
|
+
|
|
31
|
+
export interface ContractOutput {
|
|
32
|
+
amount: DecodedCompactInt
|
|
33
|
+
lockupScript: P2C
|
|
34
|
+
tokens: DecodedArray<Token>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class ContractOutputCodec implements Codec<ContractOutput> {
|
|
38
|
+
parser = Parser.start()
|
|
39
|
+
.nest('amount', {
|
|
40
|
+
type: compactUnsignedIntCodec.parser
|
|
41
|
+
})
|
|
42
|
+
.nest('lockupScript', {
|
|
43
|
+
type: Parser.start().buffer('contractId', { length: 32 })
|
|
44
|
+
})
|
|
45
|
+
.nest('tokens', {
|
|
46
|
+
type: tokensCodec.parser
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
encode(input: ContractOutput): Buffer {
|
|
50
|
+
const amount = Buffer.from(compactUnsignedIntCodec.encode(input.amount))
|
|
51
|
+
const lockupScript = (input.lockupScript as P2C).contractId
|
|
52
|
+
const tokens = Buffer.from(tokensCodec.encode(input.tokens.value))
|
|
53
|
+
|
|
54
|
+
return Buffer.concat([amount, lockupScript, tokens])
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
decode(input: Buffer): ContractOutput {
|
|
58
|
+
return this.parser.parse(input)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static convertToApiContractOutput(txIdBytes: Uint8Array, output: ContractOutput, index: number): ApiContractOutput {
|
|
62
|
+
const hint = createHint(output.lockupScript.contractId)
|
|
63
|
+
const key = binToHex(blakeHash(Buffer.concat([txIdBytes, signedIntCodec.encode(index)])))
|
|
64
|
+
const attoAlphAmount = compactUnsignedIntCodec.toU256(output.amount).toString()
|
|
65
|
+
const address = bs58.encode(Buffer.concat([Buffer.from([0x03]), output.lockupScript.contractId]))
|
|
66
|
+
const tokens = output.tokens.value.map((token) => {
|
|
67
|
+
return {
|
|
68
|
+
id: token.tokenId.toString('hex'),
|
|
69
|
+
amount: compactUnsignedIntCodec.toU256(token.amount).toString()
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
return { hint, key, attoAlphAmount, address, tokens, type: 'ContractOutput' }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static convertToOutput(apiContractOutput: ApiContractOutput): ContractOutput {
|
|
76
|
+
const amount: DecodedCompactInt = compactUnsignedIntCodec.decode(
|
|
77
|
+
compactUnsignedIntCodec.encodeU256(BigInt(apiContractOutput.attoAlphAmount))
|
|
78
|
+
)
|
|
79
|
+
const lockupScript: P2C = lockupScriptCodec.decode(Buffer.from(bs58.decode(apiContractOutput.address)))
|
|
80
|
+
.script as P2C
|
|
81
|
+
|
|
82
|
+
const tokensValue = apiContractOutput.tokens.map((token) => {
|
|
83
|
+
return {
|
|
84
|
+
tokenId: Buffer.from(token.id, 'hex'),
|
|
85
|
+
amount: compactUnsignedIntCodec.decode(compactUnsignedIntCodec.encodeU256(BigInt(token.amount)))
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
const tokens: DecodedArray<Token> = {
|
|
89
|
+
length: compactUnsignedIntCodec.decode(compactUnsignedIntCodec.encodeU32(tokensValue.length)),
|
|
90
|
+
value: tokensValue
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { amount, lockupScript, tokens }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const contractOutputCodec = new ContractOutputCodec()
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
import { ArrayCodec } from './array-codec'
|
|
20
|
+
import { Codec } from './codec'
|
|
21
|
+
import { signedIntCodec } from './signed-int-codec'
|
|
22
|
+
|
|
23
|
+
export interface ContractOutputRef {
|
|
24
|
+
hint: number
|
|
25
|
+
key: Buffer
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class ContractOutputRefCodec implements Codec<ContractOutputRef> {
|
|
29
|
+
parser = Parser.start().int32('hint').buffer('key', { length: 32 })
|
|
30
|
+
|
|
31
|
+
encode(input: ContractOutputRef): Buffer {
|
|
32
|
+
return Buffer.concat([Buffer.from([...signedIntCodec.encode(input.hint), ...input.key])])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
decode(input: Buffer): ContractOutputRef {
|
|
36
|
+
return this.parser.parse(input)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const contractOutputRefCodec = new ContractOutputRefCodec()
|
|
41
|
+
export const contractOutputRefsCodec = new ArrayCodec(contractOutputRefCodec)
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
import { Parser } from 'binary-parser'
|
|
19
|
+
import { Codec } from './codec'
|
|
20
|
+
|
|
21
|
+
export interface Either<L, R> {
|
|
22
|
+
either: number
|
|
23
|
+
value: L | R
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class EitherCodec<L, R> implements Codec<Either<L, R>> {
|
|
27
|
+
constructor(
|
|
28
|
+
private leftCodec: Codec<L>,
|
|
29
|
+
private rightCodec: Codec<R>,
|
|
30
|
+
public parser = Parser.start()
|
|
31
|
+
.uint8('either')
|
|
32
|
+
.choice('value', {
|
|
33
|
+
tag: 'either',
|
|
34
|
+
choices: {
|
|
35
|
+
0: leftCodec.parser,
|
|
36
|
+
1: rightCodec.parser
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
) {}
|
|
40
|
+
|
|
41
|
+
encode(input: Either<L, R>): Buffer {
|
|
42
|
+
const result = [input.either]
|
|
43
|
+
if (input.either === 0) {
|
|
44
|
+
result.push(...this.leftCodec.encode(input.value as L))
|
|
45
|
+
} else {
|
|
46
|
+
result.push(...this.rightCodec.encode(input.value as R))
|
|
47
|
+
}
|
|
48
|
+
return Buffer.from(result)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
decode(input: Buffer): Either<L, R> {
|
|
52
|
+
const result = this.parser.parse(input)
|
|
53
|
+
return {
|
|
54
|
+
...result,
|
|
55
|
+
value:
|
|
56
|
+
result.either === 0 ? this.leftCodec.decode(result.value.value) : this.rightCodec.decode(result.value.value)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fromLeft(left: L): Either<L, R> {
|
|
61
|
+
return {
|
|
62
|
+
either: 0,
|
|
63
|
+
value: left
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
fromRight(right: R): Either<L, R> {
|
|
68
|
+
return {
|
|
69
|
+
either: 1,
|
|
70
|
+
value: right
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|