cashscript 0.7.6 → 0.8.0-next.1
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/README.md +2 -6
- package/dist/{main/Argument.d.ts → Argument.d.ts} +1 -1
- package/dist/{module/Argument.js → Argument.js} +1 -1
- package/dist/{module/Contract.d.ts → Contract.d.ts} +8 -6
- package/dist/{module/Contract.js → Contract.js} +15 -25
- package/dist/{main/Errors.d.ts → Errors.d.ts} +4 -1
- package/dist/{module/Errors.js → Errors.js} +7 -3
- package/dist/{main/SignatureTemplate.d.ts → SignatureTemplate.d.ts} +2 -3
- package/dist/{module/SignatureTemplate.js → SignatureTemplate.js} +4 -5
- package/dist/{module/Transaction.d.ts → Transaction.d.ts} +7 -5
- package/dist/Transaction.js +352 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -0
- package/dist/{main/index.d.ts → index.d.ts} +1 -1
- package/dist/{module/index.js → index.js} +2 -3
- package/dist/{module/interfaces.d.ts → interfaces.d.ts} +33 -6
- package/dist/{module/interfaces.js → interfaces.js} +0 -2
- package/dist/{module/network → network}/BitcoinRpcNetworkProvider.d.ts +2 -3
- package/dist/network/BitcoinRpcNetworkProvider.js +29 -0
- package/dist/{module/network → network}/ElectrumNetworkProvider.js +53 -72
- package/dist/network/FullStackNetworkProvider.js +33 -0
- package/dist/{main/network → network}/index.d.ts +0 -1
- package/dist/{module/network → network}/index.js +0 -1
- package/dist/{main/utils.d.ts → utils.d.ts} +10 -6
- package/dist/{module/utils.js → utils.js} +90 -46
- package/package.json +18 -16
- package/dist/main/Argument.js +0 -60
- package/dist/main/Contract.d.ts +0 -23
- package/dist/main/Contract.js +0 -87
- package/dist/main/Errors.js +0 -84
- package/dist/main/SignatureTemplate.js +0 -45
- package/dist/main/Transaction.d.ts +0 -39
- package/dist/main/Transaction.js +0 -258
- package/dist/main/constants.d.ts +0 -5
- package/dist/main/constants.js +0 -9
- package/dist/main/index.js +0 -50
- package/dist/main/interfaces.d.ts +0 -43
- package/dist/main/interfaces.js +0 -32
- package/dist/main/network/BitboxNetworkProvider.d.ts +0 -26
- package/dist/main/network/BitboxNetworkProvider.js +0 -40
- package/dist/main/network/BitcoinRpcNetworkProvider.d.ts +0 -41
- package/dist/main/network/BitcoinRpcNetworkProvider.js +0 -49
- package/dist/main/network/ElectrumNetworkProvider.js +0 -162
- package/dist/main/network/FullStackNetworkProvider.js +0 -55
- package/dist/main/network/NetworkProvider.js +0 -3
- package/dist/main/network/index.js +0 -15
- package/dist/main/utils.js +0 -205
- package/dist/module/Argument.d.ts +0 -3
- package/dist/module/Errors.d.ts +0 -66
- package/dist/module/SignatureTemplate.d.ts +0 -15
- package/dist/module/Transaction.js +0 -251
- package/dist/module/constants.d.ts +0 -5
- package/dist/module/constants.js +0 -6
- package/dist/module/index.d.ts +0 -10
- package/dist/module/network/BitboxNetworkProvider.d.ts +0 -26
- package/dist/module/network/BitboxNetworkProvider.js +0 -37
- package/dist/module/network/BitcoinRpcNetworkProvider.js +0 -46
- package/dist/module/network/ElectrumNetworkProvider.d.ts +0 -19
- package/dist/module/network/FullStackNetworkProvider.d.ts +0 -40
- package/dist/module/network/FullStackNetworkProvider.js +0 -52
- package/dist/module/network/NetworkProvider.d.ts +0 -31
- package/dist/module/network/index.d.ts +0 -5
- package/dist/module/utils.d.ts +0 -26
- /package/dist/{main/network → network}/ElectrumNetworkProvider.d.ts +0 -0
- /package/dist/{main/network → network}/FullStackNetworkProvider.d.ts +0 -0
- /package/dist/{main/network → network}/NetworkProvider.d.ts +0 -0
- /package/dist/{module/network → network}/NetworkProvider.js +0 -0
package/dist/main/Argument.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.encodeArgument = void 0;
|
|
7
|
-
const libauth_1 = require("@bitauth/libauth");
|
|
8
|
-
const utils_1 = require("@cashscript/utils");
|
|
9
|
-
const Errors_js_1 = require("./Errors.js");
|
|
10
|
-
const SignatureTemplate_js_1 = __importDefault(require("./SignatureTemplate.js"));
|
|
11
|
-
function encodeArgument(argument, typeStr) {
|
|
12
|
-
let type = (0, utils_1.parseType)(typeStr);
|
|
13
|
-
if (type === utils_1.PrimitiveType.BOOL) {
|
|
14
|
-
if (typeof argument !== 'boolean') {
|
|
15
|
-
throw new Errors_js_1.TypeError(typeof argument, type);
|
|
16
|
-
}
|
|
17
|
-
return (0, utils_1.encodeBool)(argument);
|
|
18
|
-
}
|
|
19
|
-
if (type === utils_1.PrimitiveType.INT) {
|
|
20
|
-
if (typeof argument !== 'number' && typeof argument !== 'bigint') {
|
|
21
|
-
throw new Errors_js_1.TypeError(typeof argument, type);
|
|
22
|
-
}
|
|
23
|
-
return (0, utils_1.encodeInt)(argument);
|
|
24
|
-
}
|
|
25
|
-
if (type === utils_1.PrimitiveType.STRING) {
|
|
26
|
-
if (typeof argument !== 'string') {
|
|
27
|
-
throw new Errors_js_1.TypeError(typeof argument, type);
|
|
28
|
-
}
|
|
29
|
-
return (0, utils_1.encodeString)(argument);
|
|
30
|
-
}
|
|
31
|
-
if (type === utils_1.PrimitiveType.SIG && argument instanceof SignatureTemplate_js_1.default)
|
|
32
|
-
return argument;
|
|
33
|
-
// Convert hex string to Uint8Array
|
|
34
|
-
if (typeof argument === 'string') {
|
|
35
|
-
if (argument.startsWith('0x')) {
|
|
36
|
-
argument = argument.slice(2);
|
|
37
|
-
}
|
|
38
|
-
argument = (0, libauth_1.hexToBin)(argument);
|
|
39
|
-
}
|
|
40
|
-
if (!(argument instanceof Uint8Array)) {
|
|
41
|
-
throw Error(`Value for type ${type} should be a Uint8Array or hex string`);
|
|
42
|
-
}
|
|
43
|
-
// Redefine SIG as a bytes65 so it is included in the size checks below
|
|
44
|
-
// Note that ONLY Schnorr signatures are accepted
|
|
45
|
-
if (type === utils_1.PrimitiveType.SIG && argument.byteLength !== 0) {
|
|
46
|
-
type = new utils_1.BytesType(65);
|
|
47
|
-
}
|
|
48
|
-
// Redefine SIG as a bytes64 so it is included in the size checks below
|
|
49
|
-
// Note that ONLY Schnorr signatures are accepted
|
|
50
|
-
if (type === utils_1.PrimitiveType.DATASIG && argument.byteLength !== 0) {
|
|
51
|
-
type = new utils_1.BytesType(64);
|
|
52
|
-
}
|
|
53
|
-
// Bounded bytes types require a correctly sized argument
|
|
54
|
-
if (type instanceof utils_1.BytesType && type.bound && argument.byteLength !== type.bound) {
|
|
55
|
-
throw new Errors_js_1.TypeError(`bytes${argument.byteLength}`, type);
|
|
56
|
-
}
|
|
57
|
-
return argument;
|
|
58
|
-
}
|
|
59
|
-
exports.encodeArgument = encodeArgument;
|
|
60
|
-
//# sourceMappingURL=Argument.js.map
|
package/dist/main/Contract.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Artifact } from '@cashscript/utils';
|
|
2
|
-
import { Transaction } from './Transaction.js';
|
|
3
|
-
import { Argument } from './Argument.js';
|
|
4
|
-
import { Utxo } from './interfaces.js';
|
|
5
|
-
import NetworkProvider from './network/NetworkProvider.js';
|
|
6
|
-
export declare class Contract {
|
|
7
|
-
private artifact;
|
|
8
|
-
private provider;
|
|
9
|
-
name: string;
|
|
10
|
-
address: string;
|
|
11
|
-
bytesize: number;
|
|
12
|
-
opcount: number;
|
|
13
|
-
functions: {
|
|
14
|
-
[name: string]: ContractFunction;
|
|
15
|
-
};
|
|
16
|
-
private redeemScript;
|
|
17
|
-
constructor(artifact: Artifact, constructorArgs: Argument[], provider?: NetworkProvider);
|
|
18
|
-
getBalance(): Promise<number>;
|
|
19
|
-
getUtxos(): Promise<Utxo[]>;
|
|
20
|
-
getRedeemScriptHex(): string;
|
|
21
|
-
private createFunction;
|
|
22
|
-
}
|
|
23
|
-
export declare type ContractFunction = (...args: Argument[]) => Transaction;
|
package/dist/main/Contract.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.Contract = void 0;
|
|
16
|
-
const libauth_1 = require("@bitauth/libauth");
|
|
17
|
-
const utils_1 = require("@cashscript/utils");
|
|
18
|
-
const Transaction_js_1 = require("./Transaction.js");
|
|
19
|
-
const Argument_js_1 = require("./Argument.js");
|
|
20
|
-
const utils_js_1 = require("./utils.js");
|
|
21
|
-
const SignatureTemplate_js_1 = __importDefault(require("./SignatureTemplate.js"));
|
|
22
|
-
const index_js_1 = require("./network/index.js");
|
|
23
|
-
class Contract {
|
|
24
|
-
constructor(artifact, constructorArgs, provider = new index_js_1.ElectrumNetworkProvider()) {
|
|
25
|
-
this.artifact = artifact;
|
|
26
|
-
this.provider = provider;
|
|
27
|
-
const expectedProperties = ['abi', 'bytecode', 'constructorInputs', 'contractName'];
|
|
28
|
-
if (!expectedProperties.every((property) => property in artifact)) {
|
|
29
|
-
throw new Error('Invalid or incomplete artifact provided');
|
|
30
|
-
}
|
|
31
|
-
if (artifact.constructorInputs.length !== constructorArgs.length) {
|
|
32
|
-
throw new Error(`Incorrect number of arguments passed to ${artifact.contractName} constructor`);
|
|
33
|
-
}
|
|
34
|
-
// Encode arguments (this also performs type checking)
|
|
35
|
-
const encodedArgs = constructorArgs
|
|
36
|
-
.map((arg, i) => (0, Argument_js_1.encodeArgument)(arg, artifact.constructorInputs[i].type))
|
|
37
|
-
.reverse();
|
|
38
|
-
// Check there's no signature templates in the constructor
|
|
39
|
-
if (encodedArgs.some((arg) => arg instanceof SignatureTemplate_js_1.default)) {
|
|
40
|
-
throw new Error('Cannot use signatures in constructor');
|
|
41
|
-
}
|
|
42
|
-
this.redeemScript = (0, utils_1.generateRedeemScript)((0, utils_1.asmToScript)(this.artifact.bytecode), encodedArgs);
|
|
43
|
-
// Populate the functions object with the contract's functions
|
|
44
|
-
// (with a special case for single function, which has no "function selector")
|
|
45
|
-
this.functions = {};
|
|
46
|
-
if (artifact.abi.length === 1) {
|
|
47
|
-
const f = artifact.abi[0];
|
|
48
|
-
this.functions[f.name] = this.createFunction(f);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
artifact.abi.forEach((f, i) => {
|
|
52
|
-
this.functions[f.name] = this.createFunction(f, i);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
this.name = artifact.contractName;
|
|
56
|
-
this.address = (0, utils_js_1.scriptToAddress)(this.redeemScript, this.provider.network);
|
|
57
|
-
this.bytesize = (0, utils_1.calculateBytesize)(this.redeemScript);
|
|
58
|
-
this.opcount = (0, utils_1.countOpcodes)(this.redeemScript);
|
|
59
|
-
}
|
|
60
|
-
getBalance() {
|
|
61
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
const utxos = yield this.getUtxos();
|
|
63
|
-
return utxos.reduce((acc, utxo) => acc + utxo.satoshis, 0);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
getUtxos() {
|
|
67
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
-
return this.provider.getUtxos(this.address);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
getRedeemScriptHex() {
|
|
72
|
-
return (0, libauth_1.binToHex)((0, utils_1.scriptToBytecode)(this.redeemScript));
|
|
73
|
-
}
|
|
74
|
-
createFunction(abiFunction, selector) {
|
|
75
|
-
return (...args) => {
|
|
76
|
-
if (abiFunction.inputs.length !== args.length) {
|
|
77
|
-
throw new Error(`Incorrect number of arguments passed to function ${abiFunction.name}`);
|
|
78
|
-
}
|
|
79
|
-
// Encode passed args (this also performs type checking)
|
|
80
|
-
const encodedArgs = args
|
|
81
|
-
.map((arg, i) => (0, Argument_js_1.encodeArgument)(arg, abiFunction.inputs[i].type));
|
|
82
|
-
return new Transaction_js_1.Transaction(this.address, this.provider, this.redeemScript, abiFunction, encodedArgs, selector);
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
exports.Contract = Contract;
|
|
87
|
-
//# sourceMappingURL=Contract.js.map
|
package/dist/main/Errors.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Reason = exports.FailedSigCheckError = exports.FailedTimeCheckError = exports.FailedRequireError = exports.FailedTransactionError = exports.OutputSatoshisTooSmallError = exports.TypeError = void 0;
|
|
4
|
-
const constants_js_1 = require("./constants.js");
|
|
5
|
-
class TypeError extends Error {
|
|
6
|
-
constructor(actual, expected) {
|
|
7
|
-
super(`Found type '${actual}' where type '${expected.toString()}' was expected`);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
exports.TypeError = TypeError;
|
|
11
|
-
class OutputSatoshisTooSmallError extends Error {
|
|
12
|
-
constructor(satoshis) {
|
|
13
|
-
super(`Tried to add an output with ${satoshis} satoshis, which is less than the DUST limit (${constants_js_1.DUST_LIMIT})`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.OutputSatoshisTooSmallError = OutputSatoshisTooSmallError;
|
|
17
|
-
class FailedTransactionError extends Error {
|
|
18
|
-
constructor(reason, meep) {
|
|
19
|
-
super(`Transaction failed with reason: ${reason}\n${meep}`);
|
|
20
|
-
this.reason = reason;
|
|
21
|
-
this.meep = meep;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.FailedTransactionError = FailedTransactionError;
|
|
25
|
-
class FailedRequireError extends FailedTransactionError {
|
|
26
|
-
}
|
|
27
|
-
exports.FailedRequireError = FailedRequireError;
|
|
28
|
-
class FailedTimeCheckError extends FailedTransactionError {
|
|
29
|
-
}
|
|
30
|
-
exports.FailedTimeCheckError = FailedTimeCheckError;
|
|
31
|
-
class FailedSigCheckError extends FailedTransactionError {
|
|
32
|
-
}
|
|
33
|
-
exports.FailedSigCheckError = FailedSigCheckError;
|
|
34
|
-
// TODO: Expand these reasons with non-script failures (like tx-mempool-conflict)
|
|
35
|
-
var Reason;
|
|
36
|
-
(function (Reason) {
|
|
37
|
-
Reason["EVAL_FALSE"] = "Script evaluated without error but finished with a false/empty top stack element";
|
|
38
|
-
Reason["VERIFY"] = "Script failed an OP_VERIFY operation";
|
|
39
|
-
Reason["EQUALVERIFY"] = "Script failed an OP_EQUALVERIFY operation";
|
|
40
|
-
Reason["CHECKMULTISIGVERIFY"] = "Script failed an OP_CHECKMULTISIGVERIFY operation";
|
|
41
|
-
Reason["CHECKSIGVERIFY"] = "Script failed an OP_CHECKSIGVERIFY operation";
|
|
42
|
-
Reason["CHECKDATASIGVERIFY"] = "Script failed an OP_CHECKDATASIGVERIFY operation";
|
|
43
|
-
Reason["NUMEQUALVERIFY"] = "Script failed an OP_NUMEQUALVERIFY operation";
|
|
44
|
-
Reason["SCRIPT_SIZE"] = "Script is too big";
|
|
45
|
-
Reason["PUSH_SIZE"] = "Push value size limit exceeded";
|
|
46
|
-
Reason["OP_COUNT"] = "Operation limit exceeded";
|
|
47
|
-
Reason["STACK_SIZE"] = "Stack size limit exceeded";
|
|
48
|
-
Reason["SIG_COUNT"] = "Signature count negative or greater than pubkey count";
|
|
49
|
-
Reason["PUBKEY_COUNT"] = "Pubkey count negative or limit exceeded";
|
|
50
|
-
Reason["INVALID_OPERAND_SIZE"] = "Invalid operand size";
|
|
51
|
-
Reason["INVALID_NUMBER_RANGE"] = "Given operand is not a number within the valid range";
|
|
52
|
-
Reason["IMPOSSIBLE_ENCODING"] = "The requested encoding is impossible to satisfy";
|
|
53
|
-
Reason["INVALID_SPLIT_RANGE"] = "Invalid OP_SPLIT range";
|
|
54
|
-
Reason["INVALID_BIT_COUNT"] = "Invalid number of bit set in OP_CHECKMULTISIG";
|
|
55
|
-
Reason["BAD_OPCODE"] = "Opcode missing or not understood";
|
|
56
|
-
Reason["DISABLED_OPCODE"] = "Attempted to use a disabled opcode";
|
|
57
|
-
Reason["INVALID_STACK_OPERATION"] = "Operation not valid with the current stack size";
|
|
58
|
-
Reason["INVALID_ALTSTACK_OPERATION"] = "Operation not valid with the current altstack size";
|
|
59
|
-
Reason["OP_RETURN"] = "OP_RETURN was encountered";
|
|
60
|
-
Reason["UNBALANCED_CONDITIONAL"] = "Invalid OP_IF construction";
|
|
61
|
-
Reason["DIV_BY_ZERO"] = "Division by zero error";
|
|
62
|
-
Reason["MOD_BY_ZERO"] = "Modulo by zero error";
|
|
63
|
-
Reason["INVALID_BITFIELD_SIZE"] = "Bitfield of unexpected size error";
|
|
64
|
-
Reason["INVALID_BIT_RANGE"] = "Bitfield's bit out of the expected range";
|
|
65
|
-
Reason["NEGATIVE_LOCKTIME"] = "Negative locktime";
|
|
66
|
-
Reason["UNSATISFIED_LOCKTIME"] = "Locktime requirement not satisfied";
|
|
67
|
-
Reason["SIG_HASHTYPE"] = "Signature hash type missing or not understood";
|
|
68
|
-
Reason["SIG_DER"] = "Non-canonical DER signature";
|
|
69
|
-
Reason["MINIMALDATA"] = "Data push larger than necessary";
|
|
70
|
-
Reason["SIG_PUSHONLY"] = "Only push operators allowed in signature scripts";
|
|
71
|
-
Reason["SIG_HIGH_S"] = "Non-canonical signature: S value is unnecessarily high";
|
|
72
|
-
Reason["MINIMALIF"] = "OP_IF/NOTIF argument must be minimal";
|
|
73
|
-
Reason["SIG_NULLFAIL"] = "Signature must be zero for failed CHECK(MULTI)SIG operation";
|
|
74
|
-
Reason["SIG_BADLENGTH"] = "Signature cannot be 65 bytes in CHECKMULTISIG";
|
|
75
|
-
Reason["SIG_NONSCHNORR"] = "Only Schnorr signatures allowed in this operation";
|
|
76
|
-
Reason["DISCOURAGE_UPGRADABLE_NOPS"] = "NOPx reserved for soft-fork upgrades";
|
|
77
|
-
Reason["PUBKEYTYPE"] = "Public key is neither compressed or uncompressed";
|
|
78
|
-
Reason["CLEANSTACK"] = "Script did not clean its stack";
|
|
79
|
-
Reason["NONCOMPRESSED_PUBKEY"] = "Using non-compressed public key";
|
|
80
|
-
Reason["ILLEGAL_FORKID"] = "Illegal use of SIGHASH_FORKID";
|
|
81
|
-
Reason["MUST_USE_FORKID"] = "Signature must use SIGHASH_FORKID";
|
|
82
|
-
Reason["UNKNOWN"] = "unknown error";
|
|
83
|
-
})(Reason = exports.Reason || (exports.Reason = {}));
|
|
84
|
-
//# sourceMappingURL=Errors.js.map
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const libauth_1 = require("@bitauth/libauth");
|
|
4
|
-
const utils_1 = require("@cashscript/utils");
|
|
5
|
-
const interfaces_js_1 = require("./interfaces.js");
|
|
6
|
-
class SignatureTemplate {
|
|
7
|
-
constructor(signer, hashtype = interfaces_js_1.HashType.SIGHASH_ALL, signatureAlgorithm = interfaces_js_1.SignatureAlgorithm.SCHNORR) {
|
|
8
|
-
this.hashtype = hashtype;
|
|
9
|
-
this.signatureAlgorithm = signatureAlgorithm;
|
|
10
|
-
if (isKeypair(signer)) {
|
|
11
|
-
const wif = signer.toWIF();
|
|
12
|
-
this.privateKey = decodeWif(wif);
|
|
13
|
-
}
|
|
14
|
-
else if (typeof signer === 'string') {
|
|
15
|
-
this.privateKey = decodeWif(signer);
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
this.privateKey = signer;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
generateSignature(payload, secp256k1, bchForkId) {
|
|
22
|
-
const signature = this.signatureAlgorithm === interfaces_js_1.SignatureAlgorithm.SCHNORR
|
|
23
|
-
? secp256k1.signMessageHashSchnorr(this.privateKey, payload)
|
|
24
|
-
: secp256k1.signMessageHashDER(this.privateKey, payload);
|
|
25
|
-
return Uint8Array.from([...signature, this.getHashType(bchForkId)]);
|
|
26
|
-
}
|
|
27
|
-
getHashType(bchForkId = true) {
|
|
28
|
-
return bchForkId ? (this.hashtype | libauth_1.SigningSerializationFlag.forkId) : this.hashtype;
|
|
29
|
-
}
|
|
30
|
-
getPublicKey(secp256k1) {
|
|
31
|
-
return secp256k1.derivePublicKeyCompressed(this.privateKey);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.default = SignatureTemplate;
|
|
35
|
-
function isKeypair(obj) {
|
|
36
|
-
return typeof obj.toWIF === 'function';
|
|
37
|
-
}
|
|
38
|
-
function decodeWif(wif) {
|
|
39
|
-
const result = (0, libauth_1.decodePrivateKeyWif)({ hash: utils_1.sha256 }, wif);
|
|
40
|
-
if (typeof result === 'string') {
|
|
41
|
-
throw new Error(result);
|
|
42
|
-
}
|
|
43
|
-
return result.privateKey;
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=SignatureTemplate.js.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { AbiFunction, Script } from '@cashscript/utils';
|
|
2
|
-
import { Utxo, Recipient, TransactionDetails } from './interfaces.js';
|
|
3
|
-
import NetworkProvider from './network/NetworkProvider.js';
|
|
4
|
-
import SignatureTemplate from './SignatureTemplate.js';
|
|
5
|
-
export declare class Transaction {
|
|
6
|
-
private address;
|
|
7
|
-
private provider;
|
|
8
|
-
private redeemScript;
|
|
9
|
-
private abiFunction;
|
|
10
|
-
private args;
|
|
11
|
-
private selector?;
|
|
12
|
-
private inputs;
|
|
13
|
-
private outputs;
|
|
14
|
-
private sequence;
|
|
15
|
-
private locktime;
|
|
16
|
-
private hardcodedFee;
|
|
17
|
-
private feePerByte;
|
|
18
|
-
private minChange;
|
|
19
|
-
constructor(address: string, provider: NetworkProvider, redeemScript: Script, abiFunction: AbiFunction, args: (Uint8Array | SignatureTemplate)[], selector?: number | undefined);
|
|
20
|
-
from(input: Utxo): this;
|
|
21
|
-
from(inputs: Utxo[]): this;
|
|
22
|
-
experimentalFromP2PKH(input: Utxo, template: SignatureTemplate): this;
|
|
23
|
-
experimentalFromP2PKH(inputs: Utxo[], template: SignatureTemplate): this;
|
|
24
|
-
to(to: string, amount: number): this;
|
|
25
|
-
to(outputs: Recipient[]): this;
|
|
26
|
-
withOpReturn(chunks: string[]): this;
|
|
27
|
-
withAge(age: number): this;
|
|
28
|
-
withTime(time: number): this;
|
|
29
|
-
withHardcodedFee(hardcodedFee: number): this;
|
|
30
|
-
withFeePerByte(feePerByte: number): this;
|
|
31
|
-
withMinChange(minChange: number): this;
|
|
32
|
-
withoutChange(): this;
|
|
33
|
-
build(): Promise<string>;
|
|
34
|
-
send(): Promise<TransactionDetails>;
|
|
35
|
-
send(raw: true): Promise<string>;
|
|
36
|
-
private getTxDetails;
|
|
37
|
-
meep(): Promise<string>;
|
|
38
|
-
private setInputsAndOutputs;
|
|
39
|
-
}
|
package/dist/main/Transaction.js
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.Transaction = void 0;
|
|
16
|
-
const libauth_1 = require("@bitauth/libauth");
|
|
17
|
-
const delay_1 = __importDefault(require("delay"));
|
|
18
|
-
const utils_1 = require("@cashscript/utils");
|
|
19
|
-
const interfaces_js_1 = require("./interfaces.js");
|
|
20
|
-
const utils_js_1 = require("./utils.js");
|
|
21
|
-
const constants_js_1 = require("./constants.js");
|
|
22
|
-
const SignatureTemplate_js_1 = __importDefault(require("./SignatureTemplate.js"));
|
|
23
|
-
const bip68 = require('bip68');
|
|
24
|
-
class Transaction {
|
|
25
|
-
constructor(address, provider, redeemScript, abiFunction, args, selector) {
|
|
26
|
-
this.address = address;
|
|
27
|
-
this.provider = provider;
|
|
28
|
-
this.redeemScript = redeemScript;
|
|
29
|
-
this.abiFunction = abiFunction;
|
|
30
|
-
this.args = args;
|
|
31
|
-
this.selector = selector;
|
|
32
|
-
this.inputs = [];
|
|
33
|
-
this.outputs = [];
|
|
34
|
-
this.sequence = 0xfffffffe;
|
|
35
|
-
this.feePerByte = 1.0;
|
|
36
|
-
this.minChange = constants_js_1.DUST_LIMIT;
|
|
37
|
-
}
|
|
38
|
-
from(inputOrInputs) {
|
|
39
|
-
if (!Array.isArray(inputOrInputs)) {
|
|
40
|
-
inputOrInputs = [inputOrInputs];
|
|
41
|
-
}
|
|
42
|
-
this.inputs = this.inputs.concat(inputOrInputs);
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
experimentalFromP2PKH(inputOrInputs, template) {
|
|
46
|
-
if (!Array.isArray(inputOrInputs)) {
|
|
47
|
-
inputOrInputs = [inputOrInputs];
|
|
48
|
-
}
|
|
49
|
-
inputOrInputs = inputOrInputs.map((input) => (Object.assign(Object.assign({}, input), { template })));
|
|
50
|
-
this.inputs = this.inputs.concat(inputOrInputs);
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
to(toOrOutputs, amount) {
|
|
54
|
-
if (typeof toOrOutputs === 'string' && typeof amount === 'number') {
|
|
55
|
-
return this.to([{ to: toOrOutputs, amount }]);
|
|
56
|
-
}
|
|
57
|
-
if (Array.isArray(toOrOutputs) && amount === undefined) {
|
|
58
|
-
toOrOutputs.forEach(utils_js_1.validateRecipient);
|
|
59
|
-
this.outputs = this.outputs.concat(toOrOutputs);
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
throw new Error('Incorrect arguments passed to function \'to\'');
|
|
63
|
-
}
|
|
64
|
-
withOpReturn(chunks) {
|
|
65
|
-
this.outputs.push((0, utils_js_1.createOpReturnOutput)(chunks));
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
68
|
-
withAge(age) {
|
|
69
|
-
this.sequence = bip68.encode({ blocks: age });
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
withTime(time) {
|
|
73
|
-
this.locktime = time;
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
withHardcodedFee(hardcodedFee) {
|
|
77
|
-
this.hardcodedFee = hardcodedFee;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
withFeePerByte(feePerByte) {
|
|
81
|
-
this.feePerByte = feePerByte;
|
|
82
|
-
return this;
|
|
83
|
-
}
|
|
84
|
-
withMinChange(minChange) {
|
|
85
|
-
this.minChange = minChange;
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
withoutChange() {
|
|
89
|
-
return this.withMinChange(Number.MAX_VALUE);
|
|
90
|
-
}
|
|
91
|
-
build() {
|
|
92
|
-
var _a;
|
|
93
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
this.locktime = (_a = this.locktime) !== null && _a !== void 0 ? _a : yield this.provider.getBlockHeight();
|
|
95
|
-
yield this.setInputsAndOutputs();
|
|
96
|
-
const secp256k1 = yield (0, libauth_1.instantiateSecp256k1)();
|
|
97
|
-
const bytecode = (0, utils_1.scriptToBytecode)(this.redeemScript);
|
|
98
|
-
const inputs = this.inputs.map((utxo) => ({
|
|
99
|
-
outpointIndex: utxo.vout,
|
|
100
|
-
outpointTransactionHash: (0, libauth_1.hexToBin)(utxo.txid),
|
|
101
|
-
sequenceNumber: this.sequence,
|
|
102
|
-
unlockingBytecode: new Uint8Array(),
|
|
103
|
-
}));
|
|
104
|
-
const outputs = this.outputs.map((output) => {
|
|
105
|
-
const lockingBytecode = typeof output.to === 'string'
|
|
106
|
-
? (0, utils_js_1.addressToLockScript)(output.to)
|
|
107
|
-
: output.to;
|
|
108
|
-
const satoshis = (0, libauth_1.bigIntToBinUint64LE)(BigInt(output.amount));
|
|
109
|
-
return { lockingBytecode, satoshis };
|
|
110
|
-
});
|
|
111
|
-
const transaction = {
|
|
112
|
-
inputs,
|
|
113
|
-
locktime: this.locktime,
|
|
114
|
-
outputs,
|
|
115
|
-
version: 2,
|
|
116
|
-
};
|
|
117
|
-
const inputScripts = [];
|
|
118
|
-
this.inputs.forEach((utxo, i) => {
|
|
119
|
-
// UTXO's with signature templates are signed using P2PKH
|
|
120
|
-
if ((0, interfaces_js_1.isSignableUtxo)(utxo)) {
|
|
121
|
-
const pubkey = utxo.template.getPublicKey(secp256k1);
|
|
122
|
-
const pubkeyHash = (0, utils_1.hash160)(pubkey);
|
|
123
|
-
const addressContents = { payload: pubkeyHash, type: libauth_1.AddressType.p2pkh };
|
|
124
|
-
const prevOutScript = (0, libauth_1.addressContentsToLockingBytecode)(addressContents);
|
|
125
|
-
const hashtype = utxo.template.getHashType();
|
|
126
|
-
const preimage = (0, utils_js_1.createSighashPreimage)(transaction, utxo, i, prevOutScript, hashtype);
|
|
127
|
-
const sighash = (0, utils_1.hash256)(preimage);
|
|
128
|
-
const signature = utxo.template.generateSignature(sighash, secp256k1);
|
|
129
|
-
const inputScript = (0, utils_1.scriptToBytecode)([signature, pubkey]);
|
|
130
|
-
inputScripts.push(inputScript);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
let covenantHashType = -1;
|
|
134
|
-
const completeArgs = this.args.map((arg) => {
|
|
135
|
-
if (!(arg instanceof SignatureTemplate_js_1.default))
|
|
136
|
-
return arg;
|
|
137
|
-
// First signature is used for sighash preimage (maybe not the best way)
|
|
138
|
-
if (covenantHashType < 0)
|
|
139
|
-
covenantHashType = arg.getHashType();
|
|
140
|
-
const preimage = (0, utils_js_1.createSighashPreimage)(transaction, utxo, i, bytecode, arg.getHashType());
|
|
141
|
-
const sighash = (0, utils_1.hash256)(preimage);
|
|
142
|
-
return arg.generateSignature(sighash, secp256k1);
|
|
143
|
-
});
|
|
144
|
-
const preimage = this.abiFunction.covenant
|
|
145
|
-
? (0, utils_js_1.createSighashPreimage)(transaction, utxo, i, bytecode, covenantHashType)
|
|
146
|
-
: undefined;
|
|
147
|
-
const inputScript = (0, utils_js_1.createInputScript)(this.redeemScript, completeArgs, this.selector, preimage);
|
|
148
|
-
inputScripts.push(inputScript);
|
|
149
|
-
});
|
|
150
|
-
inputScripts.forEach((script, i) => {
|
|
151
|
-
transaction.inputs[i].unlockingBytecode = script;
|
|
152
|
-
});
|
|
153
|
-
return (0, libauth_1.binToHex)((0, libauth_1.encodeTransaction)(transaction));
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
send(raw) {
|
|
157
|
-
var _a;
|
|
158
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
159
|
-
const tx = yield this.build();
|
|
160
|
-
try {
|
|
161
|
-
const txid = yield this.provider.sendRawTransaction(tx);
|
|
162
|
-
return raw ? yield this.getTxDetails(txid, raw) : yield this.getTxDetails(txid);
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
const reason = (_a = e.error) !== null && _a !== void 0 ? _a : e.message;
|
|
166
|
-
throw (0, utils_js_1.buildError)(reason, (0, utils_js_1.meep)(tx, this.inputs, this.redeemScript));
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
getTxDetails(txid, raw) {
|
|
171
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
-
for (let retries = 0; retries < 1200; retries += 1) {
|
|
173
|
-
yield (0, delay_1.default)(500);
|
|
174
|
-
try {
|
|
175
|
-
const hex = yield this.provider.getRawTransaction(txid);
|
|
176
|
-
if (raw)
|
|
177
|
-
return hex;
|
|
178
|
-
const libauthTransaction = (0, libauth_1.decodeTransaction)((0, libauth_1.hexToBin)(hex));
|
|
179
|
-
return Object.assign(Object.assign({}, libauthTransaction), { txid, hex });
|
|
180
|
-
}
|
|
181
|
-
catch (ignored) {
|
|
182
|
-
// ignored
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// Should not happen
|
|
186
|
-
throw new Error('Could not retrieve transaction details for over 10 minutes');
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
meep() {
|
|
190
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
191
|
-
const tx = yield this.build();
|
|
192
|
-
return (0, utils_js_1.meep)(tx, this.inputs, this.redeemScript);
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
setInputsAndOutputs() {
|
|
196
|
-
var _a;
|
|
197
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
-
if (this.outputs.length === 0) {
|
|
199
|
-
throw Error('Attempted to build a transaction without outputs');
|
|
200
|
-
}
|
|
201
|
-
// Replace all SignatureTemplate with 65-length placeholder Uint8Arrays
|
|
202
|
-
const placeholderArgs = this.args.map((arg) => (arg instanceof SignatureTemplate_js_1.default ? (0, utils_1.placeholder)(65) : arg));
|
|
203
|
-
// Create a placeholder preimage of the correct size
|
|
204
|
-
const placeholderPreimage = this.abiFunction.covenant
|
|
205
|
-
? (0, utils_1.placeholder)((0, utils_js_1.getPreimageSize)((0, utils_1.scriptToBytecode)(this.redeemScript)))
|
|
206
|
-
: undefined;
|
|
207
|
-
// Create a placeholder input script for size calculation using the placeholder
|
|
208
|
-
// arguments and correctly sized placeholder preimage
|
|
209
|
-
const placeholderScript = (0, utils_js_1.createInputScript)(this.redeemScript, placeholderArgs, this.selector, placeholderPreimage);
|
|
210
|
-
// Add one extra byte per input to over-estimate tx-in count
|
|
211
|
-
const inputSize = (0, utils_js_1.getInputSize)(placeholderScript) + 1;
|
|
212
|
-
// Calculate amount to send and base fee (excluding additional fees per UTXO)
|
|
213
|
-
const amount = this.outputs.reduce((acc, output) => acc + output.amount, 0);
|
|
214
|
-
let fee = (_a = this.hardcodedFee) !== null && _a !== void 0 ? _a : (0, utils_js_1.getTxSizeWithoutInputs)(this.outputs) * this.feePerByte;
|
|
215
|
-
// Select and gather UTXOs and calculate fees and available funds
|
|
216
|
-
let satsAvailable = 0;
|
|
217
|
-
if (this.inputs.length > 0) {
|
|
218
|
-
// If inputs are already defined, the user provided the UTXOs
|
|
219
|
-
// and we perform no further UTXO selection
|
|
220
|
-
if (!this.hardcodedFee)
|
|
221
|
-
fee += this.inputs.length * inputSize * this.feePerByte;
|
|
222
|
-
satsAvailable = this.inputs.reduce((acc, input) => acc + input.satoshis, 0);
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
// If inputs are not defined yet, we retrieve the contract's UTXOs and perform selection
|
|
226
|
-
const utxos = yield this.provider.getUtxos(this.address);
|
|
227
|
-
// We sort the UTXOs mainly so there is consistent behaviour between network providers
|
|
228
|
-
// even if they report UTXOs in a different order
|
|
229
|
-
utxos.sort((a, b) => b.satoshis - a.satoshis);
|
|
230
|
-
for (const utxo of utxos) {
|
|
231
|
-
this.inputs.push(utxo);
|
|
232
|
-
satsAvailable += utxo.satoshis;
|
|
233
|
-
if (!this.hardcodedFee)
|
|
234
|
-
fee += inputSize * this.feePerByte;
|
|
235
|
-
if (satsAvailable > amount + fee)
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
// Fee per byte can be a decimal number, but we need the total fee to be an integer
|
|
240
|
-
fee = Math.ceil(fee);
|
|
241
|
-
// Calculate change and check available funds
|
|
242
|
-
let change = satsAvailable - amount - fee;
|
|
243
|
-
if (change < 0) {
|
|
244
|
-
throw new Error(`Insufficient funds: available (${satsAvailable}) < needed (${amount + fee}).`);
|
|
245
|
-
}
|
|
246
|
-
// Account for the fee of a change output
|
|
247
|
-
if (!this.hardcodedFee) {
|
|
248
|
-
change -= constants_js_1.P2SH_OUTPUT_SIZE;
|
|
249
|
-
}
|
|
250
|
-
// Add a change output if applicable
|
|
251
|
-
if (change >= constants_js_1.DUST_LIMIT && change >= this.minChange) {
|
|
252
|
-
this.outputs.push({ to: this.address, amount: change });
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
exports.Transaction = Transaction;
|
|
258
|
-
//# sourceMappingURL=Transaction.js.map
|
package/dist/main/constants.d.ts
DELETED
package/dist/main/constants.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LOCKTIME_SIZE = exports.VERSION_SIZE = exports.P2SH_OUTPUT_SIZE = exports.P2PKH_OUTPUT_SIZE = exports.DUST_LIMIT = void 0;
|
|
4
|
-
exports.DUST_LIMIT = 546;
|
|
5
|
-
exports.P2PKH_OUTPUT_SIZE = 34;
|
|
6
|
-
exports.P2SH_OUTPUT_SIZE = 32;
|
|
7
|
-
exports.VERSION_SIZE = 4;
|
|
8
|
-
exports.LOCKTIME_SIZE = 4;
|
|
9
|
-
//# sourceMappingURL=constants.js.map
|