@cityofzion/neon-api
Version:
Neon-API module: High level API for neon-js
153 lines • 5.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionBuilder = void 0;
const neon_core_1 = require("@cityofzion/neon-core");
class TransactionBuilder {
constructor() {
this.vmScripts = [];
this.networkFee = neon_core_1.u.BigInteger.fromNumber(0);
this.systemFee = neon_core_1.u.BigInteger.fromNumber(0);
this.validUntilBlock = 0;
this.attributes = [];
this.signers = [];
this.witnesses = [];
}
static newBuilder() {
return new TransactionBuilder();
}
/**
* Adds the logic for claiming gas. Alternatively, you may just trigger the gas claim by performing an actual transaction involving NEO.
* @param account - Account to claim gas on.
*/
addGasClaim(account) {
const address = account.address;
return this.addContractCall(neon_core_1.sc.NeoContract.INSTANCE.transfer(address, address, 0)).addBasicSignatureField(account);
}
/**
* Adds the logic to send tokens around.
* @param account - originating account
* @param destination - account where the tokens will be sent
* @param tokenScriptHash - scripthash of the token contract
* @param amt - Amount of tokens in integer format.
*/
addNep17Transfer(account, destination, tokenScriptHash, amt) {
const address = account.address;
const contract = new neon_core_1.sc.Nep17Contract(tokenScriptHash);
return this.addContractCall(contract.transfer(address, destination, amt)).addBasicSignatureField(account);
}
/**
* Adds the logic to vote for a candidate.
* @param account - Account containing the NEO.
* @param candidatePublicKey - The candidate's publickey in hex big endian.
*/
addVote(account, candidatePublicKey) {
const address = account.address;
return this.addContractCall(neon_core_1.sc.NeoContract.INSTANCE.vote(address, candidatePublicKey)).addBasicSignatureField(account);
}
/**
* Adds a signature field representing the request for a signature from this account.
* Under the hood, this adds a Signer and empty Witness to the transaction. The Signer defaults to the basic scope.
* For more advanced usage, plase manually add your own Signers and Witnesses.
* @param account - account that has to sign the transaction.
*/
addBasicSignatureField(account) {
return this.addSigners({
account: account.scriptHash,
scopes: neon_core_1.tx.WitnessScope.CalledByEntry,
}).addEmptyWitness(account);
}
/**
* Sets an account to pay fees for this transaction.
* The first Signer defaults to the payer.
* @param account - Account to pay fees from.
*/
setFeeAccount(account) {
const ind = this.signers.findIndex((s) => s.account.equals(account.scriptHash));
// Signer exists. We shift it to first in array to become the sender.
if (ind > 0) {
const s = this.signers.splice(ind, 1)[0];
this.signers.unshift(s);
return this;
}
else if (ind === -1) {
this.signers.unshift(new neon_core_1.tx.Signer({
account: account.scriptHash,
scopes: neon_core_1.tx.WitnessScope.None,
}));
return this.addEmptyWitness(account);
}
// Account is already the sender.
return this;
}
/**
* Add signers. Will deduplicate signers and merge scopes.
* This does not add any Witnesses.
*/
addSigners(...signers) {
for (const newSigner of signers) {
const ind = this.signers.findIndex((s) => s.account.equals(newSigner.account));
if (ind !== -1) {
this.signers[ind].merge(newSigner);
}
else {
this.signers.push(new neon_core_1.tx.Signer(newSigner));
}
}
return this;
}
/**
* You can add multiple intents to the transaction
*/
addContractCall(...contractCalls) {
this.vmScripts = this.vmScripts.concat(contractCalls);
return this;
}
addScript(hexString) {
this.vmScripts.push(hexString);
return this;
}
/**
* Adds an unsigned witness to the transaction.
* Will deduplicate witnesses based on verificationScript.
* Required to calculate the network fee correctly.
*/
addEmptyWitness(account) {
const verificationScript = neon_core_1.u.HexString.fromBase64(account.contract.script);
if (!this.witnesses.some((w) => w.verificationScript.equals(verificationScript))) {
this.witnesses.push(new neon_core_1.tx.Witness({
verificationScript,
invocationScript: neon_core_1.u.HexString.fromHex(""),
}));
}
return this;
}
addEmptyWitnesses(...accounts) {
accounts.forEach((a) => this.addEmptyWitness(a));
return this;
}
setSystemFee(fee) {
this.systemFee = fee;
return this;
}
setNetworkFee(fee) {
this.networkFee = fee;
return this;
}
build() {
return new neon_core_1.tx.Transaction({
networkFee: this.networkFee,
systemFee: this.systemFee,
signers: this.signers,
attributes: this.attributes,
validUntilBlock: this.validUntilBlock,
script: this.vmScripts
.reduce((sb, cc) => typeof cc === "string"
? sb.appendScript(cc)
: sb.emitContractCall(cc), new neon_core_1.sc.ScriptBuilder())
.build(),
witnesses: this.witnesses,
});
}
}
exports.TransactionBuilder = TransactionBuilder;
//# sourceMappingURL=TransactionBuilder.js.map