@alephium/web3 1.3.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 (107) 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 +11 -5
  4. package/dist/src/api/api-alephium.d.ts +2 -4
  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.d.ts +1 -0
  61. package/dist/src/contract/contract.js +20 -13
  62. package/dist/src/contract/index.d.ts +1 -0
  63. package/dist/src/contract/index.js +1 -0
  64. package/dist/src/contract/ralph.d.ts +0 -4
  65. package/dist/src/contract/ralph.js +50 -179
  66. package/dist/src/contract/script-simulator.d.ts +27 -0
  67. package/dist/src/contract/script-simulator.js +757 -0
  68. package/dist/src/exchange/exchange.js +1 -1
  69. package/package.json +3 -4
  70. package/src/address/address.ts +15 -9
  71. package/src/api/api-alephium.ts +2 -4
  72. package/src/codec/array-codec.ts +16 -34
  73. package/src/codec/asset-output-codec.ts +38 -83
  74. package/src/codec/bigint-codec.ts +16 -2
  75. package/src/codec/bytestring-codec.ts +10 -28
  76. package/src/codec/codec.ts +121 -15
  77. package/src/codec/compact-int-codec.ts +230 -207
  78. package/src/codec/contract-codec.ts +20 -33
  79. package/src/codec/contract-output-codec.ts +22 -48
  80. package/src/codec/contract-output-ref-codec.ts +6 -17
  81. package/src/codec/either-codec.ts +4 -53
  82. package/src/codec/index.ts +4 -3
  83. package/src/codec/input-codec.ts +14 -36
  84. package/src/codec/instr-codec.ts +1229 -455
  85. package/src/codec/{signed-int-codec.ts → int-as-4bytes-codec.ts} +6 -10
  86. package/src/codec/lockup-script-codec.ts +28 -76
  87. package/src/codec/method-codec.ts +23 -61
  88. package/src/codec/option-codec.ts +13 -36
  89. package/src/codec/output-codec.ts +2 -2
  90. package/src/codec/reader.ts +56 -0
  91. package/src/codec/script-codec.ts +9 -31
  92. package/src/codec/signature-codec.ts +3 -18
  93. package/src/codec/timestamp-codec.ts +42 -0
  94. package/src/codec/token-codec.ts +7 -26
  95. package/src/codec/transaction-codec.ts +29 -58
  96. package/src/codec/unlock-script-codec.ts +44 -171
  97. package/src/codec/unsigned-tx-codec.ts +34 -63
  98. package/src/codec/val.ts +40 -0
  99. package/src/contract/contract.ts +24 -20
  100. package/src/contract/index.ts +1 -0
  101. package/src/contract/ralph.ts +76 -172
  102. package/src/contract/script-simulator.ts +838 -0
  103. package/src/exchange/exchange.ts +1 -1
  104. package/dist/src/codec/long-codec.d.ts +0 -8
  105. package/dist/src/codec/long-codec.js +0 -55
  106. package/dist/src/codec/signed-int-codec.d.ts +0 -8
  107. 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()
@@ -112,7 +111,8 @@ export const DEFAULT_NODE_COMPILER_OPTIONS: node.CompilerOptions = {
112
111
  ignoreUnusedFieldsWarnings: false,
113
112
  ignoreUnusedPrivateFunctionsWarnings: false,
114
113
  ignoreUpdateFieldsCheckWarnings: false,
115
- ignoreCheckExternalCallerWarnings: false
114
+ ignoreCheckExternalCallerWarnings: false,
115
+ ignoreUnusedFunctionReturnWarnings: false
116
116
  }
117
117
 
118
118
  export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { errorOnWarnings: true, ...DEFAULT_NODE_COMPILER_OPTIONS }
@@ -1010,6 +1010,12 @@ export abstract class ContractFactory<I extends ContractInstance, F extends Fiel
1010
1010
  }
1011
1011
  }
1012
1012
 
1013
+ async deployTemplate(signer: SignerProvider): Promise<DeployContractResult<I>> {
1014
+ return this.deploy(signer, {
1015
+ initialFields: this.contract.getInitialFieldsWithDefaultValues() as F
1016
+ })
1017
+ }
1018
+
1013
1019
  // This is used for testing contract functions
