scrypt-ts
Advanced tools
Comparing version 0.1.5-beta.13 to 0.1.5-beta.14
# CHANGELOG | ||
## 0.1.5-beta.13 | ||
- Fix [#115](https://github.com/sCrypt-Inc/scrypt-ts/issues/115) | ||
## 0.1.5-beta.14 | ||
- Fix references struct defined in library | ||
## 0.1.5-beta.12 | ||
- support use in browser | ||
## 0.1.5-beta.10 | ||
@@ -14,0 +9,0 @@ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Provider = void 0; | ||
var scryptlib_1 = require("scryptlib"); | ||
const scryptlib_1 = require("scryptlib"); | ||
/** | ||
* A Provider is an abstraction of non-account-based operations on a blockchain and is generally not directly involved in signing transaction or data. | ||
*/ | ||
var Provider = /** @class */ (function () { | ||
function Provider() { | ||
class Provider { | ||
constructor() { | ||
this._isProvider = true; | ||
@@ -18,6 +18,6 @@ } | ||
*/ | ||
Provider.prototype.sendTransaction = function (tx) { | ||
sendTransaction(tx) { | ||
// TODO: fix tx.serialize issue | ||
return this.sendRawTransaction(tx.serialize({ disableIsFullySigned: true })); | ||
}; | ||
} | ||
/** | ||
@@ -28,8 +28,8 @@ * Get a best guess of the fee for a transaction. | ||
*/ | ||
Provider.prototype.estimateFee = function (tx) { | ||
var copy = new scryptlib_1.bsv.Transaction(tx.uncheckedSerialize()); | ||
estimateFee(tx) { | ||
const copy = new scryptlib_1.bsv.Transaction(tx.uncheckedSerialize()); | ||
// use a copy bcoz `feePerKb` resets all the signatures for inputs. | ||
copy.feePerKb(this.getFeePerKb()); | ||
return copy.getEstimateFee(); | ||
}; | ||
} | ||
/** | ||
@@ -40,8 +40,7 @@ * Check if an object is a `Provider` | ||
*/ | ||
Provider.isProvider = function (value) { | ||
static isProvider(value) { | ||
return !!(value && value._isProvider); | ||
}; | ||
return Provider; | ||
}()); | ||
} | ||
} | ||
exports.Provider = Provider; | ||
//# sourceMappingURL=abstract-provider.js.map |
@@ -79,3 +79,3 @@ import { bsv } from 'scryptlib'; | ||
listUnspent(address: AddressOption, options?: UtxoQueryOptions): Promise<UTXO[]>; | ||
getBalance(address?: AddressOption): Promise<{ | ||
getBalance(address: AddressOption): Promise<{ | ||
confirmed: number; | ||
@@ -82,0 +82,0 @@ unconfirmed: number; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -43,62 +7,42 @@ exports.Signer = void 0; | ||
*/ | ||
var Signer = /** @class */ (function () { | ||
function Signer(provider) { | ||
class Signer { | ||
constructor(provider) { | ||
this._isSigner = true; | ||
this.provider = provider; | ||
} | ||
Object.defineProperty(Signer.prototype, "connectedProvider", { | ||
/** | ||
* Get the connected provider. | ||
* @returns the connected provider. | ||
* @throws if no provider is connected to `this`. | ||
*/ | ||
get: function () { | ||
if (!this.provider) { | ||
throw new Error("the provider of singer ".concat(this.constructor.name, " is not set yet!")); | ||
} | ||
return this.provider; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
* Get the connected provider. | ||
* @returns the connected provider. | ||
* @throws if no provider is connected to `this`. | ||
*/ | ||
get connectedProvider() { | ||
if (!this.provider) { | ||
throw new Error(`the provider of singer ${this.constructor.name} is not set yet!`); | ||
} | ||
return this.provider; | ||
} | ||
/** | ||
* | ||
* @returns A promise which resolves to the address to the default private key of the signer. | ||
*/ | ||
Signer.prototype.getDefaultAddress = function () { | ||
var network = this.connectedProvider.getNetwork(); | ||
return this.getDefaultPubKey().then(function (pubKey) { return pubKey.toAddress(network); }); | ||
}; | ||
getDefaultAddress() { | ||
return this.getDefaultPubKey().then(pubKey => pubKey.toAddress()); | ||
} | ||
// a shortcut to provider's `listUnspent` | ||
Signer.prototype.listUnspent = function (address, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
// default implemention using provider, can be overrided. | ||
return [2 /*return*/, this.connectedProvider.listUnspent(address, options)]; | ||
}); | ||
}); | ||
}; | ||
async listUnspent(address, options) { | ||
// default implemention using provider, can be overrided. | ||
return this.connectedProvider.listUnspent(address, options); | ||
} | ||
// a shortcut to provider's `getBalance` | ||
Signer.prototype.getBalance = function (address) { | ||
getBalance(address) { | ||
// default implemention using provider, can be overrided. | ||
return this.connectedProvider.getBalance(address); | ||
}; | ||
} | ||
// Broadcasting | ||
Signer.prototype.signAndsendTransaction = function (tx, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var signedTx; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.signTransaction(tx, options)]; | ||
case 1: | ||
signedTx = _a.sent(); | ||
return [4 /*yield*/, signedTx.sealAsync()]; | ||
case 2: | ||
_a.sent(); | ||
this.connectedProvider.sendTransaction(signedTx); | ||
return [2 /*return*/, signedTx]; | ||
} | ||
}); | ||
}); | ||
}; | ||
async signAndsendTransaction(tx, options) { | ||
const signedTx = await this.signTransaction(tx, options); | ||
await signedTx.sealAsync(); | ||
this.connectedProvider.sendTransaction(signedTx); | ||
return signedTx; | ||
} | ||
; | ||
@@ -111,8 +55,7 @@ // Inspection | ||
*/ | ||
Signer.isSigner = function (value) { | ||
static isSigner(value) { | ||
return !!(value && value._isSigner); | ||
}; | ||
return Signer; | ||
}()); | ||
} | ||
} | ||
exports.Signer = Signer; | ||
//# sourceMappingURL=abstract-signer.js.map |
@@ -27,10 +27,2 @@ import { Networks, PublicKey, Transaction } from "bsv"; | ||
signMessage(msg: string): Promise<string>; | ||
getBsvBalance(): Promise<{ | ||
address: string; | ||
balance: { | ||
confirmed: number; | ||
unconfirmed: number; | ||
total: number; | ||
}; | ||
}>; | ||
signTransaction(txHex: string, inputInfos: { | ||
@@ -52,9 +44,4 @@ inputIndex: number; | ||
constructor(provider: SensiletProvider); | ||
getSensilet(): SensiletWalletAPI; | ||
isConnected(): Promise<boolean>; | ||
getConnectedTarget(): Promise<SensiletWalletAPI>; | ||
connect(provider: Provider): Signer; | ||
getBalance(address?: AddressOption): Promise<{ | ||
confirmed: number; | ||
unconfirmed: number; | ||
}>; | ||
getDefaultPubKey(): Promise<PublicKey>; | ||
@@ -70,4 +57,3 @@ getPubKey(address: AddressOption): Promise<PublicKey>; | ||
private _delegatedProvider; | ||
private _signer; | ||
constructor(); | ||
constructor(provider: Provider); | ||
getNetwork(): Networks.Network; | ||
@@ -83,4 +69,4 @@ getFeePerKb(): number; | ||
getContractUTXOs(genesisTxHash: string, outputIndex: number): Promise<Transaction.IUnspentOutput[]>; | ||
getSigner(): SensiletSigner; | ||
getSigner(): Signer; | ||
} | ||
export {}; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SensiletProvider = exports.SensiletSigner = void 0; | ||
var dist_1 = require("scryptlib/dist"); | ||
var abstract_provider_1 = require("../abstract-provider"); | ||
var abstract_signer_1 = require("../abstract-signer"); | ||
var utils_1 = require("../utils"); | ||
var whatsonchain_provider_1 = require("./whatsonchain-provider"); | ||
const dist_1 = require("scryptlib/dist"); | ||
const abstract_provider_1 = require("../abstract-provider"); | ||
const abstract_signer_1 = require("../abstract-signer"); | ||
const utils_1 = require("../utils"); | ||
// TODO: export this default value from scryptlib | ||
var DEFAULT_SIGHASH_TYPE = dist_1.bsv.crypto.Signature.ALL; | ||
var SensiletSigner = /** @class */ (function (_super) { | ||
__extends(SensiletSigner, _super); | ||
function SensiletSigner(provider) { | ||
var _this = _super.call(this, provider) || this; | ||
const DEFAULT_SIGHASH_TYPE = dist_1.bsv.crypto.Signature.ALL; | ||
class SensiletSigner extends abstract_signer_1.Signer { | ||
constructor(provider) { | ||
super(provider); | ||
if (typeof window.sensilet !== 'undefined') { | ||
console.log(SensiletProvider.DEBUG_TAG, 'Sensilet is installed!'); | ||
_this._target = window.sensilet; | ||
this._target = window.sensilet; | ||
} | ||
@@ -73,160 +20,114 @@ else { | ||
} | ||
return _this; | ||
} | ||
SensiletSigner.prototype.getSensilet = function () { | ||
async getConnectedTarget() { | ||
if (!this._target.isConnect()) { | ||
// trigger connecting to sensilet account when it's not connected. | ||
this._address = await this._target.requestAccount(); | ||
} | ||
return this._target; | ||
}; | ||
SensiletSigner.prototype.isConnected = function () { | ||
return this._target.isConnect(); | ||
}; | ||
} | ||
// Do not allow switch provider. | ||
SensiletSigner.prototype.connect = function (provider) { | ||
connect(provider) { | ||
throw new Error("Method #connect not implemented."); | ||
}; | ||
SensiletSigner.prototype.getBalance = function (address) { | ||
// default implemention using provider, can be overrided. | ||
return this._target.getBsvBalance().then(function (r) { return r.balance; }); | ||
}; | ||
SensiletSigner.prototype.getDefaultPubKey = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var pubKey; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this._target.getPublicKey()]; | ||
case 1: | ||
pubKey = _a.sent(); | ||
return [2 /*return*/, Promise.resolve(new dist_1.bsv.PublicKey(pubKey))]; | ||
} | ||
}); | ||
} | ||
async getDefaultPubKey() { | ||
const pubKey = await this._target.getPublicKey(); | ||
return Promise.resolve(new dist_1.bsv.PublicKey(pubKey)); | ||
} | ||
async getPubKey(address) { | ||
throw new Error(`Method ${this.constructor.name}#getPubKey not implemented.`); | ||
} | ||
signRawTransaction(rawTxHex, options) { | ||
throw new Error(`Method ${this.constructor.name}#signRawTransaction not implemented.`); | ||
} | ||
async signTransaction(tx, options) { | ||
if (options?.address) { | ||
throw new Error(`${this.constructor.name}#signTransaction with \`options.address\` param is not supported`); | ||
} | ||
const sigRequests = tx.inputs.map((input, inputIndex) => { | ||
const useAddressToSign = input.output?.script.isPublicKeyHashOut() | ||
? input.output.script.toAddress() | ||
: this._address; | ||
return { | ||
inputIndex, | ||
satoshis: input.output?.satoshis, | ||
address: useAddressToSign, | ||
scriptHex: input.output?.script?.toHex(), | ||
sigHashType: DEFAULT_SIGHASH_TYPE, // TODO: get value from options | ||
}; | ||
}); | ||
}; | ||
SensiletSigner.prototype.getPubKey = function (address) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
throw new Error("Method ".concat(this.constructor.name, "#getPubKey not implemented.")); | ||
}); | ||
const sigResponses = await this.getSignatures(tx.toString(), sigRequests); | ||
tx.inputs.forEach((input, inputIndex) => { | ||
// TODO: multisig? | ||
const sigResp = sigResponses.find(sigResp => sigResp.inputIndex === inputIndex); | ||
if (sigResp && input.output?.script.isPublicKeyHashOut()) { | ||
input.setScript(dist_1.bsv.Script.buildPublicKeyHashIn(dist_1.bsv.PublicKey.fromString(sigResp.publicKey), dist_1.bsv.crypto.Signature.fromString(sigResp.sig), DEFAULT_SIGHASH_TYPE)); | ||
} | ||
}); | ||
}; | ||
SensiletSigner.prototype.signRawTransaction = function (rawTxHex, options) { | ||
throw new Error("Method ".concat(this.constructor.name, "#signRawTransaction not implemented.")); | ||
}; | ||
SensiletSigner.prototype.signTransaction = function (tx, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var sigRequests, sigResponses; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
sigRequests = tx.inputs.map(function (input, inputIndex) { | ||
var _a, _b, _c, _d; | ||
var useAddressToSign = ((_a = input.output) === null || _a === void 0 ? void 0 : _a.script.isPublicKeyHashOut()) | ||
? input.output.script.toAddress(_this.provider.getNetwork()) | ||
: _this._address; | ||
return { | ||
inputIndex: inputIndex, | ||
satoshis: (_b = input.output) === null || _b === void 0 ? void 0 : _b.satoshis, | ||
address: useAddressToSign, | ||
scriptHex: (_d = (_c = input.output) === null || _c === void 0 ? void 0 : _c.script) === null || _d === void 0 ? void 0 : _d.toHex(), | ||
sigHashType: DEFAULT_SIGHASH_TYPE, // TODO: get value from options | ||
}; | ||
}); | ||
return [4 /*yield*/, this.getSignatures(tx.toString(), sigRequests)]; | ||
case 1: | ||
sigResponses = _a.sent(); | ||
tx.inputs.forEach(function (input, inputIndex) { | ||
var _a; | ||
// TODO: multisig? | ||
var sigResp = sigResponses.find(function (sigResp) { return sigResp.inputIndex === inputIndex; }); | ||
if (sigResp && ((_a = input.output) === null || _a === void 0 ? void 0 : _a.script.isPublicKeyHashOut())) { | ||
input.setScript(dist_1.bsv.Script.buildPublicKeyHashIn(dist_1.bsv.PublicKey.fromString(sigResp.publicKey), dist_1.bsv.crypto.Signature.fromString(sigResp.sig), DEFAULT_SIGHASH_TYPE)); | ||
} | ||
}); | ||
return [2 /*return*/, tx]; | ||
} | ||
return tx; | ||
} | ||
async signMessage(message, address) { | ||
if (address) { | ||
throw new Error(`${this.constructor.name}#signMessge with \`address\` param is not supported!`); | ||
} | ||
return (await this.getConnectedTarget()).signMessage(message); | ||
} | ||
async getSignatures(rawTxHex, sigRequests) { | ||
const inputInfos = sigRequests.flatMap((sigReq) => { | ||
const addresses = (0, utils_1.addressesToList)(sigReq.address); | ||
return addresses.map(address => { | ||
return { | ||
inputIndex: sigReq.inputIndex, | ||
scriptHex: sigReq.scriptHex || dist_1.bsv.Script.buildPublicKeyHashOut(address).toHex(), | ||
satoshis: sigReq.satoshis, | ||
sighashType: sigReq.sigHashType || DEFAULT_SIGHASH_TYPE, | ||
address, | ||
}; | ||
}); | ||
}); | ||
}; | ||
SensiletSigner.prototype.signMessage = function (message, address) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
if (address) { | ||
throw new Error("".concat(this.constructor.name, "#signMessge with `address` param is not supported!")); | ||
} | ||
return [2 /*return*/, this.getSensilet().signMessage(message)]; | ||
}); | ||
const sigResults = await (await this.getConnectedTarget()).signTransaction(rawTxHex, inputInfos); | ||
return inputInfos.map((inputInfo, idx) => { | ||
return { | ||
inputIndex: inputInfo.inputIndex, | ||
sig: sigResults[idx].sig, | ||
publicKey: sigResults[idx].publicKey | ||
}; | ||
}); | ||
}; | ||
SensiletSigner.prototype.getSignatures = function (rawTxHex, sigRequests) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var inputInfos, sigResults; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
inputInfos = sigRequests.flatMap(function (sigReq) { | ||
var addresses = (0, utils_1.addressesToList)(sigReq.address); | ||
return addresses.map(function (address) { | ||
return { | ||
inputIndex: sigReq.inputIndex, | ||
scriptHex: sigReq.scriptHex || dist_1.bsv.Script.buildPublicKeyHashOut(address).toHex(), | ||
satoshis: sigReq.satoshis, | ||
sighashType: sigReq.sigHashType || DEFAULT_SIGHASH_TYPE, | ||
address: address, | ||
}; | ||
}); | ||
}); | ||
return [4 /*yield*/, this.getSensilet().signTransaction(rawTxHex, inputInfos)]; | ||
case 1: | ||
sigResults = _a.sent(); | ||
return [2 /*return*/, inputInfos.map(function (inputInfo, idx) { | ||
return { | ||
inputIndex: inputInfo.inputIndex, | ||
sig: sigResults[idx].sig, | ||
publicKey: sigResults[idx].publicKey | ||
}; | ||
})]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return SensiletSigner; | ||
}(abstract_signer_1.Signer)); | ||
} | ||
} | ||
exports.SensiletSigner = SensiletSigner; | ||
var SensiletProvider = /** @class */ (function (_super) { | ||
__extends(SensiletProvider, _super); | ||
function SensiletProvider() { | ||
var _this = _super.call(this) || this; | ||
_this._signer = new SensiletSigner(_this); | ||
_this._delegatedProvider = new whatsonchain_provider_1.WhatsonchainProvider(dist_1.bsv.Networks.testnet); | ||
return _this; | ||
class SensiletProvider extends abstract_provider_1.Provider { | ||
constructor(provider) { | ||
super(); | ||
this._delegatedProvider = provider; | ||
} | ||
// Providers methods | ||
SensiletProvider.prototype.getNetwork = function () { | ||
getNetwork() { | ||
return this._delegatedProvider.getNetwork(); | ||
}; | ||
SensiletProvider.prototype.getFeePerKb = function () { | ||
} | ||
getFeePerKb() { | ||
return this._delegatedProvider.getFeePerKb(); | ||
}; | ||
SensiletProvider.prototype.sendRawTransaction = function (rawTxHex) { | ||
} | ||
sendRawTransaction(rawTxHex) { | ||
return this._delegatedProvider.sendRawTransaction(rawTxHex); | ||
}; | ||
SensiletProvider.prototype.getTransaction = function (txHash) { | ||
} | ||
getTransaction(txHash) { | ||
return this._delegatedProvider.getTransaction(txHash); | ||
}; | ||
SensiletProvider.prototype.listUnspent = function (address, options) { | ||
} | ||
listUnspent(address, options) { | ||
return this._delegatedProvider.listUnspent(address, options); | ||
}; | ||
SensiletProvider.prototype.getBalance = function (address) { | ||
return this._signer.getBalance(); | ||
}; | ||
SensiletProvider.prototype.getContractUTXOs = function (genesisTxHash, outputIndex) { | ||
} | ||
getBalance(address) { | ||
return this._delegatedProvider.getBalance(address); | ||
} | ||
getContractUTXOs(genesisTxHash, outputIndex) { | ||
return this._delegatedProvider.getContractUTXOs(genesisTxHash, outputIndex); | ||
}; | ||
} | ||
// Singer | ||
SensiletProvider.prototype.getSigner = function () { | ||
return this._signer; | ||
}; | ||
SensiletProvider.DEBUG_TAG = 'Sensilet'; | ||
return SensiletProvider; | ||
}(abstract_provider_1.Provider)); | ||
getSigner() { | ||
return new SensiletSigner(this); | ||
} | ||
} | ||
exports.SensiletProvider = SensiletProvider; | ||
SensiletProvider.DEBUG_TAG = 'Sensilet'; | ||
//# sourceMappingURL=sensilet-provider.js.map |
@@ -12,3 +12,3 @@ import { Networks, Address } from "bsv"; | ||
listUnspent(address: string | Address, options: UtxoQueryOptions): Promise<UTXO[]>; | ||
getBalance(address?: AddressOption): Promise<{ | ||
getBalance(address: AddressOption): Promise<{ | ||
confirmed: number; | ||
@@ -15,0 +15,0 @@ unconfirmed: number; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -58,87 +7,60 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.WhatsonchainProvider = void 0; | ||
var dist_1 = require("scryptlib/dist"); | ||
var abstract_provider_1 = require("../abstract-provider"); | ||
var axios_1 = __importDefault(require("axios")); | ||
var WhatsonchainProvider = /** @class */ (function (_super) { | ||
__extends(WhatsonchainProvider, _super); | ||
function WhatsonchainProvider(network) { | ||
var _this = _super.call(this) || this; | ||
_this._network = network; | ||
return _this; | ||
const dist_1 = require("scryptlib/dist"); | ||
const abstract_provider_1 = require("../abstract-provider"); | ||
const axios_1 = __importDefault(require("axios")); | ||
class WhatsonchainProvider extends abstract_provider_1.Provider { | ||
constructor(network) { | ||
super(); | ||
this._network = network; | ||
} | ||
Object.defineProperty(WhatsonchainProvider.prototype, "apiPrefix", { | ||
get: function () { | ||
// TODO: check all avaiable networks | ||
var networkStr = this._network.name === dist_1.bsv.Networks.mainnet.name ? 'main' : 'test'; | ||
return "https://api.whatsonchain.com/v1/bsv/".concat(networkStr); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
WhatsonchainProvider.prototype.getNetwork = function () { | ||
get apiPrefix() { | ||
// TODO: check all avaiable networks | ||
const networkStr = this._network.name === dist_1.bsv.Networks.mainnet.name ? 'main' : 'test'; | ||
return `https://api.whatsonchain.com/v1/bsv/${networkStr}`; | ||
} | ||
getNetwork() { | ||
return this._network; | ||
}; | ||
WhatsonchainProvider.prototype.sendRawTransaction = function (rawTxHex) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var size, timeout, res, error_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
size = Math.max(1, rawTxHex.length / 2 / 1024); | ||
timeout = Math.max(10000, 1000 * size); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, axios_1.default.post("".concat(this.apiPrefix, "/tx/raw"), { txhex: rawTxHex }, { timeout: timeout })]; | ||
case 2: | ||
res = _a.sent(); | ||
return [2 /*return*/, res.data]; | ||
case 3: | ||
error_1 = _a.sent(); | ||
if (error_1.response && error_1.response.data === '66: insufficient priority') { | ||
throw new Error("Rejected by miner. Transaction with fee is too low"); | ||
} | ||
throw new Error('Whatsonchain provider sendRawTransaction error: '); | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
WhatsonchainProvider.prototype.listUnspent = function (address, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var data, utxos; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, axios_1.default.get("".concat(this.apiPrefix, "/address/").concat(address, "/unspent"))]; | ||
case 1: | ||
data = (_a.sent()).data; | ||
utxos = data.map(function (item) { return ({ | ||
txId: item.tx_hash, | ||
outputIndex: item.tx_pos, | ||
satoshis: item.value, | ||
script: dist_1.bsv.Script.buildPublicKeyHashOut(address).toHex(), | ||
}); }); | ||
if ((options === null || options === void 0 ? void 0 : options.minSatoshis) && utxos.reduce(function (s, u) { return s + u.satoshis; }, 0) < options.minSatoshis) { | ||
throw new Error("not enough utxos for the request amount of ".concat(options.minSatoshis, " on address ").concat(address.toString())); | ||
} | ||
return [2 /*return*/, utxos]; | ||
} | ||
}); | ||
}); | ||
}; | ||
WhatsonchainProvider.prototype.getBalance = function (address) { | ||
} | ||
async sendRawTransaction(rawTxHex) { | ||
// 1 second per KB | ||
const size = Math.max(1, rawTxHex.length / 2 / 1024); //KB | ||
const timeout = Math.max(10000, 1000 * size); | ||
try { | ||
const res = await axios_1.default.post(`${this.apiPrefix}/tx/raw`, { txhex: rawTxHex }, { timeout }); | ||
return res.data; | ||
} | ||
catch (error) { | ||
if (error.response && error.response.data === '66: insufficient priority') { | ||
throw new Error(`Rejected by miner. Transaction with fee is too low`); | ||
} | ||
throw new Error('Whatsonchain provider sendRawTransaction error: '); | ||
} | ||
} | ||
async listUnspent(address, options) { | ||
const { data } = await axios_1.default.get(`${this.apiPrefix}/address/${address}/unspent`); | ||
const utxos = data.map(item => ({ | ||
txId: item.tx_hash, | ||
outputIndex: item.tx_pos, | ||
satoshis: item.value, | ||
script: dist_1.bsv.Script.buildPublicKeyHashOut(address).toHex(), | ||
})); | ||
if (options?.minSatoshis && utxos.reduce((s, u) => s + u.satoshis, 0) < options.minSatoshis) { | ||
throw new Error(`not enough utxos for the request amount of ${options.minSatoshis} on address ${address.toString()}`); | ||
} | ||
return utxos; | ||
} | ||
async getBalance(address) { | ||
throw new Error("Method not implemented."); | ||
}; | ||
WhatsonchainProvider.prototype.getTransaction = function (txHash) { | ||
} | ||
getTransaction(txHash) { | ||
throw new Error("Method not implemented."); | ||
}; | ||
WhatsonchainProvider.prototype.getContractUTXOs = function (genesisTxHash, outputIndex) { | ||
} | ||
getContractUTXOs(genesisTxHash, outputIndex) { | ||
throw new Error("Method #getContractUTXOs not implemented in WhatsonchainProvider."); | ||
}; | ||
WhatsonchainProvider.prototype.getFeePerKb = function () { | ||
} | ||
getFeePerKb() { | ||
return 50; | ||
}; | ||
return WhatsonchainProvider; | ||
}(abstract_provider_1.Provider)); | ||
} | ||
} | ||
exports.WhatsonchainProvider = WhatsonchainProvider; | ||
//# sourceMappingURL=whatsonchain-provider.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.addressesToList = exports.utxoFromOutput = exports.getRandomAddress = exports.getDummyP2pkhUTXOs = void 0; | ||
var scryptlib_1 = require("scryptlib"); | ||
var crypto_1 = require("crypto"); | ||
function getDummyP2pkhUTXOs(count) { | ||
if (count === void 0) { count = 1; } | ||
return Array(count).map(function (_) { | ||
const scryptlib_1 = require("scryptlib"); | ||
const crypto_1 = require("crypto"); | ||
function getDummyP2pkhUTXOs(count = 1) { | ||
return Array(count).map(_ => { | ||
return { | ||
@@ -18,4 +17,3 @@ txId: (0, crypto_1.randomBytes)(32).toString('hex'), | ||
exports.getDummyP2pkhUTXOs = getDummyP2pkhUTXOs; | ||
function getRandomAddress(network) { | ||
if (network === void 0) { network = scryptlib_1.bsv.Networks.testnet; } | ||
function getRandomAddress(network = scryptlib_1.bsv.Networks.testnet) { | ||
return scryptlib_1.bsv.Address.fromPrivateKey(scryptlib_1.bsv.PrivateKey.fromRandom(network.name), network); | ||
@@ -25,9 +23,9 @@ } | ||
function utxoFromOutput(tx, outputIndex) { | ||
var output = tx.outputs[outputIndex]; | ||
const output = tx.outputs[outputIndex]; | ||
if (!output) { | ||
throw new Error("outputIndex ".concat(outputIndex, " does not exist on tx ").concat(tx.id)); | ||
throw new Error(`outputIndex ${outputIndex} does not exist on tx ${tx.id}`); | ||
} | ||
return { | ||
txId: tx.id, | ||
outputIndex: outputIndex, | ||
outputIndex, | ||
script: output.script.toHex(), | ||
@@ -39,5 +37,5 @@ satoshis: output.satoshis | ||
function addressesToList(addresses) { | ||
return Array.from([addresses]).flat().map(function (addr) { return addr.toString(); }); | ||
return Array.from([addresses]).flat().map(addr => addr.toString()); | ||
} | ||
exports.addressesToList = addressesToList; | ||
//# sourceMappingURL=utils.js.map |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestWallet = void 0; | ||
var abstract_signer_1 = require("../abstract-signer"); | ||
var dist_1 = require("scryptlib/dist"); | ||
const abstract_signer_1 = require("../abstract-signer"); | ||
const dist_1 = require("scryptlib/dist"); | ||
/** | ||
@@ -63,90 +12,61 @@ * An implemention of a simple wallet which should just be used in dev/test environments. | ||
*/ | ||
var TestWallet = /** @class */ (function (_super) { | ||
__extends(TestWallet, _super); | ||
function TestWallet(privateKey, provider) { | ||
var _this = _super.call(this, provider) || this; | ||
class TestWallet extends abstract_signer_1.Signer { | ||
constructor(privateKey, provider) { | ||
super(provider); | ||
if (privateKey instanceof Array) { | ||
_this._privateKeys = privateKey; | ||
this._privateKeys = privateKey; | ||
} | ||
else { | ||
_this._privateKeys = [privateKey]; | ||
this._privateKeys = [privateKey]; | ||
} | ||
_this._utxoManagers = new Map(); | ||
return _this; | ||
this._utxoManagers = new Map(); | ||
} | ||
Object.defineProperty(TestWallet.prototype, "network", { | ||
get: function () { | ||
var _a; | ||
return ((_a = this.provider) === null || _a === void 0 ? void 0 : _a.getNetwork()) || dist_1.bsv.Networks.testnet; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(TestWallet.prototype, "addresses", { | ||
get: function () { | ||
var _this = this; | ||
return this._privateKeys.map(function (p) { return p.toAddress(_this.network).toString(); }); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
TestWallet.prototype.getDefaultPubKey = function () { | ||
get network() { | ||
return this.provider?.getNetwork() || dist_1.bsv.Networks.testnet; | ||
} | ||
get addresses() { | ||
return this._privateKeys.map(p => p.toAddress(this.network).toString()); | ||
} | ||
getDefaultPubKey() { | ||
return Promise.resolve(this._defaultPrivateKey.toPublicKey()); | ||
}; | ||
TestWallet.prototype.getPubKey = function (address) { | ||
} | ||
getPubKey(address) { | ||
return Promise.resolve(this._getPrivateKeys(address)[0].toPublicKey()); | ||
}; | ||
TestWallet.prototype.signRawTransaction = function (rawTxHex, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var sigReqsByInputIndex, tx, signedTx; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
sigReqsByInputIndex = ((options === null || options === void 0 ? void 0 : options.sigRequests) || []).reduce(function (m, sigReq) { m.set(sigReq.inputIndex, sigReq); return m; }, new Map()); | ||
tx = new dist_1.bsv.Transaction(rawTxHex); | ||
tx.inputs.forEach(function (_, inputIndex) { | ||
var sigReq = sigReqsByInputIndex.get(inputIndex); | ||
if (!sigReq) { | ||
throw new Error("`SignatureRequest` info should be provided for the input ".concat(inputIndex, " to call #signRawTransaction")); | ||
} | ||
var script = sigReq.scriptHex ? new dist_1.bsv.Script(sigReq.scriptHex) : dist_1.bsv.Script.buildPublicKeyHashOut(sigReq.address.toString()); | ||
// set ref output of the input | ||
tx.inputs[inputIndex].output = new dist_1.bsv.Transaction.Output({ | ||
script: script, | ||
satoshis: sigReq.satoshis | ||
}); | ||
}); | ||
return [4 /*yield*/, this.signTransaction(tx, options)]; | ||
case 1: | ||
signedTx = _a.sent(); | ||
return [2 /*return*/, signedTx.toString()]; | ||
} | ||
} | ||
async signRawTransaction(rawTxHex, options) { | ||
const sigReqsByInputIndex = (options?.sigRequests || []).reduce((m, sigReq) => { m.set(sigReq.inputIndex, sigReq); return m; }, new Map()); | ||
const tx = new dist_1.bsv.Transaction(rawTxHex); | ||
tx.inputs.forEach((_, inputIndex) => { | ||
const sigReq = sigReqsByInputIndex.get(inputIndex); | ||
if (!sigReq) { | ||
throw new Error(`\`SignatureRequest\` info should be provided for the input ${inputIndex} to call #signRawTransaction`); | ||
} | ||
const script = sigReq.scriptHex ? new dist_1.bsv.Script(sigReq.scriptHex) : dist_1.bsv.Script.buildPublicKeyHashOut(sigReq.address.toString()); | ||
// set ref output of the input | ||
tx.inputs[inputIndex].output = new dist_1.bsv.Transaction.Output({ | ||
script, | ||
satoshis: sigReq.satoshis | ||
}); | ||
}); | ||
}; | ||
TestWallet.prototype.signTransaction = function (tx, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var addresses; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
addresses = options === null || options === void 0 ? void 0 : options.address; | ||
this._checkAddressOption(addresses); | ||
tx.outputs.forEach(function (output, outputIndex) { | ||
_this._utxoManagers.forEach(function (mgr) { | ||
mgr.collectUtxoFrom(output, tx.id, outputIndex); | ||
}); | ||
}); | ||
// TODO: take account of SignatureRequests in options. | ||
return [2 /*return*/, Promise.resolve(tx.sign(this._getPrivateKeys(addresses)))]; | ||
const signedTx = await this.signTransaction(tx, options); | ||
return signedTx.toString(); | ||
} | ||
async signTransaction(tx, options) { | ||
const addresses = options?.address; | ||
this._checkAddressOption(addresses); | ||
tx.outputs.forEach((output, outputIndex) => { | ||
this._utxoManagers.forEach(mgr => { | ||
mgr.collectUtxoFrom(output, tx.id, outputIndex); | ||
}); | ||
}); | ||
}; | ||
TestWallet.prototype.signMessage = function (message, address) { | ||
// TODO: take account of SignatureRequests in options. | ||
return Promise.resolve(tx.sign(this._getPrivateKeys(addresses))); | ||
} | ||
signMessage(message, address) { | ||
throw new Error("Method #signMessage not implemented."); | ||
}; | ||
TestWallet.prototype.getSignatures = function (rawTxHex, sigRequests) { | ||
var _this = this; | ||
} | ||
getSignatures(rawTxHex, sigRequests) { | ||
this._checkAddressOption(this._getAddressesIn(sigRequests)); | ||
var tx = new dist_1.bsv.Transaction(rawTxHex); | ||
var sigResponses = sigRequests.flatMap(function (sigReq) { | ||
const tx = new dist_1.bsv.Transaction(rawTxHex); | ||
const sigResponses = sigRequests.flatMap(sigReq => { | ||
tx.inputs[sigReq.inputIndex].output = new dist_1.bsv.Transaction.Output({ | ||
@@ -157,5 +77,5 @@ // TODO: support multiSig? | ||
}); | ||
var privkeys = _this._getPrivateKeys(sigReq.address); | ||
return privkeys.map(function (privKey) { | ||
var sig = tx.getSignature(sigReq.inputIndex, privKey, sigReq.sigHashType); | ||
const privkeys = this._getPrivateKeys(sigReq.address); | ||
return privkeys.map(privKey => { | ||
const sig = tx.getSignature(sigReq.inputIndex, privKey, sigReq.sigHashType); | ||
return { | ||
@@ -169,29 +89,19 @@ sig: sig, | ||
return Promise.resolve(sigResponses); | ||
}; | ||
TestWallet.prototype.connect = function (provider) { | ||
} | ||
connect(provider) { | ||
return new TestWallet(this._privateKeys, provider); | ||
}; | ||
TestWallet.prototype.listUnspent = function (address, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var utxoManager; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
utxoManager = this._utxoManagers.get(address.toString()); | ||
if (!!utxoManager) return [3 /*break*/, 2]; | ||
utxoManager = new CacheableUtxoManager(address, this); | ||
this._utxoManagers.set(address.toString(), utxoManager); | ||
return [4 /*yield*/, utxoManager.init()]; | ||
case 1: | ||
_a.sent(); | ||
_a.label = 2; | ||
case 2: return [2 /*return*/, utxoManager.fetchUtxos(options === null || options === void 0 ? void 0 : options.minSatoshis)]; | ||
} | ||
}); | ||
}); | ||
}; | ||
TestWallet.prototype._getAddressesIn = function (sigRequests) { | ||
return (sigRequests || []).flatMap(function (req) { | ||
} | ||
async listUnspent(address, options) { | ||
let utxoManager = this._utxoManagers.get(address.toString()); | ||
if (!utxoManager) { | ||
utxoManager = new CacheableUtxoManager(address, this); | ||
this._utxoManagers.set(address.toString(), utxoManager); | ||
await utxoManager.init(); | ||
} | ||
return utxoManager.fetchUtxos(options?.minSatoshis); | ||
} | ||
_getAddressesIn(sigRequests) { | ||
return (sigRequests || []).flatMap((req) => { | ||
if (req.address instanceof Array) { | ||
return req.address.map(function (addr) { return addr.toString(); }); | ||
return req.address.map(addr => addr.toString()); | ||
} | ||
@@ -202,31 +112,25 @@ else { | ||
}); | ||
}; | ||
TestWallet.prototype._checkAddressOption = function (address) { | ||
var _this = this; | ||
} | ||
_checkAddressOption(address) { | ||
if (!address) | ||
return; | ||
if (address instanceof Array) { | ||
address.forEach(function (address) { return _this._checkAddressOption(address); }); | ||
address.forEach(address => this._checkAddressOption(address)); | ||
} | ||
else { | ||
if (!this.addresses.includes(address.toString())) { | ||
throw new Error("the address ".concat(address.toString(), " is not belong to this SimpleWallet")); | ||
throw new Error(`the address ${address.toString()} is not belong to this SimpleWallet`); | ||
} | ||
} | ||
}; | ||
Object.defineProperty(TestWallet.prototype, "_defaultPrivateKey", { | ||
get: function () { | ||
return this._privateKeys[0]; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
TestWallet.prototype._getPrivateKeys = function (address) { | ||
var _this = this; | ||
} | ||
get _defaultPrivateKey() { | ||
return this._privateKeys[0]; | ||
} | ||
_getPrivateKeys(address) { | ||
if (!address) | ||
return [this._defaultPrivateKey]; | ||
this._checkAddressOption(address); | ||
var addresses = []; | ||
let addresses = []; | ||
if (address instanceof Array) { | ||
address.forEach(function (addr) { return addresses.push(addr.toString()); }); | ||
address.forEach(addr => addresses.push(addr.toString())); | ||
} | ||
@@ -236,6 +140,5 @@ else { | ||
} | ||
return this._privateKeys.filter(function (priv) { return addresses.includes(priv.toAddress(_this.network).toString()); }); | ||
}; | ||
return TestWallet; | ||
}(abstract_signer_1.Signer)); | ||
return this._privateKeys.filter(priv => addresses.includes(priv.toAddress(this.network).toString())); | ||
} | ||
} | ||
exports.TestWallet = TestWallet; | ||
@@ -249,4 +152,4 @@ var InitState; | ||
; | ||
var CacheableUtxoManager = /** @class */ (function () { | ||
function CacheableUtxoManager(address, signer) { | ||
class CacheableUtxoManager { | ||
constructor(address, signer) { | ||
this.availableUtxos = []; | ||
@@ -258,118 +161,90 @@ this.initStates = InitState.UNINITIALIZED; | ||
} | ||
CacheableUtxoManager.prototype.init = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (this.initStates === InitState.INITIALIZED) { | ||
return [2 /*return*/, this]; | ||
} | ||
if (!(this.initStates === InitState.UNINITIALIZED)) return [3 /*break*/, 2]; | ||
this.initStates = InitState.INITIALIZING; | ||
_a = this; | ||
return [4 /*yield*/, this.signer.connectedProvider.listUnspent(this.address)]; | ||
case 1: | ||
_a.availableUtxos = _b.sent(); | ||
this.initStates = InitState.INITIALIZED; | ||
this.initUtxoCnt = this.availableUtxos.length; | ||
console.log("current balance of address ".concat(this.address, " is ").concat(this.availableUtxos.reduce(function (r, utxo) { return r + utxo.satoshis; }, 0), " satoshis")); | ||
_b.label = 2; | ||
case 2: | ||
if (!(this.initStates === InitState.INITIALIZING)) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, sleep(1)]; | ||
case 3: | ||
_b.sent(); | ||
return [3 /*break*/, 2]; | ||
case 4: return [2 /*return*/, this]; | ||
async init() { | ||
if (this.initStates === InitState.INITIALIZED) { | ||
return this; | ||
} | ||
if (this.initStates === InitState.UNINITIALIZED) { | ||
this.initStates = InitState.INITIALIZING; | ||
this.availableUtxos = await this.signer.connectedProvider.listUnspent(this.address); | ||
this.initStates = InitState.INITIALIZED; | ||
this.initUtxoCnt = this.availableUtxos.length; | ||
console.log(`current balance of address ${this.address} is ${this.availableUtxos.reduce((r, utxo) => r + utxo.satoshis, 0)} satoshis`); | ||
} | ||
while (this.initStates === InitState.INITIALIZING) { | ||
await sleep(1); | ||
} | ||
return this; | ||
} | ||
async fetchUtxos(targetSatoshis) { | ||
if (this.initStates === InitState.INITIALIZED | ||
&& this.initUtxoCnt > 0 | ||
&& this.availableUtxos.length === 0) { | ||
const timeoutSec = 30; | ||
for (let i = 0; i < timeoutSec; i++) { | ||
console.log('waiting for available utxos'); | ||
await sleep(1); | ||
if (this.availableUtxos.length > 0) { | ||
break; | ||
} | ||
}); | ||
}); | ||
}; | ||
CacheableUtxoManager.prototype.fetchUtxos = function (targetSatoshis) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var timeoutSec, i, allUtxos, sortedUtxos, idx, accAmt, i, usedUtxos, dustLimit, splitTx, txId; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(this.initStates === InitState.INITIALIZED | ||
&& this.initUtxoCnt > 0 | ||
&& this.availableUtxos.length === 0)) return [3 /*break*/, 4]; | ||
timeoutSec = 30; | ||
i = 0; | ||
_a.label = 1; | ||
case 1: | ||
if (!(i < timeoutSec)) return [3 /*break*/, 4]; | ||
console.log('waiting for available utxos'); | ||
return [4 /*yield*/, sleep(1)]; | ||
case 2: | ||
_a.sent(); | ||
if (this.availableUtxos.length > 0) { | ||
return [3 /*break*/, 4]; | ||
} | ||
_a.label = 3; | ||
case 3: | ||
i++; | ||
return [3 /*break*/, 1]; | ||
case 4: | ||
if (targetSatoshis === undefined) { | ||
allUtxos = this.availableUtxos; | ||
this.availableUtxos = []; | ||
return [2 /*return*/, allUtxos]; | ||
} | ||
sortedUtxos = this.availableUtxos.sort(function (a, b) { return a.satoshis - b.satoshis; }); | ||
if (targetSatoshis > sortedUtxos.reduce(function (r, utxo) { return r + utxo.satoshis; }, 0)) { | ||
throw new Error('no sufficient utxos to pay the fee of ' + targetSatoshis); | ||
} | ||
idx = 0; | ||
accAmt = 0; | ||
for (i = 0; i < sortedUtxos.length; i++) { | ||
accAmt += sortedUtxos[i].satoshis; | ||
if (accAmt >= targetSatoshis) { | ||
idx = i; | ||
break; | ||
} | ||
} | ||
usedUtxos = sortedUtxos.slice(0, idx + 1); | ||
// update the available utxos, remove used ones | ||
this.availableUtxos = sortedUtxos.slice(idx + 1); | ||
dustLimit = 1; | ||
if (!(accAmt > targetSatoshis + dustLimit)) return [3 /*break*/, 6]; | ||
splitTx = new dist_1.bsv.Transaction().from(usedUtxos) | ||
.addOutput(new dist_1.bsv.Transaction.Output({ | ||
script: dist_1.bsv.Script.buildPublicKeyHashOut(this.address), | ||
satoshis: targetSatoshis | ||
})) | ||
.change(this.address); | ||
return [4 /*yield*/, this.signer.signAndsendTransaction(splitTx)]; | ||
case 5: | ||
txId = (_a.sent()).id; | ||
// update the available utxos, add the new created on as the change | ||
if (splitTx.outputs.length === 2) { | ||
this.availableUtxos = this.availableUtxos.concat({ | ||
txId: txId, | ||
outputIndex: 1, | ||
script: splitTx.outputs[1].script.toHex(), | ||
satoshis: splitTx.outputs[1].satoshis | ||
}); | ||
} | ||
// return the new created utxo which has value of `targetSatoshis` | ||
return [2 /*return*/, [ | ||
{ | ||
txId: txId, | ||
outputIndex: 0, | ||
script: splitTx.outputs[0].script.toHex(), | ||
satoshis: splitTx.outputs[0].satoshis, | ||
} | ||
]]; | ||
case 6: return [2 /*return*/, usedUtxos]; | ||
} | ||
} | ||
if (targetSatoshis === undefined) { | ||
const allUtxos = this.availableUtxos; | ||
this.availableUtxos = []; | ||
return allUtxos; | ||
} | ||
const sortedUtxos = this.availableUtxos.sort((a, b) => a.satoshis - b.satoshis); | ||
if (targetSatoshis > sortedUtxos.reduce((r, utxo) => r + utxo.satoshis, 0)) { | ||
throw new Error('no sufficient utxos to pay the fee of ' + targetSatoshis); | ||
} | ||
let idx = 0; | ||
let accAmt = 0; | ||
for (let i = 0; i < sortedUtxos.length; i++) { | ||
accAmt += sortedUtxos[i].satoshis; | ||
if (accAmt >= targetSatoshis) { | ||
idx = i; | ||
break; | ||
} | ||
} | ||
const usedUtxos = sortedUtxos.slice(0, idx + 1); | ||
// update the available utxos, remove used ones | ||
this.availableUtxos = sortedUtxos.slice(idx + 1); | ||
const dustLimit = 1; | ||
if (accAmt > targetSatoshis + dustLimit) { | ||
// split `accAmt` to `targetSatoshis` + `change` | ||
const splitTx = new dist_1.bsv.Transaction().from(usedUtxos) | ||
.addOutput(new dist_1.bsv.Transaction.Output({ | ||
script: dist_1.bsv.Script.buildPublicKeyHashOut(this.address), | ||
satoshis: targetSatoshis | ||
})) | ||
.change(this.address); // here generates a new available utxo for address | ||
const txId = (await this.signer.signAndsendTransaction(splitTx)).id; // sendTx(splitTx); | ||
// update the available utxos, add the new created on as the change | ||
if (splitTx.outputs.length === 2) { | ||
this.availableUtxos = this.availableUtxos.concat({ | ||
txId, | ||
outputIndex: 1, | ||
script: splitTx.outputs[1].script.toHex(), | ||
satoshis: splitTx.outputs[1].satoshis | ||
}); | ||
} | ||
// return the new created utxo which has value of `targetSatoshis` | ||
return [ | ||
{ | ||
txId, | ||
outputIndex: 0, | ||
script: splitTx.outputs[0].script.toHex(), | ||
satoshis: splitTx.outputs[0].satoshis, | ||
} | ||
}); | ||
}); | ||
}; | ||
CacheableUtxoManager.prototype.collectUtxoFrom = function (output, txId, outputIndex) { | ||
]; | ||
} | ||
else { | ||
return usedUtxos; | ||
} | ||
} | ||
collectUtxoFrom(output, txId, outputIndex) { | ||
if (output.script.toHex() === this.utxoScriptHex) { | ||
this.availableUtxos.push({ | ||
txId: txId, | ||
outputIndex: outputIndex, | ||
txId, | ||
outputIndex, | ||
satoshis: output.satoshis, | ||
@@ -379,22 +254,15 @@ script: output.script.toHex() | ||
} | ||
}; | ||
Object.defineProperty(CacheableUtxoManager.prototype, "utxoScriptHex", { | ||
get: function () { | ||
// all managed utxos should have the same P2PKH script for `this.address` | ||
return dist_1.bsv.Script.buildPublicKeyHashOut(this.address).toHex(); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
} | ||
get utxoScriptHex() { | ||
// all managed utxos should have the same P2PKH script for `this.address` | ||
return dist_1.bsv.Script.buildPublicKeyHashOut(this.address).toHex(); | ||
} | ||
} | ||
const sleep = async (seconds) => { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve({}); | ||
}, seconds * 1000); | ||
}); | ||
return CacheableUtxoManager; | ||
}()); | ||
var sleep = function (seconds) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, new Promise(function (resolve) { | ||
setTimeout(function () { | ||
resolve({}); | ||
}, seconds * 1000); | ||
})]; | ||
}); | ||
}); }; | ||
}; | ||
//# sourceMappingURL=test-wallet.js.map |
@@ -12,6 +12,4 @@ import { prop, method } from './smart-contract/decorators'; | ||
export { WhatsonchainProvider } from './bsv/providers/whatsonchain-provider'; | ||
export { SensiletProvider, SensiletSigner } from './bsv/providers/sensilet-provider'; | ||
export { Provider, TransactionResponse, TxHash } from './bsv/abstract-provider'; | ||
export { Signer, SignatureRequest, SignTransactionOptions, SignatureResponse, SignerError } from './bsv/abstract-signer'; | ||
export { SensiletProvider } from './bsv/providers/sensilet-provider'; | ||
export * from './bsv/abstract-signer'; | ||
export { TestWallet } from './bsv/wallets/test-wallet'; |
@@ -17,9 +17,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestWallet = exports.Signer = exports.Provider = exports.SensiletSigner = exports.SensiletProvider = exports.WhatsonchainProvider = exports.FunctionCall = exports.buildOpreturnScript = exports.buildPublicKeyHashScript = exports.toHex = exports.bsv = exports.SmartContractLib = exports.SmartContract = exports.method = exports.prop = void 0; | ||
var decorators_1 = require("./smart-contract/decorators"); | ||
exports.TestWallet = exports.SensiletProvider = exports.WhatsonchainProvider = exports.FunctionCall = exports.buildOpreturnScript = exports.buildPublicKeyHashScript = exports.toHex = exports.bsv = exports.SmartContractLib = exports.SmartContract = exports.method = exports.prop = void 0; | ||
const decorators_1 = require("./smart-contract/decorators"); | ||
Object.defineProperty(exports, "prop", { enumerable: true, get: function () { return decorators_1.prop; } }); | ||
Object.defineProperty(exports, "method", { enumerable: true, get: function () { return decorators_1.method; } }); | ||
var contract_1 = require("./smart-contract/contract"); | ||
const contract_1 = require("./smart-contract/contract"); | ||
Object.defineProperty(exports, "SmartContract", { enumerable: true, get: function () { return contract_1.SmartContract; } }); | ||
var library_1 = require("./smart-contract/library"); | ||
const library_1 = require("./smart-contract/library"); | ||
Object.defineProperty(exports, "SmartContractLib", { enumerable: true, get: function () { return library_1.SmartContractLib; } }); | ||
@@ -42,7 +42,2 @@ __exportStar(require("./smart-contract/builtins/types"), exports); | ||
Object.defineProperty(exports, "SensiletProvider", { enumerable: true, get: function () { return sensilet_provider_1.SensiletProvider; } }); | ||
Object.defineProperty(exports, "SensiletSigner", { enumerable: true, get: function () { return sensilet_provider_1.SensiletSigner; } }); | ||
var abstract_provider_1 = require("./bsv/abstract-provider"); | ||
Object.defineProperty(exports, "Provider", { enumerable: true, get: function () { return abstract_provider_1.Provider; } }); | ||
var abstract_signer_1 = require("./bsv/abstract-signer"); | ||
Object.defineProperty(exports, "Signer", { enumerable: true, get: function () { return abstract_signer_1.Signer; } }); | ||
/* export Wallets */ | ||
@@ -49,0 +44,0 @@ __exportStar(require("./bsv/abstract-signer"), exports); |
@@ -134,2 +134,14 @@ import { SigHashType } from "scryptlib"; | ||
/** | ||
* @category bitwise | ||
*/ | ||
/** | ||
* @category bitwise | ||
*/ | ||
/** | ||
* @category bitwise | ||
*/ | ||
/** | ||
* @category bitwise | ||
*/ | ||
/** | ||
* @category bitshift | ||
@@ -136,0 +148,0 @@ */ |
@@ -5,4 +5,4 @@ "use strict"; | ||
exports.Constants = exports.Tx = exports.VarIntWriter = exports.VarIntReader = exports.SigHash = exports.Utils = exports.OpCode = exports.asm = exports.rshift = exports.lshift = exports.pow2 = exports.assert = exports.flattenSha256 = exports.hash256 = exports.hash160 = exports.sha256 = exports.sha1 = exports.ripemd160 = exports.within = exports.max = exports.min = exports.abs = exports.exit = exports.checkMultiSig = exports.reverseBytes = exports.len = exports.int2str = exports.unpack = exports.pack = exports.getSortedItem = exports.invert = exports.or = exports.xor = exports.and = void 0; | ||
var scryptlib_1 = require("scryptlib"); | ||
var types_1 = require("./types"); | ||
const scryptlib_1 = require("scryptlib"); | ||
const types_1 = require("./types"); | ||
var builtins_1 = require("scryptlib/dist/builtins"); | ||
@@ -20,3 +20,3 @@ Object.defineProperty(exports, "and", { enumerable: true, get: function () { return builtins_1.and; } }); | ||
function pack(n) { | ||
var num = new scryptlib_1.bsv.crypto.BN(n); | ||
const num = new scryptlib_1.bsv.crypto.BN(n); | ||
return num.toSM({ endian: 'little' }).toString('hex'); | ||
@@ -61,5 +61,5 @@ } | ||
function reverseBytes(b, size) { | ||
var l = len(b); | ||
let l = len(b); | ||
if (l != size) { | ||
throw new Error("reverseBytes error, expected c = ".concat(l)); | ||
throw new Error(`reverseBytes error, expected c = ${l}`); | ||
} | ||
@@ -202,3 +202,3 @@ return b.match(/[a-fA-F0-9]{2}/g).reverse().join(''); | ||
if (!condition) { | ||
var message = 'Execution failed' + (msg ? ", ".concat(msg) : ''); | ||
const message = 'Execution failed' + (msg ? `, ${msg}` : ''); | ||
throw new Error(message); | ||
@@ -220,9 +220,2 @@ } | ||
*/ | ||
function simplePow(x, y) { | ||
var calced = (0, scryptlib_1.Int)(1); | ||
for (var i = 0, e = y; i < e; i++) { | ||
calced *= x; | ||
} | ||
return calced; | ||
} | ||
/** | ||
@@ -232,3 +225,3 @@ * @category bitshift | ||
function pow2(n) { | ||
return simplePow((0, scryptlib_1.Int)(2), n); | ||
return 2n ** n; | ||
} | ||
@@ -250,4 +243,4 @@ exports.pow2 = pow2; | ||
assert(n >= 0); | ||
var ret = x / pow2(n); | ||
return n == (0, scryptlib_1.Int)(0) ? x : (x % (0, scryptlib_1.Int)(2) == (0, scryptlib_1.Int)(-1) ? (ret - (0, scryptlib_1.Int)(1)) : (x < (0, scryptlib_1.Int)(0) && ret == (0, scryptlib_1.Int)(0)) ? (0, scryptlib_1.Int)(-1) : ret); | ||
let ret = x / pow2(n); | ||
return n == 0n ? x : (x % 2n == -1n ? (ret - 1n) : (x < 0n && ret == 0n) ? -1n : ret); | ||
} | ||
@@ -266,151 +259,146 @@ exports.rshift = rshift; | ||
*/ | ||
var OpCode = /** @class */ (function () { | ||
function OpCode() { | ||
} | ||
// push value | ||
OpCode.OP_0 = (0, types_1.OpCodeType)('00'); | ||
OpCode.OP_FALSE = (0, types_1.OpCodeType)('00'); | ||
OpCode.OP_PUSHDATA1 = (0, types_1.OpCodeType)('4c'); | ||
OpCode.OP_PUSHDATA2 = (0, types_1.OpCodeType)('4d'); | ||
OpCode.OP_PUSHDATA4 = (0, types_1.OpCodeType)('4e'); | ||
OpCode.OP_1NEGATE = (0, types_1.OpCodeType)('4f'); | ||
OpCode.OP_RESERVED = (0, types_1.OpCodeType)('50'); | ||
OpCode.OP_1 = (0, types_1.OpCodeType)('51'); | ||
OpCode.OP_TRUE = (0, types_1.OpCodeType)('51'); | ||
OpCode.OP_2 = (0, types_1.OpCodeType)('52'); | ||
OpCode.OP_3 = (0, types_1.OpCodeType)('53'); | ||
OpCode.OP_4 = (0, types_1.OpCodeType)('54'); | ||
OpCode.OP_5 = (0, types_1.OpCodeType)('55'); | ||
OpCode.OP_6 = (0, types_1.OpCodeType)('56'); | ||
OpCode.OP_7 = (0, types_1.OpCodeType)('57'); | ||
OpCode.OP_8 = (0, types_1.OpCodeType)('58'); | ||
OpCode.OP_9 = (0, types_1.OpCodeType)('59'); | ||
OpCode.OP_10 = (0, types_1.OpCodeType)('5a'); | ||
OpCode.OP_11 = (0, types_1.OpCodeType)('5b'); | ||
OpCode.OP_12 = (0, types_1.OpCodeType)('5c'); | ||
OpCode.OP_13 = (0, types_1.OpCodeType)('5d'); | ||
OpCode.OP_14 = (0, types_1.OpCodeType)('5e'); | ||
OpCode.OP_15 = (0, types_1.OpCodeType)('5f'); | ||
OpCode.OP_16 = (0, types_1.OpCodeType)('60'); | ||
// control | ||
OpCode.OP_NOP = (0, types_1.OpCodeType)('61'); | ||
OpCode.OP_VER = (0, types_1.OpCodeType)('62'); | ||
OpCode.OP_IF = (0, types_1.OpCodeType)('63'); | ||
OpCode.OP_NOTIF = (0, types_1.OpCodeType)('64'); | ||
OpCode.OP_VERIF = (0, types_1.OpCodeType)('65'); | ||
OpCode.OP_VERNOTIF = (0, types_1.OpCodeType)('66'); | ||
OpCode.OP_ELSE = (0, types_1.OpCodeType)('67'); | ||
OpCode.OP_ENDIF = (0, types_1.OpCodeType)('68'); | ||
OpCode.OP_VERIFY = (0, types_1.OpCodeType)('69'); | ||
OpCode.OP_RETURN = (0, types_1.OpCodeType)('6a'); | ||
// stack ops | ||
OpCode.OP_TOALTSTACK = (0, types_1.OpCodeType)('6b'); | ||
OpCode.OP_FROMALTSTACK = (0, types_1.OpCodeType)('6c'); | ||
OpCode.OP_2DROP = (0, types_1.OpCodeType)('6d'); | ||
OpCode.OP_2DUP = (0, types_1.OpCodeType)('6e'); | ||
OpCode.OP_3DUP = (0, types_1.OpCodeType)('6f'); | ||
OpCode.OP_2OVER = (0, types_1.OpCodeType)('70'); | ||
OpCode.OP_2ROT = (0, types_1.OpCodeType)('71'); | ||
OpCode.OP_2SWAP = (0, types_1.OpCodeType)('72'); | ||
OpCode.OP_IFDUP = (0, types_1.OpCodeType)('73'); | ||
OpCode.OP_DEPTH = (0, types_1.OpCodeType)('74'); | ||
OpCode.OP_DROP = (0, types_1.OpCodeType)('75'); | ||
OpCode.OP_DUP = (0, types_1.OpCodeType)('76'); | ||
OpCode.OP_NIP = (0, types_1.OpCodeType)('77'); | ||
OpCode.OP_OVER = (0, types_1.OpCodeType)('78'); | ||
OpCode.OP_PICK = (0, types_1.OpCodeType)('79'); | ||
OpCode.OP_ROLL = (0, types_1.OpCodeType)('7a'); | ||
OpCode.OP_ROT = (0, types_1.OpCodeType)('7b'); | ||
OpCode.OP_SWAP = (0, types_1.OpCodeType)('7c'); | ||
OpCode.OP_TUCK = (0, types_1.OpCodeType)('7d'); | ||
// splice ops | ||
OpCode.OP_CAT = (0, types_1.OpCodeType)('7e'); | ||
OpCode.OP_SPLIT = (0, types_1.OpCodeType)('7f'); // after monolith upgrade (May 2018) | ||
OpCode.OP_NUM2BIN = (0, types_1.OpCodeType)('80'); // after monolith upgrade (May 2018) | ||
OpCode.OP_BIN2NUM = (0, types_1.OpCodeType)('81'); // after monolith upgrade (May 2018) | ||
OpCode.OP_SIZE = (0, types_1.OpCodeType)('82'); | ||
// bit logic | ||
OpCode.OP_INVERT = (0, types_1.OpCodeType)('83'); | ||
OpCode.OP_AND = (0, types_1.OpCodeType)('84'); | ||
OpCode.OP_OR = (0, types_1.OpCodeType)('85'); | ||
OpCode.OP_XOR = (0, types_1.OpCodeType)('86'); | ||
OpCode.OP_EQUAL = (0, types_1.OpCodeType)('87'); | ||
OpCode.OP_EQUALVERIFY = (0, types_1.OpCodeType)('88'); | ||
OpCode.OP_RESERVED1 = (0, types_1.OpCodeType)('89'); | ||
OpCode.OP_RESERVED2 = (0, types_1.OpCodeType)('8a'); | ||
// numeric | ||
OpCode.OP_1ADD = (0, types_1.OpCodeType)('8b'); | ||
OpCode.OP_1SUB = (0, types_1.OpCodeType)('8c'); | ||
OpCode.OP_2MUL = (0, types_1.OpCodeType)('8d'); | ||
OpCode.OP_2DIV = (0, types_1.OpCodeType)('8e'); | ||
OpCode.OP_NEGATE = (0, types_1.OpCodeType)('8f'); | ||
OpCode.OP_ABS = (0, types_1.OpCodeType)('90'); | ||
OpCode.OP_NOT = (0, types_1.OpCodeType)('91'); | ||
OpCode.OP_0NOTEQUAL = (0, types_1.OpCodeType)('92'); | ||
OpCode.OP_ADD = (0, types_1.OpCodeType)('93'); | ||
OpCode.OP_SUB = (0, types_1.OpCodeType)('94'); | ||
OpCode.OP_MUL = (0, types_1.OpCodeType)('95'); | ||
OpCode.OP_DIV = (0, types_1.OpCodeType)('96'); | ||
OpCode.OP_MOD = (0, types_1.OpCodeType)('97'); | ||
OpCode.OP_LSHIFT = (0, types_1.OpCodeType)('98'); | ||
OpCode.OP_RSHIFT = (0, types_1.OpCodeType)('99'); | ||
OpCode.OP_BOOLAND = (0, types_1.OpCodeType)('9a'); | ||
OpCode.OP_BOOLOR = (0, types_1.OpCodeType)('9b'); | ||
OpCode.OP_NUMEQUAL = (0, types_1.OpCodeType)('9c'); | ||
OpCode.OP_NUMEQUALVERIFY = (0, types_1.OpCodeType)('9d'); | ||
OpCode.OP_NUMNOTEQUAL = (0, types_1.OpCodeType)('9e'); | ||
OpCode.OP_LESSTHAN = (0, types_1.OpCodeType)('9f'); | ||
OpCode.OP_GREATERTHAN = (0, types_1.OpCodeType)('a0'); | ||
OpCode.OP_LESSTHANOREQUAL = (0, types_1.OpCodeType)('a1'); | ||
OpCode.OP_GREATERTHANOREQUAL = (0, types_1.OpCodeType)('a2'); | ||
OpCode.OP_MIN = (0, types_1.OpCodeType)('a3'); | ||
OpCode.OP_MAX = (0, types_1.OpCodeType)('a4'); | ||
OpCode.OP_WITHIN = (0, types_1.OpCodeType)('a5'); | ||
// crypto | ||
OpCode.OP_RIPEMD160 = (0, types_1.OpCodeType)('a6'); | ||
OpCode.OP_SHA1 = (0, types_1.OpCodeType)('a7'); | ||
OpCode.OP_SHA256 = (0, types_1.OpCodeType)('a8'); | ||
OpCode.OP_HASH160 = (0, types_1.OpCodeType)('a9'); | ||
OpCode.OP_HASH256 = (0, types_1.OpCodeType)('aa'); | ||
OpCode.OP_CODESEPARATOR = (0, types_1.OpCodeType)('ab'); | ||
OpCode.OP_CHECKSIG = (0, types_1.OpCodeType)('ac'); | ||
OpCode.OP_CHECKSIGVERIFY = (0, types_1.OpCodeType)('ad'); | ||
OpCode.OP_CHECKMULTISIG = (0, types_1.OpCodeType)('ae'); | ||
OpCode.OP_CHECKMULTISIGVERIFY = (0, types_1.OpCodeType)('af'); | ||
// expansion | ||
OpCode.OP_NOP1 = (0, types_1.OpCodeType)('b0'); | ||
OpCode.OP_NOP2 = (0, types_1.OpCodeType)('b1'); // previously OP_CHECKLOCKTIMEVERIFY | ||
OpCode.OP_NOP3 = (0, types_1.OpCodeType)('b2'); // OpCode.OP_CHECKSEQUENCEVERIFY; | ||
OpCode.OP_NOP4 = (0, types_1.OpCodeType)('b3'); | ||
OpCode.OP_NOP5 = (0, types_1.OpCodeType)('b4'); | ||
OpCode.OP_NOP6 = (0, types_1.OpCodeType)('b5'); | ||
OpCode.OP_NOP7 = (0, types_1.OpCodeType)('b6'); | ||
OpCode.OP_NOP8 = (0, types_1.OpCodeType)('b7'); | ||
OpCode.OP_NOP9 = (0, types_1.OpCodeType)('b8'); | ||
OpCode.OP_NOP10 = (0, types_1.OpCodeType)('b9'); | ||
// The first static const OpCodeType OP_code value after all defined opcodes | ||
//FIRST_UNDEFINED_OP_VALUE | ||
// template matching params | ||
OpCode.OP_PUBKEYHASH = (0, types_1.OpCodeType)('fd'); | ||
OpCode.OP_PUBKEY = (0, types_1.OpCodeType)('fe'); | ||
OpCode.OP_INVALIDOPCODE = (0, types_1.OpCodeType)('ff'); | ||
return OpCode; | ||
}()); | ||
class OpCode { | ||
} | ||
exports.OpCode = OpCode; | ||
// push value | ||
OpCode.OP_0 = (0, types_1.OpCodeType)('00'); | ||
OpCode.OP_FALSE = (0, types_1.OpCodeType)('00'); | ||
OpCode.OP_PUSHDATA1 = (0, types_1.OpCodeType)('4c'); | ||
OpCode.OP_PUSHDATA2 = (0, types_1.OpCodeType)('4d'); | ||
OpCode.OP_PUSHDATA4 = (0, types_1.OpCodeType)('4e'); | ||
OpCode.OP_1NEGATE = (0, types_1.OpCodeType)('4f'); | ||
OpCode.OP_RESERVED = (0, types_1.OpCodeType)('50'); | ||
OpCode.OP_1 = (0, types_1.OpCodeType)('51'); | ||
OpCode.OP_TRUE = (0, types_1.OpCodeType)('51'); | ||
OpCode.OP_2 = (0, types_1.OpCodeType)('52'); | ||
OpCode.OP_3 = (0, types_1.OpCodeType)('53'); | ||
OpCode.OP_4 = (0, types_1.OpCodeType)('54'); | ||
OpCode.OP_5 = (0, types_1.OpCodeType)('55'); | ||
OpCode.OP_6 = (0, types_1.OpCodeType)('56'); | ||
OpCode.OP_7 = (0, types_1.OpCodeType)('57'); | ||
OpCode.OP_8 = (0, types_1.OpCodeType)('58'); | ||
OpCode.OP_9 = (0, types_1.OpCodeType)('59'); | ||
OpCode.OP_10 = (0, types_1.OpCodeType)('5a'); | ||
OpCode.OP_11 = (0, types_1.OpCodeType)('5b'); | ||
OpCode.OP_12 = (0, types_1.OpCodeType)('5c'); | ||
OpCode.OP_13 = (0, types_1.OpCodeType)('5d'); | ||
OpCode.OP_14 = (0, types_1.OpCodeType)('5e'); | ||
OpCode.OP_15 = (0, types_1.OpCodeType)('5f'); | ||
OpCode.OP_16 = (0, types_1.OpCodeType)('60'); | ||
// control | ||
OpCode.OP_NOP = (0, types_1.OpCodeType)('61'); | ||
OpCode.OP_VER = (0, types_1.OpCodeType)('62'); | ||
OpCode.OP_IF = (0, types_1.OpCodeType)('63'); | ||
OpCode.OP_NOTIF = (0, types_1.OpCodeType)('64'); | ||
OpCode.OP_VERIF = (0, types_1.OpCodeType)('65'); | ||
OpCode.OP_VERNOTIF = (0, types_1.OpCodeType)('66'); | ||
OpCode.OP_ELSE = (0, types_1.OpCodeType)('67'); | ||
OpCode.OP_ENDIF = (0, types_1.OpCodeType)('68'); | ||
OpCode.OP_VERIFY = (0, types_1.OpCodeType)('69'); | ||
OpCode.OP_RETURN = (0, types_1.OpCodeType)('6a'); | ||
// stack ops | ||
OpCode.OP_TOALTSTACK = (0, types_1.OpCodeType)('6b'); | ||
OpCode.OP_FROMALTSTACK = (0, types_1.OpCodeType)('6c'); | ||
OpCode.OP_2DROP = (0, types_1.OpCodeType)('6d'); | ||
OpCode.OP_2DUP = (0, types_1.OpCodeType)('6e'); | ||
OpCode.OP_3DUP = (0, types_1.OpCodeType)('6f'); | ||
OpCode.OP_2OVER = (0, types_1.OpCodeType)('70'); | ||
OpCode.OP_2ROT = (0, types_1.OpCodeType)('71'); | ||
OpCode.OP_2SWAP = (0, types_1.OpCodeType)('72'); | ||
OpCode.OP_IFDUP = (0, types_1.OpCodeType)('73'); | ||
OpCode.OP_DEPTH = (0, types_1.OpCodeType)('74'); | ||
OpCode.OP_DROP = (0, types_1.OpCodeType)('75'); | ||
OpCode.OP_DUP = (0, types_1.OpCodeType)('76'); | ||
OpCode.OP_NIP = (0, types_1.OpCodeType)('77'); | ||
OpCode.OP_OVER = (0, types_1.OpCodeType)('78'); | ||
OpCode.OP_PICK = (0, types_1.OpCodeType)('79'); | ||
OpCode.OP_ROLL = (0, types_1.OpCodeType)('7a'); | ||
OpCode.OP_ROT = (0, types_1.OpCodeType)('7b'); | ||
OpCode.OP_SWAP = (0, types_1.OpCodeType)('7c'); | ||
OpCode.OP_TUCK = (0, types_1.OpCodeType)('7d'); | ||
// splice ops | ||
OpCode.OP_CAT = (0, types_1.OpCodeType)('7e'); | ||
OpCode.OP_SPLIT = (0, types_1.OpCodeType)('7f'); // after monolith upgrade (May 2018) | ||
OpCode.OP_NUM2BIN = (0, types_1.OpCodeType)('80'); // after monolith upgrade (May 2018) | ||
OpCode.OP_BIN2NUM = (0, types_1.OpCodeType)('81'); // after monolith upgrade (May 2018) | ||
OpCode.OP_SIZE = (0, types_1.OpCodeType)('82'); | ||
// bit logic | ||
OpCode.OP_INVERT = (0, types_1.OpCodeType)('83'); | ||
OpCode.OP_AND = (0, types_1.OpCodeType)('84'); | ||
OpCode.OP_OR = (0, types_1.OpCodeType)('85'); | ||
OpCode.OP_XOR = (0, types_1.OpCodeType)('86'); | ||
OpCode.OP_EQUAL = (0, types_1.OpCodeType)('87'); | ||
OpCode.OP_EQUALVERIFY = (0, types_1.OpCodeType)('88'); | ||
OpCode.OP_RESERVED1 = (0, types_1.OpCodeType)('89'); | ||
OpCode.OP_RESERVED2 = (0, types_1.OpCodeType)('8a'); | ||
// numeric | ||
OpCode.OP_1ADD = (0, types_1.OpCodeType)('8b'); | ||
OpCode.OP_1SUB = (0, types_1.OpCodeType)('8c'); | ||
OpCode.OP_2MUL = (0, types_1.OpCodeType)('8d'); | ||
OpCode.OP_2DIV = (0, types_1.OpCodeType)('8e'); | ||
OpCode.OP_NEGATE = (0, types_1.OpCodeType)('8f'); | ||
OpCode.OP_ABS = (0, types_1.OpCodeType)('90'); | ||
OpCode.OP_NOT = (0, types_1.OpCodeType)('91'); | ||
OpCode.OP_0NOTEQUAL = (0, types_1.OpCodeType)('92'); | ||
OpCode.OP_ADD = (0, types_1.OpCodeType)('93'); | ||
OpCode.OP_SUB = (0, types_1.OpCodeType)('94'); | ||
OpCode.OP_MUL = (0, types_1.OpCodeType)('95'); | ||
OpCode.OP_DIV = (0, types_1.OpCodeType)('96'); | ||
OpCode.OP_MOD = (0, types_1.OpCodeType)('97'); | ||
OpCode.OP_LSHIFT = (0, types_1.OpCodeType)('98'); | ||
OpCode.OP_RSHIFT = (0, types_1.OpCodeType)('99'); | ||
OpCode.OP_BOOLAND = (0, types_1.OpCodeType)('9a'); | ||
OpCode.OP_BOOLOR = (0, types_1.OpCodeType)('9b'); | ||
OpCode.OP_NUMEQUAL = (0, types_1.OpCodeType)('9c'); | ||
OpCode.OP_NUMEQUALVERIFY = (0, types_1.OpCodeType)('9d'); | ||
OpCode.OP_NUMNOTEQUAL = (0, types_1.OpCodeType)('9e'); | ||
OpCode.OP_LESSTHAN = (0, types_1.OpCodeType)('9f'); | ||
OpCode.OP_GREATERTHAN = (0, types_1.OpCodeType)('a0'); | ||
OpCode.OP_LESSTHANOREQUAL = (0, types_1.OpCodeType)('a1'); | ||
OpCode.OP_GREATERTHANOREQUAL = (0, types_1.OpCodeType)('a2'); | ||
OpCode.OP_MIN = (0, types_1.OpCodeType)('a3'); | ||
OpCode.OP_MAX = (0, types_1.OpCodeType)('a4'); | ||
OpCode.OP_WITHIN = (0, types_1.OpCodeType)('a5'); | ||
// crypto | ||
OpCode.OP_RIPEMD160 = (0, types_1.OpCodeType)('a6'); | ||
OpCode.OP_SHA1 = (0, types_1.OpCodeType)('a7'); | ||
OpCode.OP_SHA256 = (0, types_1.OpCodeType)('a8'); | ||
OpCode.OP_HASH160 = (0, types_1.OpCodeType)('a9'); | ||
OpCode.OP_HASH256 = (0, types_1.OpCodeType)('aa'); | ||
OpCode.OP_CODESEPARATOR = (0, types_1.OpCodeType)('ab'); | ||
OpCode.OP_CHECKSIG = (0, types_1.OpCodeType)('ac'); | ||
OpCode.OP_CHECKSIGVERIFY = (0, types_1.OpCodeType)('ad'); | ||
OpCode.OP_CHECKMULTISIG = (0, types_1.OpCodeType)('ae'); | ||
OpCode.OP_CHECKMULTISIGVERIFY = (0, types_1.OpCodeType)('af'); | ||
// expansion | ||
OpCode.OP_NOP1 = (0, types_1.OpCodeType)('b0'); | ||
OpCode.OP_NOP2 = (0, types_1.OpCodeType)('b1'); // previously OP_CHECKLOCKTIMEVERIFY | ||
OpCode.OP_NOP3 = (0, types_1.OpCodeType)('b2'); // OpCode.OP_CHECKSEQUENCEVERIFY; | ||
OpCode.OP_NOP4 = (0, types_1.OpCodeType)('b3'); | ||
OpCode.OP_NOP5 = (0, types_1.OpCodeType)('b4'); | ||
OpCode.OP_NOP6 = (0, types_1.OpCodeType)('b5'); | ||
OpCode.OP_NOP7 = (0, types_1.OpCodeType)('b6'); | ||
OpCode.OP_NOP8 = (0, types_1.OpCodeType)('b7'); | ||
OpCode.OP_NOP9 = (0, types_1.OpCodeType)('b8'); | ||
OpCode.OP_NOP10 = (0, types_1.OpCodeType)('b9'); | ||
// The first static const OpCodeType OP_code value after all defined opcodes | ||
//FIRST_UNDEFINED_OP_VALUE | ||
// template matching params | ||
OpCode.OP_PUBKEYHASH = (0, types_1.OpCodeType)('fd'); | ||
OpCode.OP_PUBKEY = (0, types_1.OpCodeType)('fe'); | ||
OpCode.OP_INVALIDOPCODE = (0, types_1.OpCodeType)('ff'); | ||
/** | ||
* @category Standard Contracts | ||
*/ | ||
var Utils = /** @class */ (function () { | ||
function Utils() { | ||
} | ||
class Utils { | ||
// convert signed integer `n` to unsigned integer of `l` string, in little endian | ||
Utils.toLEUnsigned = function (n, l) { | ||
var m = int2str(n, l + (0, scryptlib_1.Int)(1)); | ||
static toLEUnsigned(n, l) { | ||
let m = int2str(n, l + 1n); | ||
// remove sign byte | ||
return m.slice(0, len(m) * 2 - 2); | ||
}; | ||
} | ||
// convert string to unsigned integer, in sign-magnitude little endian | ||
Utils.fromLEUnsigned = function (bytes) { | ||
static fromLEUnsigned(bytes) { | ||
return unpack(bytes + (0, types_1.toByteString)('00')); | ||
}; | ||
} | ||
/* | ||
@@ -421,68 +409,65 @@ * VarInt (variable integer) is used to encode fields of variable length in a bitcoin transaction | ||
// read a VarInt field from the beginning of 'b' | ||
Utils.readVarint = function (buf) { | ||
var l = (0, scryptlib_1.Int)(0); | ||
var ret = (0, types_1.toByteString)(''); | ||
var header = buf.slice(0, 2); | ||
static readVarint(buf) { | ||
let l = 0n; | ||
let ret = (0, types_1.toByteString)(''); | ||
let header = buf.slice(0, 2); | ||
if (header == (0, types_1.toByteString)('fd')) { | ||
l = Utils.fromLEUnsigned(buf.slice(2, 6)); | ||
ret = buf.slice(6, 6 + Number(l * (0, scryptlib_1.Int)(2))); | ||
ret = buf.slice(6, 6 + Number(l * 2n)); | ||
} | ||
else if (header == (0, types_1.toByteString)('fe')) { | ||
l = Utils.fromLEUnsigned(buf.slice(2, 10)); | ||
ret = buf.slice(10, 10 + Number(l * (0, scryptlib_1.Int)(2))); | ||
ret = buf.slice(10, 10 + Number(l * 2n)); | ||
} | ||
else if (header == (0, types_1.toByteString)('ff')) { | ||
l = Utils.fromLEUnsigned(buf.slice(2, 18)); | ||
ret = buf.slice(18, 18 + Number(l * (0, scryptlib_1.Int)(2))); | ||
ret = buf.slice(18, 18 + Number(l * 2n)); | ||
} | ||
else { | ||
l = Utils.fromLEUnsigned(buf.slice(0, 2)); | ||
ret = buf.slice(2, 2 + Number(l * (0, scryptlib_1.Int)(2))); | ||
ret = buf.slice(2, 2 + Number(l * 2n)); | ||
} | ||
return ret; | ||
}; | ||
} | ||
// convert 'b' to a VarInt field, including the preceding length | ||
Utils.writeVarint = function (buf) { | ||
var n = len(buf); | ||
var header = (0, types_1.toByteString)(''); | ||
static writeVarint(buf) { | ||
let n = len(buf); | ||
let header = (0, types_1.toByteString)(''); | ||
if (n < 0xfd) { | ||
header = Utils.toLEUnsigned((0, scryptlib_1.Int)(n), (0, scryptlib_1.Int)(1)); | ||
header = Utils.toLEUnsigned(BigInt(n), 1n); | ||
} | ||
else if (n < 0x10000) { | ||
header = (0, types_1.toByteString)('fd') + Utils.toLEUnsigned((0, scryptlib_1.Int)(n), (0, scryptlib_1.Int)(2)); | ||
header = (0, types_1.toByteString)('fd') + Utils.toLEUnsigned(BigInt(n), 2n); | ||
} | ||
else if (n < 0x100000000) { | ||
header = (0, types_1.toByteString)('fe') + Utils.toLEUnsigned((0, scryptlib_1.Int)(n), (0, scryptlib_1.Int)(4)); | ||
header = (0, types_1.toByteString)('fe') + Utils.toLEUnsigned(BigInt(n), 4n); | ||
} | ||
else if (n < 0x10000000000000000) { | ||
header = (0, types_1.toByteString)('ff') + Utils.toLEUnsigned((0, scryptlib_1.Int)(n), (0, scryptlib_1.Int)(8)); | ||
header = (0, types_1.toByteString)('ff') + Utils.toLEUnsigned(BigInt(n), 8n); | ||
} | ||
return header + buf; | ||
}; | ||
} | ||
// build a tx output from its script and satoshi amount | ||
Utils.buildOutput = function (outputScript, outputSatoshis) { | ||
static buildOutput(outputScript, outputSatoshis) { | ||
return int2str(outputSatoshis, Constants.OutputValueLen) + Utils.writeVarint(outputScript); | ||
}; | ||
} | ||
// build P2PKH script from PubKeyHash | ||
Utils.buildPublicKeyHashScript = function (pubKeyHash) { | ||
static buildPublicKeyHashScript(pubKeyHash) { | ||
return (0, types_1.toByteString)(OpCode.OP_DUP) + (0, types_1.toByteString)(OpCode.OP_HASH160) + pack(Constants.PubKeyHashLen /* "OP_PUSHDATA0" */) | ||
+ pubKeyHash + (0, types_1.toByteString)(OpCode.OP_EQUALVERIFY) + (0, types_1.toByteString)(OpCode.OP_CHECKSIG); | ||
}; | ||
} | ||
// build false OPRETURN script from data payload | ||
Utils.buildOpreturnScript = function (data) { | ||
static buildOpreturnScript(data) { | ||
return (0, types_1.toByteString)(OpCode.OP_FALSE) + (0, types_1.toByteString)(OpCode.OP_RETURN) + Utils.writeVarint(data); | ||
}; | ||
// number of string to denote output value | ||
Utils.OutputValueLen = (0, scryptlib_1.Int)(8); | ||
// number of string to denote a public key hash | ||
Utils.PubKeyHashLen = (0, scryptlib_1.Int)(20); | ||
return Utils; | ||
}()); | ||
} | ||
} | ||
exports.Utils = Utils; | ||
// number of string to denote output value | ||
Utils.OutputValueLen = 8n; | ||
// number of string to denote a public key hash | ||
Utils.PubKeyHashLen = 20n; | ||
/** | ||
* @category Standard Contracts | ||
*/ | ||
var SigHash = /** @class */ (function () { | ||
function SigHash() { | ||
} | ||
class SigHash { | ||
/* | ||
@@ -493,94 +478,93 @@ * util functions to parse every field of a sighash preimage | ||
*/ | ||
SigHash.nVersion = function (preimage) { | ||
static nVersion(preimage) { | ||
return (0, types_1.toByteString)(preimage).slice(0, 8); | ||
}; | ||
SigHash.hashPrevouts = function (preimage) { | ||
} | ||
static hashPrevouts(preimage) { | ||
return (0, types_1.toByteString)(preimage).slice(8, 72); | ||
}; | ||
SigHash.hashSequence = function (preimage) { | ||
} | ||
static hashSequence(preimage) { | ||
return (0, types_1.toByteString)(preimage).slice(36 * 2, 68 * 2); | ||
}; | ||
SigHash.outpoint = function (preimage) { | ||
} | ||
static outpoint(preimage) { | ||
return (0, types_1.toByteString)(preimage).slice(68 * 2, 104 * 2); | ||
}; | ||
} | ||
// scriptCode is just scriptPubKey if there is no CODESEPARATOR in the latter | ||
SigHash.scriptCode = function (preimage) { | ||
static scriptCode(preimage) { | ||
return Utils.readVarint((0, types_1.toByteString)(preimage).slice(104 * 2)); | ||
}; | ||
SigHash.valueRaw = function (preimage) { | ||
var l = len((0, types_1.toByteString)(preimage)); | ||
} | ||
static valueRaw(preimage) { | ||
let l = len((0, types_1.toByteString)(preimage)); | ||
return (0, types_1.toByteString)(preimage).slice(l * 2 - 104, l * 2 - 88); | ||
}; | ||
SigHash.value = function (preimage) { | ||
} | ||
static value(preimage) { | ||
return Utils.fromLEUnsigned(SigHash.valueRaw(preimage)); | ||
}; | ||
SigHash.nSequenceRaw = function (preimage) { | ||
var l = len((0, types_1.toByteString)(preimage)); | ||
} | ||
static nSequenceRaw(preimage) { | ||
let l = len((0, types_1.toByteString)(preimage)); | ||
return (0, types_1.toByteString)(preimage).slice(l * 2 - 88, l * 2 - 80); | ||
}; | ||
SigHash.nSequence = function (preimage) { | ||
} | ||
static nSequence(preimage) { | ||
return Utils.fromLEUnsigned(SigHash.nSequenceRaw(preimage)); | ||
}; | ||
} | ||
; | ||
SigHash.hashOutputs = function (preimage) { | ||
var l = len((0, types_1.toByteString)(preimage)); | ||
static hashOutputs(preimage) { | ||
let l = len((0, types_1.toByteString)(preimage)); | ||
return (0, types_1.toByteString)(preimage).slice(l * 2 - 80, l * 2 - 16); | ||
}; | ||
SigHash.nLocktimeRaw = function (preimage) { | ||
var l = len((0, types_1.toByteString)(preimage)); | ||
} | ||
static nLocktimeRaw(preimage) { | ||
let l = len((0, types_1.toByteString)(preimage)); | ||
return (0, types_1.toByteString)(preimage).slice(l * 2 - 16, l * 2 - 8); | ||
}; | ||
SigHash.nLocktime = function (preimage) { | ||
} | ||
static nLocktime(preimage) { | ||
return Utils.fromLEUnsigned(SigHash.nLocktimeRaw(preimage)); | ||
}; | ||
} | ||
; | ||
SigHash.sigHashType = function (preimage) { | ||
var l = len((0, types_1.toByteString)(preimage)); | ||
var sigHashType = Utils.fromLEUnsigned((0, types_1.toByteString)(preimage).slice(l * 2 - 8, l * 2 - 6)); | ||
static sigHashType(preimage) { | ||
let l = len((0, types_1.toByteString)(preimage)); | ||
let sigHashType = Utils.fromLEUnsigned((0, types_1.toByteString)(preimage).slice(l * 2 - 8, l * 2 - 6)); | ||
return (0, scryptlib_1.SigHashType)(Number(sigHashType)); | ||
}; | ||
SigHash.ALL = (0, scryptlib_1.SigHashType)(65); | ||
SigHash.NONE = (0, scryptlib_1.SigHashType)(66); | ||
SigHash.SINGLE = (0, scryptlib_1.SigHashType)(67); | ||
SigHash.ANYONECANPAY_ALL = (0, scryptlib_1.SigHashType)(193); | ||
SigHash.ANYONECANPAY_NONE = (0, scryptlib_1.SigHashType)(194); | ||
SigHash.ANYONECANPAY_SINGLE = (0, scryptlib_1.SigHashType)(195); | ||
return SigHash; | ||
}()); | ||
} | ||
} | ||
exports.SigHash = SigHash; | ||
SigHash.ALL = (0, scryptlib_1.SigHashType)(65); | ||
SigHash.NONE = (0, scryptlib_1.SigHashType)(66); | ||
SigHash.SINGLE = (0, scryptlib_1.SigHashType)(67); | ||
SigHash.ANYONECANPAY_ALL = (0, scryptlib_1.SigHashType)(193); | ||
SigHash.ANYONECANPAY_NONE = (0, scryptlib_1.SigHashType)(194); | ||
SigHash.ANYONECANPAY_SINGLE = (0, scryptlib_1.SigHashType)(195); | ||
/** | ||
* @category Standard Contracts | ||
*/ | ||
var VarIntReader = /** @class */ (function () { | ||
function VarIntReader(buf) { | ||
class VarIntReader { | ||
constructor(buf) { | ||
this.buf = buf; | ||
this.pos = (0, scryptlib_1.Int)(0); | ||
this.pos = 0n; | ||
} | ||
VarIntReader.prototype.eof = function () { | ||
eof() { | ||
return this.pos >= len(this.buf); | ||
}; | ||
VarIntReader.prototype.readBytes = function () { | ||
var l = (0, scryptlib_1.Int)(0); | ||
var buf = this.buf; | ||
var ret = (0, types_1.toByteString)(''); | ||
var header = unpack(buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + (0, scryptlib_1.Int)(1)) * (0, scryptlib_1.Int)(2)))); | ||
} | ||
readBytes() { | ||
let l = 0n; | ||
let buf = this.buf; | ||
let ret = (0, types_1.toByteString)(''); | ||
let header = unpack(buf.slice(Number(this.pos * 2n), Number((this.pos + 1n) * 2n))); | ||
this.pos++; | ||
if (header < (0, scryptlib_1.Int)(0x4c)) { | ||
if (header < 0x4cn) { | ||
l = header; | ||
ret = buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + l) * (0, scryptlib_1.Int)(2))); | ||
ret = buf.slice(Number(this.pos * 2n), Number((this.pos + l) * 2n)); | ||
} | ||
else if (header == (0, scryptlib_1.Int)(0x4c)) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + (0, scryptlib_1.Int)(1)) * (0, scryptlib_1.Int)(2)))); | ||
this.pos += (0, scryptlib_1.Int)(1); | ||
ret = buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + l) * (0, scryptlib_1.Int)(2))); | ||
else if (header == 0x4cn) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * 2n), Number((this.pos + 1n) * 2n))); | ||
this.pos += 1n; | ||
ret = buf.slice(Number(this.pos * 2n), Number((this.pos + l) * 2n)); | ||
} | ||
else if (header == (0, scryptlib_1.Int)(0x4d)) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + (0, scryptlib_1.Int)(2)) * (0, scryptlib_1.Int)(2)))); | ||
this.pos += (0, scryptlib_1.Int)(2); | ||
ret = buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + l) * (0, scryptlib_1.Int)(2))); | ||
else if (header == 0x4dn) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * 2n), Number((this.pos + 2n) * 2n))); | ||
this.pos += 2n; | ||
ret = buf.slice(Number(this.pos * 2n), Number((this.pos + l) * 2n)); | ||
} | ||
else if (header == (0, scryptlib_1.Int)(0x4e)) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + (0, scryptlib_1.Int)(4)) * (0, scryptlib_1.Int)(2)))); | ||
this.pos += (0, scryptlib_1.Int)(4); | ||
ret = buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + l) * (0, scryptlib_1.Int)(2))); | ||
else if (header == 0x4en) { | ||
l = Utils.fromLEUnsigned(buf.slice(Number(this.pos * 2n), Number((this.pos + 4n) * 2n))); | ||
this.pos += 4n; | ||
ret = buf.slice(Number(this.pos * 2n), Number((this.pos + l) * 2n)); | ||
} | ||
@@ -593,52 +577,49 @@ else { | ||
return ret; | ||
}; | ||
VarIntReader.prototype.readBool = function () { | ||
var buf = this.buf.slice(Number(this.pos * (0, scryptlib_1.Int)(2)), Number((this.pos + (0, scryptlib_1.Int)(1)) * (0, scryptlib_1.Int)(2))); | ||
} | ||
readBool() { | ||
let buf = this.buf.slice(Number(this.pos * 2n), Number((this.pos + 1n) * 2n)); | ||
this.pos++; | ||
return (0, types_1.toByteString)('00') != buf; | ||
}; | ||
VarIntReader.prototype.readInt = function () { | ||
} | ||
readInt() { | ||
return unpack(this.readBytes()); | ||
}; | ||
VarIntReader.getStateStart = function (scriptCode) { | ||
} | ||
static getStateStart(scriptCode) { | ||
// locking script: code + opreturn + data(state + state_len + version) | ||
var scriptLen = BigInt(len(scriptCode)); | ||
let scriptLen = BigInt(len(scriptCode)); | ||
// read state length | ||
var start = scriptLen - VarIntReader.StateLen - VarIntReader.VersionLen; | ||
var end = scriptLen - VarIntReader.VersionLen; | ||
var lb = scriptCode.slice(Number(start * (0, scryptlib_1.Int)(2)), Number(end * (0, scryptlib_1.Int)(2))); | ||
var stateLen = unpack(lb); | ||
let start = scriptLen - VarIntReader.StateLen - VarIntReader.VersionLen; | ||
let end = scriptLen - VarIntReader.VersionLen; | ||
let lb = scriptCode.slice(Number(start * 2n), Number(end * 2n)); | ||
let stateLen = unpack(lb); | ||
// TODO: check version is as expected | ||
return scriptLen - stateLen - VarIntReader.StateLen - VarIntReader.VersionLen; | ||
}; | ||
// fixed number of string to denote length of serialized state | ||
VarIntReader.StateLen = (0, scryptlib_1.Int)(4); | ||
// fixed number of string to denote version | ||
VarIntReader.VersionLen = (0, scryptlib_1.Int)(1); | ||
// version | ||
VarIntReader.Version = (0, scryptlib_1.Int)(0); | ||
return VarIntReader; | ||
}()); | ||
} | ||
} | ||
exports.VarIntReader = VarIntReader; | ||
// fixed number of string to denote length of serialized state | ||
VarIntReader.StateLen = 4n; | ||
// fixed number of string to denote version | ||
VarIntReader.VersionLen = 1n; | ||
// version | ||
VarIntReader.Version = 0n; | ||
/** | ||
* @category Standard Contracts | ||
*/ | ||
var VarIntWriter = /** @class */ (function () { | ||
function VarIntWriter() { | ||
} | ||
class VarIntWriter { | ||
// return VarInt encoding | ||
VarIntWriter.writeBytes = function (buf) { | ||
var n = BigInt(len(buf)); | ||
var header = (0, types_1.toByteString)(''); | ||
static writeBytes(buf) { | ||
let n = BigInt(len(buf)); | ||
let header = (0, types_1.toByteString)(''); | ||
if (n < 0x4c) { | ||
header = Utils.toLEUnsigned(n, (0, scryptlib_1.Int)(1)); | ||
header = Utils.toLEUnsigned(n, 1n); | ||
} | ||
else if (n < 0x100) { | ||
header = (0, types_1.toByteString)('4c') + Utils.toLEUnsigned(n, (0, scryptlib_1.Int)(1)); | ||
header = (0, types_1.toByteString)('4c') + Utils.toLEUnsigned(n, 1n); | ||
} | ||
else if (n < 0x10000) { | ||
header = (0, types_1.toByteString)('4d') + Utils.toLEUnsigned(n, (0, scryptlib_1.Int)(2)); | ||
header = (0, types_1.toByteString)('4d') + Utils.toLEUnsigned(n, 2n); | ||
} | ||
else if (n < 0x100000000) { | ||
header = (0, types_1.toByteString)('4e') + Utils.toLEUnsigned(n, (0, scryptlib_1.Int)(4)); | ||
header = (0, types_1.toByteString)('4e') + Utils.toLEUnsigned(n, 4n); | ||
} | ||
@@ -650,18 +631,17 @@ else { | ||
return header + buf; | ||
}; | ||
} | ||
// uses fixed 1 byte to represent a boolean, plus length | ||
VarIntWriter.writeBool = function (x) { | ||
static writeBool(x) { | ||
return x ? (0, types_1.toByteString)('01') : (0, types_1.toByteString)('00'); | ||
}; | ||
} | ||
// bigint is little endian | ||
VarIntWriter.writeInt = function (x) { | ||
return VarIntWriter.writeBytes(x == (0, scryptlib_1.Int)(0) ? (0, types_1.toByteString)('00') : pack(x)); | ||
}; | ||
VarIntWriter.serializeState = function (stateBuf) { | ||
static writeInt(x) { | ||
return VarIntWriter.writeBytes(x == 0n ? (0, types_1.toByteString)('00') : pack(x)); | ||
} | ||
static serializeState(stateBuf) { | ||
// locking script: code + opreturn + data(state + state_len + version) | ||
var lenBuf = int2str(BigInt(len(stateBuf)), VarIntReader.StateLen); | ||
let lenBuf = int2str(BigInt(len(stateBuf)), VarIntReader.StateLen); | ||
return stateBuf + lenBuf + int2str(VarIntReader.Version, VarIntReader.VersionLen); | ||
}; | ||
return VarIntWriter; | ||
}()); | ||
} | ||
} | ||
exports.VarIntWriter = VarIntWriter; | ||
@@ -672,17 +652,15 @@ /** | ||
*/ | ||
var Tx = /** @class */ (function () { | ||
function Tx() { | ||
} | ||
Tx.normalize = function (k, modulus) { | ||
var res = k % modulus; | ||
class Tx { | ||
static normalize(k, modulus) { | ||
let res = k % modulus; | ||
// ensure it's positive | ||
return (res < 0) ? res + modulus : res; | ||
}; | ||
Tx.sign = function (h, privKey, inverseK, r, rBigEndian, sigHashType) { | ||
} | ||
static sign(h, privKey, inverseK, r, rBigEndian, sigHashType) { | ||
// TODO: r * privKey can also be precomputed | ||
var s = inverseK * (h + r * privKey); | ||
var N = (0, scryptlib_1.Int)('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'); | ||
let s = inverseK * (h + r * privKey); | ||
let N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n; | ||
s = Tx.normalize(s, N); | ||
// lower S | ||
if (s > N / (0, scryptlib_1.Int)(2)) { | ||
if (s > N / 2n) { | ||
s = N - s; | ||
@@ -695,69 +673,65 @@ } | ||
*/ | ||
var rlen = BigInt(len(rBigEndian)); | ||
var slen = len(pack(s)); | ||
let rlen = BigInt(len(rBigEndian)); | ||
let slen = len(pack(s)); | ||
// we convert s to 32 bytes, otherwise reverseBytes(, 32) fails when s is strictly less than 31 bytes (note: 31 bytes works) | ||
// slice it after reversing to remove extra leading zeros, otherwise strict DER rule fails it due to not minimally encoded | ||
var sBigEndian = reverseBytes(int2str(s, (0, scryptlib_1.Int)(32)), 32).slice(32 * 2 - slen * 2); | ||
var l = (0, scryptlib_1.Int)(4) + rlen + BigInt(slen); | ||
let sBigEndian = reverseBytes(int2str(s, 32n), 32).slice(32 * 2 - slen * 2); | ||
let l = 4n + rlen + BigInt(slen); | ||
// rBigEndian must be mininally encoded, to conform to strict DER rule | ||
var rb = (0, types_1.toByteString)('30') + pack(l) + (0, types_1.toByteString)('02') + pack(rlen) + rBigEndian + (0, types_1.toByteString)('02') + pack(BigInt(slen)) + sBigEndian + (0, types_1.toByteString)(sigHashType); | ||
let rb = (0, types_1.toByteString)('30') + pack(l) + (0, types_1.toByteString)('02') + pack(rlen) + rBigEndian + (0, types_1.toByteString)('02') + pack(BigInt(slen)) + sBigEndian + (0, types_1.toByteString)(sigHashType); | ||
return (0, types_1.Sig)(rb); | ||
}; | ||
Tx.fromBEUnsigned = function (bytes) { | ||
} | ||
static fromBEUnsigned(bytes) { | ||
// change endian first | ||
// append positive sign byte. This does not hurt even when sign bit is already positive | ||
return unpack(reverseBytes(bytes, 32) + (0, types_1.toByteString)('00')); | ||
}; | ||
} | ||
// optimal pushtx | ||
Tx.checkPreimageOpt = function (txPreimage) { throw new Error('unimplemented'); }; | ||
static checkPreimageOpt(txPreimage) { throw new Error('unimplemented'); } | ||
// customize sigHashType | ||
Tx.checkPreimageOpt_ = function (txPreimage) { throw new Error('unimplemented'); }; | ||
Tx.checkPreimageAdvancedOCS = function (txPreimage, privKey, pubKey, inverseK, r, rBigEndian, sigHashType) { throw new Error('unimplemented'); }; | ||
Tx.checkPreimageOCS = function (txPreimage) { throw new Error('unimplemented'); }; | ||
Tx.checkPreimageSigHashTypeOCS = function (txPreimage, sigHashType) { throw new Error('unimplemented'); }; | ||
static checkPreimageOpt_(txPreimage) { throw new Error('unimplemented'); } | ||
static checkPreimageAdvancedOCS(txPreimage, privKey, pubKey, inverseK, r, rBigEndian, sigHashType) { throw new Error('unimplemented'); } | ||
static checkPreimageOCS(txPreimage) { throw new Error('unimplemented'); } | ||
static checkPreimageSigHashTypeOCS(txPreimage, sigHashType) { throw new Error('unimplemented'); } | ||
// optimal pushtx | ||
Tx.checkPreimageOptOCS = function (txPreimage) { throw new Error('unimplemented'); }; | ||
static checkPreimageOptOCS(txPreimage) { throw new Error('unimplemented'); } | ||
// customize sigHashType | ||
Tx.checkPreimageOptOCS_ = function (txPreimage) { throw new Error('unimplemented'); }; | ||
static checkPreimageOptOCS_(txPreimage) { throw new Error('unimplemented'); } | ||
// return whether is the first call of series public function calls in stateful contract | ||
Tx.isFirstCall = function (txPreimage) { | ||
var scriptCode = SigHash.scriptCode(txPreimage); | ||
var stateStart = VarIntReader.getStateStart(scriptCode); | ||
var reader = new VarIntReader(scriptCode.slice(Number(stateStart) * 2)); | ||
static isFirstCall(txPreimage) { | ||
let scriptCode = SigHash.scriptCode(txPreimage); | ||
let stateStart = VarIntReader.getStateStart(scriptCode); | ||
let reader = new VarIntReader(scriptCode.slice(Number(stateStart) * 2)); | ||
return reader.readBool(); | ||
}; | ||
// The following arguments can be generated using sample code at | ||
// https://gist.github.com/scrypt-sv/f6882be580780a88984cee75dd1564c4.js | ||
Tx.privKey = (0, types_1.PrivKey)((0, scryptlib_1.Int)("0x26f00fe2340a84335ebdf30f57e9bb58487117b29355718f5e46bf5168d7df97")); | ||
Tx.pubKey = (0, types_1.PubKey)('02ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382'); | ||
// invK is the modular inverse of k, the ephemeral key | ||
Tx.invK = (0, scryptlib_1.Int)('0xc8ffdbaa05d93aa4ede79ec58f06a72562048b775a3507c2bf44bde4f007c40a'); | ||
// r is x coordinate of R, which is kG | ||
Tx.r = (0, scryptlib_1.Int)('0x1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c'); | ||
// rBigEndian is the signed magnitude representation of r, in big endian | ||
Tx.rBigEndian = (0, types_1.toByteString)('1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c'); | ||
return Tx; | ||
}()); | ||
} | ||
} | ||
exports.Tx = Tx; | ||
// The following arguments can be generated using sample code at | ||
// https://gist.github.com/scrypt-sv/f6882be580780a88984cee75dd1564c4.js | ||
Tx.privKey = (0, types_1.PrivKey)(0x26f00fe2340a84335ebdf30f57e9bb58487117b29355718f5e46bf5168d7df97n); | ||
Tx.pubKey = (0, types_1.PubKey)((0, types_1.toByteString)('02ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382')); | ||
// invK is the modular inverse of k, the ephemeral key | ||
Tx.invK = 0xc8ffdbaa05d93aa4ede79ec58f06a72562048b775a3507c2bf44bde4f007c40an; | ||
// r is x coordinate of R, which is kG | ||
Tx.r = 0x1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266cn; | ||
// rBigEndian is the signed magnitude representation of r, in big endian | ||
Tx.rBigEndian = (0, types_1.toByteString)('1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c'); | ||
/** | ||
* @category Standard Contracts | ||
*/ | ||
var Constants = /** @class */ (function () { | ||
function Constants() { | ||
} | ||
// number of string to denote input sequence | ||
Constants.InputSeqLen = (0, scryptlib_1.Int)(4); | ||
// number of string to denote output value | ||
Constants.OutputValueLen = (0, scryptlib_1.Int)(8); | ||
// number of string to denote a public key (compressed) | ||
Constants.PubKeyLen = (0, scryptlib_1.Int)(33); | ||
// number of string to denote a public key hash | ||
Constants.PubKeyHashLen = (0, scryptlib_1.Int)(20); | ||
// number of string to denote a tx id | ||
Constants.TxIdLen = (0, scryptlib_1.Int)(32); | ||
// number of string to denote a outpoint | ||
Constants.OutpointLen = (0, scryptlib_1.Int)(36); | ||
return Constants; | ||
}()); | ||
class Constants { | ||
} | ||
exports.Constants = Constants; | ||
// number of string to denote input sequence | ||
Constants.InputSeqLen = 4n; | ||
// number of string to denote output value | ||
Constants.OutputValueLen = 8n; | ||
// number of string to denote a public key (compressed) | ||
Constants.PubKeyLen = 33n; | ||
// number of string to denote a public key hash | ||
Constants.PubKeyHashLen = 20n; | ||
// number of string to denote a tx id | ||
Constants.TxIdLen = 32n; | ||
// number of string to denote a outpoint | ||
Constants.OutpointLen = 36n; | ||
//# sourceMappingURL=functions.js.map |
@@ -1,2 +0,2 @@ | ||
import { Bytes, SigHashPreimage, AbstractContract, Int } from "scryptlib"; | ||
import { Bytes, SigHashPreimage, AbstractContract } from "scryptlib"; | ||
import { SubBytes, SupportedParamType } from "scryptlib/dist/scryptTypes"; | ||
@@ -56,4 +56,4 @@ export { PubKey, Sig, SigHashPreimage, PrivKey, Ripemd160, PubKeyHash, Sha256, Sha1, OpCodeType, SigHashType } from "scryptlib"; | ||
export declare class HashedMap<K extends SupportedParamType, V extends SupportedParamType> { | ||
static readonly H_SIZE: Int; | ||
static readonly ITEM_SIZE: Int; | ||
static readonly H_SIZE = 32n; | ||
static readonly ITEM_SIZE = 64n; | ||
private innerMap; | ||
@@ -83,3 +83,3 @@ private _keyType?; | ||
innerSet: Set<E>; | ||
static readonly H_SIZE: Int; | ||
static readonly H_SIZE = 32n; | ||
private _elemType?; | ||
@@ -86,0 +86,0 @@ private _type?; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HashedSet = exports.HashedMap = exports.equals = exports.utf8ToByteString = exports.toByteString = exports.SigHashType = exports.OpCodeType = exports.Sha1 = exports.Sha256 = exports.PubKeyHash = exports.Ripemd160 = exports.PrivKey = exports.SigHashPreimage = exports.Sig = exports.PubKey = void 0; | ||
var scryptlib_1 = require("scryptlib"); | ||
var functions_1 = require("./functions"); | ||
const scryptlib_1 = require("scryptlib"); | ||
const functions_1 = require("./functions"); | ||
var scryptlib_2 = require("scryptlib"); | ||
@@ -37,7 +37,7 @@ Object.defineProperty(exports, "PubKey", { enumerable: true, get: function () { return scryptlib_2.PubKey; } }); | ||
if (Array.isArray(a[0])) { | ||
var results = []; | ||
for (var i = 0; i < a.length; i++) { | ||
let results = []; | ||
for (let i = 0; i < a.length; i++) { | ||
results.push(equals(a[i], b[i])); | ||
} | ||
for (var i = 0; i < results.length; i++) { | ||
for (let i = 0; i < results.length; i++) { | ||
if (!results[i]) { | ||
@@ -52,3 +52,3 @@ return false; | ||
} | ||
for (var i = 0; i < a.length; i++) { | ||
for (let i = 0; i < a.length; i++) { | ||
if (!equals(a[i], b[i])) { | ||
@@ -61,12 +61,12 @@ return false; | ||
function equalsStruct(a, b) { | ||
var akeys = Object.keys(a); | ||
var bkeys = Object.keys(b); | ||
let akeys = Object.keys(a); | ||
let bkeys = Object.keys(b); | ||
if (akeys.length !== bkeys.length) { | ||
return false; | ||
} | ||
var results = []; | ||
for (var i = 0; i < akeys.length; i++) { | ||
let results = []; | ||
for (let i = 0; i < akeys.length; i++) { | ||
results.push(equals(a[akeys[i]], b[bkeys[i]])); | ||
} | ||
for (var i = 0; i < results.length; i++) { | ||
for (let i = 0; i < results.length; i++) { | ||
if (!results[i]) { | ||
@@ -89,8 +89,8 @@ return false; | ||
; | ||
var HashedMap = /** @class */ (function () { | ||
function HashedMap(map) { | ||
class HashedMap { | ||
constructor(map) { | ||
this.innerMap = map; | ||
} | ||
HashedMap.prototype.init = function (type, clazz) { | ||
var _a = (0, scryptlib_1.parseGenericType)(type), name = _a[0], genericTypes = _a[1]; | ||
init(type, clazz) { | ||
const [name, genericTypes] = (0, scryptlib_1.parseGenericType)(type); | ||
this._keyType = genericTypes[0]; | ||
@@ -100,26 +100,25 @@ this._valueType = genericTypes[1]; | ||
this._type = type; | ||
}; | ||
} | ||
// compare two bytes' order | ||
HashedMap.prototype._checkInOrder = function (low, high) { | ||
_checkInOrder(low, high) { | ||
// Note: low & high are both 256 bits, so they can not be converted to the same number unless they are the same. | ||
// Not working if their size are not equal due to non-minimal number format, ex. unpack('7180') == unpack('710080') | ||
return (0, functions_1.unpack)(low) < (0, functions_1.unpack)(high); | ||
}; | ||
} | ||
// insert / update (`key`, `val`) at `idx`, return false if `idx` is invalid or hash256ed' `key` is not in ascending order | ||
HashedMap.prototype._set = function (key, val) { | ||
var _a, _b; | ||
var r = false; | ||
var size = this.size(); | ||
var newKeyHash = (_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(key.item, this._keyType); | ||
var newElem = newKeyHash + ((_b = this.DelegateClazz) === null || _b === void 0 ? void 0 : _b.flattenSha256(val, this._valueType)); | ||
if (key.idx >= (0, scryptlib_1.Int)(0) && key.idx <= size) { | ||
var isFirst = key.idx == (0, scryptlib_1.Int)(0); | ||
var isLast = key.idx >= size - (0, scryptlib_1.Int)(1); // idx == size if appending | ||
var before_1 = isFirst ? toByteString("") : this.data().slice(0, Number(key.idx * HashedMap.ITEM_SIZE) * 2); | ||
var curElem = key.idx == size ? toByteString("") : this.data().slice(Number(key.idx * HashedMap.ITEM_SIZE) * 2, Number(key.idx * HashedMap.ITEM_SIZE + HashedMap.ITEM_SIZE) * 2); | ||
var curKeyHash = curElem == toByteString("") ? toByteString("") : curElem.slice(0, Number(HashedMap.H_SIZE) * 2); | ||
var after_1 = isLast ? toByteString("") : this.data().slice(Number((key.idx + (0, scryptlib_1.Int)(1)) * HashedMap.ITEM_SIZE) * 2); | ||
_set(key, val) { | ||
let r = false; | ||
let size = this.size(); | ||
let newKeyHash = this.DelegateClazz?.flattenSha256(key.item, this._keyType); | ||
let newElem = newKeyHash + this.DelegateClazz?.flattenSha256(val, this._valueType); | ||
if (key.idx >= 0n && key.idx <= size) { | ||
let isFirst = key.idx == 0n; | ||
let isLast = key.idx >= size - 1n; // idx == size if appending | ||
let before = isFirst ? toByteString("") : this.data().slice(0, Number(key.idx * HashedMap.ITEM_SIZE) * 2); | ||
let curElem = key.idx == size ? toByteString("") : this.data().slice(Number(key.idx * HashedMap.ITEM_SIZE) * 2, Number(key.idx * HashedMap.ITEM_SIZE + HashedMap.ITEM_SIZE) * 2); | ||
let curKeyHash = curElem == toByteString("") ? toByteString("") : curElem.slice(0, Number(HashedMap.H_SIZE) * 2); | ||
let after = isLast ? toByteString("") : this.data().slice(Number((key.idx + 1n) * HashedMap.ITEM_SIZE) * 2); | ||
// check prevKeyHash < newKeyHash && newKeyHash < afterKeyHash | ||
if ((isFirst || this._checkInOrder(before_1.slice(Number((key.idx - (0, scryptlib_1.Int)(1)) * HashedMap.ITEM_SIZE) * 2, Number((key.idx - (0, scryptlib_1.Int)(1)) * HashedMap.ITEM_SIZE + HashedMap.H_SIZE) * 2), newKeyHash)) && | ||
(isLast || this._checkInOrder(newKeyHash, after_1.slice(0, Number(HashedMap.H_SIZE) * 2)))) { | ||
if ((isFirst || this._checkInOrder(before.slice(Number((key.idx - 1n) * HashedMap.ITEM_SIZE) * 2, Number((key.idx - 1n) * HashedMap.ITEM_SIZE + HashedMap.H_SIZE) * 2), newKeyHash)) && | ||
(isLast || this._checkInOrder(newKeyHash, after.slice(0, Number(HashedMap.H_SIZE) * 2)))) { | ||
if (curKeyHash == newKeyHash) { | ||
@@ -136,23 +135,21 @@ // update current element if key hashes matches | ||
return r; | ||
}; | ||
} | ||
// check whether if (`key`,`val`) exists at `idx` | ||
HashedMap.prototype._canGet = function (key, val) { | ||
var _a; | ||
var r = false; | ||
if (key.idx >= (0, scryptlib_1.Int)(0) && key.idx < this.size()) { | ||
var startPos = key.idx * HashedMap.ITEM_SIZE; | ||
var k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
var v = this.data().slice(Number(startPos + HashedMap.H_SIZE) * 2, Number(startPos + HashedMap.ITEM_SIZE) * 2); | ||
r = ((_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(key.item, this._keyType)) == k && this.DelegateClazz.flattenSha256(val, this._valueType) == v; | ||
_canGet(key, val) { | ||
let r = false; | ||
if (key.idx >= 0n && key.idx < this.size()) { | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
let v = this.data().slice(Number(startPos + HashedMap.H_SIZE) * 2, Number(startPos + HashedMap.ITEM_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k && this.DelegateClazz.flattenSha256(val, this._valueType) == v; | ||
} | ||
return r; | ||
}; | ||
} | ||
// delete `key` which at `idx` from map | ||
HashedMap.prototype._delete = function (key) { | ||
var _a; | ||
var r = false; | ||
_delete(key) { | ||
let r = false; | ||
if (key.idx >= 0 && key.idx < this.size()) { | ||
var startPos = key.idx * HashedMap.ITEM_SIZE; | ||
var k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
if (((_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(key.item, this._keyType)) == k) { | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
if (this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k) { | ||
r = true; | ||
@@ -162,29 +159,27 @@ } | ||
return r; | ||
}; | ||
} | ||
// check whether has `key` at `idx` | ||
HashedMap.prototype._has = function (key) { | ||
var _a; | ||
var r = false; | ||
_has(key) { | ||
let r = false; | ||
if (key.idx >= 0 && key.idx < this.size()) { | ||
var startPos = key.idx * HashedMap.ITEM_SIZE; | ||
var k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
r = ((_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(key.item, this._keyType)) == k; | ||
let startPos = key.idx * HashedMap.ITEM_SIZE; | ||
let k = this.data().slice(Number(startPos) * 2, Number(startPos + HashedMap.H_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(key.item, this._keyType) == k; | ||
} | ||
return r; | ||
}; | ||
} | ||
// delete all | ||
HashedMap.prototype.clear = function () { | ||
clear() { | ||
this.innerMap = new Map(); | ||
return true; | ||
}; | ||
} | ||
// return map size | ||
HashedMap.prototype.size = function () { | ||
size() { | ||
return BigInt((0, functions_1.len)(this.data())) / HashedMap.ITEM_SIZE; | ||
}; | ||
} | ||
// return the underlaying data storage | ||
HashedMap.prototype.data = function () { | ||
var _a; | ||
return (_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.toData(this.innerMap, this._type); | ||
}; | ||
HashedMap.prototype.set = function (key, value) { | ||
data() { | ||
return this.DelegateClazz?.toData(this.innerMap, this._type); | ||
} | ||
set(key, value) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
@@ -199,4 +194,4 @@ if (this._set(key, value)) { | ||
return true; | ||
}; | ||
HashedMap.prototype.has = function (key) { | ||
} | ||
has(key) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
@@ -206,4 +201,4 @@ return this._has(key); | ||
return this.innerMap.has(key.item); | ||
}; | ||
HashedMap.prototype.delete = function (key) { | ||
} | ||
delete(key) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
@@ -218,4 +213,4 @@ if (this._delete(key)) { | ||
return this.innerMap.delete(key.item); | ||
}; | ||
HashedMap.prototype.canGet = function (key, val) { | ||
} | ||
canGet(key, val) { | ||
if (this.DelegateClazz && this._keyType && this._valueType) { | ||
@@ -225,45 +220,43 @@ return this._canGet(key, val); | ||
return (this.innerMap.get(key.item) === val); | ||
}; | ||
HashedMap.prototype.toMap = function () { | ||
} | ||
toMap() { | ||
return this.innerMap; | ||
}; | ||
HashedMap.prototype.attach = function (map) { | ||
} | ||
attach(map) { | ||
this.innerMap = new Map(map); | ||
}; | ||
HashedMap.H_SIZE = (0, scryptlib_1.Int)(32); // hash256'ed key/value size, 32 bytes | ||
HashedMap.ITEM_SIZE = (0, scryptlib_1.Int)(64); // 2 * H_SIZE | ||
return HashedMap; | ||
}()); | ||
} | ||
} | ||
exports.HashedMap = HashedMap; | ||
var HashedSet = /** @class */ (function () { | ||
function HashedSet(set) { | ||
HashedMap.H_SIZE = 32n; // hash256'ed key/value size, 32 bytes | ||
HashedMap.ITEM_SIZE = 64n; // 2 * H_SIZE | ||
class HashedSet { | ||
constructor(set) { | ||
this.innerSet = set; | ||
} | ||
HashedSet.prototype.init = function (type, clazz) { | ||
var _a = (0, scryptlib_1.parseGenericType)(type), name = _a[0], genericTypes = _a[1]; | ||
init(type, clazz) { | ||
const [name, genericTypes] = (0, scryptlib_1.parseGenericType)(type); | ||
this._type = type; | ||
this._elemType = genericTypes[0]; | ||
this.DelegateClazz = clazz; | ||
}; | ||
} | ||
// compare two bytes' order | ||
HashedSet.prototype._checkInOrder = function (low, high) { | ||
_checkInOrder(low, high) { | ||
// Note: low & high are both 256 bits, so they can not be converted to the same number unless they are the same. | ||
// Not working if their size are not equal due to non-minimal number format, ex. unpack('7180') == unpack('710080') | ||
return (0, functions_1.unpack)(low) < (0, functions_1.unpack)(high); | ||
}; | ||
} | ||
// add / update element `elem` at `idx`, return false if `idx` is invalid or hash256ed' `elem` is not in ascending order | ||
HashedSet.prototype._add = function (elem) { | ||
var _a; | ||
var r = false; | ||
var size = this.size(); | ||
var newHash = (_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(elem.item, this._elemType); | ||
_add(elem) { | ||
let r = false; | ||
let size = this.size(); | ||
let newHash = this.DelegateClazz?.flattenSha256(elem.item, this._elemType); | ||
if (elem.idx >= 0 && elem.idx <= size) { | ||
var isFirst = elem.idx == (0, scryptlib_1.Int)(0); | ||
var isLast = elem.idx >= size - (0, scryptlib_1.Int)(1); // idx == size if appending | ||
var before_2 = isFirst ? toByteString("") : this.data().slice(0, Number(elem.idx * HashedSet.H_SIZE) * 2); | ||
var curHash = elem.idx == size ? toByteString("") : this.data().slice(Number(elem.idx * HashedSet.H_SIZE) * 2, Number(elem.idx * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2); | ||
var after_2 = isLast ? toByteString("") : this.data().slice(Number((elem.idx + (0, scryptlib_1.Int)(1)) * HashedSet.H_SIZE) * 2); | ||
let isFirst = elem.idx == 0n; | ||
let isLast = elem.idx >= size - 1n; // idx == size if appending | ||
let before = isFirst ? toByteString("") : this.data().slice(0, Number(elem.idx * HashedSet.H_SIZE) * 2); | ||
let curHash = elem.idx == size ? toByteString("") : this.data().slice(Number(elem.idx * HashedSet.H_SIZE) * 2, Number(elem.idx * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2); | ||
let after = isLast ? toByteString("") : this.data().slice(Number((elem.idx + 1n) * HashedSet.H_SIZE) * 2); | ||
// check prevHash < newHash && newHash < afterHash | ||
if ((isFirst || this._checkInOrder(before_2.slice(Number((elem.idx - (0, scryptlib_1.Int)(1)) * HashedSet.H_SIZE) * 2, Number((elem.idx - (0, scryptlib_1.Int)(1)) * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2), newHash)) && | ||
(isLast || this._checkInOrder(newHash, after_2.slice(0, Number(HashedSet.H_SIZE) * 2)))) { | ||
if ((isFirst || this._checkInOrder(before.slice(Number((elem.idx - 1n) * HashedSet.H_SIZE) * 2, Number((elem.idx - 1n) * HashedSet.H_SIZE + HashedSet.H_SIZE) * 2), newHash)) && | ||
(isLast || this._checkInOrder(newHash, after.slice(0, Number(HashedSet.H_SIZE) * 2)))) { | ||
if (curHash == newHash) { | ||
@@ -280,11 +273,10 @@ // duplicated adding | ||
return r; | ||
}; | ||
} | ||
// delete `elem` which at `idx` from set | ||
HashedSet.prototype._delete = function (elem) { | ||
var _a; | ||
var r = false; | ||
_delete(elem) { | ||
let r = false; | ||
if (elem.idx >= 0 && elem.idx < this.size()) { | ||
var startPos = elem.idx * HashedSet.H_SIZE; | ||
var v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
if (((_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(elem.item, this._elemType)) == v) { | ||
let startPos = elem.idx * HashedSet.H_SIZE; | ||
let v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
if (this.DelegateClazz?.flattenSha256(elem.item, this._elemType) == v) { | ||
r = true; | ||
@@ -294,15 +286,14 @@ } | ||
return r; | ||
}; | ||
} | ||
// check whether has `elem` at `idx` | ||
HashedSet.prototype._has = function (elem) { | ||
var _a; | ||
var r = false; | ||
_has(elem) { | ||
let r = false; | ||
if (elem.idx >= 0 && elem.idx < this.size()) { | ||
var startPos = elem.idx * HashedSet.H_SIZE; | ||
var v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
r = ((_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.flattenSha256(elem.item, this._elemType)) == v; | ||
let startPos = elem.idx * HashedSet.H_SIZE; | ||
let v = this.data().slice(Number(startPos) * 2, Number(startPos + HashedSet.H_SIZE) * 2); | ||
r = this.DelegateClazz?.flattenSha256(elem.item, this._elemType) == v; | ||
} | ||
return r; | ||
}; | ||
HashedSet.prototype.add = function (key) { | ||
} | ||
add(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
@@ -317,4 +308,4 @@ if (this._add(key)) { | ||
return true; | ||
}; | ||
HashedSet.prototype.has = function (key) { | ||
} | ||
has(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
@@ -324,4 +315,4 @@ return this._has(key); | ||
return this.innerSet.has(key.item); | ||
}; | ||
HashedSet.prototype.delete = function (key) { | ||
} | ||
delete(key) { | ||
if (this.DelegateClazz && this._elemType) { | ||
@@ -336,27 +327,25 @@ if (this._delete(key)) { | ||
return this.innerSet.delete(key.item); | ||
}; | ||
} | ||
// delete all | ||
HashedSet.prototype.clear = function () { | ||
clear() { | ||
this.innerSet = new Set(); | ||
return true; | ||
}; | ||
} | ||
// return set size | ||
HashedSet.prototype.size = function () { | ||
size() { | ||
return BigInt((0, functions_1.len)(this.data())) / HashedSet.H_SIZE; | ||
}; | ||
} | ||
// return the underlaying data storage | ||
HashedSet.prototype.data = function () { | ||
var _a; | ||
return (_a = this.DelegateClazz) === null || _a === void 0 ? void 0 : _a.toData(this.innerSet, this._type); | ||
}; | ||
HashedSet.prototype.toSet = function () { | ||
data() { | ||
return this.DelegateClazz?.toData(this.innerSet, this._type); | ||
} | ||
toSet() { | ||
return this.innerSet; | ||
}; | ||
HashedSet.prototype.attach = function (set) { | ||
} | ||
attach(set) { | ||
this.innerSet = new Set(set); | ||
}; | ||
HashedSet.H_SIZE = (0, scryptlib_1.Int)(32); // hash256'ed elem size, 32 bytes | ||
return HashedSet; | ||
}()); | ||
} | ||
} | ||
exports.HashedSet = HashedSet; | ||
HashedSet.H_SIZE = 32n; // hash256'ed elem size, 32 bytes | ||
//# sourceMappingURL=types.js.map |
@@ -7,3 +7,3 @@ import "reflect-metadata"; | ||
import { UTXO } from "../bsv/types"; | ||
import { TransformInfo, TranspileError } from "../transformation/transpiler"; | ||
import { TranspileError } from "../transformation/transpiler"; | ||
/** | ||
@@ -94,12 +94,6 @@ * A reference to an input of a transaction | ||
private delegateInstance; | ||
private static transformInfo; | ||
private static compileImpl; | ||
static compile(): Promise<TranspileError[] | undefined>; | ||
static loadArtifact(artifact: ContractArtifact): void; | ||
static init(transform: TransformInfo, artifact: ContractArtifact): void; | ||
private static _getTransform; | ||
private static _getScryptFile; | ||
private static _getArtifactFile; | ||
private static _loadArtifact; | ||
getContractArtifact(): ContractArtifact | undefined; | ||
private static _getCtxMethods; | ||
@@ -106,0 +100,0 @@ getCtxMethods(): string[]; |
@@ -25,47 +25,2 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -77,16 +32,16 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
require("reflect-metadata"); | ||
var fs = __importStar(require("fs")); | ||
var os_1 = require("os"); | ||
var path_1 = require("path"); | ||
var indexer_1 = require("../transformation/indexer"); | ||
var scryptlib_1 = require("scryptlib"); | ||
var types_1 = require("./builtins/types"); | ||
var functions_1 = require("./builtins/functions"); | ||
var clone_1 = __importDefault(require("clone")); | ||
var library_1 = require("./library"); | ||
var typeCheck_1 = require("scryptlib/dist/typeCheck"); | ||
var abstract_provider_1 = require("../bsv/abstract-provider"); | ||
var abstract_signer_1 = require("../bsv/abstract-signer"); | ||
var utils_1 = require("../bsv/utils"); | ||
var diffUtils_1 = require("./utils/diffUtils"); | ||
const fs = __importStar(require("fs")); | ||
const os_1 = require("os"); | ||
const path_1 = require("path"); | ||
const indexer_1 = require("../transformation/indexer"); | ||
const scryptlib_1 = require("scryptlib"); | ||
const types_1 = require("./builtins/types"); | ||
const functions_1 = require("./builtins/functions"); | ||
const clone_1 = __importDefault(require("clone")); | ||
const library_1 = require("./library"); | ||
const typeCheck_1 = require("scryptlib/dist/typeCheck"); | ||
const abstract_provider_1 = require("../bsv/abstract-provider"); | ||
const abstract_signer_1 = require("../bsv/abstract-signer"); | ||
const utils_1 = require("../bsv/utils"); | ||
const diffUtils_1 = require("./utils/diffUtils"); | ||
/** | ||
@@ -102,14 +57,10 @@ * The main contract class. To write a contract, extend this class as such: | ||
*/ | ||
var SmartContract = /** @class */ (function () { | ||
function SmartContract() { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
class SmartContract { | ||
constructor(...args) { | ||
this.enableUpdateEMC = false; // a flag indicateing whether can update `this.entryMethodCall` | ||
var DelegateClazz = this.getDelegateClazz(); | ||
const DelegateClazz = this.getDelegateClazz(); | ||
if (!DelegateClazz) { | ||
throw new Error("'".concat(this.constructor.name, ".compile' or '").concat(this.constructor.name, ".loadArtifact' should be called before initializing any instance!")); | ||
throw new Error(`'${this.constructor.name}.compile' or '${this.constructor.name}.loadArtifact' should be called before initializing any instance!`); | ||
} | ||
var args_ = args.map(function (arg, index) { | ||
const args_ = args.map((arg, index) => { | ||
if (arg instanceof library_1.SmartContractLib) { | ||
@@ -119,4 +70,4 @@ return arg.getArgs(); | ||
else if (arg instanceof types_1.HashedMap) { | ||
var ctorAbi = DelegateClazz.abi.find(function (abi) { return abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR; }); | ||
var type = ctorAbi.params[index].type; | ||
const ctorAbi = DelegateClazz.abi.find(abi => abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR); | ||
const type = ctorAbi.params[index].type; | ||
arg.init(type, DelegateClazz); | ||
@@ -126,4 +77,4 @@ return arg.toMap(); | ||
else if (arg instanceof types_1.HashedSet) { | ||
var ctorAbi = DelegateClazz.abi.find(function (abi) { return abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR; }); | ||
var type = ctorAbi.params[index].type; | ||
const ctorAbi = DelegateClazz.abi.find(abi => abi.type === scryptlib_1.ABIEntityType.CONSTRUCTOR); | ||
const type = ctorAbi.params[index].type; | ||
arg.init(type, DelegateClazz); | ||
@@ -134,151 +85,92 @@ return arg.toSet(); | ||
}); | ||
this.delegateInstance = new (DelegateClazz.bind.apply(DelegateClazz, __spreadArray([void 0], args_, false)))(); | ||
this.delegateInstance = new DelegateClazz(...args_); | ||
this.delegateInstance.isGenesis = false; | ||
} | ||
SmartContract.compileImpl = function (filePath) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var tmpDir, result, artifactFileName_1, artifactFile; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
tmpDir = fs.mkdtempSync((0, path_1.join)((0, os_1.tmpdir)(), "scrypt-ts-")); | ||
return [4 /*yield*/, (0, scryptlib_1.compileContractAsync)(filePath, { | ||
sourceMap: true, | ||
artifact: true, | ||
out: tmpDir | ||
})]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.errors.length > 0) { | ||
throw new Error("Compiled failed for class `".concat(this.name, "`, check the output details at project building time!")); | ||
} | ||
else { | ||
artifactFileName_1 = (0, path_1.basename)(filePath).replace('.scrypt', '.json'); | ||
artifactFile = fs.readdirSync(tmpDir).filter(function (fn) { return fn == artifactFileName_1; })[0]; | ||
if (artifactFile) { | ||
fs.copyFileSync((0, path_1.join)(tmpDir, artifactFile), (0, path_1.join)((0, path_1.dirname)(filePath), artifactFile)); | ||
} | ||
} | ||
return [2 /*return*/, result]; | ||
} | ||
}); | ||
static async compile() { | ||
const transform = this._getTransform(); | ||
if (!transform.success) { | ||
return transform.errors; | ||
} | ||
const tmpDir = fs.mkdtempSync((0, path_1.join)((0, os_1.tmpdir)(), "scrypt-ts-")); | ||
let filePath = this._getScryptFile(); | ||
const result = await (0, scryptlib_1.compileContractAsync)(filePath, { | ||
sourceMap: true, | ||
artifact: true, | ||
out: tmpDir | ||
}); | ||
}; | ||
SmartContract.compile = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var transform, artifact, filePath, result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
transform = this._getTransform(); | ||
if (!transform.success) { | ||
return [2 /*return*/, transform.errors]; | ||
} | ||
artifact = this._loadArtifact(); | ||
if (!artifact) return [3 /*break*/, 1]; | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(artifact); | ||
return [3 /*break*/, 3]; | ||
case 1: | ||
filePath = this._getScryptFile(); | ||
return [4 /*yield*/, this.compileImpl(filePath)]; | ||
case 2: | ||
result = _a.sent(); | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(result); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
SmartContract.loadArtifact = function (artifact) { | ||
var filePath = this._getScryptFile(); | ||
var sourceContent = fs.readFileSync(filePath, 'utf8'); | ||
var md5Hash = (0, scryptlib_1.md5)(sourceContent); | ||
if (result.errors.length > 0) { | ||
throw new Error(`Compiled failed for class \`${this.name}\`, check the output details at project building time!`); | ||
} | ||
else { | ||
const artifactFileName = (0, path_1.basename)(filePath).replace('.scrypt', '.json'); | ||
const artifactFile = fs.readdirSync(tmpDir).filter(fn => fn == artifactFileName)[0]; | ||
if (artifactFile) { | ||
fs.copyFileSync((0, path_1.join)(tmpDir, artifactFile), (0, path_1.join)((0, path_1.dirname)(filePath), artifactFile)); | ||
} | ||
} | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(result); | ||
} | ||
static loadArtifact(artifact) { | ||
let filePath = this._getScryptFile(); | ||
const sourceContent = fs.readFileSync(filePath, 'utf8'); | ||
const md5Hash = (0, scryptlib_1.md5)(sourceContent); | ||
if (this.name !== artifact.contract || artifact.md5 !== md5Hash) { | ||
throw new Error("Contract artifact file cannot match contract `".concat(this.name, "`!")); | ||
throw new Error(`Contract artifact file cannot match contract \`${this.name}\`!`); | ||
} | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(artifact); | ||
}; | ||
SmartContract.init = function (transform, artifact) { | ||
this.transformInfo = transform; | ||
this.DelegateClazz = (0, scryptlib_1.buildContractClass)(artifact); | ||
}; | ||
SmartContract._getTransform = function () { | ||
if (this.transformInfo) { | ||
return this.transformInfo; | ||
} | ||
var transformFile = Reflect.getMetadata("scrypt:transform", this); | ||
} | ||
static _getTransform() { | ||
let transformFile = Reflect.getMetadata("scrypt:transform", this); | ||
if (!transformFile) { | ||
throw new Error('the ts-scrypt transformer plugin may not be activated for the project, check your `tsconfig` file!'); | ||
} | ||
var srcFile = Reflect.getMetadata("__filename", this); | ||
var indexFile = indexer_1.Indexer.queryIndexFile(srcFile, process.cwd()); | ||
let srcFile = Reflect.getMetadata("__filename", this); | ||
let indexFile = indexer_1.Indexer.queryIndexFile(srcFile, process.cwd()); | ||
if (!indexFile) { | ||
throw new Error("can not find `scrypt.index.json` file for contract `".concat(this.name, "`, search path from ").concat(srcFile, " to ").concat(process.cwd())); | ||
throw new Error(`can not find \`scrypt.index.json\` file for contract \`${this.name}\`, search path from ${srcFile} to ${process.cwd()}`); | ||
} | ||
var indexer = new indexer_1.Indexer(indexFile); | ||
var filePath = indexer.getFullPath(transformFile); | ||
let indexer = new indexer_1.Indexer(indexFile); | ||
let filePath = indexer.getFullPath(transformFile); | ||
return JSON.parse(fs.readFileSync(filePath).toString()); | ||
}; | ||
SmartContract._getScryptFile = function () { | ||
var transform = this._getTransform(); | ||
var scryptFile = transform.scryptfile; | ||
} | ||
static _getScryptFile() { | ||
let transform = this._getTransform(); | ||
let scryptFile = transform.scryptfile; | ||
if (!scryptFile) { | ||
throw new Error('the ts-scrypt transformer plugin may not be activated for the project, check your `tsconfig` file!'); | ||
} | ||
var srcFile = Reflect.getMetadata("__filename", this); | ||
var indexFile = indexer_1.Indexer.queryIndexFile(srcFile, process.cwd()); | ||
let srcFile = Reflect.getMetadata("__filename", this); | ||
let indexFile = indexer_1.Indexer.queryIndexFile(srcFile, process.cwd()); | ||
if (!indexFile) { | ||
throw new Error("can not find `scrypt.index.json` file for contract `".concat(this.name, "`, search path from ").concat(srcFile, " to ").concat(process.cwd())); | ||
throw new Error(`can not find \`scrypt.index.json\` file for contract \`${this.name}\`, search path from ${srcFile} to ${process.cwd()}`); | ||
} | ||
var indexer = new indexer_1.Indexer(indexFile); | ||
var filePath = indexer.getFullPath(scryptFile); | ||
let indexer = new indexer_1.Indexer(indexFile); | ||
let filePath = indexer.getFullPath(scryptFile); | ||
if (!fs.existsSync(filePath)) { | ||
throw new Error("can not find the bundled scrypt file for `".concat(typeof this, "` at ").concat(filePath)); | ||
throw new Error(`can not find the bundled scrypt file for \`${typeof this}\` at ${filePath}`); | ||
} | ||
return filePath; | ||
}; | ||
SmartContract._getArtifactFile = function () { | ||
var scryptFile = this._getScryptFile(); | ||
return (0, path_1.join)((0, path_1.dirname)(scryptFile), "".concat((0, path_1.basename)(scryptFile, ".scrypt"), ".json")); | ||
}; | ||
SmartContract._loadArtifact = function () { | ||
var artifactFile = this._getArtifactFile(); | ||
if (!fs.existsSync(artifactFile)) { | ||
return undefined; | ||
} | ||
var artifact = JSON.parse(fs.readFileSync(artifactFile, 'utf8').toString()); | ||
var scryptFile = this._getScryptFile(); | ||
var sourceContent = fs.readFileSync(scryptFile, 'utf8'); | ||
if (artifact.contract !== this.name || artifact.md5 === (0, scryptlib_1.md5)(sourceContent)) { | ||
return artifact; | ||
} | ||
; | ||
}; | ||
SmartContract.prototype.getContractArtifact = function () { | ||
return Object.getPrototypeOf(this).constructor._loadArtifact(); | ||
}; | ||
SmartContract._getCtxMethods = function () { | ||
var transform = this._getTransform(); | ||
} | ||
static _getCtxMethods() { | ||
let transform = this._getTransform(); | ||
return transform.ctxMethods; | ||
}; | ||
SmartContract.prototype.getCtxMethods = function () { | ||
} | ||
getCtxMethods() { | ||
return Object.getPrototypeOf(this).constructor._getCtxMethods(); | ||
}; | ||
SmartContract.prototype.getDelegateClazz = function () { | ||
var _a; | ||
return (_a = Object.getOwnPropertyDescriptor(this.constructor, 'DelegateClazz')) === null || _a === void 0 ? void 0 : _a.value; | ||
}; | ||
SmartContract.prototype.verify = function (entryMethodInvoking) { | ||
var srcFile = Reflect.getMetadata("__filename", Object.getPrototypeOf(this).constructor); | ||
var scryptFile = Object.getPrototypeOf(this).constructor._getScryptFile(); | ||
var sourceMapFile = scryptFile.replace(/\.scrypt$/, '.scrypt.map'); | ||
} | ||
getDelegateClazz() { | ||
return Object.getOwnPropertyDescriptor(this.constructor, 'DelegateClazz')?.value; | ||
} | ||
verify(entryMethodInvoking) { | ||
let srcFile = Reflect.getMetadata("__filename", Object.getPrototypeOf(this).constructor); | ||
let scryptFile = Object.getPrototypeOf(this).constructor._getScryptFile(); | ||
const sourceMapFile = scryptFile.replace(/\.scrypt$/, '.scrypt.map'); | ||
if (!fs.existsSync(sourceMapFile)) { | ||
throw new Error("can not find the bundled sourcemap file for `".concat(typeof this, "` at ").concat(sourceMapFile)); | ||
throw new Error(`can not find the bundled sourcemap file for \`${typeof this}\` at ${sourceMapFile}`); | ||
} | ||
var sourceMap = JSON.parse(fs.readFileSync(sourceMapFile).toString()); | ||
var txContext = {}; | ||
let sourceMap = JSON.parse(fs.readFileSync(sourceMapFile).toString()); | ||
let txContext = {}; | ||
if (this.unlockFrom) { | ||
txContext.tx = this.unlockFrom.tx; | ||
var inputIndex = this.unlockFrom.inputIndex; | ||
let inputIndex = this.unlockFrom.inputIndex; | ||
txContext.inputIndex = inputIndex; | ||
@@ -288,19 +180,19 @@ txContext.inputSatoshis = this.unlockFrom.tx.inputs[inputIndex].output.satoshis; | ||
try { | ||
var verifyEntryCall_1 = (function (ec) { | ||
var result = ec.verify(txContext); | ||
const verifyEntryCall = ((ec) => { | ||
const result = ec.verify(txContext); | ||
if (!result.success && result.error) { | ||
var matches = /\[(.+?)\]\((.+?)#(\d+)\)/.exec(result.error); | ||
const matches = /\[(.+?)\]\((.+?)#(\d+)\)/.exec(result.error); | ||
result.error.substring(0, matches.index); | ||
var line = parseInt(matches[3]); | ||
var tsLine = sourceMap[line - 1][0][2] + 1; | ||
result.error = "[Go to Source](file://".concat(srcFile, ":").concat(tsLine, ")"); | ||
const line = parseInt(matches[3]); | ||
const tsLine = sourceMap[line - 1][0][2] + 1; | ||
result.error = `[Go to Source](file://${srcFile}:${tsLine})`; | ||
} | ||
return result; | ||
}).bind(this); | ||
var entryCall = this.buildEntryMethodCall(entryMethodInvoking); | ||
let entryCall = this.buildEntryMethodCall(entryMethodInvoking); | ||
if (entryCall instanceof Promise) { | ||
return entryCall.then(function (v) { return verifyEntryCall_1(v); }); | ||
return entryCall.then(v => verifyEntryCall(v)); | ||
} | ||
else { | ||
return verifyEntryCall_1(entryCall); | ||
return verifyEntryCall(entryCall); | ||
} | ||
@@ -311,8 +203,8 @@ } | ||
} | ||
}; | ||
SmartContract.prototype.getUnlockingScript = function (callPub) { | ||
} | ||
getUnlockingScript(callPub) { | ||
try { | ||
var r = this.clone().buildEntryMethodCall(callPub); | ||
let r = this.clone().buildEntryMethodCall(callPub); | ||
if (r instanceof Promise) { | ||
return r.then(function (v) { return v.unlockingScript; }); | ||
return r.then(v => v.unlockingScript); | ||
} | ||
@@ -326,71 +218,61 @@ else { | ||
} | ||
}; | ||
SmartContract.prototype.genLaunchConfig = function (a, tx, inputIndex) { | ||
} | ||
genLaunchConfig(a, tx, inputIndex) { | ||
return this.delegateInstance.genLaunchConfig(a, tx, inputIndex); | ||
}; | ||
} | ||
// sync properties values to delegateInstance iff it's not the genesis. | ||
SmartContract.prototype.syncStateProps = function () { | ||
var _this = this; | ||
syncStateProps() { | ||
if (!this.delegateInstance.isGenesis) { | ||
var statePropKeys = Reflect.getMetadata("scrypt:stateProps", this) || []; | ||
statePropKeys.forEach(function (statePropKey) { | ||
if (_this[statePropKey] instanceof library_1.SmartContractLib) { | ||
_this.delegateInstance[statePropKey] = _this[statePropKey].getState(); | ||
const statePropKeys = Reflect.getMetadata("scrypt:stateProps", this) || []; | ||
statePropKeys.forEach(statePropKey => { | ||
if (this[statePropKey] instanceof library_1.SmartContractLib) { | ||
this.delegateInstance[statePropKey] = this[statePropKey].getState(); | ||
} | ||
else if (_this[statePropKey] instanceof types_1.HashedMap) { | ||
_this.delegateInstance[statePropKey] = _this[statePropKey].toMap(); | ||
else if (this[statePropKey] instanceof types_1.HashedMap) { | ||
this.delegateInstance[statePropKey] = this[statePropKey].toMap(); | ||
} | ||
else if (_this[statePropKey] instanceof types_1.HashedSet) { | ||
_this.delegateInstance[statePropKey] = _this[statePropKey].toSet(); | ||
else if (this[statePropKey] instanceof types_1.HashedSet) { | ||
this.delegateInstance[statePropKey] = this[statePropKey].toSet(); | ||
} | ||
else { | ||
_this.delegateInstance[statePropKey] = _this[statePropKey]; | ||
this.delegateInstance[statePropKey] = this[statePropKey]; | ||
} | ||
}); | ||
} | ||
}; | ||
Object.defineProperty(SmartContract.prototype, "lockingScript", { | ||
get: function () { | ||
this.syncStateProps(); | ||
return this.delegateInstance.lockingScript; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(SmartContract.prototype, "codePart", { | ||
get: function () { | ||
return this.delegateInstance.codePart.toHex(); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
SmartContract.prototype.clone = function () { | ||
var obj = (0, clone_1.default)(this); | ||
} | ||
get lockingScript() { | ||
this.syncStateProps(); | ||
return this.delegateInstance.lockingScript; | ||
} | ||
get codePart() { | ||
return this.delegateInstance.codePart.toHex(); | ||
} | ||
clone() { | ||
const obj = (0, clone_1.default)(this); | ||
return obj; | ||
}; | ||
SmartContract.prototype.next = function () { | ||
var obj = (0, clone_1.default)(this); | ||
} | ||
next() { | ||
const obj = (0, clone_1.default)(this); | ||
obj.delegateInstance.isGenesis = false; | ||
obj.syncStateProps(); | ||
return obj; | ||
}; | ||
SmartContract.prototype.markAsGenesis = function () { | ||
} | ||
markAsGenesis() { | ||
this.delegateInstance.isGenesis = true; | ||
return this; | ||
}; | ||
SmartContract.prototype.updateStateSigHashType = function (txPreimage, amount, sigHashType) { | ||
} | ||
updateStateSigHashType(txPreimage, amount, sigHashType) { | ||
(0, functions_1.assert)(this.checkPreimageSigHashType(txPreimage, sigHashType)); | ||
var output = this.buildStateOutput(amount); | ||
let output = this.buildStateOutput(amount); | ||
return (0, functions_1.hash256)(output) == functions_1.SigHash.hashOutputs(txPreimage); | ||
}; | ||
SmartContract.prototype.buildStateOutput = function (amount) { | ||
var outputScript = this.getStateScript(); | ||
} | ||
buildStateOutput(amount) { | ||
let outputScript = this.getStateScript(); | ||
return functions_1.Utils.buildOutput(outputScript, amount); | ||
}; | ||
SmartContract.prototype.getStateScript = function () { | ||
var _this = this; | ||
var sBuf = functions_1.VarIntWriter.writeBool(false); | ||
} | ||
getStateScript() { | ||
let sBuf = functions_1.VarIntWriter.writeBool(false); | ||
this.delegateInstance.stateProps | ||
.forEach(function (p) { | ||
var value = _this[p.name]; | ||
.forEach(p => { | ||
let value = this[p.name]; | ||
if (value instanceof types_1.HashedMap || value instanceof types_1.HashedSet) { | ||
@@ -403,6 +285,6 @@ value = { | ||
value: value | ||
}), _this.delegateInstance.resolver, { | ||
}), this.delegateInstance.resolver, { | ||
state: true, | ||
ignoreValue: false | ||
}).forEach(function (p) { | ||
}).forEach(p => { | ||
if (['bytes', 'PubKey', 'Ripemd160', 'Sig', 'Sha1', 'SigHashPreimage', 'Sha256', 'SigHashType', 'OpCodeType'].includes(p.type)) { | ||
@@ -420,3 +302,3 @@ sBuf += functions_1.VarIntWriter.writeBytes(p.value); | ||
return this.codePart + functions_1.VarIntWriter.serializeState(sBuf); | ||
}; | ||
} | ||
/** | ||
@@ -427,7 +309,7 @@ * verifies an ECDSA signature. It takes two inputs from the stack, a public key (on top of the stack) and an ECDSA signature in its DER_CANONISED format concatenated with sighash flags. It outputs true or false on the stack based on whether the signature check passes or fails. | ||
*/ | ||
SmartContract.prototype.checkSig = function (signature, publickey) { | ||
checkSig(signature, publickey) { | ||
if (!this.checkSignatureEncoding(signature) || !this.checkPubkeyEncoding(publickey)) { | ||
return false; | ||
} | ||
var fSuccess = false; | ||
let fSuccess = false; | ||
if (!this.unlockFrom) { | ||
@@ -437,7 +319,7 @@ throw new Error('unlockFrom should be set when checkSig executes'); | ||
try { | ||
var sig = scryptlib_1.bsv.crypto.Signature.fromTxFormat(Buffer.from((0, types_1.toByteString)(signature), 'hex')); | ||
var pubkey = scryptlib_1.bsv.PublicKey.fromBuffer(Buffer.from((0, types_1.toByteString)(publickey), 'hex'), false); | ||
var tx = this.unlockFrom.tx; | ||
var inputIndex = this.unlockFrom.inputIndex || 0; | ||
var inputSatoshis = this.unlockFrom.tx.inputs[inputIndex].output.satoshis; | ||
const sig = scryptlib_1.bsv.crypto.Signature.fromTxFormat(Buffer.from((0, types_1.toByteString)(signature), 'hex')); | ||
const pubkey = scryptlib_1.bsv.PublicKey.fromBuffer(Buffer.from((0, types_1.toByteString)(publickey), 'hex'), false); | ||
const tx = this.unlockFrom.tx; | ||
const inputIndex = this.unlockFrom.inputIndex || 0; | ||
const inputSatoshis = this.unlockFrom.tx.inputs[inputIndex].output.satoshis; | ||
fSuccess = tx.verifySignature(sig, pubkey, inputIndex, this.delegateInstance.lockingScript, scryptlib_1.bsv.crypto.BN.fromNumber(inputSatoshis), scryptlib_1.DEFAULT_FLAGS); | ||
@@ -450,17 +332,17 @@ } | ||
return fSuccess; | ||
}; | ||
} | ||
// rBigEndian must be mininally encoded, to conform to strict DER rule https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#der-encoding | ||
SmartContract.prototype.checkPreimageAdvanced = function (txPreimage, privKey, pubKey, inverseK, r, rBigEndian, sigHashType) { | ||
checkPreimageAdvanced(txPreimage, privKey, pubKey, inverseK, r, rBigEndian, sigHashType) { | ||
// hash is big endian | ||
var h = (0, functions_1.hash256)((0, types_1.toByteString)(txPreimage)); | ||
var sig = functions_1.Tx.sign(functions_1.Tx.fromBEUnsigned(h), privKey, inverseK, r, rBigEndian, sigHashType); | ||
let h = (0, functions_1.hash256)((0, types_1.toByteString)(txPreimage)); | ||
let sig = functions_1.Tx.sign(functions_1.Tx.fromBEUnsigned(h), privKey, inverseK, r, rBigEndian, sigHashType); | ||
return this.checkSig(sig, pubKey); | ||
}; | ||
} | ||
// wrapper for OP_PUSH_TX with customized sighash type | ||
SmartContract.prototype.checkPreimageSigHashType = function (txPreimage, sigHashType) { | ||
checkPreimageSigHashType(txPreimage, sigHashType) { | ||
return this.checkPreimageAdvanced(txPreimage, functions_1.Tx.privKey, functions_1.Tx.pubKey, functions_1.Tx.invK, functions_1.Tx.r, functions_1.Tx.rBigEndian, sigHashType); | ||
}; | ||
SmartContract.prototype.checkPreimage = function (txPreimage) { | ||
} | ||
checkPreimage(txPreimage) { | ||
return this.checkPreimageAdvanced(txPreimage, functions_1.Tx.privKey, functions_1.Tx.pubKey, functions_1.Tx.invK, functions_1.Tx.r, functions_1.Tx.rBigEndian, functions_1.SigHash.ALL); | ||
}; | ||
} | ||
/** | ||
@@ -471,10 +353,10 @@ * Compares the first signature against each public key until it finds an ECDSA match. Starting with the subsequent public key, it compares the second signature against each remaining public key until it finds an ECDSA match. The process is repeated until all signatures have been checked or not enough public keys remain to produce a successful result. All signatures need to match a public key. Because public keys are not checked again if they fail any signature comparison, signatures must be placed in the scriptSig using the same order as their corresponding public keys were placed in the scriptPubKey or redeemScript. If all signatures are valid, 1 is returned, 0 otherwise. Due to a bug, one extra unused value is removed from the stack. | ||
*/ | ||
SmartContract.prototype.checkMultiSig = function (signatures, publickeys) { | ||
checkMultiSig(signatures, publickeys) { | ||
//TODO: unimplemented | ||
return true; | ||
}; | ||
SmartContract.prototype.updateState = function (preimage, amount) { | ||
} | ||
updateState(preimage, amount) { | ||
return this.updateStateSigHashType(preimage, amount, functions_1.SigHash.ALL); | ||
}; | ||
SmartContract.prototype.checkPubkeyEncoding = function (publickey) { | ||
} | ||
checkPubkeyEncoding(publickey) { | ||
if ((scryptlib_1.DEFAULT_FLAGS & scryptlib_1.bsv.Script.Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0 && !scryptlib_1.bsv.PublicKey.isValid((0, types_1.toByteString)(publickey))) { | ||
@@ -484,4 +366,4 @@ return false; | ||
return true; | ||
}; | ||
SmartContract.prototype.checkSignatureEncoding = function (signature) { | ||
} | ||
checkSignatureEncoding(signature) { | ||
var buf = Buffer.from((0, types_1.toByteString)(signature), 'hex'); | ||
@@ -518,10 +400,5 @@ var sig; | ||
return true; | ||
}; | ||
SmartContract.prototype.callDelegatedMethod = function (methodName) { | ||
var _a; | ||
var args = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
args[_i - 1] = arguments[_i]; | ||
} | ||
var abi = this.getDelegateClazz().abi.find(function (func) { return func.name === methodName; }); | ||
} | ||
callDelegatedMethod(methodName, ...args) { | ||
const abi = this.getDelegateClazz().abi.find(func => func.name === methodName); | ||
if (abi) { | ||
@@ -535,6 +412,6 @@ // only entry (public) method calls will be delegated to the target instance. | ||
} | ||
var txPreimage = (0, types_1.SigHashPreimage)(this.unlockFrom.tx.getPreimage(this._unlockFrom.inputIndex)); | ||
const txPreimage = (0, types_1.SigHashPreimage)(this.unlockFrom.tx.getPreimage(this._unlockFrom.inputIndex)); | ||
args.push(txPreimage); | ||
} | ||
return (_a = this.getDelegateClazz().prototype[methodName]).call.apply(_a, __spreadArray([this.delegateInstance], args, false)); | ||
return this.getDelegateClazz().prototype[methodName].call(this.delegateInstance, ...args); | ||
} | ||
@@ -544,33 +421,28 @@ else { | ||
} | ||
}; | ||
SmartContract.prototype.setDataPartInASM = function (dataPart) { | ||
} | ||
setDataPartInASM(dataPart) { | ||
this.delegateInstance.setDataPartInASM(dataPart); | ||
}; | ||
SmartContract.prototype.setDataPartInHex = function (dataPart) { | ||
} | ||
setDataPartInHex(dataPart) { | ||
this.delegateInstance.setDataPartInHex(dataPart); | ||
}; | ||
Object.defineProperty(SmartContract.prototype, "dataPart", { | ||
get: function () { | ||
return this.delegateInstance.dataPart; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
SmartContract.prototype.buildEntryMethodCall = function (callPub) { | ||
var _this = this; | ||
} | ||
get dataPart() { | ||
return this.delegateInstance.dataPart; | ||
} | ||
buildEntryMethodCall(callPub) { | ||
this.entryMethodCall = undefined; | ||
this.enableUpdateEMC = true; | ||
var afterCall = (function () { | ||
if (!_this.entryMethodCall) { | ||
const afterCall = (() => { | ||
if (!this.entryMethodCall) { | ||
throw new Error('a contract public method should be called on the `self` parameter within the `callPub` function'); | ||
} | ||
var entryCall = _this.entryMethodCall; | ||
_this.entryMethodCall = undefined; | ||
_this.enableUpdateEMC = false; | ||
const entryCall = this.entryMethodCall; | ||
this.entryMethodCall = undefined; | ||
this.enableUpdateEMC = false; | ||
return entryCall; | ||
}).bind(this); | ||
// `this.entryMethodCall` should be set properly in call back: `callPub` | ||
var callPubRet = callPub(this); | ||
const callPubRet = callPub(this); | ||
if (callPubRet instanceof Promise) { | ||
return callPubRet.then(function () { return afterCall(); }); | ||
return callPubRet.then(() => afterCall()); | ||
} | ||
@@ -580,43 +452,35 @@ else { | ||
} | ||
}; | ||
Object.defineProperty(SmartContract.prototype, "unlockFrom", { | ||
get: function () { | ||
return this._unlockFrom; | ||
}, | ||
set: function (ref) { | ||
this._unlockFrom = ref; | ||
var txPreimage = (0, types_1.SigHashPreimage)(ref.tx.getPreimage(ref.inputIndex)); | ||
var outpoint = functions_1.SigHash.outpoint(txPreimage); | ||
this.ctx = { | ||
version: functions_1.SigHash.nVersion(txPreimage), | ||
utxo: { | ||
value: functions_1.SigHash.value(txPreimage), | ||
script: functions_1.SigHash.scriptCode(txPreimage), | ||
outpoint: { | ||
txid: outpoint.slice(0, 32 * 2), | ||
outputIndex: functions_1.Utils.fromLEUnsigned(outpoint.slice(32 * 2)) | ||
} | ||
}, | ||
hashPrevouts: functions_1.SigHash.hashPrevouts(txPreimage), | ||
hashSequence: functions_1.SigHash.hashSequence(txPreimage), | ||
sequence: functions_1.SigHash.nSequence(txPreimage), | ||
hashOutputs: functions_1.SigHash.hashOutputs(txPreimage), | ||
locktime: functions_1.SigHash.nLocktime(txPreimage), | ||
sigHashType: functions_1.SigHash.sigHashType(txPreimage), | ||
}; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(SmartContract.prototype, "lockTo", { | ||
get: function () { | ||
return this._lockTo; | ||
}, | ||
set: function (ref) { | ||
this._lockTo = ref; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
SmartContract.prototype.connect = function (providerOrSigner) { | ||
} | ||
set unlockFrom(ref) { | ||
this._unlockFrom = ref; | ||
const txPreimage = (0, types_1.SigHashPreimage)(ref.tx.getPreimage(ref.inputIndex)); | ||
const outpoint = functions_1.SigHash.outpoint(txPreimage); | ||
this.ctx = { | ||
version: functions_1.SigHash.nVersion(txPreimage), | ||
utxo: { | ||
value: functions_1.SigHash.value(txPreimage), | ||
script: functions_1.SigHash.scriptCode(txPreimage), | ||
outpoint: { | ||
txid: outpoint.slice(0, 32 * 2), | ||
outputIndex: functions_1.Utils.fromLEUnsigned(outpoint.slice(32 * 2)) | ||
} | ||
}, | ||
hashPrevouts: functions_1.SigHash.hashPrevouts(txPreimage), | ||
hashSequence: functions_1.SigHash.hashSequence(txPreimage), | ||
sequence: functions_1.SigHash.nSequence(txPreimage), | ||
hashOutputs: functions_1.SigHash.hashOutputs(txPreimage), | ||
locktime: functions_1.SigHash.nLocktime(txPreimage), | ||
sigHashType: functions_1.SigHash.sigHashType(txPreimage), | ||
}; | ||
} | ||
get unlockFrom() { | ||
return this._unlockFrom; | ||
} | ||
get lockTo() { | ||
return this._lockTo; | ||
} | ||
set lockTo(ref) { | ||
this._lockTo = ref; | ||
} | ||
connect(providerOrSigner) { | ||
if (abstract_signer_1.Signer.isSigner(providerOrSigner)) { | ||
@@ -632,25 +496,17 @@ this._signer = providerOrSigner; | ||
} | ||
}; | ||
Object.defineProperty(SmartContract.prototype, "signer", { | ||
get: function () { | ||
if (!this._signer) { | ||
throw new Error('signer has not been connected yet! call `contract.connect(signer)`'); | ||
} | ||
return this._signer; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(SmartContract.prototype, "provider", { | ||
get: function () { | ||
if (!this._provider) { | ||
throw new Error('provider has not been connected yet! call `contract.connect(providerOrSigner)`'); | ||
} | ||
return this._provider; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
SmartContract.prototype.buildDeployTransaction = function (utxos, amount, changeAddress) { | ||
var deployTx = new scryptlib_1.bsv.Transaction().from(utxos) | ||
} | ||
get signer() { | ||
if (!this._signer) { | ||
throw new Error('signer has not been connected yet! call `contract.connect(signer)`'); | ||
} | ||
return this._signer; | ||
} | ||
get provider() { | ||
if (!this._provider) { | ||
throw new Error('provider has not been connected yet! call `contract.connect(providerOrSigner)`'); | ||
} | ||
return this._provider; | ||
} | ||
buildDeployTransaction(utxos, amount, changeAddress) { | ||
const deployTx = new scryptlib_1.bsv.Transaction().from(utxos) | ||
.addOutput(new scryptlib_1.bsv.Transaction.Output({ | ||
@@ -667,40 +523,18 @@ script: this.lockingScript, | ||
return deployTx; | ||
}; | ||
SmartContract.prototype.deploy = function (amount, options) { | ||
if (amount === void 0) { amount = 1; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var changeAddress, _a, dummyTx, estimatedFee, requestAmt, address, _b, utxos, deployTx; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
this.markAsGenesis(); | ||
_a = (options === null || options === void 0 ? void 0 : options.changeAddress); | ||
if (_a) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.signer.getDefaultAddress()]; | ||
case 1: | ||
_a = (_c.sent()); | ||
_c.label = 2; | ||
case 2: | ||
changeAddress = _a; | ||
dummyTx = this.buildDeployTransaction((0, utils_1.getDummyP2pkhUTXOs)(2), amount, changeAddress); | ||
estimatedFee = dummyTx.getEstimateFee(); | ||
requestAmt = amount + estimatedFee; | ||
_b = (options === null || options === void 0 ? void 0 : options.address); | ||
if (_b) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, this.signer.getDefaultAddress()]; | ||
case 3: | ||
_b = (_c.sent()); | ||
_c.label = 4; | ||
case 4: | ||
address = _b; | ||
return [4 /*yield*/, this.signer.listUnspent(address, { minSatoshis: requestAmt })]; | ||
case 5: | ||
utxos = _c.sent(); | ||
deployTx = this.buildDeployTransaction(utxos, amount, changeAddress); | ||
return [2 /*return*/, this.signer.signAndsendTransaction(deployTx, { address: address })]; | ||
} | ||
}); | ||
}); | ||
}; | ||
SmartContract.findKeyIndex = function (collection, key, keyType) { | ||
} | ||
async deploy(amount = 1, options) { | ||
this.markAsGenesis(); | ||
/** | ||
* Use a dummy transaction to estimate fee. | ||
* Add two p2pkh inputs trying to avoid re-fetching utxos if the request amount is not enough. | ||
*/ | ||
const dummyTx = this.buildDeployTransaction((0, utils_1.getDummyP2pkhUTXOs)(2), amount, options?.changeAddress); | ||
const estimatedFee = dummyTx.getEstimateFee(); | ||
const requestAmt = amount + estimatedFee; | ||
const address = options?.address || await this.signer.getDefaultAddress(); | ||
const utxos = await this.signer.listUnspent(address, { minSatoshis: requestAmt }); | ||
const deployTx = this.buildDeployTransaction(utxos, amount, options?.changeAddress); | ||
return this.signer.signAndsendTransaction(deployTx, { address }); | ||
} | ||
static findKeyIndex(collection, key, keyType) { | ||
if (!keyType) { | ||
@@ -722,4 +556,4 @@ switch (typeof key) { | ||
return this.DelegateClazz.findKeyIndex(collection, key, keyType); | ||
}; | ||
SmartContract.prototype.diffOutputs = function (outputs) { | ||
} | ||
diffOutputs(outputs) { | ||
if (!this.unlockFrom) { | ||
@@ -729,3 +563,3 @@ throw new Error('unlockFrom should be set'); | ||
try { | ||
var info = (0, diffUtils_1.diffOutputs)(this.delegateInstance, outputs, this.unlockFrom.tx); | ||
const info = (0, diffUtils_1.diffOutputs)(this.delegateInstance, outputs, this.unlockFrom.tx); | ||
console.info(info); | ||
@@ -737,19 +571,13 @@ } | ||
} | ||
}; | ||
Object.defineProperty(SmartContract.prototype, "debug", { | ||
get: function () { | ||
var self = this; | ||
return { | ||
diffOutputs: function (outputs) { | ||
self.diffOutputs(outputs); | ||
} | ||
}; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
SmartContract.transformInfo = undefined; | ||
return SmartContract; | ||
}()); | ||
} | ||
get debug() { | ||
const self = this; | ||
return { | ||
diffOutputs: (outputs) => { | ||
self.diffOutputs(outputs); | ||
} | ||
}; | ||
} | ||
} | ||
exports.SmartContract = SmartContract; | ||
//# sourceMappingURL=contract.js.map |
"use strict"; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.prop = exports.method = void 0; | ||
var dist_1 = require("scryptlib/dist"); | ||
var functions_1 = require("./builtins/functions"); | ||
const dist_1 = require("scryptlib/dist"); | ||
const functions_1 = require("./builtins/functions"); | ||
/** | ||
@@ -19,52 +10,46 @@ * Indicates whether the method is a contract method, and ordinary methods do not affect the execution of the contract | ||
*/ | ||
function method(sigHashType) { | ||
if (sigHashType === void 0) { sigHashType = functions_1.SigHash.ALL; } | ||
function method(sigHashType = functions_1.SigHash.ALL) { | ||
return function (target, methodName, descriptor) { | ||
var originalMethod = descriptor.value; | ||
var newDescriptor = { | ||
const originalMethod = descriptor.value; | ||
const newDescriptor = { | ||
configurable: true, | ||
enumerable: false, | ||
get: function () { | ||
var _this = this; | ||
var wrappedMethod = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
get() { | ||
const wrappedMethod = (...args) => { | ||
// static method on subclasses of `SmartContract` | ||
var isSmartContractLibStatic = typeof target === "function" | ||
&& Object.getPrototypeOf(_this).name === "SmartContractLib"; | ||
const isSmartContractLibStatic = typeof target === "function" | ||
&& Object.getPrototypeOf(this).name === "SmartContractLib"; | ||
// instance method on subclasses of `SmartContractLib` | ||
var isSmartContractLibMethod = typeof target === "object" | ||
&& Object.getPrototypeOf(_this.constructor).name === "SmartContractLib"; | ||
const isSmartContractLibMethod = typeof target === "object" | ||
&& Object.getPrototypeOf(this.constructor).name === "SmartContractLib"; | ||
if (isSmartContractLibStatic || isSmartContractLibMethod) { | ||
return originalMethod.apply(_this, args); | ||
return originalMethod.apply(this, args); | ||
} | ||
// static method on subclasses of `SmartContract` | ||
var isSmartContractStatic = typeof target === "function" | ||
&& Object.getPrototypeOf(_this).name === "SmartContract"; | ||
const isSmartContractStatic = typeof target === "function" | ||
&& Object.getPrototypeOf(this).name === "SmartContract"; | ||
// instance method on subclasses of `SmartContract` | ||
var isSmartContractMethod = typeof target === "object" | ||
&& Object.getPrototypeOf(_this.constructor).name === "SmartContract"; | ||
const isSmartContractMethod = typeof target === "object" | ||
&& Object.getPrototypeOf(this.constructor).name === "SmartContract"; | ||
if (isSmartContractStatic || isSmartContractMethod) { | ||
// update `this.entryMethodCall` iff the update flag is true & its value is undefined. | ||
if (_this.enableUpdateEMC && !_this.entryMethodCall) { | ||
_this.entryMethodCall = _this.callDelegatedMethod.apply(_this, __spreadArray([methodName], args, false)); | ||
var ctxMethods = _this.getCtxMethods(); | ||
if (this.enableUpdateEMC && !this.entryMethodCall) { | ||
this.entryMethodCall = this.callDelegatedMethod(methodName, ...args); | ||
const ctxMethods = this.getCtxMethods(); | ||
// check preimage before run the method | ||
if (ctxMethods.includes(methodName)) { | ||
if (!_this.unlockFrom) { | ||
if (!this.unlockFrom) { | ||
throw new Error('unlockFrom should be set'); | ||
} | ||
var ref = _this.unlockFrom; | ||
var txPreimage = (0, dist_1.SigHashPreimage)(ref.tx.getPreimage(ref.inputIndex)); | ||
(0, functions_1.assert)(_this.checkPreimageSigHashType(txPreimage, sigHashType)); | ||
const ref = this.unlockFrom; | ||
const txPreimage = (0, dist_1.SigHashPreimage)(ref.tx.getPreimage(ref.inputIndex)); | ||
(0, functions_1.assert)(this.checkPreimageSigHashType(txPreimage, sigHashType)); | ||
} | ||
if (_this.entryMethodCall) { | ||
args = _this.entryMethodCall.args.map(function (a) { return a.value; }); | ||
if (this.entryMethodCall) { | ||
args = this.entryMethodCall.args.map(a => a.value); | ||
} | ||
} | ||
return originalMethod.apply(_this, args); | ||
return originalMethod.apply(this, args); | ||
} | ||
throw new Error("@method decorator used on `".concat(_this.name || _this.constructor.name, "#").concat(methodName, "`, it should only be used in subclasses of `SmartContract`")); | ||
throw new Error(`@method decorator used on \`${this.name || this.constructor.name}#${methodName}\`, it should only be used in subclasses of \`SmartContract\``); | ||
}; | ||
@@ -83,8 +68,7 @@ return wrappedMethod; | ||
*/ | ||
function prop(state) { | ||
if (state === void 0) { state = false; } | ||
function prop(state = false) { | ||
return function (target, propertyName) { | ||
if (state) { | ||
var statePropsMetaKey = "scrypt:stateProps"; | ||
var stateProps = (Reflect.getMetadata(statePropsMetaKey, target) || []).concat(propertyName); | ||
const statePropsMetaKey = "scrypt:stateProps"; | ||
let stateProps = (Reflect.getMetadata(statePropsMetaKey, target) || []).concat(propertyName); | ||
Reflect.defineMetadata(statePropsMetaKey, stateProps, target); | ||
@@ -91,0 +75,0 @@ } |
@@ -15,13 +15,9 @@ "use strict"; | ||
*/ | ||
var SmartContractLib = /** @class */ (function () { | ||
function SmartContractLib() { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
class SmartContractLib { | ||
constructor(...args) { | ||
this.args = []; | ||
this.args = args; | ||
} | ||
SmartContractLib.prototype.getArgs = function () { | ||
return (this.args || []).map(function (arg) { | ||
getArgs() { | ||
return (this.args || []).map(arg => { | ||
if (arg instanceof SmartContractLib) { | ||
@@ -32,16 +28,14 @@ return arg.getArgs(); | ||
}); | ||
}; | ||
SmartContractLib.prototype.getState = function () { | ||
var _this = this; | ||
return Object.keys(this).reduce(function (acc, key) { | ||
var _a, _b; | ||
if (typeof _this[key] === 'bigint' || typeof _this[key] === 'boolean' || typeof _this[key] === 'string') { | ||
return Object.assign(acc, (_a = {}, | ||
_a[key] = _this[key], | ||
_a)); | ||
} | ||
getState() { | ||
return Object.keys(this).reduce((acc, key) => { | ||
if (typeof this[key] === 'bigint' || typeof this[key] === 'boolean' || typeof this[key] === 'string') { | ||
return Object.assign(acc, { | ||
[key]: this[key] | ||
}); | ||
} | ||
else if (_this[key] instanceof SmartContractLib) { | ||
return Object.assign(acc, (_b = {}, | ||
_b[key] = _this[key].getState(), | ||
_b)); | ||
else if (this[key] instanceof SmartContractLib) { | ||
return Object.assign(acc, { | ||
[key]: this[key].getState() | ||
}); | ||
} | ||
@@ -52,6 +46,5 @@ else { | ||
}, {}); | ||
}; | ||
return SmartContractLib; | ||
}()); | ||
} | ||
} | ||
exports.SmartContractLib = SmartContractLib; | ||
//# sourceMappingURL=library.js.map |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.diffOutputs = void 0; | ||
var fast_diff_1 = __importDefault(require("fast-diff")); | ||
var scryptlib_1 = require("scryptlib"); | ||
var scryptlib_2 = require("scryptlib"); | ||
var chalk_1 = __importDefault(require("chalk")); | ||
var customChalk = chalk_1.default; | ||
const chalk = require("chalk"); | ||
const Diff = require("fast-diff"); | ||
const scryptlib_1 = require("scryptlib"); | ||
const scryptlib_2 = require("scryptlib"); | ||
const customChalk = new chalk.Instance({ level: 1 }); | ||
//If the lengths differ by more than 50%, the two are considered as significantly different | ||
function isTooDifferent(str1, str2) { | ||
var maxLen = Math.max(str1.length, str2.length); | ||
var diffLen = Math.abs(str1.length - str2.length); | ||
var startswith = str2.startsWith(str1) || str1.startsWith(str2); | ||
let maxLen = Math.max(str1.length, str2.length); | ||
let diffLen = Math.abs(str1.length - str2.length); | ||
let startswith = str2.startsWith(str1) || str1.startsWith(str2); | ||
return diffLen / maxLen > 0.5 && maxLen > 3000 && !startswith; | ||
@@ -32,10 +18,10 @@ } | ||
function toASMAndCut(hex1, hex2) { | ||
var tooDifferent = isTooDifferent(hex1, hex2); | ||
var asm1 = scryptlib_1.bsv.Script.fromHex(hex1).toASM(); | ||
var asm2 = scryptlib_1.bsv.Script.fromHex(hex2).toASM(); | ||
let tooDifferent = isTooDifferent(hex1, hex2); | ||
let asm1 = scryptlib_1.bsv.Script.fromHex(hex1).toASM(); | ||
let asm2 = scryptlib_1.bsv.Script.fromHex(hex2).toASM(); | ||
if (tooDifferent) { | ||
var arr1 = asm1.split(' '); | ||
var arr2 = asm2.split(' '); | ||
var minLen = Math.min(arr1.length, arr2.length); | ||
var maxLen = Math.min(minLen, 1000); | ||
let arr1 = asm1.split(' '); | ||
let arr2 = asm2.split(' '); | ||
let minLen = Math.min(arr1.length, arr2.length); | ||
let maxLen = Math.min(minLen, 1000); | ||
asm1 = arr1.slice(0, maxLen).join(' '); | ||
@@ -53,3 +39,3 @@ if (arr1.length > maxLen) { | ||
function stringify(state) { | ||
return JSON.stringify(state, function (key, value) { | ||
return JSON.stringify(state, (key, value) => { | ||
if (typeof value === 'bigint') { | ||
@@ -61,32 +47,31 @@ return value.toString(); | ||
function getTxContextOutputs(tx) { | ||
return tx.outputs.map(function (output) { return ({ | ||
return tx.outputs.map(output => ({ | ||
script: output.script.toHex(), | ||
satoshis: output.satoshis | ||
}); }); | ||
})); | ||
} | ||
function getContractOutputs(realOutputsHex) { | ||
var reader = new scryptlib_1.bsv.encoding.BufferReader(Buffer.from(realOutputsHex, 'hex')); | ||
var outputs = []; | ||
const reader = new scryptlib_1.bsv.encoding.BufferReader(Buffer.from(realOutputsHex, 'hex')); | ||
const outputs = []; | ||
while (!reader.eof()) { | ||
var output = scryptlib_1.bsv.Transaction.Output.fromBufferReader(reader); | ||
const output = scryptlib_1.bsv.Transaction.Output.fromBufferReader(reader); | ||
outputs.push(output); | ||
} | ||
return outputs.map(function (output) { return ({ | ||
return outputs.map(output => ({ | ||
script: output.script.toHex(), | ||
satoshis: output.satoshis | ||
}); }); | ||
})); | ||
} | ||
function formatOutputs(contract, contractOutputs, ctxOutputs) { | ||
if (scryptlib_2.AbstractContract.isStateful(contract)) { | ||
var codePart_1 = contract.codePart.toHex(); | ||
var indexs1 = ctxOutputs.map(function (o, index) { return o.script.startsWith(codePart_1) ? index : -1; }).filter(function (i) { return i > -1; }); | ||
var indexs2_1 = contractOutputs.map(function (o, index) { return o.script.startsWith(codePart_1) ? index : -1; }).filter(function (i) { return i > -1; }); | ||
var commonIndexs_1 = indexs1.map(function (indexc, index) { return indexc === indexs2_1[index] ? indexc : -1; }).filter(function (i) { return i > -1; }); | ||
var formater = function (output, index) { | ||
if (commonIndexs_1.includes(index)) { | ||
var CLS = contract.ContractClass; | ||
var statesProps = CLS.fromHex(output.script).statePropsArgs; | ||
var states = statesProps.reduce(function (a, v) { | ||
var _a; | ||
return __assign(__assign({}, a), (_a = {}, _a[v.name] = v.value, _a)); | ||
const codePart = contract.codePart.toHex(); | ||
const indexs1 = ctxOutputs.map((o, index) => o.script.startsWith(codePart) ? index : -1).filter(i => i > -1); | ||
const indexs2 = contractOutputs.map((o, index) => o.script.startsWith(codePart) ? index : -1).filter(i => i > -1); | ||
const commonIndexs = indexs1.map((indexc, index) => indexc === indexs2[index] ? indexc : -1).filter(i => i > -1); | ||
let formater = (output, index) => { | ||
if (commonIndexs.includes(index)) { | ||
const CLS = contract.ContractClass; | ||
const statesProps = CLS.fromHex(output.script).statePropsArgs; | ||
let states = statesProps.reduce((a, v) => { | ||
return { ...a, [v.name]: v.value }; | ||
}, {}); | ||
@@ -111,6 +96,6 @@ return { | ||
function diffState(contractOutputs, txContextOutputs) { | ||
var state = ''; | ||
var index = 0; | ||
let state = ''; | ||
let index = 0; | ||
state += customChalk.grey("["); | ||
contractOutputs.forEach(function (output) { | ||
contractOutputs.forEach(output => { | ||
if (typeof output.states !== 'undefined') { | ||
@@ -124,7 +109,7 @@ if (index > 0) { | ||
else { | ||
(0, fast_diff_1.default)(stringify(txContextOutputs[index].states), stringify(output.states)).forEach(function (part) { | ||
if (part[0] === fast_diff_1.default.INSERT) { | ||
Diff(stringify(txContextOutputs[index].states), stringify(output.states)).forEach((part) => { | ||
if (part[0] === Diff.INSERT) { | ||
state += customChalk.red(part[1]); | ||
} | ||
else if (part[0] === fast_diff_1.default.DELETE) { | ||
else if (part[0] === Diff.DELETE) { | ||
state += customChalk.green(part[1]); | ||
@@ -141,3 +126,3 @@ } | ||
for (; index < txContextOutputs.length; index++) { | ||
var output = txContextOutputs[index]; | ||
const output = txContextOutputs[index]; | ||
if (typeof output.states !== 'undefined') { | ||
@@ -151,10 +136,12 @@ state += customChalk.green(stringify(output.states)); | ||
function diffOutputs(contract, realOutputsHex, tx) { | ||
var contractOutputs = getContractOutputs(realOutputsHex); | ||
var txContextOutputs = getTxContextOutputs(tx); | ||
var result = "1. Outputs from ".concat(customChalk.green('Transaction'), " is marked green\n2. Outputs from (").concat(customChalk.red('Contract'), ") is marked red\n3. Identical parts are marked in gray\n\n"); | ||
var _a = formatOutputs(contract, contractOutputs, txContextOutputs), contractOutputs_ = _a[0], txContextOutputs_ = _a[1]; | ||
var outputs = ''; | ||
var index = 0; | ||
const contractOutputs = getContractOutputs(realOutputsHex); | ||
const txContextOutputs = getTxContextOutputs(tx); | ||
let result = `1. Outputs from ${customChalk.green('Transaction')} is marked green | ||
2. Outputs from (${customChalk.red('Contract')}) is marked red | ||
3. Identical parts are marked in gray\n\n`; | ||
let [contractOutputs_, txContextOutputs_] = formatOutputs(contract, contractOutputs, txContextOutputs); | ||
let outputs = ''; | ||
let index = 0; | ||
outputs += customChalk.grey("["); | ||
contractOutputs_.forEach(function (output) { | ||
contractOutputs_.forEach(output => { | ||
if (index > 0) { | ||
@@ -188,8 +175,8 @@ outputs += customChalk.grey(", "); | ||
else { | ||
var _a = toASMAndCut(txContextOutputs_[index].script, output.script), asm1 = _a[0], asm2 = _a[1]; | ||
(0, fast_diff_1.default)(asm1, asm2).forEach(function (part) { | ||
if (part[0] === fast_diff_1.default.INSERT) { | ||
const [asm1, asm2] = toASMAndCut(txContextOutputs_[index].script, output.script); | ||
Diff(asm1, asm2).forEach((part) => { | ||
if (part[0] === Diff.INSERT) { | ||
outputs += customChalk.red(foldStr(part[1])); | ||
} | ||
else if (part[0] === fast_diff_1.default.DELETE) { | ||
else if (part[0] === Diff.DELETE) { | ||
outputs += customChalk.green(foldStr(part[1])); | ||
@@ -207,4 +194,4 @@ } | ||
for (; index < txContextOutputs_.length; index++) { | ||
var output = txContextOutputs_[index]; | ||
outputs += customChalk.grey(","); | ||
const output = txContextOutputs_[index]; | ||
outputs += customChalk.gray(","); | ||
outputs += customChalk.green("{\n"); | ||
@@ -219,5 +206,5 @@ outputs += customChalk.green(" satoshi:" + output.satoshis); | ||
outputs += customChalk.grey("]"); | ||
result = result + "Outputs: ".concat(outputs); | ||
result = result + `Outputs: ${outputs}`; | ||
if (scryptlib_2.AbstractContract.isStateful(contract)) { | ||
result = result + "\n\nState: ".concat(diffState(contractOutputs_, txContextOutputs_)); | ||
result = result + `\n\nState: ${diffState(contractOutputs_, txContextOutputs_)}`; | ||
} | ||
@@ -228,3 +215,3 @@ return result; | ||
function foldStr(str) { | ||
var arr = str.split(' '); | ||
let arr = str.split(' '); | ||
if (arr.length > 10) { | ||
@@ -231,0 +218,0 @@ return arr.slice(0, 5).concat(['...']).concat(arr.slice(arr.length - 5)).join(' '); |
@@ -27,7 +27,7 @@ "use strict"; | ||
exports.Indexer = void 0; | ||
var path = __importStar(require("path")); | ||
var fs = __importStar(require("fs")); | ||
var INDEX_FILE_NAME = 'scrypt.index.json'; | ||
var Indexer = /** @class */ (function () { | ||
function Indexer(pathParam) { | ||
const path = __importStar(require("path")); | ||
const fs = __importStar(require("fs")); | ||
const INDEX_FILE_NAME = 'scrypt.index.json'; | ||
class Indexer { | ||
constructor(pathParam) { | ||
this.symbolPaths = new Map(); | ||
@@ -53,65 +53,61 @@ if (typeof pathParam === "string") { | ||
} | ||
Indexer.prototype.query = function (symbol, includeBase) { | ||
if (includeBase === void 0) { includeBase = false; } | ||
var sPath = this.symbolPaths.get(symbol); | ||
query(symbol, includeBase = false) { | ||
const sPath = this.symbolPaths.get(symbol); | ||
return sPath && includeBase ? path.join(this.scryptBasePath, sPath) : sPath; | ||
}; | ||
Indexer.prototype.save = function () { | ||
var _this = this; | ||
var content = { | ||
} | ||
save() { | ||
let content = { | ||
'scryptBase': this.scryptBasePath, | ||
'bindings': Array.from(this.symbolPaths.keys()).map(function (symbol) { | ||
return { symbol: symbol, path: _this.symbolPaths.get(symbol) }; | ||
'bindings': Array.from(this.symbolPaths.keys()).map(symbol => { | ||
return { symbol, path: this.symbolPaths.get(symbol) }; | ||
}) | ||
}; | ||
fs.writeFileSync(this.filePath, JSON.stringify(content)); | ||
}; | ||
Indexer.prototype.load = function () { | ||
var _this = this; | ||
} | ||
load() { | ||
if (!fs.existsSync(this.filePath)) { | ||
throw new Error("index file not exist: ".concat(this.filePath)); | ||
throw new Error(`index file not exist: ${this.filePath}`); | ||
} | ||
var content = JSON.parse(fs.readFileSync(this.filePath).toString()); | ||
let content = JSON.parse(fs.readFileSync(this.filePath).toString()); | ||
if (!content.scryptBase) { | ||
throw new Error("missing `scryptBase` in index file ".concat(this.filePath)); | ||
throw new Error(`missing \`scryptBase\` in index file ${this.filePath}`); | ||
} | ||
this.scryptBasePath = content.scryptBase; | ||
if (!content.bindings) { | ||
throw new Error("missing `bindings` in index file ".concat(this.filePath)); | ||
throw new Error(`missing \`bindings\` in index file ${this.filePath}`); | ||
} | ||
content.bindings.forEach(function (binding) { | ||
content.bindings.forEach(binding => { | ||
if (binding.symbol && binding.path) { | ||
_this.symbolPaths.set(binding.symbol, binding.path); | ||
this.symbolPaths.set(binding.symbol, binding.path); | ||
} | ||
}); | ||
}; | ||
Indexer.prototype.bindSymbols2Path = function (symbolsWithRange, symbolPath) { | ||
var _this = this; | ||
symbolsWithRange.forEach(function (symbolWithRange) { | ||
if (_this.symbolPaths.has(symbolWithRange.name)) { | ||
var srcFileName = symbolWithRange.srcRange.fileName; | ||
var startLine = symbolWithRange.srcRange.start.line + 1; | ||
var startCol = symbolWithRange.srcRange.start.character + 1; | ||
var endLine = symbolWithRange.srcRange.end.line + 1; | ||
var endCol = symbolWithRange.srcRange.end.character + 1; | ||
console.log("scrypt-ts WARNING - ".concat(srcFileName, ":").concat(startLine, ":").concat(startCol, ":").concat(endLine, ":").concat(endCol, " - symbol `").concat(symbolWithRange.name, "` already has a path binding `").concat(_this.symbolPaths.get(symbolWithRange.name), "` in ").concat(_this.filePath, "\n")); | ||
} | ||
bindSymbols2Path(symbolsWithRange, symbolPath) { | ||
symbolsWithRange.forEach(symbolWithRange => { | ||
if (this.symbolPaths.has(symbolWithRange.name)) { | ||
const srcFileName = symbolWithRange.srcRange.fileName; | ||
const startLine = symbolWithRange.srcRange.start.line + 1; | ||
const startCol = symbolWithRange.srcRange.start.character + 1; | ||
const endLine = symbolWithRange.srcRange.end.line + 1; | ||
const endCol = symbolWithRange.srcRange.end.character + 1; | ||
console.log(`scrypt-ts WARNING - ${srcFileName}:${startLine}:${startCol}:${endLine}:${endCol} - symbol \`${symbolWithRange.name}\` already has a path binding \`${this.symbolPaths.get(symbolWithRange.name)}\` in ${this.filePath}\n`); | ||
} | ||
_this.symbolPaths.set(symbolWithRange.name, symbolPath); | ||
this.symbolPaths.set(symbolWithRange.name, symbolPath); | ||
}); | ||
this.save(); | ||
}; | ||
Indexer.prototype.getPath = function (symbol) { | ||
} | ||
getPath(symbol) { | ||
return this.symbolPaths.get(symbol); | ||
}; | ||
Indexer.prototype.getFullPath = function (scryptFile) { | ||
} | ||
getFullPath(scryptFile) { | ||
return path.join(path.dirname(this.filePath), this.scryptBasePath, scryptFile); | ||
}; | ||
Indexer.queryIndexFile = function (fromPath, toPath) { | ||
var searchDir = fromPath; | ||
} | ||
static queryIndexFile(fromPath, toPath) { | ||
let searchDir = fromPath; | ||
toPath = toPath === undefined ? process.cwd() : toPath; | ||
var isTheSamePath = function (pathA, pathB) { | ||
const isTheSamePath = (pathA, pathB) => { | ||
return path.resolve(pathA).toLowerCase() == path.resolve(pathB).toLowerCase(); | ||
}; | ||
do { | ||
var indexFile = path.join(searchDir, INDEX_FILE_NAME); | ||
let indexFile = path.join(searchDir, INDEX_FILE_NAME); | ||
if (fs.existsSync(indexFile)) { | ||
@@ -123,6 +119,5 @@ return indexFile; | ||
return undefined; | ||
}; | ||
return Indexer; | ||
}()); | ||
} | ||
} | ||
exports.Indexer = Indexer; | ||
//# sourceMappingURL=indexer.js.map |
@@ -26,20 +26,18 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var path = __importStar(require("path")); | ||
var indexer_1 = require("./indexer"); | ||
var transpiler_1 = require("./transpiler"); | ||
var dist_1 = require("scryptlib/dist"); | ||
const path = __importStar(require("path")); | ||
const indexer_1 = require("./indexer"); | ||
const transpiler_1 = require("./transpiler"); | ||
const dist_1 = require("scryptlib/dist"); | ||
/*** | ||
* @ignore | ||
*/ | ||
function transformProgram(program, host, pluginOptions, _a) { | ||
var _b, _c; | ||
var tsInstance = _a.ts; | ||
var compilerOptions = program.getCompilerOptions(); | ||
var compilerHost = getPatchedHost(host, tsInstance, compilerOptions); | ||
var rootFileNames = program.getRootFileNames().map(path.normalize); | ||
var tsconfigDir = process.env['TS_NODE_PROJECT'] ? path.dirname(process.env['TS_NODE_PROJECT']) : '.'; | ||
function transformProgram(program, host, pluginOptions, { ts: tsInstance }) { | ||
const compilerOptions = program.getCompilerOptions(); | ||
const compilerHost = getPatchedHost(host, tsInstance, compilerOptions); | ||
const rootFileNames = program.getRootFileNames().map(path.normalize); | ||
let tsconfigDir = process.env['TS_NODE_PROJECT'] ? path.dirname(process.env['TS_NODE_PROJECT']) : '.'; | ||
tsconfigDir = path.isAbsolute(tsconfigDir) ? tsconfigDir : path.join(program.getCurrentDirectory(), tsconfigDir); | ||
var tsRootDir = (_b = program.getCompilerOptions().rootDir) !== null && _b !== void 0 ? _b : tsconfigDir; | ||
var jsOutDir = (_c = program.getCompilerOptions().outDir) !== null && _c !== void 0 ? _c : tsconfigDir; | ||
var scryptOutDir = pluginOptions.outDir | ||
let tsRootDir = program.getCompilerOptions().rootDir ?? tsconfigDir; | ||
let jsOutDir = program.getCompilerOptions().outDir ?? tsconfigDir; | ||
let scryptOutDir = pluginOptions.outDir | ||
? path.join(tsconfigDir, pluginOptions.outDir) | ||
@@ -51,7 +49,7 @@ : jsOutDir; | ||
console.log(Array(20).fill('*').join(''), 'path context', Array(20).fill('*').join('')); | ||
console.log("tsRootDir: ".concat(tsRootDir, "\ntsconfigDir: ").concat(tsconfigDir, "\njsOutDir: ").concat(jsOutDir, "\nscryptOutDir: ").concat(scryptOutDir)); | ||
console.log(`tsRootDir: ${tsRootDir}\ntsconfigDir: ${tsconfigDir}\njsOutDir: ${jsOutDir}\nscryptOutDir: ${scryptOutDir}`); | ||
console.log(Array(50).fill('*').join(''), '\n'); | ||
} | ||
var indexer = new indexer_1.Indexer({ tsconfigDir: tsconfigDir, scryptOutDir: scryptOutDir }); | ||
var checker = program.getTypeChecker(); | ||
let indexer = new indexer_1.Indexer({ tsconfigDir, scryptOutDir }); | ||
let checker = program.getTypeChecker(); | ||
/* Apply the transformation */ | ||
@@ -66,4 +64,4 @@ tsInstance.transform(program.getSourceFiles(), [ | ||
function getPatchedHost(maybeHost, tsInstance, compilerOptions) { | ||
var fileCache = new Map(); | ||
var compilerHost = maybeHost !== null && maybeHost !== void 0 ? maybeHost : tsInstance.createCompilerHost(compilerOptions, true); | ||
const fileCache = new Map(); | ||
const compilerHost = maybeHost ?? tsInstance.createCompilerHost(compilerOptions, true); | ||
if (compilerHost.fileCache !== undefined) { | ||
@@ -73,10 +71,10 @@ // return the already patched host | ||
} | ||
var cacheableVersion = function (originalFunc) { | ||
const cacheableVersion = (originalFunc) => { | ||
return function (fileName) { | ||
if (fileCache.has(fileName)) { | ||
var file = fileCache.get(fileName); | ||
const file = fileCache.get(fileName); | ||
fileCache.delete(fileName); // patch for making `tsc --watch` to work | ||
return file; | ||
} | ||
var sourceFile = originalFunc.apply(void 0, Array.from(arguments)); | ||
const sourceFile = originalFunc.apply(void 0, Array.from(arguments)); | ||
fileCache.set(fileName, sourceFile); | ||
@@ -88,3 +86,3 @@ return sourceFile; | ||
getSourceFile: cacheableVersion(compilerHost.getSourceFile), | ||
fileCache: fileCache | ||
fileCache | ||
}, compilerHost.getSourceFileByPath ? | ||
@@ -95,10 +93,10 @@ { getSourceFileByPath: cacheableVersion(compilerHost.getSourceFileByPath) } | ||
function applyInjections(tsInstance, host, sourceFile, injections) { | ||
var fileName = sourceFile.fileName, originText = sourceFile.text, languageVersion = sourceFile.languageVersion; | ||
var updatedText = ""; | ||
var lastInjectedIdx = 0; | ||
injections.sort(function (a, b) { return a.pos - b.pos; }).forEach(function (injection) { | ||
const { fileName, text: originText, languageVersion } = sourceFile; | ||
let updatedText = ""; | ||
let lastInjectedIdx = 0; | ||
injections.sort((a, b) => a.pos - b.pos).forEach(injection => { | ||
if (injection.pos < 1 || injection.pos > originText.length + 1) { | ||
throw new Error("invalid injection position: ".concat(injection.pos, " on ").concat(originText.length)); | ||
throw new Error(`invalid injection position: ${injection.pos} on ${originText.length}`); | ||
} | ||
var idx = injection.pos - 1; | ||
const idx = injection.pos - 1; | ||
updatedText += originText.slice(lastInjectedIdx, idx) + injection.code; | ||
@@ -108,3 +106,3 @@ lastInjectedIdx = idx; | ||
updatedText += originText.slice(lastInjectedIdx); | ||
var newFile = tsInstance.createSourceFile(fileName, updatedText, languageVersion, true); | ||
const newFile = tsInstance.createSourceFile(fileName, updatedText, languageVersion, true); | ||
newFile.version = (0, dist_1.md5)(updatedText); // patch for making `tsc --watch` work | ||
@@ -114,4 +112,4 @@ return newFile; | ||
function transformFile(host, checker, tsRootDir, scryptOutDir, indexer, ctx) { | ||
var tsInstance = this; | ||
return function (sourceFile) { | ||
const tsInstance = this; | ||
return (sourceFile) => { | ||
// skip declaration files of *.d.ts | ||
@@ -122,7 +120,7 @@ if (sourceFile.fileName.endsWith('.d.ts')) { | ||
// ts source file to root dir relative path which will be keeped in scrypt output structure. | ||
var root2srcRelativePath = path.relative(tsRootDir, sourceFile.fileName); | ||
const root2srcRelativePath = path.relative(tsRootDir, sourceFile.fileName); | ||
// the relative path from the scrypt output root directory to the file | ||
var scryptFile = root2srcRelativePath.replace(/\.ts$/, '.scrypt').replaceAll('\\', '/'); | ||
var transformFile = root2srcRelativePath.replace(/\.ts$/, '.transformer.json').replaceAll('\\', '/'); | ||
var transpiler = new transpiler_1.Transpiler(sourceFile, checker, scryptOutDir, scryptFile, transformFile, indexer); | ||
const scryptFile = root2srcRelativePath.replace(/\.ts$/, '.scrypt').replaceAll('\\', '/'); | ||
const transformFile = root2srcRelativePath.replace(/\.ts$/, '.transformer.json').replaceAll('\\', '/'); | ||
let transpiler = new transpiler_1.Transpiler(sourceFile, checker, scryptOutDir, scryptFile, transformFile, indexer); | ||
if (!transpiler.isTransformable()) { | ||
@@ -132,12 +130,11 @@ return sourceFile; | ||
transpiler.transform(); | ||
var injections = []; | ||
let injections = []; | ||
function visitor(node) { | ||
var _a; | ||
if (transpiler.scComponents.includes(node)) { | ||
var classNode = node; | ||
var className = (_a = classNode.name) === null || _a === void 0 ? void 0 : _a.escapedText.toString(); | ||
const classNode = node; | ||
const className = classNode.name?.escapedText.toString(); | ||
if (className) { | ||
injections.push({ | ||
pos: classNode.end + 1, | ||
code: "Reflect.defineMetadata(\"scrypt:transform\", \"".concat(transformFile, "\", ").concat(className, ");Reflect.defineMetadata(\"__filename\", __filename, ").concat(className, ");") | ||
code: `Reflect.defineMetadata("scrypt:transform", "${transformFile}", ${className});Reflect.defineMetadata("__filename", __filename, ${className});` | ||
}); | ||
@@ -150,3 +147,3 @@ } | ||
tsInstance.visitEachChild(sourceFile, visitor, ctx); | ||
var updatedSourceFile = applyInjections(tsInstance, host, sourceFile, injections); | ||
const updatedSourceFile = applyInjections(tsInstance, host, sourceFile, injections); | ||
host.fileCache.set(sourceFile.fileName, updatedSourceFile); | ||
@@ -153,0 +150,0 @@ return updatedSourceFile; |
@@ -27,3 +27,3 @@ "use strict"; | ||
exports.isNumberLiteralExpr = exports.hasModifier = exports.number2hex = exports.getBuildInType = exports.getPreimage = exports.signTx = void 0; | ||
var ts = __importStar(require("typescript")); | ||
const ts = __importStar(require("typescript")); | ||
var scryptlib_1 = require("scryptlib"); | ||
@@ -60,3 +60,3 @@ Object.defineProperty(exports, "signTx", { enumerable: true, get: function () { return scryptlib_1.signTx; } }); | ||
function number2hex(val) { | ||
var hex = val.toString(16); | ||
let hex = val.toString(16); | ||
if (hex.length % 2 === 1) { | ||
@@ -68,17 +68,11 @@ hex = '0' + hex; | ||
exports.number2hex = number2hex; | ||
function hasModifier(node) { | ||
var kinds = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
kinds[_i - 1] = arguments[_i]; | ||
} | ||
function hasModifier(node, ...kinds) { | ||
if (ts.canHaveModifiers(node)) { | ||
var modifiers = ts.getModifiers(node); | ||
let modifiers = ts.getModifiers(node); | ||
if (typeof modifiers === 'undefined') { | ||
return false; | ||
} | ||
for (var _a = 0, modifiers_1 = modifiers; _a < modifiers_1.length; _a++) { | ||
var modifier = modifiers_1[_a]; | ||
for (const modifier of modifiers) | ||
if (kinds.includes(modifier.kind)) | ||
return true; | ||
} | ||
} | ||
@@ -85,0 +79,0 @@ return false; |
{ | ||
"name": "scrypt-ts", | ||
"version": "0.1.5-beta.13", | ||
"version": "0.1.5-beta.14", | ||
"description": "A toolset for building sCrypt smart contract applications on Bitcoin SV network written in typescript.", | ||
@@ -11,9 +11,7 @@ "main": "dist/index.js", | ||
"gendocs": "typedoc --readme none --plugin typedoc-plugin-markdown --out scryptTS-docs src/index.ts", | ||
"clean-test-out": "rimraf test/scrypt.index.json && rimraf test/out", | ||
"pretest": "npm run build && cross-env TS_NODE_PROJECT=test/tsconfig.json NODE_ENV=test tsc -p test", | ||
"clean-test-out": "rimraf test/scrypt.index.json && rimraf test/out && rimraf test/artifacts", | ||
"pretest": "npm run build && npm run clean-test-out && cross-env TS_NODE_PROJECT=test/tsconfig.json NODE_ENV=test tsc -p test", | ||
"test": "cd test && mocha 'out/test/local/**/*.test.js' --timeout 1200000", | ||
"pretestnet": "cross-env TS_NODE_PROJECT=test/tsconfig.json tsc test/testnet/hashpuzzle.ts", | ||
"testnet": "cd test && node out/test/testnet/hashpuzzle.js", | ||
"publish:beta": "npm run build && npm publish --tag beta", | ||
"publish:test": "npm run build && npm publish --tag test", | ||
"single-test": "npm run build && npm run clean-test-out && cross-env TS_NODE_PROJECT=test/tsconfig.json NODE_ENV=test mocha -r ts-node/register" | ||
@@ -58,3 +56,3 @@ }, | ||
"reflect-metadata": "^0.1.13", | ||
"scryptlib": "=2.1.0", | ||
"scryptlib": "=2.0.4", | ||
"sourcemap-codec": "^1.4.8", | ||
@@ -61,0 +59,0 @@ "ts-patch": "^2.0.2", |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
272548
5970
Updatedscryptlib@=2.0.4