@alephium/web3 1.4.0 → 1.5.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.
Files changed (106) hide show
  1. package/dist/alephium-web3.min.js +1 -1
  2. package/dist/alephium-web3.min.js.map +1 -1
  3. package/dist/src/address/address.js +5 -5
  4. package/dist/src/api/api-alephium.d.ts +1 -1
  5. package/dist/src/api/api-alephium.js +1 -1
  6. package/dist/src/codec/array-codec.d.ts +4 -12
  7. package/dist/src/codec/array-codec.js +15 -28
  8. package/dist/src/codec/asset-output-codec.d.ts +6 -11
  9. package/dist/src/codec/asset-output-codec.js +32 -71
  10. package/dist/src/codec/bigint-codec.d.ts +2 -1
  11. package/dist/src/codec/bigint-codec.js +14 -2
  12. package/dist/src/codec/bytestring-codec.d.ts +6 -11
  13. package/dist/src/codec/bytestring-codec.js +9 -23
  14. package/dist/src/codec/codec.d.ts +54 -5
  15. package/dist/src/codec/codec.js +112 -14
  16. package/dist/src/codec/compact-int-codec.d.ts +65 -44
  17. package/dist/src/codec/compact-int-codec.js +222 -204
  18. package/dist/src/codec/contract-codec.d.ts +5 -8
  19. package/dist/src/codec/contract-codec.js +15 -29
  20. package/dist/src/codec/contract-output-codec.d.ts +4 -10
  21. package/dist/src/codec/contract-output-codec.js +20 -40
  22. package/dist/src/codec/contract-output-ref-codec.d.ts +2 -8
  23. package/dist/src/codec/contract-output-ref-codec.js +7 -17
  24. package/dist/src/codec/either-codec.d.ts +8 -15
  25. package/dist/src/codec/either-codec.js +5 -46
  26. package/dist/src/codec/index.d.ts +4 -3
  27. package/dist/src/codec/index.js +7 -4
  28. package/dist/src/codec/input-codec.d.ts +4 -10
  29. package/dist/src/codec/input-codec.js +11 -46
  30. package/dist/src/codec/instr-codec.d.ts +633 -40
  31. package/dist/src/codec/instr-codec.js +1040 -434
  32. package/dist/src/codec/int-as-4bytes-codec.d.ts +7 -0
  33. package/dist/src/codec/{signed-int-codec.js → int-as-4bytes-codec.js} +6 -12
  34. package/dist/src/codec/lockup-script-codec.d.ts +23 -26
  35. package/dist/src/codec/lockup-script-codec.js +12 -58
  36. package/dist/src/codec/method-codec.d.ts +6 -18
  37. package/dist/src/codec/method-codec.js +20 -48
  38. package/dist/src/codec/option-codec.d.ts +8 -13
  39. package/dist/src/codec/option-codec.js +14 -32
  40. package/dist/src/codec/output-codec.d.ts +2 -2
  41. package/dist/src/codec/output-codec.js +1 -1
  42. package/dist/src/codec/reader.d.ts +8 -0
  43. package/dist/src/codec/reader.js +48 -0
  44. package/dist/src/codec/script-codec.d.ts +6 -14
  45. package/dist/src/codec/script-codec.js +6 -22
  46. package/dist/src/codec/signature-codec.d.ts +4 -12
  47. package/dist/src/codec/signature-codec.js +3 -15
  48. package/dist/src/codec/timestamp-codec.d.ts +8 -0
  49. package/dist/src/codec/timestamp-codec.js +39 -0
  50. package/dist/src/codec/token-codec.d.ts +3 -10
  51. package/dist/src/codec/token-codec.js +6 -24
  52. package/dist/src/codec/transaction-codec.d.ts +6 -11
  53. package/dist/src/codec/transaction-codec.js +24 -49
  54. package/dist/src/codec/unlock-script-codec.d.ts +25 -36
  55. package/dist/src/codec/unlock-script-codec.js +26 -147
  56. package/dist/src/codec/unsigned-tx-codec.d.ts +8 -14
  57. package/dist/src/codec/unsigned-tx-codec.js +24 -66
  58. package/dist/src/codec/val.d.ts +27 -0
  59. package/dist/src/codec/val.js +33 -0
  60. package/dist/src/contract/contract.js +6 -6
  61. package/dist/src/contract/index.d.ts +1 -0
  62. package/dist/src/contract/index.js +1 -0
  63. package/dist/src/contract/ralph.d.ts +0 -4
  64. package/dist/src/contract/ralph.js +50 -179
  65. package/dist/src/contract/script-simulator.d.ts +27 -0
  66. package/dist/src/contract/script-simulator.js +757 -0
  67. package/dist/src/exchange/exchange.js +1 -1
  68. package/package.json +3 -4
  69. package/src/address/address.ts +8 -8
  70. package/src/api/api-alephium.ts +1 -1
  71. package/src/codec/array-codec.ts +16 -34
  72. package/src/codec/asset-output-codec.ts +38 -83
  73. package/src/codec/bigint-codec.ts +16 -2
  74. package/src/codec/bytestring-codec.ts +10 -28
  75. package/src/codec/codec.ts +121 -15
  76. package/src/codec/compact-int-codec.ts +230 -207
  77. package/src/codec/contract-codec.ts +20 -33
  78. package/src/codec/contract-output-codec.ts +22 -48
  79. package/src/codec/contract-output-ref-codec.ts +6 -17
  80. package/src/codec/either-codec.ts +4 -53
  81. package/src/codec/index.ts +4 -3
  82. package/src/codec/input-codec.ts +14 -36
  83. package/src/codec/instr-codec.ts +1229 -455
  84. package/src/codec/{signed-int-codec.ts → int-as-4bytes-codec.ts} +6 -10
  85. package/src/codec/lockup-script-codec.ts +28 -76
  86. package/src/codec/method-codec.ts +23 -61
  87. package/src/codec/option-codec.ts +13 -36
  88. package/src/codec/output-codec.ts +2 -2
  89. package/src/codec/reader.ts +56 -0
  90. package/src/codec/script-codec.ts +9 -31
  91. package/src/codec/signature-codec.ts +3 -18
  92. package/src/codec/timestamp-codec.ts +42 -0
  93. package/src/codec/token-codec.ts +7 -26
  94. package/src/codec/transaction-codec.ts +29 -58
  95. package/src/codec/unlock-script-codec.ts +44 -171
  96. package/src/codec/unsigned-tx-codec.ts +34 -63
  97. package/src/codec/val.ts +40 -0
  98. package/src/contract/contract.ts +9 -13
  99. package/src/contract/index.ts +1 -0
  100. package/src/contract/ralph.ts +76 -172
  101. package/src/contract/script-simulator.ts +838 -0
  102. package/src/exchange/exchange.ts +1 -1
  103. package/dist/src/codec/long-codec.d.ts +0 -8
  104. package/dist/src/codec/long-codec.js +0 -55
  105. package/dist/src/codec/signed-int-codec.d.ts +0 -8
  106. package/src/codec/long-codec.ts +0 -58