1014
1020
  stateForTest(initFields: F, asset?: Asset, address?: string): ContractState<F> {
1015
1021
  const newAsset = {
@@ -1681,10 +1687,10 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi
1681
1687
  ): Promise<SignExecuteScriptTxResult> {
1682
1688
  const methodIndex = contract.contract.getMethodIndex(methodName)
1683
1689
  const functionSig = contract.contract.functions[methodIndex]
1684
- const usePreapprovedAssets = contract.contract.decodedMethods[methodIndex].usePreapprovedAssets
1690
+ const methodUsePreapprovedAssets = contract.contract.decodedMethods[methodIndex].usePreapprovedAssets
1685
1691
  const bytecodeTemplate = getBytecodeTemplate(
1686
1692
  methodIndex,
1687
- usePreapprovedAssets,
1693
+ methodUsePreapprovedAssets,
1688
1694
  functionSig,
1689
1695
  contract.contract.structs,
1690
1696
  params.attoAlphAmount,
@@ -1716,7 +1722,7 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi
1716
1722
 
1717
1723
  function getBytecodeTemplate(
1718
1724
  methodIndex: number,
1719
- usePreapprovedAssets: boolean,
1725
+ methodUsePreapprovedAssets: boolean,
1720
1726
  functionSig: FunctionSig,
1721
1727
  structs: Struct[],
1722
1728
  attoAlphAmount?: Number256,
@@ -1725,14 +1731,19 @@ function getBytecodeTemplate(
1725
1731
  // For the default TxScript main function
1726
1732
  const numberOfMethods = '01'
1727
1733
  const isPublic = '01'
1728
- const modifier = usePreapprovedAssets ? '03' : '00'
1734
+ const scriptUseApprovedAssets = attoAlphAmount !== undefined || tokens !== undefined
1735
+ const modifier = scriptUseApprovedAssets ? '03' : '00'
1729
1736
  const argsLength = '00'
1730
1737
  const returnsLength = '00'
1731
1738
 
1739
+ if (methodUsePreapprovedAssets && !scriptUseApprovedAssets) {
1740
+ throw new Error('The contract call requires preapproved assets but none are provided')
1741
+ }
1742
+
1732
1743
  const [templateVarStoreLocalInstrs, templateVarsLength] = getTemplateVarStoreLocalInstrs(functionSig, structs)
1733
1744
 
1734
- const approveAlphInstrs: string[] = getApproveAlphInstrs(usePreapprovedAssets ? attoAlphAmount : undefined)
1735
- const approveTokensInstrs: string[] = getApproveTokensInstrs(usePreapprovedAssets ? tokens : undefined)
1745
+ const approveAlphInstrs: string[] = getApproveAlphInstrs(methodUsePreapprovedAssets ? attoAlphAmount : undefined)
1746
+ const approveTokensInstrs: string[] = getApproveTokensInstrs(methodUsePreapprovedAssets ? tokens : undefined)
1736
1747
  const callerInstrs: string[] = getCallAddressInstrs(approveAlphInstrs.length / 2 + approveTokensInstrs.length / 3)
1737
1748
 
1738
1749
  // First template var is the contract
@@ -1797,14 +1808,7 @@ function getApproveTokensInstrs(tokens?: Token[]): string[] {
1797
1808
  if (tokens) {
1798
1809
  tokens.forEach((token) => {
1799
1810
  const tokenIdBin = hexToBinUnsafe(token.id)
1800
- approveTokensInstrs.push(
1801
- encodeInstr(
1802
- ByteConst({
1803
- length: compactSignedIntCodec.fromI32(tokenIdBin.length),
1804
- value: tokenIdBin
1805
- })
1806
- )
1807
- )
1811
+ approveTokensInstrs.push(encodeInstr(BytesConst(tokenIdBin)))
1808
1812
  approveTokensInstrs.push(encodeU256Const(BigInt(token.amount)))
1809
1813
  approveTokensInstrs.push(encodeInstr(ApproveToken))
1810
1814
  })
@@ -1891,7 +1895,7 @@ function encodeLoadLocalInstr(index: number): string {
1891
1895
  }
1892
1896
 
1893
1897
  function encodeI32(value: number): string {
1894
- return binToHex(compactSignedIntCodec.encodeI32(value))
1898
+ return binToHex(i32Codec.encode(value))
1895
1899
  }
1896
1900
 
1897
1901
  function encodeU256Const(value: bigint): string {
@@ -1902,7 +1906,7 @@ function encodeU256Const(value: bigint): string {
1902
1906
  if (value < 6) {
1903
1907
  return (BigInt(0x0c) + value).toString(16).padStart(2, '0')
1904
1908
  } else {
1905
- return encodeInstr(U256Const(compactUnsignedIntCodec.fromU256(BigInt(value))))
1909
+ return encodeInstr(U256Const(value))
1906
1910
  }
1907
1911
  }
1908
1912