UNPKG

@unisat/wallet-sdk

Version:
433 lines (432 loc) 16.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeystoneKeyring = void 0; const keystone_sdk_1 = __importStar(require("@keystonehq/keystone-sdk")); const utils_1 = require("@keystonehq/keystone-sdk/dist/utils"); const bitcoinjs_lib_1 = require("bitcoinjs-lib"); const bitcore_lib_1 = __importDefault(require("bitcore-lib")); const events_1 = require("events"); const message_1 = require("../message"); const type = 'Keystone'; const DEFAULT_CONNECTION_TYPE = 'QR'; class KeystoneKeyring extends events_1.EventEmitter { constructor(opts) { super(); this.type = type; this.mfp = ''; this.keys = []; this.activeIndexes = []; this.root = null; this.connectionType = 'QR'; this.page = 0; this.perPage = 5; this.origin = 'UniSat Wallet'; if (opts) { this.deserialize(opts); } } initFromUR(type, cbor, connectionType) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); const account = keystoneSDK.parseAccount(new keystone_sdk_1.UR(Buffer.from(cbor, 'hex'), type)); yield this.deserialize({ mfp: account.masterFingerprint, keys: account.keys.map((k) => ({ path: k.path, extendedPublicKey: k.extendedPublicKey })), connectionType: connectionType !== null && connectionType !== void 0 ? connectionType : DEFAULT_CONNECTION_TYPE }); }); } getHardenedPath(hdPath) { const paths = hdPath.split('/'); return paths.slice(0, 4).join('/'); } getHDPublicKey(hdPath) { const path = this.getHardenedPath(hdPath); const key = this.keys.find((v) => v.path === path); if (!key) { throw new Error('Invalid path'); } return new bitcore_lib_1.default.HDPublicKey(key.extendedPublicKey); } getDefaultHdPath() { return "m/44'/0'/0'/0"; } getConnectionType() { var _a; return (_a = this.connectionType) !== null && _a !== void 0 ? _a : DEFAULT_CONNECTION_TYPE; } initRoot() { var _a; this.root = this.getHDPublicKey((_a = this.hdPath) !== null && _a !== void 0 ? _a : this.getDefaultHdPath()); } deserialize(opts) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { this.mfp = opts.mfp; this.keys = opts.keys; this.hdPath = (_a = opts.hdPath) !== null && _a !== void 0 ? _a : this.getDefaultHdPath(); this.activeIndexes = opts.activeIndexes ? [...opts.activeIndexes] : []; this.connectionType = (_b = opts.connectionType) !== null && _b !== void 0 ? _b : DEFAULT_CONNECTION_TYPE; this.initRoot(); if (opts.hdPath !== null && opts.hdPath !== undefined && opts.hdPath.length >= 13 && opts.hdPath[opts.hdPath.length - 1] === '1') { this.root = this.root.derive(`m/1`); } }); } serialize() { return __awaiter(this, void 0, void 0, function* () { return { mfp: this.mfp, keys: this.keys, hdPath: this.hdPath, activeIndexes: this.activeIndexes, connectionType: this.connectionType }; }); } addAccounts(numberOfAccounts = 1) { return __awaiter(this, void 0, void 0, function* () { let count = numberOfAccounts; let i = 0; const pubkeys = []; while (count) { if (this.activeIndexes.includes(i)) { i++; } else { const w = this.getWalletByIndex(i); pubkeys.push(w.publicKey); this.activeIndexes.push(i); count--; } } return Promise.resolve(pubkeys); }); } addChangeAddressAccounts(numberOfAccounts = 1) { return __awaiter(this, void 0, void 0, function* () { let count = numberOfAccounts; let i = 0; const pubkeys = []; while (count) { if (this.activeIndexes.includes(i)) { i++; } else { const w = this.getChangeAddressWalletByIndex(i); pubkeys.push(w.publicKey); this.activeIndexes.push(i); count--; } } return Promise.resolve(pubkeys); }); } getAccounts() { return __awaiter(this, void 0, void 0, function* () { if (this.hdPath !== null && this.hdPath !== undefined && this.hdPath.length >= 13 && this.hdPath[this.hdPath.length - 1] === '1') { return this.activeIndexes.map((index) => { const child = this.root.derive(`m/${index}`); return child.publicKey.toString('hex'); }); } return this.activeIndexes.map((i) => this.getWalletByIndex(i).publicKey); }); } getAccounts2() { return __awaiter(this, void 0, void 0, function* () { return this.activeIndexes.map((index) => { const child = this.root.derive(`m/${index}`); return { index, path: `${this.hdPath}/${index}`, publicKey: child.publicKey.toString('hex') }; }); }); } getAccountsWithBrand() { return __awaiter(this, void 0, void 0, function* () { return this.activeIndexes.map((i) => { const w = this.getWalletByIndex(i); return { address: w.publicKey, index: i }; }); }); } getWalletByIndex(index) { const child = this.root.derive(`m/0/${index}`); return { index, path: `${this.hdPath}/${index}`, publicKey: child.publicKey.toString('hex') }; } getChangeAddressWalletByIndex(index) { const child = this.root.derive(`m/1/${index}`); return { index, path: `${this.hdPath}/${index}`, publicKey: child.publicKey.toString('hex') }; } removeAccount(publicKey) { const index = this.activeIndexes.findIndex((i) => { const w = this.getWalletByIndex(i); return w.publicKey === publicKey; }); if (index !== -1) { this.activeIndexes.splice(index, 1); } } // eslint-disable-next-line @typescript-eslint/no-unused-vars exportAccount(_publicKey) { return __awaiter(this, void 0, void 0, function* () { throw new Error('Not supported'); }); } getFirstPage() { this.page = 0; return this.getPage(1); } getNextPage() { return this.getPage(1); } getPreviousPage() { return this.getPage(-1); } getAddresses(start, end) { const from = start; const to = end; const accounts = []; for (let i = from; i < to; i++) { const w = this.getWalletByIndex(i); accounts.push({ address: w.publicKey, index: i + 1 }); } return accounts; } getPage(increment) { return __awaiter(this, void 0, void 0, function* () { this.page += increment; if (!this.page || this.page <= 0) { this.page = 1; } const from = (this.page - 1) * this.perPage; const to = from + this.perPage; const accounts = []; for (let i = from; i < to; i++) { const w = this.getWalletByIndex(i); accounts.push({ address: w.publicKey, index: i + 1 }); } return accounts; }); } activeAccounts(indexes) { const accounts = []; for (const index of indexes) { const w = this.getWalletByIndex(index); if (!this.activeIndexes.includes(index)) { this.activeIndexes.push(index); } accounts.push(w.publicKey); } return accounts; } changeHdPath(hdPath) { this.hdPath = hdPath; this.initRoot(); this.activeAccounts(this.activeIndexes); } changeChangeAddressHdPath(hdPath) { var _a; this.hdPath = hdPath; this.root = this.getHDPublicKey((_a = this.hdPath) !== null && _a !== void 0 ? _a : this.getDefaultHdPath()); this.root = this.root.derive(`m/1`); this.activeIndexes = []; return []; } getAccountByHdPath(hdPath, index) { const root = this.getHDPublicKey(hdPath); const child = root.derive(`m/0/${index}`); return child.publicKey.toString('hex'); } getChangeAddressAccountByHdPath(hdPath, index) { const root = this.getHDPublicKey(hdPath); const child = root.derive(`m/1/${index}`); return child.publicKey.toString('hex'); } genSignPsbtUr(psbtHex) { return __awaiter(this, void 0, void 0, function* () { const psbt = bitcoinjs_lib_1.Psbt.fromHex(psbtHex); const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); const ur = keystoneSDK.btc.generatePSBT(psbt.data.toBuffer()); return { type: ur.type, cbor: ur.cbor.toString('hex') }; }); } parseSignPsbtUr(type, cbor) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); return keystoneSDK.btc.parsePSBT(new keystone_sdk_1.UR(Buffer.from(cbor, 'hex'), type)); }); } genSignMsgUr(publicKey, text) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); let i = undefined; if (this.hdPath !== null && this.hdPath !== undefined && this.hdPath.length >= 13 && this.hdPath[this.hdPath.length - 1] === '1') { const root = this.getHDPublicKey(this.hdPath); i = this.activeIndexes.find((i) => { const child = root.derive(`m/1/${i}`); if (child.publicKey.toString('hex') === publicKey) { return true; } }); } else { i = this.activeIndexes.find((i) => this.getWalletByIndex(i).publicKey === publicKey); } if (i === undefined) { throw new Error('publicKey not found'); } const requestId = utils_1.uuid.v4(); const ur = keystoneSDK.btc.generateSignRequest({ requestId, signData: Buffer.from(text).toString('hex'), dataType: keystone_sdk_1.KeystoneBitcoinSDK.DataType.message, accounts: [ { path: `${this.hdPath}/${i}`, xfp: this.mfp } ], origin: this.origin }); return { requestId, type: ur.type, cbor: ur.cbor.toString('hex') }; }); } parseSignMsgUr(type, cbor) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); return keystoneSDK.btc.parseSignature(new keystone_sdk_1.UR(Buffer.from(cbor, 'hex'), type)); }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars signMessage(publicKey, text) { return __awaiter(this, void 0, void 0, function* () { return 'Signing Message with Keystone should use genSignMsgUr and parseSignMsgUr'; }); } genSignCosmosUr(cosmosSignRequest) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); const requestId = cosmosSignRequest.requestId || utils_1.uuid.v4(); const ur = keystoneSDK.cosmos.generateSignRequest({ requestId, signData: cosmosSignRequest.signData, dataType: cosmosSignRequest.dataType, accounts: [ { path: cosmosSignRequest.path, xfp: this.mfp, address: cosmosSignRequest.address || '' } ], origin: this.origin }); return { requestId, type: ur.type, cbor: ur.cbor.toString('hex') }; }); } parseSignCosmosUr(type, cbor) { return __awaiter(this, void 0, void 0, function* () { const keystoneSDK = new keystone_sdk_1.default({ origin: this.origin }); return keystoneSDK.cosmos.parseSignature(new keystone_sdk_1.UR(Buffer.from(cbor, 'hex'), type)); }); } verifyMessage(publicKey, text, sig) { return __awaiter(this, void 0, void 0, function* () { return (0, message_1.verifyMessageOfECDSA)(publicKey, text, sig); }); } } exports.KeystoneKeyring = KeystoneKeyring; KeystoneKeyring.type = type;