@@ -16,9 +16,6 @@ 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 { Parser } from 'binary-parser'
20
- import { DecodedArray } from './array-codec'
21
-
22
19
  import { UnsignedTxCodec, UnsignedTx, unsignedTxCodec } from './unsigned-tx-codec'
23
20
  import { Signature, signaturesCodec } from './signature-codec'
24
21
  import { ContractOutputRef, contractOutputRefsCodec } from './contract-output-ref-codec'
@@ -26,61 +23,28 @@ import { Either } from './either-codec'
26
23
  import { AssetOutput, AssetOutputCodec } from './asset-output-codec'
27
24
  import { ContractOutput, ContractOutputCodec } from './contract-output-codec'
28
25
  import { FixedAssetOutput, Transaction as ApiTransaction } from '../api/api-alephium'
29
- import { binToHex, hexToBinUnsafe, concatBytes } from '../utils'
26
+ import { binToHex, hexToBinUnsafe } from '../utils'
30
27
  import { ContractOutput as ApiContractOutput } from '../api/api-alephium'
31
- import { Codec } from './codec'
28
+ import { byteCodec, ObjectCodec } from './codec'
32
29
  import { Output, outputCodec, outputsCodec } from './output-codec'
33
30
 
34
31
  export interface Transaction {
35
32
  unsigned: UnsignedTx
36
33
  scriptExecutionOk: number
37
- contractInputs: DecodedArray<ContractOutputRef>
38
- generatedOutputs: DecodedArray<Output>
39
- inputSignatures: DecodedArray<Signature>
40
- scriptSignatures: DecodedArray<Signature>
34
+ contractInputs: ContractOutputRef[]
35
+ generatedOutputs: Output[]
36
+ inputSignatures: Signature[]
37
+ scriptSignatures: Signature[]
41
38
  }
42
39
 
