1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const client_common_1 = require("@neo-one/client-common");
|
4 | const client_full_common_1 = require("@neo-one/client-full-common");
|
5 | const errors_1 = require("../errors");
|
6 | const utils_1 = require("../utils");
|
7 | const TransactionBase_1 = require("./TransactionBase");
|
8 | const TransactionType_1 = require("./TransactionType");
|
9 | class IssueTransaction extends TransactionBase_1.TransactionBase(client_full_common_1.IssueTransactionModel) {
|
10 | constructor(add) {
|
11 | super(add);
|
12 | this.sizeExclusive = utils_1.utils.lazy(() => client_common_1.IOHelper.sizeOfUInt8);
|
13 | const getScriptHashesForVerifying = super.getScriptHashesForVerifying.bind(this);
|
14 | this.issueGetScriptHashesForVerifyingInternal = utils_1.utils.lazyAsync(async (options) => {
|
15 | const { getOutput, getAsset } = options;
|
16 | const [hashes, issuerHashes] = await Promise.all([
|
17 | getScriptHashesForVerifying(options),
|
18 | this.getTransactionResults({ getOutput }).then(async (results) => Promise.all(Object.entries(results)
|
19 | .filter(([_, value]) => value.lt(utils_1.utils.ZERO))
|
20 | .map(async ([assetHash, _]) => {
|
21 | const asset = await getAsset({
|
22 | hash: client_common_1.common.hexToUInt256(assetHash),
|
23 | });
|
24 | return client_common_1.common.uInt160ToHex(asset.issuer);
|
25 | }))),
|
26 | ]);
|
27 | return new Set([...hashes, ...issuerHashes]);
|
28 | });
|
29 | }
|
30 | static deserializeWireBase(options) {
|
31 | const { type, version } = super.deserializeTransactionBaseStartWireBase(options);
|
32 | if (type !== TransactionType_1.TransactionType.Issue) {
|
33 | throw new client_common_1.InvalidFormatError(`Expected transaction type to be ${TransactionType_1.TransactionType.Issue}. Received: ${type}`);
|
34 | }
|
35 | const { attributes, inputs, outputs, scripts } = super.deserializeTransactionBaseEndWireBase(options);
|
36 | return new this({
|
37 | version,
|
38 | attributes,
|
39 | inputs,
|
40 | outputs,
|
41 | scripts,
|
42 | });
|
43 | }
|
44 | async serializeJSON(context) {
|
45 | const transactionBaseJSON = await super.serializeTransactionBaseJSON(context);
|
46 | return Object.assign(Object.assign({}, transactionBaseJSON), { type: 'IssueTransaction' });
|
47 | }
|
48 | getSystemFee(context) {
|
49 | if (this.version >= 1) {
|
50 | return utils_1.utils.ZERO;
|
51 | }
|
52 | const { governingToken, utilityToken } = context;
|
53 | if (this.outputs.every((output) => client_common_1.common.uInt256Equal(output.asset, governingToken.hash) ||
|
54 | client_common_1.common.uInt256Equal(output.asset, utilityToken.hash))) {
|
55 | return utils_1.utils.ZERO;
|
56 | }
|
57 | return super.getSystemFee(context);
|
58 | }
|
59 | async getScriptHashesForVerifying(options) {
|
60 | return this.issueGetScriptHashesForVerifyingInternal(options);
|
61 | }
|
62 | async verify(options) {
|
63 | const [results] = await Promise.all([super.verify(options), this.verifyInternal(options)]);
|
64 | return results;
|
65 | }
|
66 | async verifyInternal(options) {
|
67 | const { getOutput, getAsset, memPool = [] } = options;
|
68 | const results = await this.getTransactionResults({ getOutput });
|
69 | await Promise.all(Object.entries(results).map(async ([assetHex, value]) => {
|
70 | const hash = client_common_1.common.hexToUInt256(assetHex);
|
71 | const asset = await getAsset({ hash });
|
72 | if (asset.amount.lt(utils_1.utils.ZERO)) {
|
73 | return;
|
74 | }
|
75 | const issued = asset.available.add(memPool
|
76 | .filter((transaction) => transaction !== this)
|
77 | .reduce((acc, transaction) => transaction.outputs
|
78 | .filter((output) => client_common_1.common.uInt256Equal(hash, output.asset))
|
79 | .reduce((innerAcc, output) => innerAcc.add(output.value), acc), utils_1.utils.ZERO));
|
80 | if (asset.amount.sub(issued).lt(value.neg())) {
|
81 | throw new errors_1.VerifyError('Invalid issue amount');
|
82 | }
|
83 | }));
|
84 | }
|
85 | }
|
86 | exports.IssueTransaction = IssueTransaction;
|
87 |
|
88 |
|