@alephium/web3 0.39.3 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +1 -1
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/api/node-provider.d.ts +2 -0
- package/dist/src/api/node-provider.js +12 -6
- package/dist/src/api/utils.d.ts +1 -1
- package/dist/src/block/block.d.ts +28 -0
- package/dist/src/block/block.js +131 -0
- package/dist/src/block/index.d.ts +1 -0
- package/dist/src/block/index.js +22 -0
- package/dist/src/codec/contract-output-codec.js +4 -4
- package/dist/src/codec/instr-codec.d.ts +3 -0
- package/dist/src/codec/instr-codec.js +19 -3
- package/dist/src/codec/lockup-script-codec.js +2 -2
- package/dist/src/codec/method-codec.d.ts +3 -1
- package/dist/src/codec/method-codec.js +27 -2
- package/dist/src/codec/script-codec.d.ts +11 -6
- package/dist/src/codec/script-codec.js +13 -2
- package/dist/src/codec/transaction-codec.js +2 -2
- package/dist/src/codec/unlock-script-codec.d.ts +2 -2
- package/dist/src/codec/unsigned-tx-codec.d.ts +2 -2
- package/dist/src/contract/contract.d.ts +25 -7
- package/dist/src/contract/contract.js +136 -51
- package/dist/src/contract/events.d.ts +1 -2
- package/dist/src/contract/events.js +28 -14
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/signer/tx-builder.js +4 -4
- package/dist/src/transaction/status.js +28 -4
- package/dist/src/utils/address.js +29 -16
- package/dist/src/utils/exchange.js +25 -15
- package/dist/src/utils/number.d.ts +1 -1
- package/dist/src/utils/sign.js +6 -6
- package/dist/src/utils/subscription.d.ts +4 -4
- package/dist/src/utils/subscription.js +1 -1
- package/package.json +5 -5
- package/src/api/api-alephium.ts +1 -1
- package/src/api/node-provider.ts +8 -1
- package/src/api/utils.ts +1 -1
- package/src/block/block.ts +139 -0
- package/src/block/index.ts +19 -0
- package/src/codec/contract-output-codec.ts +1 -1
- package/src/codec/instr-codec.ts +14 -1
- package/src/codec/lockup-script-codec.ts +3 -3
- package/src/codec/method-codec.ts +41 -3
- package/src/codec/script-codec.ts +23 -5
- package/src/codec/transaction-codec.ts +1 -1
- package/src/codec/unlock-script-codec.ts +2 -2
- package/src/codec/unsigned-tx-codec.ts +2 -2
- package/src/contract/contract.ts +178 -67
- package/src/contract/events.ts +6 -18
- package/src/index.ts +1 -0
- package/src/signer/tx-builder.ts +2 -2
- package/src/transaction/status.ts +4 -4
- package/src/utils/address.ts +15 -2
- package/src/utils/exchange.ts +32 -10
- package/src/utils/number.ts +1 -1
- package/src/utils/sign.ts +1 -1
- package/src/utils/subscription.ts +4 -4
- package/std/fungible_token_interface.ral +1 -0
- package/std/nft_collection_interface.ral +1 -0
- package/std/nft_collection_with_royalty_interface.ral +1 -0
- package/std/nft_interface.ral +1 -0
|
@@ -1007,7 +1007,7 @@ export declare class HttpClient<SecurityDataType = unknown> {
|
|
|
1007
1007
|
}
|
|
1008
1008
|
/**
|
|
1009
1009
|
* @title Alephium API
|
|
1010
|
-
* @version 2.
|
|
1010
|
+
* @version 2.14.0
|
|
1011
1011
|
* @baseUrl ../
|
|
1012
1012
|
*/
|
|
1013
1013
|
export declare class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ApiRequestArguments, ApiRequestHandler, FungibleTokenMetaData, NFTMetaData, NFTCollectionMetaData } from './types';
|
|
2
2
|
import { Api as NodeApi } from './api-alephium';
|
|
3
3
|
import { HexString } from '../utils';
|
|
4
|
+
import * as node from '../api/api-alephium';
|
|
4
5
|
interface NodeProviderApis {
|
|
5
6
|
wallets: NodeApi<string>['wallets'];
|
|
6
7
|
infos: NodeApi<string>['infos'];
|
|
@@ -41,4 +42,5 @@ export declare class NodeProvider implements NodeProviderApis {
|
|
|
41
42
|
guessFollowsNFTCollectionWithRoyaltyStd: (contractId: HexString) => Promise<boolean>;
|
|
42
43
|
guessStdTokenType: (tokenId: HexString) => Promise<'fungible' | 'non-fungible' | undefined>;
|
|
43
44
|
}
|
|
45
|
+
export declare function tryGetCallResult(result: node.CallContractResult): node.CallContractSucceeded;
|
|
44
46
|
export {};
|
|
@@ -17,10 +17,9 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
17
17
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.NodeProvider = void 0;
|
|
20
|
+
exports.tryGetCallResult = exports.NodeProvider = void 0;
|
|
21
21
|
const types_1 = require("./types");
|
|
22
22
|
const api_alephium_1 = require("./api-alephium");
|
|
23
|
-
const contract_1 = require("../contract");
|
|
24
23
|
const utils_1 = require("../utils");
|
|
25
24
|
function initializeNodeApi(baseUrl, apiKey, customFetch) {
|
|
26
25
|
const nodeApi = new api_alephium_1.Api({
|
|
@@ -45,7 +44,7 @@ class NodeProvider {
|
|
|
45
44
|
const result = await this.contracts.postContractsMulticallContract({
|
|
46
45
|
calls: calls
|
|
47
46
|
});
|
|
48
|
-
const callResults = result.results.map((r) =>
|
|
47
|
+
const callResults = result.results.map((r) => tryGetCallResult(r));
|
|
49
48
|
return {
|
|
50
49
|
symbol: callResults[0].returns[0].value,
|
|
51
50
|
name: callResults[1].returns[0].value,
|
|
@@ -61,7 +60,7 @@ class NodeProvider {
|
|
|
61
60
|
const result = await this.contracts.postContractsMulticallContract({
|
|
62
61
|
calls: calls
|
|
63
62
|
});
|
|
64
|
-
const tokenUri = (0, utils_1.hexToString)(
|
|
63
|
+
const tokenUri = (0, utils_1.hexToString)(tryGetCallResult(result.results[0]).returns[0].value);
|
|
65
64
|
const collectionIndexResult = result.results[1];
|
|
66
65
|
if (collectionIndexResult.type === 'CallContractSucceeded') {
|
|
67
66
|
const successfulCollectionIndexResult = result.results[1];
|
|
@@ -104,7 +103,7 @@ class NodeProvider {
|
|
|
104
103
|
const group = (0, utils_1.groupOfAddress)(address);
|
|
105
104
|
const calls = Array.from([0, 1], (index) => ({ methodIndex: index, group: group, address: address }));
|
|
106
105
|
const result = await this.contracts.postContractsMulticallContract({ calls });
|
|
107
|
-
const callResults = result.results.map((r) =>
|
|
106
|
+
const callResults = result.results.map((r) => tryGetCallResult(r));
|
|
108
107
|
return {
|
|
109
108
|
collectionUri: (0, utils_1.hexToString)(callResults[0].returns[0].value),
|
|
110
109
|
totalSupply: BigInt(callResults[1].returns[0].value)
|
|
@@ -129,7 +128,7 @@ class NodeProvider {
|
|
|
129
128
|
}
|
|
130
129
|
]
|
|
131
130
|
});
|
|
132
|
-
const result =
|
|
131
|
+
const result = tryGetCallResult(apiResult);
|
|
133
132
|
return BigInt(result.returns[0].value);
|
|
134
133
|
};
|
|
135
134
|
this.guessStdInterfaceId = async (tokenId) => {
|
|
@@ -196,3 +195,10 @@ class NodeProvider {
|
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
exports.NodeProvider = NodeProvider;
|
|
198
|
+
function tryGetCallResult(result) {
|
|
199
|
+
if (result.type === 'CallContractFailed') {
|
|
200
|
+
throw new Error(`Failed to call contract, error: ${result.error}`);
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
exports.tryGetCallResult = tryGetCallResult;
|
package/dist/src/api/utils.d.ts
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Subscription, SubscribeOptions } from '../utils/subscription';
|
|
2
|
+
import * as node from '../api/api-alephium';
|
|
3
|
+
import { NodeProvider } from '../api';
|
|
4
|
+
export type ReorgCallback = (orphanBlocks: node.BlockEntry[], newBlocks: node.BlockEntry[]) => Promise<void> | void;
|
|
5
|
+
export interface BlockSubscribeOptions extends SubscribeOptions<node.BlockEntry> {
|
|
6
|
+
reorgCallback?: ReorgCallback;
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class BlockSubscriptionBase extends Subscription<node.BlockEntry> {
|
|
9
|
+
abstract readonly reorgCallback?: ReorgCallback;
|
|
10
|
+
abstract readonly fromGroup: number;
|
|
11
|
+
abstract readonly toGroup: number;
|
|
12
|
+
abstract getHashesAtHeight(height: number): Promise<string[]>;
|
|
13
|
+
abstract getBlockByHash(hash: string): Promise<node.BlockEntry>;
|
|
14
|
+
protected getParentHash(block: node.BlockEntry): string;
|
|
15
|
+
protected handleReorg(blockHash: string, blockHeight: number): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare class BlockSubscription extends BlockSubscriptionBase {
|
|
18
|
+
readonly nodeProvider: NodeProvider;
|
|
19
|
+
readonly fromGroup: number;
|
|
20
|
+
readonly toGroup: number;
|
|
21
|
+
readonly reorgCallback?: ReorgCallback;
|
|
22
|
+
private currentBlockHeight;
|
|
23
|
+
private parentBlockHash;
|
|
24
|
+
constructor(options: BlockSubscribeOptions, fromGroup: number, toGroup: number, fromBlockHeight: number, nodeProvider?: NodeProvider | undefined);
|
|
25
|
+
getHashesAtHeight(height: number): Promise<string[]>;
|
|
26
|
+
getBlockByHash(hash: string): Promise<node.BlockEntry>;
|
|
27
|
+
polling(): Promise<void>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
4
|
+
This file is part of the alephium project.
|
|
5
|
+
|
|
6
|
+
The library is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
The library is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.BlockSubscription = exports.BlockSubscriptionBase = void 0;
|
|
44
|
+
const subscription_1 = require("../utils/subscription");
|
|
45
|
+
const web3 = __importStar(require("../global"));
|
|
46
|
+
class BlockSubscriptionBase extends subscription_1.Subscription {
|
|
47
|
+
getParentHash(block) {
|
|
48
|
+
const index = Math.floor(block.deps.length / 2) + this.toGroup;
|
|
49
|
+
return block.deps[index];
|
|
50
|
+
}
|
|
51
|
+
async handleReorg(blockHash, blockHeight) {
|
|
52
|
+
console.info(`reorg occur, hash: ${blockHash}, height: ${blockHeight}`);
|
|
53
|
+
if (this.reorgCallback === undefined)
|
|
54
|
+
return;
|
|
55
|
+
const orphans = [];
|
|
56
|
+
const newHashes = [];
|
|
57
|
+
let fromHash = blockHash;
|
|
58
|
+
let fromHeight = blockHeight;
|
|
59
|
+
while (true) {
|
|
60
|
+
const hashes = await this.getHashesAtHeight(fromHeight);
|
|
61
|
+
const canonicalHash = hashes[0];
|
|
62
|
+
if (canonicalHash !== fromHash) {
|
|
63
|
+
orphans.push(fromHash);
|
|
64
|
+
newHashes.push(canonicalHash);
|
|
65
|
+
const block = await this.getBlockByHash(fromHash);
|
|
66
|
+
fromHash = this.getParentHash(block);
|
|
67
|
+
fromHeight -= 1;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const orphanBlocks = [];
|
|
74
|
+
for (const hash of orphans.reverse()) {
|
|
75
|
+
const block = await this.getBlockByHash(hash);
|
|
76
|
+
orphanBlocks.push(block);
|
|
77
|
+
}
|
|
78
|
+
const newBlocks = [];
|
|
79
|
+
for (const hash of newHashes.reverse()) {
|
|
80
|
+
const block = await this.getBlockByHash(hash);
|
|
81
|
+
newBlocks.push(block);
|
|
82
|
+
}
|
|
83
|
+
console.info(`orphan hashes: ${orphanBlocks.map((b) => b.hash)}, new hashes: ${newBlocks.map((b) => b.hash)}`);
|
|
84
|
+
await this.reorgCallback(orphanBlocks, newBlocks);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.BlockSubscriptionBase = BlockSubscriptionBase;
|
|
88
|
+
class BlockSubscription extends BlockSubscriptionBase {
|
|
89
|
+
constructor(options, fromGroup, toGroup, fromBlockHeight, nodeProvider = undefined) {
|
|
90
|
+
super(options);
|
|
91
|
+
this.nodeProvider = nodeProvider ?? web3.getCurrentNodeProvider();
|
|
92
|
+
this.fromGroup = fromGroup;
|
|
93
|
+
this.toGroup = toGroup;
|
|
94
|
+
this.reorgCallback = options.reorgCallback;
|
|
95
|
+
this.currentBlockHeight = fromBlockHeight;
|
|
96
|
+
this.parentBlockHash = undefined;
|
|
97
|
+
}
|
|
98
|
+
async getHashesAtHeight(height) {
|
|
99
|
+
const result = await this.nodeProvider.blockflow.getBlockflowHashes({
|
|
100
|
+
fromGroup: this.fromGroup,
|
|
101
|
+
toGroup: this.toGroup,
|
|
102
|
+
height
|
|
103
|
+
});
|
|
104
|
+
return result.headers;
|
|
105
|
+
}
|
|
106
|
+
async getBlockByHash(hash) {
|
|
107
|
+
return await this.nodeProvider.blockflow.getBlockflowBlocksBlockHash(hash);
|
|
108
|
+
}
|
|
109
|
+
async polling() {
|
|
110
|
+
try {
|
|
111
|
+
const chainInfo = await this.nodeProvider.blockflow.getBlockflowChainInfo({
|
|
112
|
+
fromGroup: this.fromGroup,
|
|
113
|
+
toGroup: this.toGroup
|
|
114
|
+
});
|
|
115
|
+
while (this.currentBlockHeight <= chainInfo.currentHeight) {
|
|
116
|
+
const hashes = await this.getHashesAtHeight(this.currentBlockHeight);
|
|
117
|
+
const block = await this.getBlockByHash(hashes[0]);
|
|
118
|
+
if (this.parentBlockHash !== undefined && this.getParentHash(block) !== this.parentBlockHash) {
|
|
119
|
+
await this.handleReorg(this.parentBlockHash, this.currentBlockHeight - 1);
|
|
120
|
+
}
|
|
121
|
+
await this.messageCallback(block);
|
|
122
|
+
this.currentBlockHeight += 1;
|
|
123
|
+
this.parentBlockHash = hashes[0];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
await this.errorCallback(err, this);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.BlockSubscription = BlockSubscription;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ReorgCallback, BlockSubscribeOptions, BlockSubscription } from './block';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
4
|
+
This file is part of the alephium project.
|
|
5
|
+
|
|
6
|
+
The library is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
The library is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.BlockSubscription = void 0;
|
|
21
|
+
var block_1 = require("./block");
|
|
22
|
+
Object.defineProperty(exports, "BlockSubscription", { enumerable: true, get: function () { return block_1.BlockSubscription; } });
|
|
@@ -23,7 +23,7 @@ const binary_parser_1 = require("binary-parser");
|
|
|
23
23
|
const compact_int_codec_1 = require("./compact-int-codec");
|
|
24
24
|
const token_codec_1 = require("./token-codec");
|
|
25
25
|
const hash_1 = require("./hash");
|
|
26
|
-
const
|
|
26
|
+
const utils_1 = require("../utils");
|
|
27
27
|
const signed_int_codec_1 = require("./signed-int-codec");
|
|
28
28
|
const lockup_script_codec_1 = require("./lockup-script-codec");
|
|
29
29
|
class ContractOutputCodec {
|
|
@@ -50,9 +50,9 @@ class ContractOutputCodec {
|
|
|
50
50
|
}
|
|
51
51
|
static convertToApiContractOutput(txIdBytes, output, index) {
|
|
52
52
|
const hint = (0, hash_1.createHint)(output.lockupScript.contractId);
|
|
53
|
-
const key = (0,
|
|
53
|
+
const key = (0, utils_1.binToHex)((0, hash_1.blakeHash)(buffer_1.Buffer.concat([txIdBytes, signed_int_codec_1.signedIntCodec.encode(index)])));
|
|
54
54
|
const attoAlphAmount = compact_int_codec_1.compactUnsignedIntCodec.toU256(output.amount).toString();
|
|
55
|
-
const address =
|
|
55
|
+
const address = utils_1.bs58.encode(buffer_1.Buffer.concat([buffer_1.Buffer.from([0x03]), output.lockupScript.contractId]));
|
|
56
56
|
const tokens = output.tokens.value.map((token) => {
|
|
57
57
|
return {
|
|
58
58
|
id: token.tokenId.toString('hex'),
|
|
@@ -63,7 +63,7 @@ class ContractOutputCodec {
|
|
|
63
63
|
}
|
|
64
64
|
static convertToOutput(apiContractOutput) {
|
|
65
65
|
const amount = compact_int_codec_1.compactUnsignedIntCodec.fromU256(BigInt(apiContractOutput.attoAlphAmount));
|
|
66
|
-
const lockupScript = lockup_script_codec_1.lockupScriptCodec.decode(buffer_1.Buffer.from(
|
|
66
|
+
const lockupScript = lockup_script_codec_1.lockupScriptCodec.decode(buffer_1.Buffer.from(utils_1.bs58.decode(apiContractOutput.address)))
|
|
67
67
|
.script;
|
|
68
68
|
const tokensValue = apiContractOutput.tokens.map((token) => {
|
|
69
69
|
return {
|
|
@@ -170,6 +170,7 @@ export declare const AddModN: Instr;
|
|
|
170
170
|
export declare const U256ToString: Instr;
|
|
171
171
|
export declare const I256ToString: Instr;
|
|
172
172
|
export declare const BoolToString: Instr;
|
|
173
|
+
export declare const GroupOfAddress: Instr;
|
|
173
174
|
export declare const LoadMutField: (index: number) => Instr;
|
|
174
175
|
export declare const StoreMutField: (index: number) => Instr;
|
|
175
176
|
export declare const ApproveAlph: Instr;
|
|
@@ -221,6 +222,8 @@ export declare const LoadImmFieldByIndex: Instr;
|
|
|
221
222
|
export declare const PayGasFee: Instr;
|
|
222
223
|
export declare const MinimalContractDeposit: Instr;
|
|
223
224
|
export declare const CreateMapEntry: (immFields: number, mutFields: number) => Instr;
|
|
225
|
+
export declare const MethodSelector: (selector: number) => Instr;
|
|
226
|
+
export declare const CallExternalBySelector: (selector: number) => Instr;
|
|
224
227
|
export declare class InstrCodec implements Codec<Instr> {
|
|
225
228
|
parser: Parser;
|
|
226
229
|
encode(instr: Instr): Buffer;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.U256Lt = exports.U256Neq = exports.U256Eq = exports.U256Mod = exports.U256Div = exports.U256Mul = exports.U256Sub = exports.U256Add = exports.I256Ge = exports.I256Gt = exports.I256Le = exports.I256Lt = exports.I256Neq = exports.I256Eq = exports.I256Mod = exports.I256Div = exports.I256Mul = exports.I256Sub = exports.I256Add = exports.BoolToByteVec = exports.BoolNeq = exports.BoolEq = exports.BoolOr = exports.BoolAnd = exports.BoolNot = exports.Pop = exports.StoreLocal = exports.LoadLocal = exports.AddressConst = exports.ByteConst = exports.U256Const = exports.I256Const = exports.U256Const5 = exports.U256Const4 = exports.U256Const3 = exports.U256Const2 = exports.U256Const1 = exports.U256Const0 = exports.I256ConstN1 = exports.I256Const5 = exports.I256Const4 = exports.I256Const3 = exports.I256Const2 = exports.I256Const1 = exports.I256Const0 = exports.ConstFalse = exports.ConstTrue = exports.Return = exports.CallExternal = exports.CallLocal = void 0;
|
|
4
4
|
exports.ByteVecToAddress = exports.ByteVecSlice = exports.Log5 = exports.Log4 = exports.Log3 = exports.Log2 = exports.Log1 = exports.VerifyRelativeLocktime = exports.VerifyAbsoluteLocktime = exports.TxInputsSize = exports.TxInputAddressAt = exports.TxId = exports.BlockTarget = exports.BlockTimeStamp = exports.NetworkId = exports.VerifyED25519 = exports.VerifySecP256K1 = exports.VerifyTxSignature = exports.Sha3 = exports.Sha256 = exports.Keccak256 = exports.Blake2b = exports.Assert = exports.IfFalse = exports.IfTrue = exports.Jump = exports.IsContractAddress = exports.IsAssetAddress = exports.AddressToByteVec = exports.AddressNeq = exports.AddressEq = exports.ByteVecConcat = exports.ByteVecSize = exports.ByteVecNeq = exports.ByteVecEq = exports.U256ToByteVec = exports.U256ToI256 = exports.I256ToByteVec = exports.I256ToU256 = exports.U256SHR = exports.U256SHL = exports.U256Xor = exports.U256BitOr = exports.U256BitAnd = exports.U256ModMul = exports.U256ModSub = exports.U256ModAdd = exports.U256Ge = exports.U256Gt = exports.U256Le = void 0;
|
|
5
|
-
exports.
|
|
6
|
-
exports.instrsCodec = exports.instrCodec = exports.InstrCodec = exports.CreateMapEntry = exports.MinimalContractDeposit = exports.PayGasFee = exports.LoadImmFieldByIndex = exports.LoadImmField = exports.AlphTokenId = exports.SubContractIdOf = exports.SubContractId = exports.NullContractAddress = exports.CopyCreateSubContractAndTransferToken = exports.CreateSubContractAndTransferToken = exports.CopyCreateContractAndTransferToken = exports.CreateContractAndTransferToken = exports.ContractExists = exports.StoreMutFieldByIndex = exports.LoadMutFieldByIndex = exports.CopyCreateSubContractWithToken = exports.CopyCreateSubContract = exports.CreateSubContractWithToken = exports.CreateSubContract = exports.LockApprovedAssets = exports.BurnToken = exports.CopyCreateContractWithToken = exports.MigrateWithFields = exports.MigrateSimple = exports.ContractInitialCodeHash = exports.ContractInitialStateHash = exports.CallerCodeHash = exports.CallerInitialStateHash = exports.IsCallerFromTxScript = exports.CallerAddress = exports.CallerContractId = exports.SelfAddress = exports.SelfContractId = exports.DestroySelf = exports.CopyCreateContract = exports.CreateContractWithToken = exports.CreateContract = exports.TransferTokenToSelf = exports.TransferTokenFromSelf = exports.TransferToken = void 0;
|
|
5
|
+
exports.TransferAlphFromSelf = exports.TransferAlph = exports.IsPaying = exports.TokenRemaining = exports.AlphRemaining = exports.ApproveToken = exports.ApproveAlph = exports.StoreMutField = exports.LoadMutField = exports.GroupOfAddress = exports.BoolToString = exports.I256ToString = exports.U256ToString = exports.AddModN = exports.MulModN = exports.GetSegragatedSignature = exports.VerifyBIP340Schnorr = exports.U256ModExp = exports.U256Exp = exports.I256Exp = exports.TxGasFee = exports.TxGasAmount = exports.TxGasPrice = exports.DEBUG = exports.BlockHash = exports.Swap = exports.AssertWithErrorCode = exports.Dup = exports.StoreLocalByIndex = exports.LoadLocalByIndex = exports.ContractIdToAddress = exports.Log9 = exports.Log8 = exports.Log7 = exports.Log6 = exports.EthEcRecover = exports.U256From32Byte = exports.U256From16Byte = exports.U256From8Byte = exports.U256From4Byte = exports.U256From2Byte = exports.U256From1Byte = exports.U256To32Byte = exports.U256To16Byte = exports.U256To8Byte = exports.U256To4Byte = exports.U256To2Byte = exports.U256To1Byte = exports.Zeros = exports.Encode = void 0;
|
|
6
|
+
exports.instrsCodec = exports.instrCodec = exports.InstrCodec = exports.CallExternalBySelector = exports.MethodSelector = exports.CreateMapEntry = exports.MinimalContractDeposit = exports.PayGasFee = exports.LoadImmFieldByIndex = exports.LoadImmField = exports.AlphTokenId = exports.SubContractIdOf = exports.SubContractId = exports.NullContractAddress = exports.CopyCreateSubContractAndTransferToken = exports.CreateSubContractAndTransferToken = exports.CopyCreateContractAndTransferToken = exports.CreateContractAndTransferToken = exports.ContractExists = exports.StoreMutFieldByIndex = exports.LoadMutFieldByIndex = exports.CopyCreateSubContractWithToken = exports.CopyCreateSubContract = exports.CreateSubContractWithToken = exports.CreateSubContract = exports.LockApprovedAssets = exports.BurnToken = exports.CopyCreateContractWithToken = exports.MigrateWithFields = exports.MigrateSimple = exports.ContractInitialCodeHash = exports.ContractInitialStateHash = exports.CallerCodeHash = exports.CallerInitialStateHash = exports.IsCallerFromTxScript = exports.CallerAddress = exports.CallerContractId = exports.SelfAddress = exports.SelfContractId = exports.DestroySelf = exports.CopyCreateContract = exports.CreateContractWithToken = exports.CreateContract = exports.TransferTokenToSelf = exports.TransferTokenFromSelf = exports.TransferToken = exports.TransferAlphToSelf = void 0;
|
|
7
7
|
/*
|
|
8
8
|
Copyright 2018 - 2022 The Alephium Authors
|
|
9
9
|
This file is part of the alephium project.
|
|
@@ -27,6 +27,7 @@ const array_codec_1 = require("./array-codec");
|
|
|
27
27
|
const compact_int_codec_1 = require("./compact-int-codec");
|
|
28
28
|
const bytestring_codec_1 = require("./bytestring-codec");
|
|
29
29
|
const lockup_script_codec_1 = require("./lockup-script-codec");
|
|
30
|
+
const signed_int_codec_1 = require("./signed-int-codec");
|
|
30
31
|
const byteStringArrayCodec = new array_codec_1.ArrayCodec(bytestring_codec_1.byteStringCodec);
|
|
31
32
|
const CallLocal = (index) => ({ code: 0x00, value: { index } });
|
|
32
33
|
exports.CallLocal = CallLocal;
|
|
@@ -180,6 +181,7 @@ exports.AddModN = { code: 0x88, value: {} };
|
|
|
180
181
|
exports.U256ToString = { code: 0x89, value: {} };
|
|
181
182
|
exports.I256ToString = { code: 0x8a, value: {} };
|
|
182
183
|
exports.BoolToString = { code: 0x8b, value: {} };
|
|
184
|
+
exports.GroupOfAddress = { code: 0x8c, value: {} };
|
|
183
185
|
const LoadMutField = (index) => ({ code: 0xa0, value: { index } });
|
|
184
186
|
exports.LoadMutField = LoadMutField;
|
|
185
187
|
const StoreMutField = (index) => ({ code: 0xa1, value: { index } });
|
|
@@ -235,6 +237,14 @@ exports.PayGasFee = { code: 0xd0, value: {} };
|
|
|
235
237
|
exports.MinimalContractDeposit = { code: 0xd1, value: {} };
|
|
236
238
|
const CreateMapEntry = (immFields, mutFields) => ({ code: 0xd2, value: { immFields, mutFields } });
|
|
237
239
|
exports.CreateMapEntry = CreateMapEntry;
|
|
240
|
+
const MethodSelector = (selector) => {
|
|
241
|
+
return { code: 0xd3, value: { index: selector } };
|
|
242
|
+
};
|
|
243
|
+
exports.MethodSelector = MethodSelector;
|
|
244
|
+
const CallExternalBySelector = (selector) => {
|
|
245
|
+
return { code: 0xd4, value: { index: selector } };
|
|
246
|
+
};
|
|
247
|
+
exports.CallExternalBySelector = CallExternalBySelector;
|
|
238
248
|
class InstrCodec {
|
|
239
249
|
constructor() {
|
|
240
250
|
this.parser = binary_parser_1.Parser.start()
|
|
@@ -382,6 +392,7 @@ class InstrCodec {
|
|
|
382
392
|
[exports.U256ToString.code]: binary_parser_1.Parser.start(),
|
|
383
393
|
[exports.I256ToString.code]: binary_parser_1.Parser.start(),
|
|
384
394
|
[exports.BoolToString.code]: binary_parser_1.Parser.start(),
|
|
395
|
+
[exports.GroupOfAddress.code]: binary_parser_1.Parser.start(),
|
|
385
396
|
0xa0: binary_parser_1.Parser.start().uint8('index'),
|
|
386
397
|
0xa1: binary_parser_1.Parser.start().uint8('index'),
|
|
387
398
|
[exports.ApproveAlph.code]: binary_parser_1.Parser.start(),
|
|
@@ -432,7 +443,9 @@ class InstrCodec {
|
|
|
432
443
|
[exports.LoadImmFieldByIndex.code]: binary_parser_1.Parser.start(),
|
|
433
444
|
[exports.PayGasFee.code]: binary_parser_1.Parser.start(),
|
|
434
445
|
[exports.MinimalContractDeposit.code]: binary_parser_1.Parser.start(),
|
|
435
|
-
0xd2: binary_parser_1.Parser.start().uint8('immFields').uint8('mutFields')
|
|
446
|
+
0xd2: binary_parser_1.Parser.start().uint8('immFields').uint8('mutFields'),
|
|
447
|
+
0xd3: binary_parser_1.Parser.start().int32('index'),
|
|
448
|
+
0xd4: binary_parser_1.Parser.start().int32('index')
|
|
436
449
|
}
|
|
437
450
|
});
|
|
438
451
|
}
|
|
@@ -460,6 +473,9 @@ class InstrCodec {
|
|
|
460
473
|
const value = instrValue;
|
|
461
474
|
result.push(value.immFields, value.mutFields);
|
|
462
475
|
}
|
|
476
|
+
else if (instr.code === 0xd3 || instr.code === 0xd4) {
|
|
477
|
+
result.push(...signed_int_codec_1.signedIntCodec.encode(instrValue.index));
|
|
478
|
+
}
|
|
463
479
|
return buffer_1.Buffer.from(result);
|
|
464
480
|
}
|
|
465
481
|
decode(input) {
|
|
@@ -37,7 +37,7 @@ const publicKeyHashCodec = new PublicKeyHashCodec();
|
|
|
37
37
|
const publicKeyHashesCodec = new array_codec_1.ArrayCodec(publicKeyHashCodec);
|
|
38
38
|
const multiSigParser = binary_parser_1.Parser.start()
|
|
39
39
|
.nest('publicKeyHashes', { type: publicKeyHashesCodec.parser })
|
|
40
|
-
.nest('m', { type: compact_int_codec_1.
|
|
40
|
+
.nest('m', { type: compact_int_codec_1.compactSignedIntCodec.parser });
|
|
41
41
|
class LockupScriptCodec {
|
|
42
42
|
constructor() {
|
|
43
43
|
this.parser = binary_parser_1.Parser.start()
|
|
@@ -59,7 +59,7 @@ class LockupScriptCodec {
|
|
|
59
59
|
}
|
|
60
60
|
else if (input.scriptType === 1) {
|
|
61
61
|
result.push(...publicKeyHashesCodec.encode(input.script.publicKeyHashes.value));
|
|
62
|
-
result.push(...compact_int_codec_1.
|
|
62
|
+
result.push(...compact_int_codec_1.compactSignedIntCodec.encode(input.script.m));
|
|
63
63
|
}
|
|
64
64
|
else if (input.scriptType === 2) {
|
|
65
65
|
result.push(...input.script.scriptHash);
|
|
@@ -14,7 +14,9 @@ export interface DecodedMethod {
|
|
|
14
14
|
}
|
|
15
15
|
export interface Method {
|
|
16
16
|
isPublic: boolean;
|
|
17
|
-
|
|
17
|
+
usePreapprovedAssets: boolean;
|
|
18
|
+
useContractAssets: boolean;
|
|
19
|
+
usePayToContractOnly: boolean;
|
|
18
20
|
argsLength: number;
|
|
19
21
|
localsLength: number;
|
|
20
22
|
returnLength: number;
|
|
@@ -23,6 +23,31 @@ const binary_parser_1 = require("binary-parser");
|
|
|
23
23
|
const array_codec_1 = require("./array-codec");
|
|
24
24
|
const compact_int_codec_1 = require("./compact-int-codec");
|
|
25
25
|
const instr_codec_1 = require("./instr-codec");
|
|
26
|
+
function decodeAssetModifier(encoded) {
|
|
27
|
+
const usePayToContractOnly = (encoded & 4) !== 0;
|
|
28
|
+
switch (encoded & 3) {
|
|
29
|
+
case 0:
|
|
30
|
+
return { usePayToContractOnly, usePreapprovedAssets: false, useContractAssets: false };
|
|
31
|
+
case 1:
|
|
32
|
+
return { usePayToContractOnly, usePreapprovedAssets: true, useContractAssets: true };
|
|
33
|
+
case 2:
|
|
34
|
+
return { usePayToContractOnly, usePreapprovedAssets: false, useContractAssets: true };
|
|
35
|
+
case 3:
|
|
36
|
+
return { usePayToContractOnly, usePreapprovedAssets: true, useContractAssets: false };
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Invalid asset modifier: ${encoded}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function encodeAssetModifier(arg) {
|
|
42
|
+
const encoded = !arg.usePreapprovedAssets && !arg.useContractAssets
|
|
43
|
+
? 0
|
|
44
|
+
: arg.usePreapprovedAssets && arg.useContractAssets
|
|
45
|
+
? 1
|
|
46
|
+
: !arg.usePreapprovedAssets && arg.useContractAssets
|
|
47
|
+
? 2
|
|
48
|
+
: 3;
|
|
49
|
+
return encoded | (arg.usePayToContractOnly ? 4 : 0);
|
|
50
|
+
}
|
|
26
51
|
class MethodCodec {
|
|
27
52
|
constructor() {
|
|
28
53
|
this.parser = binary_parser_1.Parser.start()
|
|
@@ -55,7 +80,7 @@ class MethodCodec {
|
|
|
55
80
|
static toMethod(decodedMethod) {
|
|
56
81
|
return {
|
|
57
82
|
isPublic: decodedMethod.isPublic === 1,
|
|
58
|
-
|
|
83
|
+
...decodeAssetModifier(decodedMethod.assetModifier),
|
|
59
84
|
argsLength: compact_int_codec_1.compactUnsignedIntCodec.toU32(decodedMethod.argsLength),
|
|
60
85
|
localsLength: compact_int_codec_1.compactUnsignedIntCodec.toU32(decodedMethod.localsLength),
|
|
61
86
|
returnLength: compact_int_codec_1.compactUnsignedIntCodec.toU32(decodedMethod.returnLength),
|
|
@@ -65,7 +90,7 @@ class MethodCodec {
|
|
|
65
90
|
static fromMethod(method) {
|
|
66
91
|
return {
|
|
67
92
|
isPublic: method.isPublic ? 1 : 0,
|
|
68
|
-
assetModifier: method
|
|
93
|
+
assetModifier: encodeAssetModifier(method),
|
|
69
94
|
argsLength: compact_int_codec_1.compactUnsignedIntCodec.fromU32(method.argsLength),
|
|
70
95
|
localsLength: compact_int_codec_1.compactUnsignedIntCodec.fromU32(method.localsLength),
|
|
71
96
|
returnLength: compact_int_codec_1.compactUnsignedIntCodec.fromU32(method.returnLength),
|
|
@@ -2,15 +2,20 @@ import { Buffer } from 'buffer/';
|
|
|
2
2
|
import { Parser } from 'binary-parser';
|
|
3
3
|
import { DecodedArray } from './array-codec';
|
|
4
4
|
import { Codec } from './codec';
|
|
5
|
-
import { DecodedMethod } from './method-codec';
|
|
5
|
+
import { DecodedMethod, Method } from './method-codec';
|
|
6
6
|
import { OptionCodec } from './option-codec';
|
|
7
|
-
export interface
|
|
7
|
+
export interface DecodedScript {
|
|
8
8
|
methods: DecodedArray<DecodedMethod>;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
10
|
+
export interface Script {
|
|
11
|
+
methods: Method[];
|
|
12
|
+
}
|
|
13
|
+
export declare class ScriptCodec implements Codec<DecodedScript> {
|
|
11
14
|
parser: Parser;
|
|
12
|
-
encode(input:
|
|
13
|
-
decode(input: Buffer):
|
|
15
|
+
encode(input: DecodedScript): Buffer;
|
|
16
|
+
decode(input: Buffer): DecodedScript;
|
|
17
|
+
decodeScript(input: Buffer): Script;
|
|
18
|
+
encodeScript(inputTxScript: Script): Buffer;
|
|
14
19
|
}
|
|
15
20
|
export declare const scriptCodec: ScriptCodec;
|
|
16
|
-
export declare const statefulScriptCodecOpt: OptionCodec<
|
|
21
|
+
export declare const statefulScriptCodecOpt: OptionCodec<DecodedScript>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.statefulScriptCodecOpt = exports.scriptCodec = exports.ScriptCodec = void 0;
|
|
4
2
|
/*
|
|
5
3
|
Copyright 2018 - 2022 The Alephium Authors
|
|
6
4
|
This file is part of the alephium project.
|
|
@@ -18,10 +16,13 @@ GNU Lesser General Public License for more details.
|
|
|
18
16
|
You should have received a copy of the GNU Lesser General Public License
|
|
19
17
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
20
18
|
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.statefulScriptCodecOpt = exports.scriptCodec = exports.ScriptCodec = void 0;
|
|
21
21
|
const buffer_1 = require("buffer/");
|
|
22
22
|
const binary_parser_1 = require("binary-parser");
|
|
23
23
|
const method_codec_1 = require("./method-codec");
|
|
24
24
|
const option_codec_1 = require("./option-codec");
|
|
25
|
+
const compact_int_codec_1 = require("./compact-int-codec");
|
|
25
26
|
class ScriptCodec {
|
|
26
27
|
constructor() {
|
|
27
28
|
this.parser = binary_parser_1.Parser.start().nest('methods', {
|
|
@@ -35,6 +36,16 @@ class ScriptCodec {
|
|
|
35
36
|
decode(input) {
|
|
36
37
|
return this.parser.parse(input);
|
|
37
38
|
}
|
|
39
|
+
decodeScript(input) {
|
|
40
|
+
const decodedTxScript = this.decode(input);
|
|
41
|
+
const methods = decodedTxScript.methods.value.map((decodedMethod) => method_codec_1.MethodCodec.toMethod(decodedMethod));
|
|
42
|
+
return { methods };
|
|
43
|
+
}
|
|
44
|
+
encodeScript(inputTxScript) {
|
|
45
|
+
const methodLength = compact_int_codec_1.compactUnsignedIntCodec.fromU32(inputTxScript.methods.length);
|
|
46
|
+
const decodedMethods = inputTxScript.methods.map((method) => method_codec_1.MethodCodec.fromMethod(method));
|
|
47
|
+
return this.encode({ methods: { value: decodedMethods, length: methodLength } });
|
|
48
|
+
}
|
|
38
49
|
}
|
|
39
50
|
exports.ScriptCodec = ScriptCodec;
|
|
40
51
|
exports.scriptCodec = new ScriptCodec();
|
|
@@ -25,7 +25,7 @@ const signature_codec_1 = require("./signature-codec");
|
|
|
25
25
|
const contract_output_ref_codec_1 = require("./contract-output-ref-codec");
|
|
26
26
|
const asset_output_codec_1 = require("./asset-output-codec");
|
|
27
27
|
const contract_output_codec_1 = require("./contract-output-codec");
|
|
28
|
-
const
|
|
28
|
+
const utils_1 = require("../utils");
|
|
29
29
|
const output_codec_1 = require("./output-codec");
|
|
30
30
|
class TransactionCodec {
|
|
31
31
|
constructor() {
|
|
@@ -77,7 +77,7 @@ class TransactionCodec {
|
|
|
77
77
|
const key = contractInput.key.toString('hex');
|
|
78
78
|
return { hint, key };
|
|
79
79
|
});
|
|
80
|
-
const txIdBytes = (0,
|
|
80
|
+
const txIdBytes = (0, utils_1.hexToBinUnsafe)(txId);
|
|
81
81
|
const generatedOutputs = transaction.generatedOutputs.value.map((output, index) => {
|
|
82
82
|
if (output.either === 0) {
|
|
83
83
|
const fixedAssetOutput = asset_output_codec_1.AssetOutputCodec.toFixedAssetOutput(txIdBytes, output.value, index);
|
|
@@ -3,7 +3,7 @@ import { Parser } from 'binary-parser';
|
|
|
3
3
|
import { DecodedArray } from './array-codec';
|
|
4
4
|
import { DecodedCompactInt } from './compact-int-codec';
|
|
5
5
|
import { Codec } from './codec';
|
|
6
|
-
import {
|
|
6
|
+
import { DecodedScript } from './script-codec';
|
|
7
7
|
import { ByteString } from './bytestring-codec';
|
|
8
8
|
import { LockupScript } from './lockup-script-codec';
|
|
9
9
|
export interface P2PKH {
|
|
@@ -20,7 +20,7 @@ export interface Val {
|
|
|
20
20
|
val: number | DecodedCompactInt | ByteString | LockupScript;
|
|
21
21
|
}
|
|
22
22
|
export interface P2SH {
|
|
23
|
-
script:
|
|
23
|
+
script: DecodedScript;
|
|
24
24
|
params: DecodedArray<Val>;
|
|
25
25
|
}
|
|
26
26
|
export declare class P2SHCodec implements Codec<P2SH> {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Buffer } from 'buffer/';
|
|
2
2
|
import { Parser } from 'binary-parser';
|
|
3
3
|
import { UnsignedTx as ApiUnsignedTx } from '../api/api-alephium';
|
|
4
|
-
import {
|
|
4
|
+
import { DecodedScript } from './script-codec';
|
|
5
5
|
import { Option } from './option-codec';
|
|
6
6
|
import { DecodedCompactInt } from './compact-int-codec';
|
|
7
7
|
import { Input } from './input-codec';
|
|
@@ -11,7 +11,7 @@ import { Codec } from './codec';
|
|
|
11
11
|
export interface UnsignedTx {
|
|
12
12
|
version: number;
|
|
13
13
|
networkId: number;
|
|
14
|
-
statefulScript: Option<
|
|
14
|
+
statefulScript: Option<DecodedScript>;
|
|
15
15
|
gasAmount: DecodedCompactInt;
|
|
16
16
|
gasPrice: DecodedCompactInt;
|
|
17
17
|
inputs: DecodedArray<Input>;
|