43
- export class TransactionCodec implements Codec<Transaction> {
44
- parser = new Parser()
45
- .nest('unsigned', {
46
- type: unsignedTxCodec.parser
47
- })
48
- .uint8('scriptExecutionOk')
49
- .nest('contractInputs', {
50
- type: contractOutputRefsCodec.parser
51
- })
52
- .nest('generatedOutputs', {
53
- type: outputsCodec.parser
54
- })
55
- .nest('inputSignatures', {
56
- type: signaturesCodec.parser
57
- })
58
- .nest('scriptSignatures', {
59
- type: signaturesCodec.parser
60
- })
61
-
62
- encode(decodedTx: Transaction): Uint8Array {
63
- return concatBytes([
64
- unsignedTxCodec.encode(decodedTx.unsigned),
65
- new Uint8Array([decodedTx.scriptExecutionOk]),
66
- contractOutputRefsCodec.encode(decodedTx.contractInputs.value),
67
- outputsCodec.encode(decodedTx.generatedOutputs.value),
68
- signaturesCodec.encode(decodedTx.inputSignatures.value),
69
- signaturesCodec.encode(decodedTx.scriptSignatures.value)
70
- ])
71
- }
72
-
73
- decode(input: Uint8Array): Transaction {
74
- return this.parser.parse(input)
75
- }
76
-
40
+ export class TransactionCodec extends ObjectCodec<Transaction> {
77
41
  encodeApiTransaction(input: ApiTransaction): Uint8Array {
78
42
  const decodedTx = TransactionCodec.fromApiTransaction(input)
79
43
  return this.encode(decodedTx)
80
44
  }
81
45
 
82
46
  decodeApiTransaction(input: Uint8Array): ApiTransaction {
83
- const decodedTx = this.parser.parse(input)
47
+ const decodedTx = this.decode(input)
84
48
  return TransactionCodec.toApiTransaction(decodedTx)
85
49
  }
86
50
 
@@ -88,14 +52,14 @@ export class TransactionCodec implements Codec<Transaction> {
88
52
  const txId = UnsignedTxCodec.txId(transaction.unsigned)
89
53
  const unsigned = UnsignedTxCodec.toApiUnsignedTx(transaction.unsigned)
90
54
  const scriptExecutionOk = !!transaction.scriptExecutionOk
91
- const contractInputs = transaction.contractInputs.value.map((contractInput) => {
55
+ const contractInputs = transaction.contractInputs.map((contractInput) => {
92
56
  const hint = contractInput.hint
93
57
  const key = binToHex(contractInput.key)
94
58
  return { hint, key }
95
59
  })
96
60
  const txIdBytes = hexToBinUnsafe(txId)
97
- const generatedOutputs = transaction.generatedOutputs.value.map((output, index) => {
98
- if (output.either === 0) {
61
+ const generatedOutputs = transaction.generatedOutputs.map((output, index) => {
62
+ if (output.kind === 'Left') {
99
63
  const fixedAssetOutput = AssetOutputCodec.toFixedAssetOutput(txIdBytes, output.value as AssetOutput, index)
100
64
  return { ...fixedAssetOutput, type: 'AssetOutput' }
101
65
  } else {
@@ -103,8 +67,8 @@ export class TransactionCodec implements Codec<Transaction> {
103
67
  }
104
68
  })
105
69
 
106
- const inputSignatures = transaction.inputSignatures.value.map((signature) => binToHex(signature.value))
107
- const scriptSignatures = transaction.scriptSignatures.value.map((signature) => binToHex(signature.value))
70
+ const inputSignatures = transaction.inputSignatures.map((signature) => binToHex(signature))
71
+ const scriptSignatures = transaction.scriptSignatures.map((signature) => binToHex(signature))
108
72
 
109
73
  return { unsigned, scriptExecutionOk, contractInputs, generatedOutputs, inputSignatures, scriptSignatures }
110
74
  }
@@ -117,30 +81,37 @@ export class TransactionCodec implements Codec<Transaction> {
117
81
  })
118
82
  const generatedOutputs: Either<AssetOutput, ContractOutput>[] = tx.generatedOutputs.map((output) => {
119
83
  if (output.type === 'AssetOutput') {
120
- return outputCodec.fromLeft(AssetOutputCodec.fromFixedAssetOutput(output as FixedAssetOutput))
84
+ return { kind: 'Left', value: AssetOutputCodec.fromFixedAssetOutput(output as FixedAssetOutput) }
121
85
  } else if (output.type === 'ContractOutput') {
122
- return outputCodec.fromRight(ContractOutputCodec.convertToOutput(output as ApiContractOutput))
86
+ return { kind: 'Right', value: ContractOutputCodec.convertToOutput(output as ApiContractOutput) }
123
87
  } else {
124
88
  throw new Error('Invalid output type')
125
89
  }
126
90
  })
127
91
 
128
92
  const inputSignatures: Signature[] = tx.inputSignatures.map((signature) => {
129
- return { value: hexToBinUnsafe(signature) }
93
+ return hexToBinUnsafe(signature)
130
94
  })
131
95
  const scriptSignatures: Signature[] = tx.scriptSignatures.map((signature) => {
132
- return { value: hexToBinUnsafe(signature) }
96
+ return hexToBinUnsafe(signature)
133
97
  })
134
98
 
135
99
  return {
136
100
  unsigned,
137
101
  scriptExecutionOk,
138
- contractInputs: contractOutputRefsCodec.fromArray(contractInputs),
139
- generatedOutputs: outputsCodec.fromArray(generatedOutputs),
140
- inputSignatures: signaturesCodec.fromArray(inputSignatures),
141
- scriptSignatures: signaturesCodec.fromArray(scriptSignatures)
102
+ contractInputs: contractInputs,
103
+ generatedOutputs: generatedOutputs,
104
+ inputSignatures: inputSignatures,
105
+ scriptSignatures: scriptSignatures
142
106
  }
143
107
  }
144
108
  }
145
109
 
146
- export const transactionCodec = new TransactionCodec()
110
+ export const transactionCodec = new TransactionCodec({
111
+ unsigned: unsignedTxCodec,
112
+ scriptExecutionOk: byteCodec,
113
+ contractInputs: contractOutputRefsCodec,
114
+ generatedOutputs: outputsCodec,
115
+ inputSignatures: signaturesCodec,
116
+ scriptSignatures: signaturesCodec
117
+ })
@@ -15,179 +15,52 @@ GNU Lesser General Public License for more details.
15
15
  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
- import { Parser } from 'binary-parser'
19
- import { ArrayCodec, DecodedArray } from './array-codec'
20
- import { compactUnsignedIntCodec, compactSignedIntCodec, DecodedCompactInt } from './compact-int-codec'
21
- import { Codec, fixedSizeBytes } from './codec'
22
- import { DecodedScript, scriptCodec } from './script-codec'
23
- import { ByteString, byteStringCodec } from './bytestring-codec'
24
- import { LockupScript, lockupScriptCodec } from './lockup-script-codec'
25
- import { concatBytes } from '../utils'
26
-
27
- export interface P2PKH {
28
- publicKey: Uint8Array
29
- }
30
-
31
- class P2PKHCodec implements Codec<P2PKH> {
32
- parser = fixedSizeBytes('publicKey', 33)
33
-
34
- encode(input: P2PKH): Uint8Array {
35
- return input.publicKey
36
- }
37
-
38
- decode(input: Uint8Array): P2PKH {
39
- return this.parser.parse(input)
40
- }
41
- }
42
- const p2pkhCodec = new P2PKHCodec()
43
-
44
- export interface P2MPKH {
45
- publicKeys: DecodedArray<{
46
- publicKey: P2PKH
47
- index: DecodedCompactInt
48
- }>
49
- }
50
-
51
- class P2MPKHCodec implements Codec<P2MPKH> {
52
- parser = Parser.start().nest('publicKeys', {
53
- type: ArrayCodec.arrayParser(
54
- Parser.start()
55
- .nest('publicKey', { type: p2pkhCodec.parser })
56
- .nest('index', { type: compactUnsignedIntCodec.parser })
57
- )
58
- })
59
-
60
- encode(input: P2MPKH): Uint8Array {
61
- return concatBytes([
62
- compactUnsignedIntCodec.encode(input.publicKeys.length),
63
- ...input.publicKeys.value.map((v) => {
64
- return concatBytes([v.publicKey.publicKey, compactUnsignedIntCodec.encode(v.index)])
65
- })
66
- ])
67
- }
68
-
69
- decode(input: Uint8Array): any {
70
- return this.parser.parse(input)
71
- }
72
- }
73
- const p2mpkhCodec = new P2MPKHCodec()
74
-
75
- export interface Val {
76
- type: number
77
- val: number | DecodedCompactInt | ByteString | LockupScript
78
- }
79
- class ValCodec implements Codec<Val> {
80
- parser = Parser.start()
81
- .int8('type')
82
- .choice('val', {
83
- tag: 'type',
84
- choices: {
85
- 0x00: new Parser().uint8('value'), // Boolean
86
- 0x01: compactSignedIntCodec.parser, // I256
87
- 0x02: compactUnsignedIntCodec.parser, // U256
88
- 0x03: byteStringCodec.parser, // ByteVec
89
- 0x04: lockupScriptCodec.parser // Address
90
- }
91
- })
92
-
93
- encode(input: Val): Uint8Array {
94
- const valType = input.type
95
-
96
- if (valType === 0x00) {
97
- // Boolean
98
- return new Uint8Array([valType, input.val as number])
99
- } else if (valType === 0x01) {
100
- // I256
101
- return new Uint8Array([valType, ...compactUnsignedIntCodec.encode(input.val as DecodedCompactInt)])
102
- } else if (valType === 0x02) {
103
- // U256
104
- return new Uint8Array([valType, ...compactUnsignedIntCodec.encode(input.val as DecodedCompactInt)])
105
- } else if (valType === 0x03) {
106
- // ByteVec
107
- return new Uint8Array([valType, ...byteStringCodec.encode(input.val as ByteString)])
108
- } else if (valType === 0x04) {
109
- // Address
110
- return new Uint8Array([valType, ...lockupScriptCodec.encode(input.val as LockupScript)])
111
- } else {
112
- throw new Error(`ValCodec: unsupported val type: ${valType}`)
113
- }
114
- }
115
-
116
- decode(input: Uint8Array): Val {
117
- return this.parser.parse(input)
118
- }
18
+ import { ArrayCodec } from './array-codec'
19
+ import { i32Codec } from './compact-int-codec'
20
+ import { Codec, EnumCodec, FixedSizeCodec, ObjectCodec } from './codec'
21
+ import { Script, scriptCodec } from './script-codec'
22
+ import { Val, valsCodec } from './val'
23
+
24
+ export type P2PKH = Uint8Array
25
+ export interface KeyWithIndex {
26
+ publicKey: P2PKH
27
+ index: number
119
28
  }
120
-
121
- const valCodec = new ValCodec()
122
- const valsCodec = new ArrayCodec(valCodec)
123
-
29
+ export type P2MPKH = KeyWithIndex[]
124
30
  export interface P2SH {
125
- script: DecodedScript
126
- params: DecodedArray<Val>
127
- }
128
-
129
- export class P2SHCodec implements Codec<P2SH> {
130
- parser = Parser.start()
131
- .nest('script', {
132
- type: scriptCodec.parser
133
- })
134
- .nest('params', {
135
- type: valsCodec.parser
136
- })
137
-
138
- encode(input: P2SH): Uint8Array {
139
- return concatBytes([scriptCodec.encode(input.script), valsCodec.encode(input.params.value)])
140
- }
141
-
142
- decode(input: Uint8Array): P2SH {
143
- return this.parser.parse(input)
144
- }
31
+ script: Script
32
+ params: Val[]
145
33
  }
146
-
147
- const p2shCodec = new P2SHCodec()
148
-
149
- export interface UnlockScript {
150
- scriptType: number
151
- script: P2PKH | P2MPKH | P2SH
152
- }
153
-
154
- export class UnlockScriptCodec implements Codec<UnlockScript> {
155
- parser = Parser.start()
156
- .uint8('scriptType')
157
- .choice('script', {
158
- tag: 'scriptType',
159
- choices: {
160
- 0: p2pkhCodec.parser,
161
- 1: p2mpkhCodec.parser,
162
- 2: p2shCodec.parser,
163
- 3: Parser.start() // TODO: SameAsPrevious, FIXME
164
- }
165
- })
166
-
167
- encode(input: UnlockScript): Uint8Array {
168
- const scriptType = input.scriptType
169
- const inputUnLockScript = input.script
170
-
171
- if (scriptType === 0) {
172
- // P2PKH
173
- return new Uint8Array([scriptType, ...p2pkhCodec.encode(inputUnLockScript as P2PKH)])
174
- } else if (scriptType === 1) {
175
- // P2MPKH
176
- return new Uint8Array([scriptType, ...p2mpkhCodec.encode(inputUnLockScript as P2MPKH)])
177
- } else if (scriptType === 2) {
178
- // P2SH
179
- return new Uint8Array([scriptType, ...p2shCodec.encode(inputUnLockScript as P2SH)])
180
- } else if (scriptType === 3) {
181
- // SameAsPrevious
182
- return new Uint8Array([scriptType])
183
- } else {
184
- throw new Error(`TODO: encode unlock script: ${scriptType}`)
185
- }
34
+ export type SameAsPrevious = 'SameAsPrevious'
35
+
36
+ export type UnlockScript =
37
+ | { kind: 'P2PKH'; value: P2PKH }
38
+ | { kind: 'P2MPKH'; value: P2MPKH }
39
+ | { kind: 'P2SH'; value: P2SH }
40
+ | { kind: 'SameAsPrevious'; value: SameAsPrevious }
41
+
42
+ const p2pkhCodec = new FixedSizeCodec(33)
43
+ const keyWithIndexCodec = new ObjectCodec<KeyWithIndex>({
44
+ publicKey: p2pkhCodec,
45
+ index: i32Codec
46
+ })
47
+ const p2mpkhCodec: Codec<P2MPKH> = new ArrayCodec(keyWithIndexCodec)
48
+ const p2shCodec = new ObjectCodec<P2SH>({
49
+ script: scriptCodec,
50
+ params: valsCodec
51
+ })
52
+ const sameAsPreviousCodec = new (class extends Codec<SameAsPrevious> {
53
+ encode(): Uint8Array {
54
+ return new Uint8Array([])
186
55
  }
187
-
188
- decode(input: Uint8Array): UnlockScript {
189
- return this.parser.parse(input)
56
+ _decode(): SameAsPrevious {
57
+ return 'SameAsPrevious'
190
58
  }
191
- }
192
-
193
- export const unlockScriptCodec = new UnlockScriptCodec()
59
+ })()
60
+
61
+ export const unlockScriptCodec = new EnumCodec<UnlockScript>('unlock script', {
62
+ P2PKH: p2pkhCodec,
63
+ P2MPKH: p2mpkhCodec,
64
+ P2SH: p2shCodec,
65
+ SameAsPrevious: sameAsPreviousCodec
66
+ })
@@ -15,70 +15,34 @@ GNU Lesser General Public License for more details.
15
15
  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
- import { Parser } from 'binary-parser'
19
18
  import { UnsignedTx as ApiUnsignedTx } from '../api/api-alephium'
20
- import { binToHex, concatBytes, hexToBinUnsafe } from '../utils'
21
- import { DecodedScript, scriptCodec, statefulScriptCodecOpt } from './script-codec'
19
+ import { binToHex, hexToBinUnsafe } from '../utils'
20
+ import { Script, scriptCodec, statefulScriptCodecOpt } from './script-codec'
22
21
  import { Option } from './option-codec'
23
- import { DecodedCompactInt, compactSignedIntCodec, compactUnsignedIntCodec } from './compact-int-codec'
22
+ import { i32Codec, u256Codec } from './compact-int-codec'
24
23
  import { Input, InputCodec, inputsCodec } from './input-codec'
25
24
  import { AssetOutput, AssetOutputCodec, assetOutputsCodec } from './asset-output-codec'
26
- import { DecodedArray } from './array-codec'
27
25
  import { blakeHash } from './hash'
28
- import { Codec } from './codec'
26
+ import { byteCodec, ObjectCodec } from './codec'
29
27
 
30
28
  export interface UnsignedTx {
31
29
  version: number
32
30
  networkId: number
33
- statefulScript: Option<DecodedScript>
34
- gasAmount: DecodedCompactInt
35
- gasPrice: DecodedCompactInt
36
- inputs: DecodedArray<Input>
37
- fixedOutputs: DecodedArray<AssetOutput>
31
+ statefulScript: Option<Script>
32
+ gasAmount: number
33
+ gasPrice: bigint
34
+ inputs: Input[]
35
+ fixedOutputs: AssetOutput[]
38
36
  }
39
37
 
40
- export class UnsignedTxCodec implements Codec<UnsignedTx> {
41
- parser = new Parser()
42
- .uint8('version')
43
- .uint8('networkId')
44
- .nest('statefulScript', {
45
- type: statefulScriptCodecOpt.parser
46
- })
47
- .nest('gasAmount', {
48
- type: compactSignedIntCodec.parser
49
- })
50
- .nest('gasPrice', {
51
- type: compactUnsignedIntCodec.parser
52
- })
53
- .nest('inputs', {
54
- type: inputsCodec.parser
55
- })
56
- .nest('fixedOutputs', {
57
- type: assetOutputsCodec.parser
58
- })
59
-
60
- encode(decodedUnsignedTx: UnsignedTx): Uint8Array {
61
- return concatBytes([
62
- new Uint8Array([decodedUnsignedTx.version, decodedUnsignedTx.networkId]),
63
- statefulScriptCodecOpt.encode(decodedUnsignedTx.statefulScript),
64
- compactSignedIntCodec.encode(decodedUnsignedTx.gasAmount),
65
- compactUnsignedIntCodec.encode(decodedUnsignedTx.gasPrice),
66
- inputsCodec.encode(decodedUnsignedTx.inputs.value),
67
- assetOutputsCodec.encode(decodedUnsignedTx.fixedOutputs.value)
68
- ])
69
- }
70
-
71
- decode(input: Uint8Array): UnsignedTx {
72
- return this.parser.parse(input)
73
- }
74
-
38
+ export class UnsignedTxCodec extends ObjectCodec<UnsignedTx> {
75
39
  encodeApiUnsignedTx(input: ApiUnsignedTx): Uint8Array {
76
40
  const decoded = UnsignedTxCodec.fromApiUnsignedTx(input)
77
41
  return this.encode(decoded)
78
42
  }
79
43
 
80
44
  decodeApiUnsignedTx(input: Uint8Array): ApiUnsignedTx {
81
- const decoded = this.parser.parse(input)
45
+ const decoded = this.decode(input)
82
46
  return UnsignedTxCodec.toApiUnsignedTx(decoded)
83
47
  }
84
48
 
@@ -91,13 +55,13 @@ export class UnsignedTxCodec implements Codec<UnsignedTx> {
91
55
  const txIdBytes = hexToBinUnsafe(txId)
92
56
  const version = unsigned.version
93
57
  const networkId = unsigned.networkId
94
- const gasAmount = compactSignedIntCodec.toI32(unsigned.gasAmount)
95
- const gasPrice = compactUnsignedIntCodec.toU256(unsigned.gasPrice).toString()
96
- const inputs = InputCodec.toAssetInputs(unsigned.inputs.value)
97
- const fixedOutputs = AssetOutputCodec.toFixedAssetOutputs(txIdBytes, unsigned.fixedOutputs.value)
58
+ const gasAmount = unsigned.gasAmount
59
+ const gasPrice = unsigned.gasPrice.toString()
60
+ const inputs = InputCodec.toAssetInputs(unsigned.inputs)
61
+ const fixedOutputs = AssetOutputCodec.toFixedAssetOutputs(txIdBytes, unsigned.fixedOutputs)
98
62
  let scriptOpt: string | undefined = undefined
99
- if (unsigned.statefulScript.option === 1) {
100
- scriptOpt = binToHex(scriptCodec.encode(unsigned.statefulScript.value!))
63
+ if (unsigned.statefulScript.kind === 'Some') {
64
+ scriptOpt = binToHex(scriptCodec.encode(unsigned.statefulScript.value))
101
65
  }
102
66
 
103
67
  return { txId, version, networkId, gasAmount, scriptOpt, gasPrice, inputs, fixedOutputs }
@@ -106,18 +70,25 @@ export class UnsignedTxCodec implements Codec<UnsignedTx> {
106
70
  static fromApiUnsignedTx(unsignedTx: ApiUnsignedTx): UnsignedTx {
107
71
  const version = unsignedTx.version
108
72
  const networkId = unsignedTx.networkId
109
- const gasAmount = compactSignedIntCodec.fromI32(unsignedTx.gasAmount)
110
- const gasPrice = compactUnsignedIntCodec.fromU256(BigInt(unsignedTx.gasPrice))
111
- const inputsValue = InputCodec.fromAssetInputs(unsignedTx.inputs)
112
- const inputs = inputsCodec.fromArray(inputsValue)
113
- const fixedOutputsValue = AssetOutputCodec.fromFixedAssetOutputs(unsignedTx.fixedOutputs)
114
- const fixedOutputs = assetOutputsCodec.fromArray(fixedOutputsValue)
115
- const statefulScript = statefulScriptCodecOpt.fromBytes(
116
- unsignedTx.scriptOpt ? hexToBinUnsafe(unsignedTx.scriptOpt) : undefined
117
- )
73
+ const gasAmount = unsignedTx.gasAmount
74
+ const gasPrice = BigInt(unsignedTx.gasPrice)
75
+ const inputs = InputCodec.fromAssetInputs(unsignedTx.inputs)
76
+ const fixedOutputs = AssetOutputCodec.fromFixedAssetOutputs(unsignedTx.fixedOutputs)
77
+ const statefulScript: Option<Script> =
78
+ unsignedTx.scriptOpt !== undefined
79
+ ? { kind: 'Some', value: scriptCodec.decode(hexToBinUnsafe(unsignedTx.scriptOpt)) }
80
+ : { kind: 'None', value: undefined }
118
81
 
119
82
  return { version, networkId, gasAmount, gasPrice, inputs, fixedOutputs, statefulScript }
120
83
  }
121
84
  }
122
85
 
123
- export const unsignedTxCodec = new UnsignedTxCodec()
86
+ export const unsignedTxCodec = new UnsignedTxCodec({
87
+ version: byteCodec,
88
+ networkId: byteCodec,
89
+ statefulScript: statefulScriptCodecOpt,
90
+ gasAmount: i32Codec,
91
+ gasPrice: u256Codec,
92
+ inputs: inputsCodec,
93
+ fixedOutputs: assetOutputsCodec
94
+ })
@@ -0,0 +1,40 @@
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 { i256Codec, u256Codec } from './compact-int-codec'
20
+ import { ByteString, byteStringCodec } from './bytestring-codec'
21
+ import { boolCodec, EnumCodec } from './codec'
22
+ import { LockupScript, lockupScriptCodec } from './lockup-script-codec'
23
+ import { ArrayCodec } from './array-codec'
24
+
25
+ export type ValBool = { kind: 'Bool'; value: boolean }
26
+ export type ValI256 = { kind: 'I256'; value: bigint }
27
+ export type ValU256 = { kind: 'U256'; value: bigint }
28
+ export type ValByteVec = { kind: 'ByteVec'; value: ByteString }
29
+ export type ValAddress = { kind: 'Address'; value: LockupScript }
30
+
31
+ export type Val = ValBool | ValI256 | ValU256 | ValByteVec | ValAddress
32
+
33
+ export const valCodec = new EnumCodec<Val>('val', {
34
+ Bool: boolCodec,
35
+ I256: i256Codec,
36
+ U256: u256Codec,
37
+ ByteVec: byteStringCodec,
38
+ Address: lockupScriptCodec
39
+ })
40
+ export const valsCodec = new ArrayCodec(valCodec)
@@ -64,8 +64,6 @@ import * as blake from 'blakejs'
64
64
  import { isContractDebugMessageEnabled } from '../debug'
65
65
  import {
66
66
  contract,
67
- compactUnsignedIntCodec,
68
- compactSignedIntCodec,
69
67
  Method,
70
68
  LoadLocal,
71
69
  LoadImmFieldByIndex,
@@ -86,7 +84,8 @@ import {
86
84
  CallExternal,
87
85
  Dup,
88
86
  CallerAddress,
89
- ByteConst
87
+ i32Codec,
88
+ BytesConst
90
89
  } from '../codec'
91
90
 
92
91
  const crypto = new WebCrypto()
@@ -1737,6 +1736,10 @@ function getBytecodeTemplate(
1737
1736
  const argsLength = '00'
1738
1737
  const returnsLength = '00'
1739
1738
 
1739
+ if (methodUsePreapprovedAssets && !scriptUseApprovedAssets) {
1740
+ throw new Error('The contract call requires preapproved assets but none are provided')
1741
+ }
1742
+
1740
1743
  const [templateVarStoreLocalInstrs, templateVarsLength] = getTemplateVarStoreLocalInstrs(functionSig, structs)
1741
1744
 
1742
1745
  const approveAlphInstrs: string[] = getApproveAlphInstrs(methodUsePreapprovedAssets ? attoAlphAmount : undefined)
@@ -1805,14 +1808,7 @@ function getApproveTokensInstrs(tokens?: Token[]): string[] {
1805
1808
  if (tokens) {
1806
1809
  tokens.forEach((token) => {
1807
1810
  const tokenIdBin = hexToBinUnsafe(token.id)
1808
- approveTokensInstrs.push(
1809
- encodeInstr(
1810
- ByteConst({
1811
- length: compactSignedIntCodec.fromI32(tokenIdBin.length),
1812
- value: tokenIdBin
1813
- })
1814
- )
1815
- )
1811
+ approveTokensInstrs.push(encodeInstr(BytesConst(tokenIdBin)))
1816
1812
  approveTokensInstrs.push(encodeU256Const(BigInt(token.amount)))
1817
1813
  approveTokensInstrs.push(encodeInstr(ApproveToken))
1818
1814
  })
@@ -1899,7 +1895,7 @@ function encodeLoadLocalInstr(index: number): string {
1899
1895
  }
1900
1896
 
1901
1897
  function encodeI32(value: number): string {
1902
- return binToHex(compactSignedIntCodec.encodeI32(value))
1898
+ return binToHex(i32Codec.encode(value))
1903
1899
  }
1904
1900
 
1905
1901
  function encodeU256Const(value: bigint): string {
@@ -1910,7 +1906,7 @@ function encodeU256Const(value: bigint): string {
1910
1906
  if (value < 6) {
1911
1907
  return (BigInt(0x0c) + value).toString(16).padStart(2, '0')
1912
1908
  } else {
1913
- return encodeInstr(U256Const(compactUnsignedIntCodec.fromU256(BigInt(value))))
1909
+ return encodeInstr(U256Const(value))
1914
1910
  }
1915
1911
  }
1916
1912
 
@@ -19,3 +19,4 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
19
19
  export * from './ralph'
20
20
  export * from './contract'
21
21
  export * from './events'
22
+ export * from './script-simulator'