@keystonehq/eth-keyring
Advanced tools
Comparing version 0.1.2 to 0.1.4
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const events_1 = require("events"); | ||
const hash_js_1 = require("hash.js"); | ||
const hdkey_1 = require("hdkey"); | ||
const sdk_1 = require("@keystonehq/sdk"); | ||
const ethereumjs_util_1 = require("ethereumjs-util"); | ||
const bc_ur_registry_eth_1 = require("@keystonehq/bc-ur-registry-eth"); | ||
const sdk_2 = require("@keystonehq/sdk"); | ||
const bs58check_1 = require("bs58check"); | ||
const uuid = require("uuid"); | ||
const keyringType = 'Air Gaped Device'; | ||
const pathBase = 'm'; | ||
const MAX_INDEX = 1000; | ||
const readKeyringCryptoHDKey = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { | ||
var tslib_1 = require("tslib"); | ||
var events_1 = require("events"); | ||
var hash_js_1 = tslib_1.__importDefault(require("hash.js")); | ||
var hdkey_1 = tslib_1.__importDefault(require("hdkey")); | ||
var sdk_1 = tslib_1.__importDefault(require("@keystonehq/sdk")); | ||
var ethereumjs_util_1 = require("ethereumjs-util"); | ||
var bc_ur_registry_eth_1 = require("@keystonehq/bc-ur-registry-eth"); | ||
var sdk_2 = require("@keystonehq/sdk"); | ||
var bs58check_1 = require("bs58check"); | ||
var uuid = tslib_1.__importStar(require("uuid")); | ||
var keyringType = 'Air Gaped Device'; | ||
var pathBase = 'm'; | ||
var MAX_INDEX = 1000; | ||
var readKeyringCryptoHDKey = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () { | ||
var decodedResult, result, cryptoHDKey, hdPath, xfp, xpub; | ||
var _a; | ||
const decodedResult = yield sdk_1.default.read([sdk_2.SupportedResult.UR_CRYPTO_HDKEY], { | ||
title: 'Sync Keystone', | ||
description: "Please click 'Sync' in Keystone and scan the QR code displayed later", | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4, sdk_1.default.read([sdk_2.SupportedResult.UR_CRYPTO_HDKEY], { | ||
title: 'Sync Keystone', | ||
description: "Please click 'Sync' in Keystone and scan the QR code displayed later", | ||
})]; | ||
case 1: | ||
decodedResult = _b.sent(); | ||
if (decodedResult.status === 'success') { | ||
result = decodedResult.result; | ||
cryptoHDKey = bc_ur_registry_eth_1.CryptoHDKey.fromCBOR(result.cbor); | ||
hdPath = "m/" + cryptoHDKey.getOrigin().getPath(); | ||
xfp = (_a = cryptoHDKey.getOrigin().getSourceFingerprint()) === null || _a === void 0 ? void 0 : _a.toString('hex'); | ||
if (!xfp) { | ||
throw new Error('invalid crypto-hd-key, cannot get source fingerprint'); | ||
} | ||
xpub = constructXPub(cryptoHDKey); | ||
return [2, { | ||
xfp: xfp, | ||
xpub: xpub, | ||
hdPath: hdPath, | ||
}]; | ||
} | ||
else { | ||
throw new Error('Reading canceled'); | ||
} | ||
return [2]; | ||
} | ||
}); | ||
if (decodedResult.status === 'success') { | ||
const { result } = decodedResult; | ||
const cryptoHDKey = bc_ur_registry_eth_1.CryptoHDKey.fromCBOR(result.cbor); | ||
const hdPath = `m/${cryptoHDKey.getOrigin().getPath()}`; | ||
const xfp = (_a = cryptoHDKey.getOrigin().getSourceFingerprint()) === null || _a === void 0 ? void 0 : _a.toString('hex'); | ||
if (!xfp) { | ||
throw new Error('invalid crypto-hd-key, cannot get source fingerprint'); | ||
} | ||
const xpub = constructXPub(cryptoHDKey); | ||
return { | ||
xfp, | ||
xpub, | ||
hdPath, | ||
}; | ||
} | ||
else { | ||
throw new Error('Reading canceled'); | ||
} | ||
}); | ||
const constructXPub = (cryptoHDKey) => { | ||
const version = Buffer.from('0488b21e', 'hex'); | ||
const depth = cryptoHDKey.getOrigin().getDepth() || cryptoHDKey.getOrigin().getComponents().length; | ||
const depthBuffer = Buffer.alloc(1); | ||
}); }; | ||
var constructXPub = function (cryptoHDKey) { | ||
var version = Buffer.from('0488b21e', 'hex'); | ||
var depth = cryptoHDKey.getOrigin().getDepth() || cryptoHDKey.getOrigin().getComponents().length; | ||
var depthBuffer = Buffer.alloc(1); | ||
depthBuffer.writeUInt8(depth); | ||
const parentFingerprint = cryptoHDKey.getParentFingerprint(); | ||
const paths = cryptoHDKey.getOrigin().getComponents(); | ||
const lastPath = paths[paths.length - 1]; | ||
const index = lastPath.isHardened() ? lastPath.getIndex() + 0x80000000 : lastPath.getIndex(); | ||
const indexBuffer = Buffer.alloc(4); | ||
var parentFingerprint = cryptoHDKey.getParentFingerprint(); | ||
var paths = cryptoHDKey.getOrigin().getComponents(); | ||
var lastPath = paths[paths.length - 1]; | ||
var index = lastPath.isHardened() ? lastPath.getIndex() + 0x80000000 : lastPath.getIndex(); | ||
var indexBuffer = Buffer.alloc(4); | ||
indexBuffer.writeUInt32BE(index); | ||
const chainCode = cryptoHDKey.getChainCode(); | ||
const key = cryptoHDKey.getKey(); | ||
var chainCode = cryptoHDKey.getChainCode(); | ||
var key = cryptoHDKey.getKey(); | ||
return bs58check_1.encode(Buffer.concat([version, depthBuffer, parentFingerprint, indexBuffer, chainCode, key])); | ||
}; | ||
const constructCryptoKeypath = (hdPath) => { | ||
const paths = hdPath.replace('m/', '').split('/'); | ||
return new bc_ur_registry_eth_1.CryptoKeypath(paths.map((path) => { | ||
const index = parseInt(path.replace("'", '')); | ||
let isHardened = false; | ||
var constructCryptoKeypath = function (hdPath) { | ||
var paths = hdPath.replace('m/', '').split('/'); | ||
return new bc_ur_registry_eth_1.CryptoKeypath(paths.map(function (path) { | ||
var index = parseInt(path.replace("'", '')); | ||
var isHardened = false; | ||
if (path.endsWith("'")) { | ||
isHardened = true; | ||
} | ||
return new bc_ur_registry_eth_1.PathComponent({ index, hardened: isHardened }); | ||
return new bc_ur_registry_eth_1.PathComponent({ index: index, hardened: isHardened }); | ||
})); | ||
}; | ||
const constructEthSignRequest = (address, hdPath, dataType, signData, signId) => { | ||
const signPath = constructCryptoKeypath(hdPath); | ||
var constructEthSignRequest = function (address, hdPath, dataType, signData, signId) { | ||
var signPath = constructCryptoKeypath(hdPath); | ||
return new bc_ur_registry_eth_1.EthSignRequest({ | ||
requestId: Buffer.from(uuid.parse(signId)), | ||
signData, | ||
signData: signData, | ||
dataType: dataType, | ||
chainId: 1, | ||
derivationPath: signPath, | ||
address, | ||
address: address, | ||
}); | ||
}; | ||
class AirGapedKeyring extends events_1.EventEmitter { | ||
constructor(opts) { | ||
super(); | ||
this.xfp = ''; | ||
this.xpub = ''; | ||
this.hdPath = ''; | ||
this.page = 0; | ||
this.perPage = 5; | ||
this.type = keyringType; | ||
this.accounts = []; | ||
this.currentAccount = 0; | ||
this.paths = {}; | ||
this.latestAccount = 0; | ||
this.deserialize(opts); | ||
var AirGapedKeyring = (function (_super) { | ||
tslib_1.__extends(AirGapedKeyring, _super); | ||
function AirGapedKeyring(opts) { | ||
var _this = _super.call(this) || this; | ||
_this.xfp = ''; | ||
_this.xpub = ''; | ||
_this.hdPath = ''; | ||
_this.page = 0; | ||
_this.perPage = 5; | ||
_this.type = keyringType; | ||
_this.accounts = []; | ||
_this.currentAccount = 0; | ||
_this.paths = {}; | ||
_this.latestAccount = 0; | ||
_this.deserialize(opts); | ||
return _this; | ||
} | ||
static getKeyring() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { xfp, xpub, hdPath } = yield readKeyringCryptoHDKey(); | ||
return new AirGapedKeyring({ | ||
xfp, | ||
xpub, | ||
hdPath, | ||
perPage: 5, | ||
page: 0, | ||
accounts: [], | ||
currentAccount: 0, | ||
paths: {}, | ||
AirGapedKeyring.getKeyring = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var _a, xfp, xpub, hdPath; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4, readKeyringCryptoHDKey()]; | ||
case 1: | ||
_a = _b.sent(), xfp = _a.xfp, xpub = _a.xpub, hdPath = _a.hdPath; | ||
return [2, new AirGapedKeyring({ | ||
xfp: xfp, | ||
xpub: xpub, | ||
hdPath: hdPath, | ||
perPage: 5, | ||
page: 0, | ||
accounts: [], | ||
currentAccount: 0, | ||
paths: {}, | ||
})]; | ||
} | ||
}); | ||
}); | ||
} | ||
static getEmptyKeyring() { | ||
}; | ||
AirGapedKeyring.getEmptyKeyring = function () { | ||
return new AirGapedKeyring({ | ||
@@ -119,17 +136,25 @@ xfp: '', | ||
}); | ||
} | ||
readKeyring() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { xpub, xfp, hdPath } = yield readKeyringCryptoHDKey(); | ||
this.xfp = xfp; | ||
this.xpub = xpub; | ||
this.hdPath = hdPath; | ||
}; | ||
AirGapedKeyring.prototype.readKeyring = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var _a, xpub, xfp, hdPath; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4, readKeyringCryptoHDKey()]; | ||
case 1: | ||
_a = _b.sent(), xpub = _a.xpub, xfp = _a.xfp, hdPath = _a.hdPath; | ||
this.xfp = xfp; | ||
this.xpub = xpub; | ||
this.hdPath = hdPath; | ||
return [2]; | ||
} | ||
}); | ||
}); | ||
} | ||
checkKeyring() { | ||
}; | ||
AirGapedKeyring.prototype.checkKeyring = function () { | ||
if (!this.xfp || !this.xpub || !this.hdPath) { | ||
throw new Error('keyring not fulfilled, please call function `readKeyring` firstly'); | ||
} | ||
} | ||
serialize() { | ||
}; | ||
AirGapedKeyring.prototype.serialize = function () { | ||
return Promise.resolve({ | ||
@@ -145,4 +170,4 @@ xfp: this.xfp, | ||
}); | ||
} | ||
deserialize(opts) { | ||
}; | ||
AirGapedKeyring.prototype.deserialize = function (opts) { | ||
this.xfp = opts.xfp; | ||
@@ -156,26 +181,28 @@ this.xpub = opts.xpub; | ||
this.paths = opts.paths; | ||
} | ||
setCurrentAccount(index) { | ||
}; | ||
AirGapedKeyring.prototype.setCurrentAccount = function (index) { | ||
this.currentAccount = index; | ||
} | ||
getCurrentAccount() { | ||
}; | ||
AirGapedKeyring.prototype.getCurrentAccount = function () { | ||
return this.currentAccount; | ||
} | ||
getCurrentAddress() { | ||
}; | ||
AirGapedKeyring.prototype.getCurrentAddress = function () { | ||
return this.accounts[this.currentAccount]; | ||
} | ||
addAccounts(n = 1) { | ||
return new Promise((resolve, reject) => { | ||
}; | ||
AirGapedKeyring.prototype.addAccounts = function (n) { | ||
var _this = this; | ||
if (n === void 0) { n = 1; } | ||
return new Promise(function (resolve, reject) { | ||
try { | ||
const from = this.latestAccount; | ||
const to = from + n; | ||
const newAccounts = []; | ||
for (let i = from; i < to; i++) { | ||
const address = this._addressFromIndex(pathBase, i); | ||
var from = _this.latestAccount; | ||
var to = from + n; | ||
var newAccounts = []; | ||
for (var i = from; i < to; i++) { | ||
var address = _this._addressFromIndex(pathBase, i); | ||
newAccounts.push(address); | ||
this.page = 0; | ||
this.latestAccount++; | ||
_this.page = 0; | ||
_this.latestAccount++; | ||
} | ||
this.accounts = this.accounts.concat(newAccounts); | ||
resolve(this.accounts); | ||
_this.accounts = _this.accounts.concat(newAccounts); | ||
resolve(_this.accounts); | ||
} | ||
@@ -186,14 +213,15 @@ catch (e) { | ||
}); | ||
} | ||
getFirstPage() { | ||
}; | ||
AirGapedKeyring.prototype.getFirstPage = function () { | ||
this.page = 0; | ||
return this.__getPage(1); | ||
} | ||
getNextPage() { | ||
}; | ||
AirGapedKeyring.prototype.getNextPage = function () { | ||
return this.__getPage(1); | ||
} | ||
getPreviousPage() { | ||
}; | ||
AirGapedKeyring.prototype.getPreviousPage = function () { | ||
return this.__getPage(-1); | ||
} | ||
__getPage(increment) { | ||
}; | ||
AirGapedKeyring.prototype.__getPage = function (increment) { | ||
var _this = this; | ||
this.page += increment; | ||
@@ -203,15 +231,15 @@ if (this.page <= 0) { | ||
} | ||
return new Promise((resolve, reject) => { | ||
return new Promise(function (resolve, reject) { | ||
try { | ||
const from = (this.page - 1) * this.perPage; | ||
const to = from + this.perPage; | ||
const accounts = []; | ||
for (let i = from; i < to; i++) { | ||
const address = this._addressFromIndex(pathBase, i); | ||
var from = (_this.page - 1) * _this.perPage; | ||
var to = from + _this.perPage; | ||
var accounts = []; | ||
for (var i = from; i < to; i++) { | ||
var address = _this._addressFromIndex(pathBase, i); | ||
accounts.push({ | ||
address, | ||
address: address, | ||
balance: null, | ||
index: i, | ||
}); | ||
this.paths[ethereumjs_util_1.toChecksumAddress(address)] = i; | ||
_this.paths[ethereumjs_util_1.toChecksumAddress(address)] = i; | ||
} | ||
@@ -224,100 +252,137 @@ resolve(accounts); | ||
}); | ||
} | ||
getAccounts() { | ||
}; | ||
AirGapedKeyring.prototype.getAccounts = function () { | ||
return this.accounts; | ||
} | ||
removeAccount(address) { | ||
if (!this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())) { | ||
throw new Error(`Address ${address} not found in this keyring`); | ||
}; | ||
AirGapedKeyring.prototype.removeAccount = function (address) { | ||
if (!this.accounts.map(function (a) { return a.toLowerCase(); }).includes(address.toLowerCase())) { | ||
throw new Error("Address " + address + " not found in this keyring"); | ||
} | ||
this.accounts = this.accounts.filter((a) => a.toLowerCase() !== address.toLowerCase()); | ||
} | ||
readSignature(signId) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const result = yield sdk_1.default.read([sdk_2.SupportedResult.UR_ETH_SIGNATURE], { | ||
title: 'Submit signing result', | ||
description: 'Please scan signing result QR code displayed on your Keystone', | ||
this.accounts = this.accounts.filter(function (a) { return a.toLowerCase() !== address.toLowerCase(); }); | ||
}; | ||
AirGapedKeyring.prototype.readSignature = function (signId) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var result, ethSignature, requestIdBuffer, signature, requestId, signatureHex, r, s, v; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4, sdk_1.default.read([sdk_2.SupportedResult.UR_ETH_SIGNATURE], { | ||
title: 'Submit signing result', | ||
description: 'Please scan signing result QR code displayed on your Keystone', | ||
})]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.status === 'canceled') { | ||
throw new Error('read signature canceled'); | ||
} | ||
else { | ||
ethSignature = bc_ur_registry_eth_1.ETHSignature.fromCBOR(result.result.cbor); | ||
requestIdBuffer = ethSignature.getRequestId(); | ||
signature = ethSignature.getSignature(); | ||
requestId = uuid.stringify(requestIdBuffer); | ||
if (requestId !== signId) { | ||
throw new Error('read signature error: mismatched signId'); | ||
} | ||
signatureHex = signature.toString('hex'); | ||
r = Buffer.from(signatureHex.slice(0, 64), 'hex'); | ||
s = Buffer.from(signatureHex.slice(64, 128), 'hex'); | ||
v = Buffer.from(signatureHex.slice(128), 'hex'); | ||
return [2, { | ||
r: r, | ||
s: s, | ||
v: v, | ||
}]; | ||
} | ||
return [2]; | ||
} | ||
}); | ||
if (result.status === 'canceled') { | ||
throw new Error('read signature canceled'); | ||
} | ||
else { | ||
const ethSignature = bc_ur_registry_eth_1.ETHSignature.fromCBOR(result.result.cbor); | ||
const requestIdBuffer = ethSignature.getRequestId(); | ||
const signature = ethSignature.getSignature(); | ||
const requestId = uuid.stringify(requestIdBuffer); | ||
if (requestId !== signId) { | ||
throw new Error('read signature error: mismatched signId'); | ||
} | ||
const signatureHex = signature.toString('hex'); | ||
const r = Buffer.from(signatureHex.slice(0, 64), 'hex'); | ||
const s = Buffer.from(signatureHex.slice(64, 128), 'hex'); | ||
const v = Buffer.from(signatureHex.slice(128), 'hex'); | ||
return { | ||
r, | ||
s, | ||
v, | ||
}; | ||
} | ||
}); | ||
} | ||
static serializeTx(tx) { | ||
const items = [ | ||
...tx.raw.slice(0, 6), | ||
}; | ||
AirGapedKeyring.serializeTx = function (tx) { | ||
var items = tslib_1.__spreadArray(tslib_1.__spreadArray([], tx.raw.slice(0, 6)), [ | ||
ethereumjs_util_1.toBuffer(tx.getChainId()), | ||
ethereumjs_util_1.unpadBuffer(ethereumjs_util_1.toBuffer(0)), | ||
ethereumjs_util_1.unpadBuffer(ethereumjs_util_1.toBuffer(0)), | ||
]; | ||
]); | ||
return ethereumjs_util_1.rlp.encode(items); | ||
} | ||
signTransaction(address, tx) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const txHex = AirGapedKeyring.serializeTx(tx).toString('hex'); | ||
const hdPath = this._pathFromAddress(address); | ||
const signId = hash_js_1.default.sha256().update(`${txHex}${hdPath}${this.xfp}`).digest('hex').slice(0, 8); | ||
const ethSignRequest = constructEthSignRequest(address, hdPath, bc_ur_registry_eth_1.DataType.transaction, AirGapedKeyring.serializeTx(tx), signId); | ||
yield sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing transaction', | ||
description: 'Please scan the QR code below with Keystone, review transaction information and authorize to sign', | ||
}; | ||
AirGapedKeyring.prototype.signTransaction = function (address, tx) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var txHex, hdPath, signId, ethSignRequest, _a, r, s, v; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
txHex = AirGapedKeyring.serializeTx(tx).toString('hex'); | ||
hdPath = this._pathFromAddress(address); | ||
signId = hash_js_1.default.sha256().update("" + txHex + hdPath + this.xfp).digest('hex').slice(0, 8); | ||
ethSignRequest = constructEthSignRequest(address, hdPath, bc_ur_registry_eth_1.DataType.transaction, AirGapedKeyring.serializeTx(tx), signId); | ||
return [4, sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing transaction', | ||
description: 'Please scan the QR code below with Keystone, review transaction information and authorize to sign', | ||
})]; | ||
case 1: | ||
_b.sent(); | ||
return [4, this.readSignature(signId)]; | ||
case 2: | ||
_a = _b.sent(), r = _a.r, s = _a.s, v = _a.v; | ||
tx.r = r; | ||
tx.s = s; | ||
tx.v = v; | ||
return [2, tx]; | ||
} | ||
}); | ||
const { r, s, v } = yield this.readSignature(signId); | ||
tx.r = r; | ||
tx.s = s; | ||
tx.v = v; | ||
return tx; | ||
}); | ||
} | ||
signMessage(withAccount, data) { | ||
}; | ||
AirGapedKeyring.prototype.signMessage = function (withAccount, data) { | ||
return this.signPersonalMessage(withAccount, data); | ||
} | ||
signPersonalMessage(withAccount, messageHex) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const hdPath = this._pathFromAddress(withAccount); | ||
const signId = hash_js_1.default.sha256().update(`${messageHex}${hdPath}${this.xfp}`).digest('hex').slice(0, 8); | ||
const ethSignRequest = constructEthSignRequest(withAccount, hdPath, bc_ur_registry_eth_1.DataType.rawHex, Buffer.from(messageHex, 'hex'), signId); | ||
yield sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing message', | ||
description: 'Please scan the QR code below with Keystone, review message and authorize to sign', | ||
}; | ||
AirGapedKeyring.prototype.signPersonalMessage = function (withAccount, messageHex) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var hdPath, signId, ethSignRequest, _a, r, s, v; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
hdPath = this._pathFromAddress(withAccount); | ||
signId = hash_js_1.default.sha256().update("" + messageHex + hdPath + this.xfp).digest('hex').slice(0, 8); | ||
ethSignRequest = constructEthSignRequest(withAccount, hdPath, bc_ur_registry_eth_1.DataType.rawHex, Buffer.from(messageHex, 'hex'), signId); | ||
return [4, sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing message', | ||
description: 'Please scan the QR code below with Keystone, review message and authorize to sign', | ||
})]; | ||
case 1: | ||
_b.sent(); | ||
return [4, this.readSignature(signId)]; | ||
case 2: | ||
_a = _b.sent(), r = _a.r, s = _a.s, v = _a.v; | ||
return [2, '0x' + r + s + v]; | ||
} | ||
}); | ||
const { r, s, v } = yield this.readSignature(signId); | ||
return '0x' + r + s + v; | ||
}); | ||
} | ||
signTypedData(withAccount, typedData) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const hdPath = this._pathFromAddress(withAccount); | ||
const signId = uuid.v4(); | ||
const ethSignRequest = constructEthSignRequest(withAccount, hdPath, bc_ur_registry_eth_1.DataType.typedData, Buffer.from(JSON.stringify(typedData), 'utf-8'), signId); | ||
yield sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing typed data', | ||
description: 'Please scan the QR code below with Keystone, review data and authorize to sign', | ||
}; | ||
AirGapedKeyring.prototype.signTypedData = function (withAccount, typedData) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var hdPath, signId, ethSignRequest, _a, r, s, v; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
hdPath = this._pathFromAddress(withAccount); | ||
signId = uuid.v4(); | ||
ethSignRequest = constructEthSignRequest(withAccount, hdPath, bc_ur_registry_eth_1.DataType.typedData, Buffer.from(JSON.stringify(typedData), 'utf-8'), signId); | ||
return [4, sdk_1.default.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
title: 'Request signing typed data', | ||
description: 'Please scan the QR code below with Keystone, review data and authorize to sign', | ||
})]; | ||
case 1: | ||
_b.sent(); | ||
return [4, this.readSignature(signId)]; | ||
case 2: | ||
_a = _b.sent(), r = _a.r, s = _a.s, v = _a.v; | ||
return [2, Buffer.concat([r, s, v])]; | ||
} | ||
}); | ||
const { r, s, v } = yield this.readSignature(signId); | ||
return Buffer.concat([r, s, v]); | ||
}); | ||
} | ||
_addressFromIndex(pb, i) { | ||
}; | ||
AirGapedKeyring.prototype._addressFromIndex = function (pb, i) { | ||
this.checkKeyring(); | ||
@@ -327,11 +392,11 @@ if (!this.hdk) { | ||
} | ||
const dkey = this.hdk.derive(`${pb}/0/${i}`); | ||
const address = '0x' + ethereumjs_util_1.publicToAddress(dkey.publicKey, true).toString('hex'); | ||
var dkey = this.hdk.derive(pb + "/0/" + i); | ||
var address = '0x' + ethereumjs_util_1.publicToAddress(dkey.publicKey, true).toString('hex'); | ||
return ethereumjs_util_1.toChecksumAddress(address); | ||
} | ||
_pathFromAddress(address) { | ||
const checksummedAddress = ethereumjs_util_1.toChecksumAddress(address); | ||
let index = this.paths[checksummedAddress]; | ||
}; | ||
AirGapedKeyring.prototype._pathFromAddress = function (address) { | ||
var checksummedAddress = ethereumjs_util_1.toChecksumAddress(address); | ||
var index = this.paths[checksummedAddress]; | ||
if (typeof index === 'undefined') { | ||
for (let i = 0; i < MAX_INDEX; i++) { | ||
for (var i = 0; i < MAX_INDEX; i++) { | ||
if (checksummedAddress === this._addressFromIndex(pathBase, i)) { | ||
@@ -346,7 +411,8 @@ index = i; | ||
} | ||
return `${this.hdPath}/0/${index}`; | ||
} | ||
} | ||
AirGapedKeyring.type = keyringType; | ||
return this.hdPath + "/0/" + index; | ||
}; | ||
AirGapedKeyring.type = keyringType; | ||
return AirGapedKeyring; | ||
}(events_1.EventEmitter)); | ||
exports.default = AirGapedKeyring; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@keystonehq/eth-keyring", | ||
"version": "0.1.2", | ||
"version": "0.1.4", | ||
"description": "eth-keyring interact with keystone", | ||
@@ -21,4 +21,4 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@keystonehq/bc-ur-registry-eth": "^0.1.0", | ||
"@keystonehq/sdk": "^0.1.0", | ||
"@keystonehq/bc-ur-registry-eth": "^0.1.1", | ||
"@keystonehq/sdk": "^0.2.1", | ||
"bs58check": "^2.1.2", | ||
@@ -33,5 +33,6 @@ "ethereumjs-tx": "^2.1.2", | ||
"@types/bs58check": "^2.1.0", | ||
"@types/hdkey": "2.0.0", | ||
"@types/uuid": "^8.3.1" | ||
}, | ||
"gitHead": "7190f81befd3086cd9e67ef22ddd38d3a8cd07ab" | ||
"gitHead": "2eabfd976e240dfba16f226022dbba6d00956b25" | ||
} |
@@ -7,3 +7,3 @@ import { EventEmitter } from 'events'; | ||
import HDKey from 'hdkey'; | ||
import sdk from '@keystonehq/sdk'; | ||
import sdk, {SupportedResult} from '@keystonehq/sdk'; | ||
import { toChecksumAddress, publicToAddress, rlp, toBuffer, unpadBuffer } from 'ethereumjs-util'; | ||
@@ -19,3 +19,2 @@ import { Transaction } from 'ethereumjs-tx'; | ||
} from '@keystonehq/bc-ur-registry-eth'; | ||
import { SupportedResult } from '@keystonehq/sdk'; | ||
import { encode } from 'bs58check'; | ||
@@ -41,4 +40,7 @@ import * as uuid from 'uuid'; | ||
sdk.bootstrap(); | ||
const keystoneSDK =sdk.getSdk(); | ||
const readKeyringCryptoHDKey = async (): Promise<{ xfp: string; xpub: string; hdPath: string }> => { | ||
const decodedResult = await sdk.read([SupportedResult.UR_CRYPTO_HDKEY], { | ||
const decodedResult = await keystoneSDK.read([SupportedResult.UR_CRYPTO_HDKEY], { | ||
title: 'Sync Keystone', | ||
@@ -295,3 +297,3 @@ description: "Please click 'Sync' in Keystone and scan the QR code displayed later", | ||
async readSignature(signId: string): Promise<{ r: Buffer; s: Buffer; v: Buffer }> { | ||
const result = await sdk.read([SupportedResult.UR_ETH_SIGNATURE], { | ||
const result = await keystoneSDK.read([SupportedResult.UR_ETH_SIGNATURE], { | ||
title: 'Submit signing result', | ||
@@ -345,3 +347,3 @@ description: 'Please scan signing result QR code displayed on your Keystone', | ||
); | ||
await sdk.play(ethSignRequest.toUR(), { | ||
await keystoneSDK.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
@@ -373,3 +375,3 @@ title: 'Request signing transaction', | ||
); | ||
await sdk.play(ethSignRequest.toUR(), { | ||
await keystoneSDK.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
@@ -393,3 +395,3 @@ title: 'Request signing message', | ||
); | ||
await sdk.play(ethSignRequest.toUR(), { | ||
await keystoneSDK.play(ethSignRequest.toUR(), { | ||
hasNext: true, | ||
@@ -396,0 +398,0 @@ title: 'Request signing typed data', |
Sorry, the diff of this file is not supported yet
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
47221
5
856
3
+ Added@keystonehq/sdk@0.2.1(transitive)
- Removed@keystonehq/sdk@0.1.0(transitive)
Updated@keystonehq/sdk@^0.2.1