cashscript
Advanced tools
Comparing version 0.4.4 to 0.5.0
import { Artifact } from 'cashc'; | ||
import { Transaction } from './Transaction'; | ||
import { Instance } from './Instance'; | ||
import { Parameter } from './Parameter'; | ||
import { Argument } from './Argument'; | ||
import { Utxo } from './interfaces'; | ||
import NetworkProvider from './network/NetworkProvider'; | ||
export declare class Contract { | ||
artifact: Artifact; | ||
private network; | ||
private artifact; | ||
private provider; | ||
name: string; | ||
new: (...params: Parameter[]) => Instance; | ||
deployed: (at?: string) => Instance; | ||
static compile(fnOrString: string, network?: string): Contract; | ||
static import(fnOrArtifact: string | Artifact, network?: string): Contract; | ||
export(fn?: string): Artifact; | ||
constructor(artifact: Artifact, network?: string); | ||
address: string; | ||
bytesize: number; | ||
opcount: number; | ||
functions: { | ||
[name: string]: ContractFunction; | ||
}; | ||
private redeemScript; | ||
constructor(artifact: Artifact, constructorArgs: Argument[], provider?: NetworkProvider); | ||
getBalance(): Promise<number>; | ||
getUtxos(): Promise<Utxo[]>; | ||
private createFunction; | ||
} | ||
export declare type ContractFunction = (...parameters: Parameter[]) => Transaction; | ||
export declare type ContractFunction = (...args: Argument[]) => Transaction; |
"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 __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -7,9 +16,11 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
const cashc_1 = require("cashc"); | ||
const fs_1 = __importDefault(require("fs")); | ||
const Instance_1 = require("./Instance"); | ||
const Parameter_1 = require("./Parameter"); | ||
const Transaction_1 = require("./Transaction"); | ||
const Argument_1 = require("./Argument"); | ||
const util_1 = require("./util"); | ||
const SignatureTemplate_1 = __importDefault(require("./SignatureTemplate")); | ||
const network_1 = require("./network"); | ||
class Contract { | ||
constructor(artifact, network = 'testnet') { | ||
constructor(artifact, constructorArgs, provider = new network_1.ElectrumNetworkProvider()) { | ||
this.artifact = artifact; | ||
this.network = network; | ||
this.provider = provider; | ||
if (!artifact.abi || !artifact.bytecode | ||
@@ -19,52 +30,55 @@ || !artifact.constructorInputs || !artifact.contractName) { | ||
} | ||
if (artifact.constructorInputs.length !== constructorArgs.length) { | ||
throw new Error(`Incorrect number of arguments passed to ${artifact.contractName} constructor`); | ||
} | ||
// Encode arguments (this also performs type checking) | ||
const encodedArgs = constructorArgs | ||
.map((arg, i) => Argument_1.encodeArgument(arg, artifact.constructorInputs[i].type)) | ||
.reverse(); | ||
// Check there's no signature templates in the constructor | ||
if (encodedArgs.some(arg => arg instanceof SignatureTemplate_1.default)) { | ||
throw new Error('Cannot use signatures in constructor'); | ||
} | ||
this.redeemScript = [ | ||
...encodedArgs, | ||
...cashc_1.Data.asmToScript(this.artifact.bytecode), | ||
]; | ||
// Populate the functions object with the contract's functions | ||
// (with a special case for single function, which has no "function selector") | ||
this.functions = {}; | ||
if (artifact.abi.length === 1) { | ||
const f = artifact.abi[0]; | ||
this.functions[f.name] = this.createFunction(f); | ||
} | ||
else { | ||
artifact.abi.forEach((f, i) => { | ||
this.functions[f.name] = this.createFunction(f, i); | ||
}); | ||
} | ||
this.name = artifact.contractName; | ||
this.new = (...ps) => { | ||
if (artifact.constructorInputs.length !== ps.length) { | ||
throw new Error(`Incorrect number of arguments passed to ${artifact.contractName} constructor`); | ||
} | ||
const encodedParameters = ps | ||
.map((p, i) => Parameter_1.encodeParameter(p, artifact.constructorInputs[i].type)) | ||
.reverse(); | ||
// Check there's no sigs in the constructor | ||
if (encodedParameters.some(p => p instanceof Parameter_1.SignatureTemplate)) { | ||
throw new Error('Cannot use signatures in constructor'); | ||
} | ||
const redeemScript = [ | ||
...encodedParameters, | ||
...cashc_1.Data.asmToScript(this.artifact.bytecode), | ||
]; | ||
const instance = new Instance_1.Instance(this.artifact, redeemScript, this.network); | ||
const deployedContracts = this.artifact.networks[this.network] || {}; | ||
deployedContracts[instance.address] = cashc_1.Data.scriptToAsm(redeemScript); | ||
this.artifact.networks[this.network] = deployedContracts; | ||
this.artifact.updatedAt = new Date().toISOString(); | ||
return instance; | ||
}; | ||
this.deployed = (at) => { | ||
if (!this.artifact.networks[this.network]) | ||
throw new Error('No registered deployed contracts'); | ||
const redeemScript = at | ||
? this.artifact.networks[this.network][at] | ||
: Object.values(this.artifact.networks[this.network])[0]; | ||
if (!redeemScript) | ||
throw new Error(`No registered contract deployed at ${at}`); | ||
return new Instance_1.Instance(this.artifact, cashc_1.Data.asmToScript(redeemScript), this.network); | ||
}; | ||
this.address = util_1.scriptToAddress(this.redeemScript, this.provider.network); | ||
this.bytesize = util_1.calculateBytesize(this.redeemScript); | ||
this.opcount = util_1.countOpcodes(this.redeemScript); | ||
} | ||
static compile(fnOrString, network) { | ||
const artifact = fs_1.default && fs_1.default.existsSync && fs_1.default.existsSync(fnOrString) | ||
? cashc_1.CashCompiler.compileFile(fnOrString) | ||
: cashc_1.CashCompiler.compileString(fnOrString); | ||
return new Contract(artifact, network); | ||
getBalance() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const utxos = yield this.getUtxos(); | ||
return utxos.reduce((acc, utxo) => acc + utxo.satoshis, 0); | ||
}); | ||
} | ||
static import(fnOrArtifact, network) { | ||
const artifact = typeof fnOrArtifact === 'string' | ||
? cashc_1.Artifacts.require(fnOrArtifact) | ||
: fnOrArtifact; | ||
return new Contract(artifact, network); | ||
getUtxos() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.provider.getUtxos(this.address); | ||
}); | ||
} | ||
export(fn) { | ||
if (typeof fn !== 'undefined') | ||
cashc_1.Artifacts.export(this.artifact, fn); | ||
return this.artifact; | ||
createFunction(abiFunction, selector) { | ||
return (...args) => { | ||
if (abiFunction.inputs.length !== args.length) { | ||
throw new Error(`Incorrect number of arguments passed to function ${abiFunction.name}`); | ||
} | ||
// Encode passed args (this also performs type checking) | ||
const encodedArgs = args | ||
.map((arg, i) => Argument_1.encodeArgument(arg, abiFunction.inputs[i].type)); | ||
return new Transaction_1.Transaction(this.address, this.provider, this.redeemScript, abiFunction, encodedArgs, selector); | ||
}; | ||
} | ||
@@ -71,0 +85,0 @@ } |
export { Contract } from './Contract'; | ||
export { Instance } from './Instance'; | ||
export { Transaction } from './Transaction'; | ||
export { Parameter, SignatureTemplate, Sig } from './Parameter'; | ||
export { Artifacts, Artifact, AbiFunction, AbiInput, } from 'cashc'; | ||
export { Utxo, Recipient, SignatureAlgorithm, HashType, } from './interfaces'; | ||
export { Argument } from './Argument'; | ||
export { default as SignatureTemplate } from './SignatureTemplate'; | ||
export { Artifacts, Artifact, AbiFunction, AbiInput, CashCompiler, } from 'cashc'; | ||
export { Utxo, Recipient, SignatureAlgorithm, HashType, Network, } from './interfaces'; | ||
export * from './Errors'; | ||
export * from './network'; |
@@ -8,15 +8,15 @@ "use strict"; | ||
exports.Contract = Contract_1.Contract; | ||
var Instance_1 = require("./Instance"); | ||
exports.Instance = Instance_1.Instance; | ||
var Transaction_1 = require("./Transaction"); | ||
exports.Transaction = Transaction_1.Transaction; | ||
var Parameter_1 = require("./Parameter"); | ||
exports.SignatureTemplate = Parameter_1.SignatureTemplate; | ||
exports.Sig = Parameter_1.Sig; | ||
var SignatureTemplate_1 = require("./SignatureTemplate"); | ||
exports.SignatureTemplate = SignatureTemplate_1.default; | ||
var cashc_1 = require("cashc"); | ||
exports.Artifacts = cashc_1.Artifacts; | ||
exports.CashCompiler = cashc_1.CashCompiler; | ||
var interfaces_1 = require("./interfaces"); | ||
exports.SignatureAlgorithm = interfaces_1.SignatureAlgorithm; | ||
exports.HashType = interfaces_1.HashType; | ||
exports.Network = interfaces_1.Network; | ||
__export(require("./Errors")); | ||
__export(require("./network")); | ||
//# sourceMappingURL=index.js.map |
@@ -1,13 +0,11 @@ | ||
/// <reference types="node" /> | ||
import { ECPair } from 'bitcoincashjs-lib'; | ||
import SignatureTemplate from './SignatureTemplate'; | ||
export interface Utxo { | ||
txid: string; | ||
vout: number; | ||
amount: number; | ||
satoshis: number; | ||
} | ||
export interface UtxoWithKeyPair extends Utxo { | ||
keypair: ECPair; | ||
export interface SignableUtxo extends Utxo { | ||
template: SignatureTemplate; | ||
} | ||
export declare function isUtxoWithKeyPair(utxo: Utxo): utxo is UtxoWithKeyPair; | ||
export declare function isSignableUtxo(utxo: Utxo): utxo is SignableUtxo; | ||
export interface Recipient { | ||
@@ -18,34 +16,5 @@ to: string; | ||
export interface Output { | ||
to: string | Buffer; | ||
to: string | Uint8Array; | ||
amount: number; | ||
} | ||
export interface ScriptSigDetails { | ||
asm: string; | ||
hex: string; | ||
} | ||
export interface TxnDetailValueIn { | ||
cashAddress: string; | ||
legacyAddress: string; | ||
n: number; | ||
scriptSig: ScriptSigDetails; | ||
sequence: number; | ||
txid: string; | ||
value: number; | ||
vout: number; | ||
} | ||
export interface ScriptPubKeyDetails { | ||
addresses: string[]; | ||
cashAddrs: string[]; | ||
asm: string; | ||
hex: string; | ||
type: string; | ||
} | ||
export interface TxnDetailValueOut { | ||
n: number; | ||
scriptPubKey: ScriptPubKeyDetails; | ||
spendHeight: null | number; | ||
spendIndex: null | number; | ||
spendTxId: null | number; | ||
value: string; | ||
} | ||
export declare enum SignatureAlgorithm { | ||
@@ -61,1 +30,6 @@ ECDSA = 0, | ||
} | ||
export declare const Network: { | ||
MAINNET: "mainnet"; | ||
TESTNET: "testnet"; | ||
}; | ||
export declare type Network = (typeof Network)[keyof typeof Network]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function isUtxoWithKeyPair(utxo) { | ||
return 'keypair' in utxo; | ||
function isSignableUtxo(utxo) { | ||
return 'template' in utxo; | ||
} | ||
exports.isUtxoWithKeyPair = isUtxoWithKeyPair; | ||
exports.isSignableUtxo = isSignableUtxo; | ||
var SignatureAlgorithm; | ||
@@ -19,2 +19,9 @@ (function (SignatureAlgorithm) { | ||
})(HashType = exports.HashType || (exports.HashType = {})); | ||
// Weird setup to allow both Enum parameters, as well as literal strings | ||
// https://stackoverflow.com/questions/51433319/typescript-constructor-accept-string-for-enum | ||
const literal = (l) => l; | ||
exports.Network = { | ||
MAINNET: literal('mainnet'), | ||
TESTNET: literal('testnet'), | ||
}; | ||
//# sourceMappingURL=interfaces.js.map |
@@ -1,16 +0,13 @@ | ||
/// <reference types="node" /> | ||
import { ECPair } from 'bitcoincashjs-lib'; | ||
import { TxnDetailsResult } from 'bitcoin-com-rest'; | ||
import { Transaction as LibauthTransaction } from '@bitauth/libauth'; | ||
import { Script, AbiFunction } from 'cashc'; | ||
import { SignatureTemplate } from './Parameter'; | ||
import { Utxo, Recipient } from './interfaces'; | ||
import NetworkProvider from './network/NetworkProvider'; | ||
import SignatureTemplate from './SignatureTemplate'; | ||
export declare class Transaction { | ||
private address; | ||
private network; | ||
private provider; | ||
private redeemScript; | ||
private abiFunction; | ||
private parameters; | ||
private args; | ||
private selector?; | ||
private bitbox; | ||
private builder; | ||
private inputs; | ||
@@ -23,7 +20,7 @@ private outputs; | ||
private minChange; | ||
constructor(address: string, network: string, redeemScript: Script, abiFunction: AbiFunction, parameters: (Buffer | SignatureTemplate)[], selector?: number | undefined); | ||
constructor(address: string, provider: NetworkProvider, redeemScript: Script, abiFunction: AbiFunction, args: (Uint8Array | SignatureTemplate)[], selector?: number | undefined); | ||
from(input: Utxo): this; | ||
from(inputs: Utxo[]): this; | ||
experimentalFromP2PKH(input: Utxo, keypair: ECPair): this; | ||
experimentalFromP2PKH(inputs: Utxo[], keypair: ECPair): this; | ||
experimentalFromP2PKH(input: Utxo, template: SignatureTemplate): this; | ||
experimentalFromP2PKH(inputs: Utxo[], template: SignatureTemplate): this; | ||
to(to: string, amount: number): this; | ||
@@ -37,4 +34,6 @@ to(outputs: Recipient[]): this; | ||
withMinChange(minChange: number): this; | ||
withoutChange(): this; | ||
build(): Promise<string>; | ||
send(): Promise<TxnDetailsResult>; | ||
send(): Promise<LibauthTransaction>; | ||
send(raw: true): Promise<string>; | ||
private getTxDetails; | ||
@@ -41,0 +40,0 @@ meep(): Promise<string>; |
@@ -15,17 +15,17 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const libauth_1 = require("@bitauth/libauth"); | ||
const delay_1 = __importDefault(require("delay")); | ||
const Parameter_1 = require("./Parameter"); | ||
const BITBOX_1 = require("./BITBOX"); | ||
const cashc_1 = require("cashc"); | ||
const interfaces_1 = require("./interfaces"); | ||
const util_1 = require("./util"); | ||
const constants_1 = require("./constants"); | ||
const cramer = require('cramer-bch'); | ||
const bch = require('trout-bch'); | ||
const SignatureTemplate_1 = __importDefault(require("./SignatureTemplate")); | ||
const bip68 = require('bip68'); | ||
class Transaction { | ||
constructor(address, network, redeemScript, abiFunction, parameters, selector) { | ||
constructor(address, provider, redeemScript, abiFunction, args, selector) { | ||
this.address = address; | ||
this.network = network; | ||
this.provider = provider; | ||
this.redeemScript = redeemScript; | ||
this.abiFunction = abiFunction; | ||
this.parameters = parameters; | ||
this.args = args; | ||
this.selector = selector; | ||
@@ -37,4 +37,2 @@ this.inputs = []; | ||
this.minChange = constants_1.DUST_LIMIT; | ||
this.bitbox = BITBOX_1.bitbox[network]; | ||
this.builder = new this.bitbox.TransactionBuilder(this.network); | ||
} | ||
@@ -48,7 +46,7 @@ from(inputOrInputs) { | ||
} | ||
experimentalFromP2PKH(inputOrInputs, keypair) { | ||
experimentalFromP2PKH(inputOrInputs, template) { | ||
if (!Array.isArray(inputOrInputs)) { | ||
inputOrInputs = [inputOrInputs]; | ||
} | ||
inputOrInputs = inputOrInputs.map(input => (Object.assign(Object.assign({}, input), { keypair }))); | ||
inputOrInputs = inputOrInputs.map(input => (Object.assign(Object.assign({}, input), { template }))); | ||
this.inputs = this.inputs.concat(inputOrInputs); | ||
@@ -74,3 +72,3 @@ return this; | ||
withAge(age) { | ||
this.sequence = this.builder.bip68.encode({ blocks: age }); | ||
this.sequence = bip68.encode({ blocks: age }); | ||
return this; | ||
@@ -94,72 +92,83 @@ } | ||
} | ||
withoutChange() { | ||
return this.withMinChange(Number.MAX_VALUE); | ||
} | ||
build() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.locktime = this.locktime || (yield this.bitbox.Blockchain.getBlockCount()); | ||
this.builder.setLockTime(this.locktime); | ||
this.locktime = this.locktime || (yield this.provider.getBlockHeight()); | ||
yield this.setInputsAndOutputs(); | ||
this.inputs.forEach((utxo) => { | ||
this.builder.addInput(utxo.txid, utxo.vout, this.sequence); | ||
const secp256k1 = yield libauth_1.instantiateSecp256k1(); | ||
const bytecode = cashc_1.Data.scriptToBytecode(this.redeemScript); | ||
const inputs = this.inputs.map(utxo => ({ | ||
outpointIndex: utxo.vout, | ||
outpointTransactionHash: libauth_1.hexToBin(utxo.txid), | ||
sequenceNumber: this.sequence, | ||
unlockingBytecode: new Uint8Array(), | ||
})); | ||
const outputs = this.outputs.map((output) => { | ||
const lockingBytecode = typeof output.to === 'string' | ||
? util_1.addressToLockScript(output.to) | ||
: output.to; | ||
const satoshis = libauth_1.bigIntToBinUint64LE(BigInt(output.amount)); | ||
return { lockingBytecode, satoshis }; | ||
}); | ||
this.outputs.forEach((output) => { | ||
this.builder.addOutput(output.to, output.amount); | ||
}); | ||
// Vout is a misnomer used in BITBOX, should be vin | ||
const transaction = { | ||
inputs, | ||
locktime: this.locktime, | ||
outputs, | ||
version: 2, | ||
}; | ||
const inputScripts = []; | ||
// Convert all SignatureTemplate objects to valid tx signatures for current tx | ||
const tx = this.builder.transaction.buildIncomplete(); | ||
this.inputs.forEach((utxo, vin) => { | ||
// UTXO's with key pairs are signed with the key pair using P2PKH | ||
if (interfaces_1.isUtxoWithKeyPair(utxo)) { | ||
const pubkey = utxo.keypair.getPublicKeyBuffer(); | ||
const pubkeyHash = bch.crypto.hash160(pubkey); | ||
const prevOutScript = bch.script.pubKeyHash.output.encode(pubkeyHash); | ||
const hashtype = interfaces_1.HashType.SIGHASH_ALL | tx.constructor.SIGHASH_BITCOINCASHBIP143; | ||
const sighash = tx.hashForCashSignature(vin, prevOutScript, utxo.satoshis, hashtype); | ||
const signature = utxo.keypair | ||
.sign(sighash, interfaces_1.SignatureAlgorithm.SCHNORR) | ||
.toScriptSignature(hashtype, interfaces_1.SignatureAlgorithm.SCHNORR); | ||
const inputScript = bch.script.pubKeyHash.input.encode(signature, pubkey); | ||
inputScripts.push({ vout: vin, script: inputScript }); | ||
this.inputs.forEach((utxo, i) => { | ||
// UTXO's with signature templates are signed using P2PKH | ||
if (interfaces_1.isSignableUtxo(utxo)) { | ||
const pubkey = utxo.template.getPublicKey(secp256k1); | ||
const pubkeyHash = util_1.hash160(pubkey); | ||
const addressContents = { payload: pubkeyHash, type: libauth_1.AddressType.p2pkh }; | ||
const prevOutScript = libauth_1.addressContentsToLockingBytecode(addressContents); | ||
const hashtype = utxo.template.getHashType(); | ||
const preimage = util_1.createSighashPreimage(transaction, utxo, i, prevOutScript, hashtype); | ||
const sighash = util_1.sha256(util_1.sha256(preimage)); | ||
const signature = utxo.template.generateSignature(sighash, secp256k1); | ||
const inputScript = cashc_1.Data.scriptToBytecode([signature, pubkey]); | ||
inputScripts.push(inputScript); | ||
return; | ||
} | ||
let covenantHashType = -1; | ||
const completePs = this.parameters.map((p) => { | ||
if (!(p instanceof Parameter_1.SignatureTemplate)) | ||
return p; | ||
const hashtype = p.hashtype | tx.constructor.SIGHASH_BITCOINCASHBIP143; | ||
const completeArgs = this.args.map((arg) => { | ||
if (!(arg instanceof SignatureTemplate_1.default)) | ||
return arg; | ||
// First signature is used for sighash preimage (maybe not the best way) | ||
if (covenantHashType < 0) | ||
covenantHashType = hashtype; | ||
const sighash = tx.hashForCashSignature(vin, bch.script.compile(this.redeemScript), utxo.satoshis, hashtype); | ||
return p.keypair | ||
.sign(sighash, interfaces_1.SignatureAlgorithm.SCHNORR) | ||
.toScriptSignature(hashtype, interfaces_1.SignatureAlgorithm.SCHNORR); | ||
covenantHashType = arg.getHashType(); | ||
const preimage = util_1.createSighashPreimage(transaction, utxo, i, bytecode, arg.getHashType()); | ||
const sighash = util_1.sha256(util_1.sha256(preimage)); | ||
return arg.generateSignature(sighash, secp256k1); | ||
}); | ||
// This is shitty because sigHashPreimageBuf is only in James Cramer's fork | ||
// Will fix once it gets merged into main bitcoincashjs-lib | ||
const preimageTx = cramer.Transaction.fromHex(tx.toHex()); | ||
const prevout = bch.script.compile(this.redeemScript); | ||
const preimage = this.abiFunction.covenant | ||
? preimageTx.sigHashPreimageBuf(vin, prevout, utxo.satoshis, covenantHashType) | ||
? util_1.createSighashPreimage(transaction, utxo, i, bytecode, covenantHashType) | ||
: undefined; | ||
const inputScript = util_1.createInputScript(this.redeemScript, completePs, this.selector, preimage); | ||
inputScripts.push({ vout: vin, script: inputScript }); | ||
const inputScript = util_1.createInputScript(this.redeemScript, completeArgs, this.selector, preimage); | ||
inputScripts.push(inputScript); | ||
}); | ||
this.builder.addInputScripts(inputScripts); | ||
return this.builder.build().toHex(); | ||
inputScripts.forEach((script, i) => { | ||
transaction.inputs[i].unlockingBytecode = script; | ||
}); | ||
return libauth_1.binToHex(libauth_1.encodeTransaction(transaction)); | ||
}); | ||
} | ||
send() { | ||
send(raw) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const tx = yield this.build(); | ||
try { | ||
const txid = yield this.bitbox.RawTransactions.sendRawTransaction(tx); | ||
return this.getTxDetails(txid); | ||
const txid = yield this.provider.sendRawTransaction(tx); | ||
return raw ? this.getTxDetails(txid, raw) : this.getTxDetails(txid); | ||
} | ||
catch (e) { | ||
throw util_1.buildError(e.error, util_1.meep(tx, this.inputs, this.redeemScript)); | ||
const reason = e.error || e.message; | ||
throw util_1.buildError(reason, util_1.meep(tx, this.inputs, this.redeemScript)); | ||
} | ||
}); | ||
} | ||
getTxDetails(txid) { | ||
getTxDetails(txid, raw) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -169,3 +178,4 @@ while (true) { | ||
try { | ||
return yield this.bitbox.Transaction.details(txid); | ||
const txHex = yield this.provider.getRawTransaction(txid); | ||
return raw ? txHex : libauth_1.decodeTransaction(libauth_1.hexToBin(txHex)); | ||
} | ||
@@ -189,9 +199,11 @@ catch (ignored) { | ||
} | ||
// Use a placeholder script with 65-length Buffer in the place of signatures | ||
// and a correctly sized preimage Buffer if the function is a covenant | ||
// for correct size calculation of inputs | ||
// Replace all SignatureTemplate with 65-length placeholder Uint8Arrays | ||
const placeholderArgs = this.args.map(arg => (arg instanceof SignatureTemplate_1.default ? util_1.placeholder(65) : arg)); | ||
// Create a placeholder preimage of the correct size | ||
const placeholderPreimage = this.abiFunction.covenant | ||
? Buffer.alloc(util_1.getPreimageSize(bch.script.compile(this.redeemScript)), 0) | ||
? util_1.placeholder(util_1.getPreimageSize(cashc_1.Data.scriptToBytecode(this.redeemScript))) | ||
: undefined; | ||
const placeholderScript = util_1.createInputScript(this.redeemScript, this.parameters.map(p => (p instanceof Parameter_1.SignatureTemplate ? Buffer.alloc(65, 0) : p)), this.selector, placeholderPreimage); | ||
// Create a placeholder input script for size calculation using the placeholder | ||
// arguments and correctly sized placeholder preimage | ||
const placeholderScript = util_1.createInputScript(this.redeemScript, placeholderArgs, this.selector, placeholderPreimage); | ||
// Add one extra byte per input to over-estimate tx-in count | ||
@@ -214,5 +226,7 @@ const inputSize = util_1.getInputSize(placeholderScript) + 1; | ||
else { | ||
// If inputs are not defined yet, we retrieve the contract's UTXOs | ||
// and perform UTXO selection | ||
const { utxos } = yield this.bitbox.Address.utxo(this.address); | ||
// If inputs are not defined yet, we retrieve the contract's UTXOs and perform selection | ||
const utxos = yield this.provider.getUtxos(this.address); | ||
// We sort the UTXOs mainly so there is consistent behaviour between network providers | ||
// even if they report UTXOs in a different order | ||
utxos.sort((a, b) => b.satoshis - a.satoshis); | ||
for (const utxo of utxos) { | ||
@@ -219,0 +233,0 @@ this.inputs.push(utxo); |
@@ -1,13 +0,32 @@ | ||
/// <reference types="node" /> | ||
import { Script } from 'cashc'; | ||
import { Transaction } from '@bitauth/libauth'; | ||
import { Utxo, Output } from './interfaces'; | ||
import { FailedTransactionError } from './Errors'; | ||
export declare function getInputSize(script: Buffer): number; | ||
export declare function getPreimageSize(script: Buffer): number; | ||
export declare function getInputSize(inputScript: Uint8Array): number; | ||
export declare function getPreimageSize(script: Uint8Array): number; | ||
export declare function getTxSizeWithoutInputs(outputs: Output[]): number; | ||
export declare function placeholder(size: number): Uint8Array; | ||
export declare function countOpcodes(script: Script): number; | ||
export declare function calculateBytesize(script: Script): number; | ||
export declare function createInputScript(redeemScript: Script, encodedParameters: Buffer[], selector?: number, preimage?: Buffer): Buffer; | ||
export declare function createInputScript(redeemScript: Script, encodedArgs: Uint8Array[], selector?: number, preimage?: Uint8Array): Uint8Array; | ||
export declare function createOpReturnOutput(opReturnData: string[]): Output; | ||
export declare function createSighashPreimage(transaction: Transaction, input: { | ||
satoshis: number; | ||
}, inputIndex: number, coveredBytecode: Uint8Array, hashtype: number): Uint8Array; | ||
export declare function buildError(reason: string, meepStr: string): FailedTransactionError; | ||
export declare function sha512(payload: Uint8Array): Uint8Array; | ||
export declare function sha256(payload: Uint8Array): Uint8Array; | ||
export declare function ripemd160(payload: Uint8Array): Uint8Array; | ||
export declare function hash160(payload: Uint8Array): Uint8Array; | ||
export declare function meep(tx: any, utxos: Utxo[], script: Script): string; | ||
export declare function scriptToAddress(script: Script, network: string): string; | ||
export declare function scriptToLockingBytecode(script: Script): Uint8Array; | ||
/** | ||
* Helper function to convert an address to a locking script | ||
* | ||
* @param address Address to convert to locking script | ||
* | ||
* @returns a locking script corresponding to the passed address | ||
*/ | ||
export declare function addressToLockScript(address: string): Uint8Array; | ||
export declare function getNetworkPrefix(network: string): 'bitcoincash' | 'bchtest'; |
156
dist/util.js
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const cashc_1 = require("cashc"); | ||
const libauth_1 = require("@bitauth/libauth"); | ||
const hash_js_1 = __importDefault(require("hash.js")); | ||
const interfaces_1 = require("./interfaces"); | ||
const constants_1 = require("./constants"); | ||
const Errors_1 = require("./Errors"); | ||
const bch = require('trout-bch'); | ||
// ////////// SIZE CALCULATIONS /////////////////////////////////////////////// | ||
function getInputSize(script) { | ||
const scriptSize = script.byteLength; | ||
function getInputSize(inputScript) { | ||
const scriptSize = inputScript.byteLength; | ||
const varIntSize = scriptSize > 252 ? 3 : 1; | ||
@@ -50,2 +55,6 @@ return 32 + 4 + varIntSize + scriptSize + 4; | ||
exports.getTxSizeWithoutInputs = getTxSizeWithoutInputs; | ||
function placeholder(size) { | ||
return new Uint8Array(size).fill(0); | ||
} | ||
exports.placeholder = placeholder; | ||
function countOpcodes(script) { | ||
@@ -59,9 +68,9 @@ return script | ||
function calculateBytesize(script) { | ||
return bch.script.compile(script).byteLength; | ||
return cashc_1.Data.scriptToBytecode(script).byteLength; | ||
} | ||
exports.calculateBytesize = calculateBytesize; | ||
// ////////// BUILD OBJECTS /////////////////////////////////////////////////// | ||
function createInputScript(redeemScript, encodedParameters, selector, preimage) { | ||
// Create unlock script / redeemScriptSig | ||
const unlockScript = encodedParameters.reverse(); | ||
function createInputScript(redeemScript, encodedArgs, selector, preimage) { | ||
// Create unlock script / redeemScriptSig (add potential preimage and selector) | ||
const unlockScript = encodedArgs.reverse(); | ||
if (preimage !== undefined) | ||
@@ -71,4 +80,5 @@ unlockScript.push(preimage); | ||
unlockScript.push(cashc_1.Data.encodeInt(selector)); | ||
// Create total input script / scriptSig | ||
return bch.script.scriptHash.input.encode(bch.script.compile(unlockScript), bch.script.compile(redeemScript)); | ||
// Create input script and compile it to bytecode | ||
const inputScript = [...unlockScript, cashc_1.Data.scriptToBytecode(redeemScript)]; | ||
return cashc_1.Data.scriptToBytecode(inputScript); | ||
} | ||
@@ -79,3 +89,3 @@ exports.createInputScript = createInputScript; | ||
cashc_1.Op.OP_RETURN, | ||
...opReturnData.map((output) => toBuffer(output)), | ||
...opReturnData.map((output) => toBin(output)), | ||
]; | ||
@@ -85,7 +95,32 @@ return { to: encodeNullDataScript(script), amount: 0 }; | ||
exports.createOpReturnOutput = createOpReturnOutput; | ||
function toBuffer(output) { | ||
function toBin(output) { | ||
const data = output.replace(/^0x/, ''); | ||
const format = data === output ? 'utf8' : 'hex'; | ||
return Buffer.from(data, format); | ||
const encode = data === output ? libauth_1.utf8ToBin : libauth_1.hexToBin; | ||
return encode(data); | ||
} | ||
function createSighashPreimage(transaction, input, inputIndex, coveredBytecode, hashtype) { | ||
const state = libauth_1.createTransactionContextCommon({ | ||
inputIndex, | ||
sourceOutput: { satoshis: libauth_1.bigIntToBinUint64LE(BigInt(input.satoshis)) }, | ||
spendingTransaction: transaction, | ||
}); | ||
const sighashPreimage = libauth_1.generateSigningSerializationBCH({ | ||
correspondingOutput: state.correspondingOutput, | ||
coveredBytecode, | ||
forkId: new Uint8Array([0, 0, 0]), | ||
locktime: state.locktime, | ||
outpointIndex: state.outpointIndex, | ||
outpointTransactionHash: state.outpointTransactionHash, | ||
outputValue: state.outputValue, | ||
sequenceNumber: state.sequenceNumber, | ||
sha256: { hash: sha256 }, | ||
signingSerializationType: new Uint8Array([hashtype]), | ||
transactionOutpoints: state.transactionOutpoints, | ||
transactionOutputs: state.transactionOutputs, | ||
transactionSequenceNumbers: state.transactionSequenceNumbers, | ||
version: 2, | ||
}); | ||
return sighashPreimage; | ||
} | ||
exports.createSighashPreimage = createSighashPreimage; | ||
function buildError(reason, meepStr) { | ||
@@ -118,47 +153,78 @@ const require = [ | ||
} | ||
// ////////// HASH FUNCTIONS ////////////////////////////////////////////////// | ||
function sha512(payload) { | ||
return Uint8Array.from(hash_js_1.default.sha512().update(payload).digest()); | ||
} | ||
exports.sha512 = sha512; | ||
function sha256(payload) { | ||
return Uint8Array.from(hash_js_1.default.sha256().update(payload).digest()); | ||
} | ||
exports.sha256 = sha256; | ||
function ripemd160(payload) { | ||
return Uint8Array.from(hash_js_1.default.ripemd160().update(payload).digest()); | ||
} | ||
exports.ripemd160 = ripemd160; | ||
function hash160(payload) { | ||
return ripemd160(sha256(payload)); | ||
} | ||
exports.hash160 = hash160; | ||
// ////////// MISC //////////////////////////////////////////////////////////// | ||
function meep(tx, utxos, script) { | ||
const scriptHash = bch.crypto.hash160(bch.script.compile(script)); | ||
const scriptPubkey = bch.script.scriptHash.output.encode(scriptHash).toString('hex'); | ||
const scriptPubkey = libauth_1.binToHex(scriptToLockingBytecode(script)); | ||
return `meep debug --tx=${tx} --idx=0 --amt=${utxos[0].satoshis} --pkscript=${scriptPubkey}`; | ||
} | ||
exports.meep = meep; | ||
function scriptToAddress(script, network) { | ||
const lockingBytecode = scriptToLockingBytecode(script); | ||
const prefix = getNetworkPrefix(network); | ||
const address = libauth_1.lockingBytecodeToCashAddress(lockingBytecode, prefix); | ||
return address; | ||
} | ||
exports.scriptToAddress = scriptToAddress; | ||
function scriptToLockingBytecode(script) { | ||
const scriptHash = hash160(cashc_1.Data.scriptToBytecode(script)); | ||
const addressContents = { payload: scriptHash, type: libauth_1.AddressType.p2sh }; | ||
const lockingBytecode = libauth_1.addressContentsToLockingBytecode(addressContents); | ||
return lockingBytecode; | ||
} | ||
exports.scriptToLockingBytecode = scriptToLockingBytecode; | ||
/** | ||
* Helper function to convert an address to a locking script | ||
* | ||
* @param address Address to convert to locking script | ||
* | ||
* @returns a locking script corresponding to the passed address | ||
*/ | ||
function addressToLockScript(address) { | ||
const result = libauth_1.cashAddressToLockingBytecode(address); | ||
if (typeof result === 'string') | ||
throw new Error(result); | ||
return result.bytecode; | ||
} | ||
exports.addressToLockScript = addressToLockScript; | ||
function getNetworkPrefix(network) { | ||
return network === interfaces_1.Network.MAINNET ? 'bitcoincash' : 'bchtest'; | ||
} | ||
exports.getNetworkPrefix = getNetworkPrefix; | ||
// //////////////////////////////////////////////////////////////////////////// | ||
// For encoding OP_RETURN data (doesn't require BIP62.3) | ||
// These functions are a mash-up between those found in these libs: | ||
// - https://github.com/simpleledger/slpjs/blob/master/lib/utils.ts | ||
// - https://github.com/Bitcoin-com/bitcoincashjs-lib/blob/master/src/script.js | ||
// For encoding OP_RETURN data (doesn't require BIP62.3 / MINIMALDATA) | ||
function encodeNullDataScript(chunks) { | ||
const bufferSize = chunks.reduce((acc, chunk) => { | ||
if (Buffer.isBuffer(chunk)) { | ||
return libauth_1.flattenBinArray(chunks.map((chunk) => { | ||
if (chunk instanceof Uint8Array) { | ||
const pushdataOpcode = getPushDataOpcode(chunk); | ||
return acc + chunk.length + pushdataOpcode.length; | ||
return new Uint8Array([...pushdataOpcode, ...chunk]); | ||
} | ||
return acc + 1; | ||
}, 0); | ||
const buffer = Buffer.allocUnsafe(bufferSize); | ||
let offset = 0; | ||
chunks.forEach((chunk) => { | ||
if (Buffer.isBuffer(chunk)) { | ||
const pushdataOpcode = getPushDataOpcode(chunk); | ||
pushdataOpcode.copy(buffer, offset); | ||
offset += pushdataOpcode.length; | ||
chunk.copy(buffer, offset); | ||
offset += chunk.length; | ||
} | ||
else { | ||
buffer.writeUInt8(chunk, offset); | ||
offset += 1; | ||
return new Uint8Array([chunk]); | ||
} | ||
}); | ||
return buffer; | ||
})); | ||
} | ||
function getPushDataOpcode(data) { | ||
const { length } = data; | ||
if (length === 0) | ||
return Buffer.from([0x4c, 0x00]); | ||
if (length < 76) | ||
return Buffer.from([length]); | ||
if (length < 256) | ||
return Buffer.from([0x4c, length]); | ||
const { byteLength } = data; | ||
if (byteLength === 0) | ||
return Uint8Array.from([0x4c, 0x00]); | ||
if (byteLength < 76) | ||
return Uint8Array.from([byteLength]); | ||
if (byteLength < 256) | ||
return Uint8Array.from([0x4c, byteLength]); | ||
throw Error('Pushdata too large'); | ||
@@ -165,0 +231,0 @@ } |
{ | ||
"name": "cashscript", | ||
"version": "0.5.0", | ||
"description": "Easily write and interact with Bitcoin Cash contracts", | ||
"version": "0.4.4", | ||
"author": "Rosco Kalis <roscokalis@gmail.com>", | ||
"keywords": [ | ||
"bitcoin cash", | ||
"cashscript", | ||
"sdk", | ||
"smart contracts" | ||
], | ||
"homepage": "https://cashscript.org", | ||
"bugs": { | ||
"url": "https://github.com/Bitcoin-com/cashscript/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Bitcoin-com/cashscript.git" | ||
}, | ||
"license": "MIT", | ||
"author": "Rosco Kalis <roscokalis@gmail.com>", | ||
"contributors": [ | ||
"Gabriel Cardona <gabriel@bitcoin.com>" | ||
], | ||
"dependencies": { | ||
"bitbox-sdk": "^8.8.0", | ||
"cashc": "^0.4.4", | ||
"cramer-bch": "https://github.com/jcramer/bitcoincashjs-lib", | ||
"delay": "^4.3.0", | ||
"bitcoincash-ops": "github:christroutner/bitcoincash-ops", | ||
"trout-bch": "github:christroutner/bitcoincashjs-lib#34f23671b42f0ebcbeba9f1f9e7bcdba7c50d55b" | ||
}, | ||
"devDependencies": { | ||
"bignumber.js": "^9.0.0", | ||
"eslint": "^6.6.0", | ||
"jest": "^25.1.0", | ||
"ts-jest": "^25.1.0", | ||
"typescript": "3.7.5" | ||
}, | ||
"main": "dist/index", | ||
"types": "dist/index", | ||
"directories": { | ||
@@ -31,15 +30,2 @@ "lib": "src", | ||
}, | ||
"homepage": "https://cashscript.org", | ||
"keywords": [ | ||
"bitcoin cash", | ||
"cashscript", | ||
"sdk", | ||
"smart contracts" | ||
], | ||
"license": "MIT", | ||
"main": "dist/index", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Bitcoin-com/cashscript.git" | ||
}, | ||
"scripts": { | ||
@@ -51,5 +37,22 @@ "build": "npm run clean && npm run compile", | ||
"prepare": "npm run build", | ||
"prepublishOnly": "npm run lint", | ||
"test": "jest --config=../../jest.config.js packages/cashscript" | ||
}, | ||
"types": "dist/index" | ||
"dependencies": { | ||
"@bitauth/libauth": "^1.17.1", | ||
"bip68": "^1.0.4", | ||
"cashc": "^0.5.0", | ||
"delay": "^4.3.0", | ||
"electrum-cash": "^2.0.2", | ||
"hash.js": "^1.1.7" | ||
}, | ||
"devDependencies": { | ||
"@psf/bch-js": "^3.5.3", | ||
"bignumber.js": "^9.0.0", | ||
"bitbox-sdk": "^8.8.0", | ||
"eslint": "^6.6.0", | ||
"jest": "^25.1.0", | ||
"ts-jest": "^25.1.0", | ||
"typescript": "3.7.5" | ||
} | ||
} |
@@ -11,3 +11,3 @@ # CashScript | ||
See the [GitHub repository](https://github.com/Bitcoin-com/cashscript) or the [CashScript website](https://cashscript.org) for full documentation and usage examples. | ||
See the [GitHub repository](https://github.com/Bitcoin-com/cashscript) and the [CashScript website](https://cashscript.org) for full documentation and usage examples. | ||
@@ -27,7 +27,7 @@ ## The CashScript Language | ||
```ts | ||
import { Contract, ... } from 'cashscript'; | ||
import { Contract, CashCompiler, ... } from 'cashscript'; | ||
``` | ||
```js | ||
const { Contract, ... } = require('cashscript'); | ||
const { Contract, CashCompiler, ... } = require('cashscript'); | ||
``` | ||
@@ -40,19 +40,23 @@ | ||
// Compile the P2PKH contract | ||
const P2PKH = Contract.compile('./p2pkh.cash', 'mainnet'); | ||
const P2PKH = CashCompiler.compileFile('./p2pkh.cash'); | ||
// Instantiate a new P2PKH contract with constructor arguments: { pkh: pkh } | ||
const instance = P2PKH.new(pkh); | ||
// Instantiate a network provider for CashScript's network operations | ||
const provider = new ElectrumNetworkProvider('mainnet'); | ||
// Create a new P2PKH contract with constructor arguments: { pkh: pkh } | ||
const contract = new Contract(P2PKH, [pkh], provider); | ||
// Get contract balance & output address + balance | ||
console.log('contract address:', instance.address); | ||
console.log('contract balance:', await instance.getBalance()); | ||
console.log('contract address:', contract.address); | ||
console.log('contract balance:', await contract.getBalance()); | ||
// Call the spend function with the owner's signature | ||
// And use it to send 0. 000 100 00 BCH back to the contract's address | ||
const txDetails = await instance.functions | ||
const txDetails = await contract.functions | ||
.spend(pk, new SignatureTemplate(keypair)) | ||
.to(instance.address, 10000) | ||
.to(contract.address, 10000) | ||
.send(); | ||
console.log(txDetails); | ||
... | ||
``` |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 2 instances in 1 package
HTTP dependency
Supply chain riskContains a dependency which resolves to a remote HTTP URL which could be used to inject untrusted code and reduce overall package reliability.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
1344
60
0
0
66012
7
31
+ Added@bitauth/libauth@^1.17.1
+ Addedbip68@^1.0.4
+ Addedelectrum-cash@^2.0.2
+ Addedhash.js@^1.1.7
+ Added@bitauth/libauth@1.19.1(transitive)
+ Added@types/ws@7.4.7(transitive)
+ Addedasync-mutex@0.3.2(transitive)
+ Addedbip68@1.0.4(transitive)
+ Addedcashc@0.5.7(transitive)
+ Addedcommander@6.2.1(transitive)
+ Addedelectrum-cash@2.0.10(transitive)
+ Addedisomorphic-ws@4.0.1(transitive)
+ Addedtslib@2.8.1(transitive)
- Removedbitbox-sdk@^8.8.0
- Removedbitcoincash-ops@github:christroutner/bitcoincash-ops
- Removedcramer-bch@https://github.com/jcramer/bitcoincashjs-lib
- Removedtrout-bch@github:christroutner/bitcoincashjs-lib#34f23671b42f0ebcbeba9f1f9e7bcdba7c50d55b
- Removed@bitcoin-dot-com/bitcoincashjs2-lib@4.1.0(transitive)
- Removed@socket.io/component-emitter@3.1.2(transitive)
- Removed@types/bigi@1.4.5(transitive)
- Removed@types/bip39@2.4.2(transitive)
- Removed@types/engine.io@3.1.10(transitive)
- Removed@types/randombytes@2.0.3(transitive)
- Removed@types/socket.io@2.1.13(transitive)
- Removed@types/socket.io-client@1.4.36(transitive)
- Removed@types/socket.io-parser@3.0.0(transitive)
- Removed@types/wif@2.0.5(transitive)
- Removed@types/yargs@13.0.12(transitive)
- Removed@types/yargs-parser@21.0.3(transitive)
- Removedaccepts@1.3.8(transitive)
- Removedafter@0.8.2(transitive)
- Removedansi-regex@4.1.1(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedarraybuffer.slice@0.0.7(transitive)
- Removedassert@1.5.1(transitive)
- Removedaxios@0.19.0(transitive)
- Removedbacko2@1.0.2(transitive)
- Removedbase-x@3.0.10(transitive)
- Removedbase64-arraybuffer@0.1.4(transitive)
- Removedbase64id@2.0.0(transitive)
- Removedbc-bip68@1.0.5(transitive)
- Removedbech32@1.1.4(transitive)
- Removedbig-integer@1.6.52(transitive)
- Removedbig.js@3.2.0(transitive)
- Removedbigi@1.4.2(transitive)
- Removedbindings@1.5.0(transitive)
- Removedbip-schnorr@0.3.0(transitive)
- Removedbip38@2.0.3(transitive)
- Removedbip39@2.6.0(transitive)
- Removedbip66@1.1.5(transitive)
- Removedbitbox-sdk@8.11.2(transitive)
- Removedbitcoin-ts@1.15.2(transitive)
- Removedbitcoinjs-message@2.2.0(transitive)
- Removedblob@0.0.5(transitive)
- Removedbn.js@4.12.1(transitive)
- Removedbrorand@1.1.0(transitive)
- Removedbrowserify-aes@1.2.0(transitive)
- Removedbs58@4.0.1(transitive)
- Removedbs58check@2.1.2(transitive)
- Removedbuffer-equals@1.0.4(transitive)
- Removedbuffer-xor@1.0.3(transitive)
- Removedcall-bind@1.0.7(transitive)
- Removedcamelcase@5.3.1(transitive)
- Removedcashaddrjs@0.2.9(transitive)
- Removedcashc@0.4.4(transitive)
- Removedcipher-base@1.0.6(transitive)
- Removedcliui@5.0.0(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedcomponent-bind@1.0.0(transitive)
- Removedcomponent-emitter@1.2.11.3.1(transitive)
- Removedcomponent-inherit@0.0.3(transitive)
- Removedcookie@0.4.2(transitive)
- Removedcreate-hash@1.2.0(transitive)
- Removedcreate-hmac@1.1.7(transitive)
- Removeddebug@4.1.1(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removeddefine-data-property@1.1.4(transitive)
- Removeddefine-properties@1.2.1(transitive)
- Removeddrbg.js@1.0.1(transitive)
- Removedecurve@1.0.6(transitive)
- Removedelliptic@6.6.1(transitive)
- Removedemoji-regex@7.0.3(transitive)
- Removedengine.io@3.6.2(transitive)
- Removedengine.io-client@3.5.4(transitive)
- Removedengine.io-parser@2.2.1(transitive)
- Removedes-define-property@1.0.0(transitive)
- Removedes-errors@1.3.0(transitive)
- Removedeventsource@1.1.2(transitive)
- Removedevp_bytestokey@1.0.3(transitive)
- Removedfile-uri-to-path@1.0.0(transitive)
- Removedfind-up@3.0.0(transitive)
- Removedfollow-redirects@1.5.10(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedget-caller-file@2.0.5(transitive)
- Removedget-intrinsic@1.2.4(transitive)
- Removedgopd@1.1.0(transitive)
- Removedhas-binary2@1.0.3(transitive)
- Removedhas-cors@1.1.0(transitive)
- Removedhas-property-descriptors@1.0.2(transitive)
- Removedhas-proto@1.0.3(transitive)
- Removedhas-symbols@1.0.3(transitive)
- Removedhash-base@3.1.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhmac-drbg@1.0.1(transitive)
- Removedindexof@0.0.1(transitive)
- Removedinherits@2.0.3(transitive)
- Removedis-buffer@2.0.5(transitive)
- Removedis-fullwidth-code-point@2.0.0(transitive)
- Removedisarray@2.0.1(transitive)
- Removedjs-sha256@0.9.0(transitive)
- Removedlocate-path@3.0.0(transitive)
- Removedmd5.js@1.3.5(transitive)
- Removedmerkle-lib@2.0.10(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedminimalistic-crypto-utils@1.0.1(transitive)
- Removednan@2.22.0(transitive)
- Removednegotiator@0.6.3(transitive)
- Removedobject-keys@1.1.1(transitive)
- Removedobject.assign@4.1.5(transitive)
- Removedp-limit@2.3.0(transitive)
- Removedp-locate@3.0.0(transitive)
- Removedp-try@2.2.0(transitive)
- Removedparseqs@0.0.6(transitive)
- Removedparseuri@0.0.6(transitive)
- Removedpath-exists@3.0.0(transitive)
- Removedpbkdf2@3.1.2(transitive)
- Removedrandom-bytes@1.0.0(transitive)
- Removedrandombytes@2.1.0(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedrequire-directory@2.1.1(transitive)
- Removedrequire-main-filename@2.0.0(transitive)
- Removedripemd160@2.0.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsatoshi-bitcoin@1.0.5(transitive)
- Removedscryptsy@2.1.0(transitive)
- Removedsecp256k1@3.8.1(transitive)
- Removedset-blocking@2.0.0(transitive)
- Removedset-function-length@1.2.2(transitive)
- Removedsha.js@2.4.11(transitive)
- Removedsocket.io@2.5.1(transitive)
- Removedsocket.io-adapter@1.1.2(transitive)
- Removedsocket.io-client@2.5.0(transitive)
- Removedsocket.io-parser@3.3.43.4.34.2.4(transitive)
- Removedstring-width@3.1.0(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedstrip-ansi@5.2.0(transitive)
- Removedto-array@0.1.4(transitive)
- Removedtypeforce@1.18.0(transitive)
- Removedunorm@1.6.0(transitive)
- Removedutil@0.10.4(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedvaruint-bitcoin@1.1.2(transitive)
- Removedwhich-module@2.0.1(transitive)
- Removedwif@2.0.6(transitive)
- Removedwrap-ansi@5.1.0(transitive)
- Removedxmlhttprequest-ssl@1.6.3(transitive)
- Removedy18n@4.0.3(transitive)
- Removedyargs@14.2.3(transitive)
- Removedyargs-parser@15.0.3(transitive)
- Removedyeast@0.1.2(transitive)
Updatedcashc@^0.5.0