UNPKG

scrypt-ts

Version:

A toolset for building sCrypt smart contract applications on Bitcoin SV network written in typescript.

226 lines 10.7 kB
"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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TAALSigner = void 0; const abstract_signer_1 = require("../../abstract-signer"); const scryptlib_1 = require("scryptlib"); const utils_1 = require("../../utils"); const globals_1 = require("./globals"); const DEFAULT_SIGHASH_TYPE = scryptlib_1.bsv.crypto.Signature.ALL; const TAAL_EXTENSION_ID = "engokokaoeppkmchbkjeoeimiffobcke"; class TAALSigner extends abstract_signer_1.Signer { constructor(provider, app_name = "APP_NAME") { super(provider); this._app_name = app_name; } isAuthenticated() { return __awaiter(this, void 0, void 0, function* () { if (this._port) { return true; } return false; }); } requestAuth() { return __awaiter(this, void 0, void 0, function* () { let isAuthenticated = false; let error = ''; try { this._port = chrome.runtime.connect(TAAL_EXTENSION_ID, { name: this._app_name }); yield this.getDefaultAddress(); yield this.alignProviderNetwork(); isAuthenticated = this._port ? true : false; } catch (e) { error = e.toString(); } return { isAuthenticated, error }; }); } assertIsAuthenticated() { if (!this._port) { throw new Error('TAAL chrome wallet is not connected!'); } } setProvider(provider) { throw new Error("cannot alter provider"); } getDefaultAddress() { return __awaiter(this, void 0, void 0, function* () { this.assertIsAuthenticated(); const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.GetAddress); return scryptlib_1.bsv.Address.fromString(response.payload); }); } getDefaultPubKey() { return __awaiter(this, void 0, void 0, function* () { this.assertIsAuthenticated(); const network = yield this.getNetwork(); const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.GetPublicKey); const publicKey = new scryptlib_1.bsv.PublicKey(response.payload, { network: network }); return Promise.resolve(publicKey); }); } getPubKey(address) { return __awaiter(this, void 0, void 0, function* () { throw new Error(`Method ${this.constructor.name}#getPubKey not implemented.`); }); } getNetwork() { return __awaiter(this, void 0, void 0, function* () { this.assertIsAuthenticated(); const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.GetNetwork); const network = scryptlib_1.bsv.Networks.get(response.payload); return Promise.resolve(network); }); } updateInputsWithInfo(tx, inputInfos) { tx.inputs.forEach((input, index) => { // Find the corresponding inputInfo based on the inputIndex const inputInfo = inputInfos.find((info) => info.inputIndex === index); if (inputInfo) { // Update the input properties using the inputInfo data input.output = new scryptlib_1.bsv.Transaction.Output({ satoshis: inputInfo.satoshis, script: scryptlib_1.bsv.Script.fromHex(inputInfo.scriptHex), }); } }); return tx; } signTransaction(tx, options) { var _a; return __awaiter(this, void 0, void 0, function* () { const network = yield this.getNetwork(); const address = yield this.getDefaultAddress(); // Generate default `sigRequests` if not passed by user const sigRequests = ((_a = options === null || options === void 0 ? void 0 : options.sigRequests) === null || _a === void 0 ? void 0 : _a.length) ? options.sigRequests : tx.inputs.map((input, inputIndex) => { var _a, _b, _c, _d, _e, _f; const useAddressToSign = options && options.address ? options.address : ((_a = input.output) === null || _a === void 0 ? void 0 : _a.script.isPublicKeyHashOut()) ? input.output.script.toAddress(network) : address; return { prevTxId: (0, scryptlib_1.toHex)(input.prevTxId), outputIndex: input.outputIndex, inputIndex, satoshis: (_c = (_b = input.output) === null || _b === void 0 ? void 0 : _b.satoshis) !== null && _c !== void 0 ? _c : 0, //satoshis: input.output?.satoshis, address: useAddressToSign, scriptHex: (_f = (_e = (_d = input.output) === null || _d === void 0 ? void 0 : _d.script) === null || _e === void 0 ? void 0 : _e.toHex()) !== null && _f !== void 0 ? _f : '', //scriptHex: input.output?.script?.toHex(), sigHashType: DEFAULT_SIGHASH_TYPE, }; }); const rawTxHex = tx.toString(); const inputInfos = sigRequests.flatMap((sigReq) => { const addresses = (0, utils_1.parseAddresses)(sigReq.address, network); return addresses.map(address => { return { txHex: rawTxHex, inputIndex: sigReq.inputIndex, scriptHex: sigReq.scriptHex || scryptlib_1.bsv.Script.buildPublicKeyHashOut(address).toHex(), satoshis: sigReq.satoshis, sigtype: sigReq.sigHashType || DEFAULT_SIGHASH_TYPE, address: address.toString() }; }); }); // Modify the transaction object using the inputInfos data const updatedTx = this.updateInputsWithInfo(tx, inputInfos); this.assertIsAuthenticated(); const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.SignTx, updatedTx); const signedTxHex = response.payload; // Create a new Transaction object from the signed transaction hex const signedTx = new scryptlib_1.bsv.Transaction(signedTxHex); // Modify the transaction object using the inputInfos data return this.updateInputsWithInfo(signedTx, inputInfos); }); } /** * Get signatures with api * @param rawTxHex a transation raw hex * @param sigRequests a `SignatureRequest` array for the some inputs of the transaction. * @returns a `SignatureResponse` array */ getSignatures(rawTxHex, sigRequests) { return __awaiter(this, void 0, void 0, function* () { const network = yield this.getNetwork(); const payloads = sigRequests.flatMap((sigReq) => { const addresses = (0, utils_1.parseAddresses)(sigReq.address, network); return addresses.map(address => { let script = sigReq.scriptHex; if (!sigReq) { script = scryptlib_1.bsv.Script.buildPublicKeyHashOut(address).toHex(); } else if (sigReq.csIdx !== undefined) { script = scryptlib_1.bsv.Script.fromHex(script).subScript(sigReq.csIdx).toHex(); } return { tx: rawTxHex, i: sigReq.inputIndex, script, satoshis: sigReq.satoshis, sighash: sigReq.sigHashType || DEFAULT_SIGHASH_TYPE, address: address.toString() }; }); }); const inputSignatures = yield Promise.all(payloads.map(payload => this.signCustomInput(payload))); return inputSignatures.map(s => ({ inputIndex: s.inputIndex, sig: (0, scryptlib_1.toHex)(s.signature), publicKey: s.publicKey.toString(), sigHashType: s.sigtype })); }); } signMessage(message, address) { return __awaiter(this, void 0, void 0, function* () { if (address) { throw new Error(`${this.constructor.name}#signMessge with \`address\` param is not supported!`); } this.assertIsAuthenticated(); const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.SignMessage, message); return response.payload; }); } getBalance(address) { return __awaiter(this, void 0, void 0, function* () { if (address) { return this.connectedProvider.getBalance(address); } const response = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.GetBalance); return { confirmed: response.payload, unconfirmed: 0 }; }); } signCustomInput(signPreimagePayload) { return __awaiter(this, void 0, void 0, function* () { const rootPublicKey = yield this.getDefaultPubKey(); const signPreimageResponse = yield (0, globals_1.sendAction)(this._port, globals_1.TAALWalletAction.SignPreimage, signPreimagePayload); return { inputIndex: signPreimagePayload.i, sigtype: signPreimagePayload.sighash, publicKey: rootPublicKey, signature: signPreimageResponse.payload, }; }); } } exports.TAALSigner = TAALSigner; //# sourceMappingURL=index.js.map