diff --git a/package.json b/package.json index 207fba27bb..5dcd6d9973 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,16 @@ }, "scripts": { "auto-build": "node ./admin/cmds/reset-build.js && npm run build -- -w", + "auto-build-esm": "node ./admin/cmds/set-option esm && npm run build -- -w", "bootstrap": "node ./admin/cmds/reset-build.js && node ./admin/cmds/update-depgraph && lerna bootstrap --hoist", "build": "tsc --build ./tsconfig.project.json", "_build-cjs": "node ./admin/cmds/set-option cjs && npm run build", "_build-esm": "node ./admin/cmds/set-option esm && npm run build", + "_dist_ancillary": "rollup -c rollup-ancillary.config.js", "_dist-min-all": "node ./admin/cmds/set-option.js browser-lang-all && rollup -c --configMinify && rollup -c --configMinify --configModule && mv ./packages/ethers/dist/ethers.umd.min.js ./packages/ethers/dist/ethers-all.umd.min.js && mv ./packages/ethers/dist/ethers.esm.min.js ./packages/ethers/dist/ethers-all.esm.min.js", "_dist-min-en": "node ./admin/cmds/set-option.js browser-lang-en && rollup -c --configMinify && rollup -c --configMinify --configModule", "_dist-full": "rollup -c && rollup -c --configModule", - "_dist": "npm run _dist-min-all && npm run _dist-min-en && npm run _dist-full", + "_dist": "npm run _dist-min-all && npm run _dist-min-en && npm run _dist-full && npm run _dist_ancillary", "build-all": "node ./admin/cmds/update-exports.js && npm run _build-esm && npm run _build-cjs && npm run _dist", "clean": "node ./admin/cmds/reset-build.js && tsc --build --clean ./tsconfig.project.json", "__dist_ethers": "npm run _dist-min-all && npm run _dist-min-en && npm run _dist-full", diff --git a/packages/hardware-wallets/dist/hardware-wallets.esm.js b/packages/hardware-wallets/dist/hardware-wallets.esm.js new file mode 100644 index 0000000000..511cc2d425 --- /dev/null +++ b/packages/hardware-wallets/dist/hardware-wallets.esm.js @@ -0,0 +1,4353 @@ +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); +} + +function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +function getCjsExportFromNamespace (n) { + return n && n['default'] || n; +} + +var browserEthers = createCommonjsModule(function (module, exports) { +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ethers = {}; +exports.ethers = ethers; +var w = window; +if (w._ethers == null) { + console.log("WARNING: @ethersproject/hardware-wallet requires ethers loaded first"); +} +else { + exports.ethers = ethers = w._ethers; +} +}); + +var browserEthers$1 = unwrapExports(browserEthers); +var browserEthers_1 = browserEthers.ethers; + +const version = "hardware-wallets/5.0.0-beta.2"; + +var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + +var lookup = []; +var revLookup = []; +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; +var inited = false; +function init () { + inited = true; + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + + revLookup['-'.charCodeAt(0)] = 62; + revLookup['_'.charCodeAt(0)] = 63; +} + +function toByteArray (b64) { + if (!inited) { + init(); + } + var i, j, l, tmp, placeHolders, arr; + var len = b64.length; + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len; + + var L = 0; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; + arr[L++] = (tmp >> 16) & 0xFF; + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); + arr[L++] = tmp & 0xFF; + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp; + var output = []; + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output.push(tripletToBase64(tmp)); + } + return output.join('') +} + +function fromByteArray (uint8) { + if (!inited) { + init(); + } + var tmp; + var len = uint8.length; + var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes + var output = ''; + var parts = []; + var maxChunkLength = 16383; // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1]; + output += lookup[tmp >> 2]; + output += lookup[(tmp << 4) & 0x3F]; + output += '=='; + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); + output += lookup[tmp >> 10]; + output += lookup[(tmp >> 4) & 0x3F]; + output += lookup[(tmp << 2) & 0x3F]; + output += '='; + } + + parts.push(output); + + return parts.join('') +} + +function read (buffer, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? (nBytes - 1) : 0; + var d = isLE ? -1 : 1; + var s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +function write (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); + var i = isLE ? 0 : (nBytes - 1); + var d = isLE ? 1 : -1; + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; +} + +var toString = {}.toString; + +var isArray = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +var INSPECT_MAX_BYTES = 50; + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + +/* + * Export kMaxLength after typed array support is determined. + */ +var _kMaxLength = kMaxLength(); +function typedArraySupport () { + return true; + // rollup issues + // try { + // var arr = new Uint8Array(1) + // arr.__proto__ = { + // __proto__: Uint8Array.prototype, + // foo: function () { return 42 } + // } + // return arr.foo() === 42 && // typed array instances can be augmented + // typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + // arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + // } catch (e) { + // return false + // } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length); + } + that.length = length; + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192; // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype; + return arr +}; + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +}; + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype; + Buffer.__proto__ = Uint8Array; + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + // Object.defineProperty(Buffer, Symbol.species, { + // value: null, + // configurable: true + // }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size); + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +}; + +function allocUnsafe (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0; + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +}; +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +}; + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0; + that = createBuffer(that, length); + + var actual = that.write(string, encoding); + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual); + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0; + that = createBuffer(that, length); + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255; + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength; // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array); + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset); + } else { + array = new Uint8Array(array, byteOffset, length); + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array); + } + return that +} + +function fromObject (that, obj) { + if (internalIsBuffer(obj)) { + var len = checked(obj.length) | 0; + that = createBuffer(that, len); + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len); + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0; + } + return Buffer.alloc(+length) +} +Buffer.isBuffer = isBuffer; +function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!internalIsBuffer(a) || !internalIsBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length; + var y = b.length; + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +}; + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +}; + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer.allocUnsafe(length); + var pos = 0; + for (i = 0; i < list.length; ++i) { + var buf = list[i]; + if (!internalIsBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer +}; + +function byteLength (string, encoding) { + if (internalIsBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string; + } + + var len = string.length; + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +} +Buffer.byteLength = byteLength; + +function slowToString (encoding, start, end) { + var loweredCase = false; + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0; + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length; + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0; + start >>>= 0; + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8'; + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase(); + loweredCase = true; + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true; + +function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length; + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1); + } + return this +}; + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length; + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this +}; + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length; + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this +}; + +Buffer.prototype.toString = function toString () { + var length = this.length | 0; + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +}; + +Buffer.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +}; + +Buffer.prototype.inspect = function inspect () { + var str = ''; + var max = INSPECT_MAX_BYTES; + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' '); + if (this.length > max) str += ' ... '; + } + return '' +}; + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!internalIsBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0; + } + if (end === undefined) { + end = target ? target.length : 0; + } + if (thisStart === undefined) { + thisStart = 0; + } + if (thisEnd === undefined) { + thisEnd = this.length; + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0; + end >>>= 0; + thisStart >>>= 0; + thisEnd >>>= 0; + + if (this === target) return 0 + + var x = thisEnd - thisStart; + var y = end - start; + var len = Math.min(x, y); + + var thisCopy = this.slice(thisStart, thisEnd); + var targetCopy = target.slice(start, end); + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i]; + y = targetCopy[i]; + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +}; + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = 0; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + byteOffset = +byteOffset; // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1); + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset; + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1; + } else if (byteOffset < 0) { + if (dir) byteOffset = 0; + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding); + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (internalIsBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF; // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1; + var arrLength = arr.length; + var valLength = val.length; + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase(); + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2; + arrLength /= 2; + valLength /= 2; + byteOffset /= 2; + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i; + if (dir) { + var foundIndex = -1; + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i; + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex; + foundIndex = -1; + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength; + for (i = byteOffset; i >= 0; i--) { + var found = true; + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false; + break + } + } + if (found) return i + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +}; + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +}; + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +}; + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0; + var remaining = buf.length - offset; + if (!length) { + length = remaining; + } else { + length = Number(length); + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(parsed)) return i + buf[offset + i] = parsed; + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8'; + length = this.length; + offset = 0; + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0; + if (isFinite(length)) { + length = length | 0; + if (encoding === undefined) encoding = 'utf8'; + } else { + encoding = length; + length = undefined; + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset; + if (length === undefined || length > remaining) length = remaining; + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8'; + + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +}; + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +}; + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return fromByteArray(buf) + } else { + return fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end); + var res = []; + + var i = start; + while (i < end) { + var firstByte = buf[i]; + var codePoint = null; + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1; + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint; + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte; + } + break + case 2: + secondByte = buf[i + 1]; + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint; + } + } + break + case 3: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint; + } + } + break + case 4: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + fourthByte = buf[i + 3]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint; + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD; + bytesPerSequence = 1; + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000; + res.push(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + res.push(codePoint); + i += bytesPerSequence; + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000; + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length; + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = ''; + var i = 0; + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ); + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F); + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]); + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; ++i) { + out += toHex(buf[i]); + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end); + var res = ''; + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length; + start = ~~start; + end = end === undefined ? len : ~~end; + + if (start < 0) { + start += len; + if (start < 0) start = 0; + } else if (start > len) { + start = len; + } + + if (end < 0) { + end += len; + if (end < 0) end = 0; + } else if (end > len) { + end = len; + } + + if (end < start) end = start; + + var newBuf; + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer(sliceLen, undefined); + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start]; + } + } + + return newBuf +}; + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + + return val +}; + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + checkOffset(offset, byteLength, this.length); + } + + var val = this[offset + --byteLength]; + var mul = 1; + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul; + } + + return val +}; + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length); + return this[offset] +}; + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + return this[offset] | (this[offset + 1] << 8) +}; + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + return (this[offset] << 8) | this[offset + 1] +}; + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +}; + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +}; + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + mul *= 0x80; + + if (val >= mul) val -= Math.pow(2, 8 * byteLength); + + return val +}; + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var i = byteLength; + var mul = 1; + var val = this[offset + --i]; + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul; + } + mul *= 0x80; + + if (val >= mul) val -= Math.pow(2, 8 * byteLength); + + return val +}; + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length); + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +}; + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + var val = this[offset] | (this[offset + 1] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + var val = this[offset + 1] | (this[offset] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +}; + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +}; + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + return read(this, offset, true, 23, 4) +}; + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + return read(this, offset, false, 23, 4) +}; + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length); + return read(this, offset, true, 52, 8) +}; + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length); + return read(this, offset, false, 52, 8) +}; + +function checkInt (buf, value, offset, ext, max, min) { + if (!internalIsBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var mul = 1; + var i = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var i = byteLength - 1; + var mul = 1; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value); + this[offset] = (value & 0xff); + return offset + 1 +}; + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1; + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8; + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1; + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff; + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24); + this[offset + 2] = (value >>> 16); + this[offset + 1] = (value >>> 8); + this[offset] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = 0; + var mul = 1; + var sub = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = byteLength - 1; + var mul = 1; + var sub = 0; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80); + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value); + if (value < 0) value = 0xff + value + 1; + this[offset] = (value & 0xff); + return offset + 1 +}; + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + this[offset + 2] = (value >>> 16); + this[offset + 3] = (value >>> 24); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); + if (value < 0) value = 0xffffffff + value + 1; + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38); + } + write(buf, value, offset, littleEndian, 23, 4); + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +}; + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308); + } + write(buf, value, offset, littleEndian, 52, 8); + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +}; + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0; + if (!end && end !== 0) end = this.length; + if (targetStart >= target.length) targetStart = target.length; + if (!targetStart) targetStart = 0; + if (end > 0 && end < start) end = start; + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length; + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start; + } + + var len = end - start; + var i; + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start]; + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start]; + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ); + } + + return len +}; + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start; + start = 0; + end = this.length; + } else if (typeof end === 'string') { + encoding = end; + end = this.length; + } + if (val.length === 1) { + var code = val.charCodeAt(0); + if (code < 256) { + val = code; + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255; + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0; + end = end === undefined ? this.length : end >>> 0; + + if (!val) val = 0; + + var i; + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val; + } + } else { + var bytes = internalIsBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()); + var len = bytes.length; + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len]; + } + } + + return this +}; + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g; + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, ''); + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '='; + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity; + var codePoint; + var length = string.length; + var leadSurrogate = null; + var bytes = []; + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + continue + } + + // valid lead + leadSurrogate = codePoint; + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + leadSurrogate = codePoint; + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + } + + leadSurrogate = null; + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint); + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF); + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo; + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i); + hi = c >> 8; + lo = c % 256; + byteArray.push(lo); + byteArray.push(hi); + } + + return byteArray +} + + +function base64ToBytes (str) { + return toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i]; + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + + +// the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +function isBuffer(obj) { + return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) +} + +function isFastBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) +} + +/******************************************************************************** + * Ledger Node JS API + * (c) 2016-2017 Ledger + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ +function defer() { + let resolve, reject; + let promise = new Promise(function (success, failure) { + resolve = success; + reject = failure; + }); + if (!resolve || !reject) throw "defer() error"; // this never happens and is just to make flow happy + + return { + promise, + resolve, + reject + }; +} // TODO use bip32-path library + +function splitPath(path) { + let result = []; + let components = path.split("/"); + components.forEach(element => { + let number = parseInt(element, 10); + + if (isNaN(number)) { + return; // FIXME shouldn't it throws instead? + } + + if (element.length > 1 && element[element.length - 1] === "'") { + number += 0x80000000; + } + + result.push(number); + }); + return result; +} // TODO use async await + +function eachSeries(arr, fun) { + return arr.reduce((p, e) => p.then(() => fun(e)), Promise.resolve()); +} +function foreach(arr, callback) { + function iterate(index, array, result) { + if (index >= array.length) { + return result; + } else return callback(array[index], index).then(function (res) { + result.push(res); + return iterate(index + 1, array, result); + }); + } + + return Promise.resolve().then(() => iterate(0, arr, [])); +} +function doIf(condition, callback) { + return Promise.resolve().then(() => { + if (condition) { + return callback(); + } + }); +} +function asyncWhile(predicate, callback) { + function iterate(result) { + if (!predicate()) { + return result; + } else { + return callback().then(res => { + result.push(res); + return iterate(result); + }); + } + } + + return Promise.resolve([]).then(iterate); +} + +/* eslint-disable no-continue */ + +/* eslint-disable no-param-reassign */ + +/* eslint-disable no-prototype-builtins */ +const errorClasses = {}; +const deserializers = {}; +const addCustomErrorDeserializer = (name, deserializer) => { + deserializers[name] = deserializer; +}; +const createCustomErrorClass = name => { + const C = function CustomError(message, fields) { + Object.assign(this, fields); + this.name = name; + this.message = message || name; + this.stack = new Error().stack; + }; // $FlowFixMe + + + C.prototype = new Error(); + errorClasses[name] = C; // $FlowFixMe we can't easily type a subset of Error for now... + + return C; +}; // inspired from https://github.com/programble/errio/blob/master/index.js + +const deserializeError = object => { + if (typeof object === "object" && object) { + try { + // $FlowFixMe FIXME HACK + const msg = JSON.parse(object.message); + + if (msg.message && msg.name) { + object = msg; + } + } catch (e) {// nothing + } + + let error; + + if (typeof object.name === "string") { + const { + name + } = object; + const des = deserializers[name]; + + if (des) { + error = des(object); + } else { + let constructor = name === "Error" ? Error : errorClasses[name]; + + if (!constructor) { + console.warn("deserializing an unknown class '" + name + "'"); + constructor = createCustomErrorClass(name); + } + + error = Object.create(constructor.prototype); + + try { + for (const prop in object) { + if (object.hasOwnProperty(prop)) { + error[prop] = object[prop]; + } + } + } catch (e) {// sometimes setting a property can fail (e.g. .name) + } + } + } else { + error = new Error(object.message); + } + + if (!error.stack && Error.captureStackTrace) { + Error.captureStackTrace(error, deserializeError); + } + + return error; + } + + return new Error(String(object)); +}; // inspired from https://github.com/sindresorhus/serialize-error/blob/master/index.js + +const serializeError = value => { + if (!value) return value; + + if (typeof value === "object") { + return destroyCircular(value, []); + } + + if (typeof value === "function") { + return `[Function: ${value.name || "anonymous"}]`; + } + + return value; +}; // https://www.npmjs.com/package/destroy-circular + +function destroyCircular(from, seen) { + const to = {}; + seen.push(from); + + for (const key of Object.keys(from)) { + const value = from[key]; + + if (typeof value === "function") { + continue; + } + + if (!value || typeof value !== "object") { + to[key] = value; + continue; + } + + if (seen.indexOf(from[key]) === -1) { + to[key] = destroyCircular(from[key], seen.slice(0)); + continue; + } + + to[key] = "[Circular]"; + } + + if (typeof from.name === "string") { + to.name = from.name; + } + + if (typeof from.message === "string") { + to.message = from.message; + } + + if (typeof from.stack === "string") { + to.stack = from.stack; + } + + return to; +} + +const AccountNameRequiredError = createCustomErrorClass("AccountNameRequired"); +const AccountNotSupported = createCustomErrorClass("AccountNotSupported"); +const AmountRequired = createCustomErrorClass("AmountRequired"); +const BluetoothRequired = createCustomErrorClass("BluetoothRequired"); +const BtcUnmatchedApp = createCustomErrorClass("BtcUnmatchedApp"); +const CantOpenDevice = createCustomErrorClass("CantOpenDevice"); +const CashAddrNotSupported = createCustomErrorClass("CashAddrNotSupported"); +const CurrencyNotSupported = createCustomErrorClass("CurrencyNotSupported"); +const DeviceAppVerifyNotSupported = createCustomErrorClass("DeviceAppVerifyNotSupported"); +const DeviceGenuineSocketEarlyClose = createCustomErrorClass("DeviceGenuineSocketEarlyClose"); +const DeviceNotGenuineError = createCustomErrorClass("DeviceNotGenuine"); +const DeviceOnDashboardExpected = createCustomErrorClass("DeviceOnDashboardExpected"); +const DeviceOnDashboardUnexpected = createCustomErrorClass("DeviceOnDashboardUnexpected"); +const DeviceInOSUExpected = createCustomErrorClass("DeviceInOSUExpected"); +const DeviceHalted = createCustomErrorClass("DeviceHalted"); +const DeviceNameInvalid = createCustomErrorClass("DeviceNameInvalid"); +const DeviceSocketFail = createCustomErrorClass("DeviceSocketFail"); +const DeviceSocketNoBulkStatus = createCustomErrorClass("DeviceSocketNoBulkStatus"); +const DisconnectedDevice = createCustomErrorClass("DisconnectedDevice"); +const DisconnectedDeviceDuringOperation = createCustomErrorClass("DisconnectedDeviceDuringOperation"); +const EnpointConfigError = createCustomErrorClass("EnpointConfig"); +const EthAppPleaseEnableContractData = createCustomErrorClass("EthAppPleaseEnableContractData"); +const FeeEstimationFailed = createCustomErrorClass("FeeEstimationFailed"); +const HardResetFail = createCustomErrorClass("HardResetFail"); +const InvalidXRPTag = createCustomErrorClass("InvalidXRPTag"); +const InvalidAddress = createCustomErrorClass("InvalidAddress"); +const InvalidAddressBecauseDestinationIsAlsoSource = createCustomErrorClass("InvalidAddressBecauseDestinationIsAlsoSource"); +const LatestMCUInstalledError = createCustomErrorClass("LatestMCUInstalledError"); +const UnknownMCU = createCustomErrorClass("UnknownMCU"); +const LedgerAPIError = createCustomErrorClass("LedgerAPIError"); +const LedgerAPIErrorWithMessage = createCustomErrorClass("LedgerAPIErrorWithMessage"); +const LedgerAPINotAvailable = createCustomErrorClass("LedgerAPINotAvailable"); +const ManagerAppAlreadyInstalledError = createCustomErrorClass("ManagerAppAlreadyInstalled"); +const ManagerAppRelyOnBTCError = createCustomErrorClass("ManagerAppRelyOnBTC"); +const ManagerAppDepInstallRequired = createCustomErrorClass("ManagerAppDepInstallRequired"); +const ManagerAppDepUninstallRequired = createCustomErrorClass("ManagerAppDepUninstallRequired"); +const ManagerDeviceLockedError = createCustomErrorClass("ManagerDeviceLocked"); +const ManagerFirmwareNotEnoughSpaceError = createCustomErrorClass("ManagerFirmwareNotEnoughSpace"); +const ManagerNotEnoughSpaceError = createCustomErrorClass("ManagerNotEnoughSpace"); +const ManagerUninstallBTCDep = createCustomErrorClass("ManagerUninstallBTCDep"); +const NetworkDown = createCustomErrorClass("NetworkDown"); +const NoAddressesFound = createCustomErrorClass("NoAddressesFound"); +const NotEnoughBalance = createCustomErrorClass("NotEnoughBalance"); +const NotEnoughBalanceToDelegate = createCustomErrorClass("NotEnoughBalanceToDelegate"); +const NotEnoughBalanceInParentAccount = createCustomErrorClass("NotEnoughBalanceInParentAccount"); +const NotEnoughSpendableBalance = createCustomErrorClass("NotEnoughSpendableBalance"); +const NotEnoughBalanceBecauseDestinationNotCreated = createCustomErrorClass("NotEnoughBalanceBecauseDestinationNotCreated"); +const NoAccessToCamera = createCustomErrorClass("NoAccessToCamera"); +const NotEnoughGas = createCustomErrorClass("NotEnoughGas"); +const NotSupportedLegacyAddress = createCustomErrorClass("NotSupportedLegacyAddress"); +const GasLessThanEstimate = createCustomErrorClass("GasLessThanEstimate"); +const PasswordsDontMatchError = createCustomErrorClass("PasswordsDontMatch"); +const PasswordIncorrectError = createCustomErrorClass("PasswordIncorrect"); +const RecommendSubAccountsToEmpty = createCustomErrorClass("RecommendSubAccountsToEmpty"); +const RecommendUndelegation = createCustomErrorClass("RecommendUndelegation"); +const TimeoutTagged = createCustomErrorClass("TimeoutTagged"); +const UnexpectedBootloader = createCustomErrorClass("UnexpectedBootloader"); +const MCUNotGenuineToDashboard = createCustomErrorClass("MCUNotGenuineToDashboard"); +const RecipientRequired = createCustomErrorClass("RecipientRequired"); +const UnavailableTezosOriginatedAccountReceive = createCustomErrorClass("UnavailableTezosOriginatedAccountReceive"); +const UnavailableTezosOriginatedAccountSend = createCustomErrorClass("UnavailableTezosOriginatedAccountSend"); +const UpdateYourApp = createCustomErrorClass("UpdateYourApp"); +const UserRefusedDeviceNameChange = createCustomErrorClass("UserRefusedDeviceNameChange"); +const UserRefusedAddress = createCustomErrorClass("UserRefusedAddress"); +const UserRefusedFirmwareUpdate = createCustomErrorClass("UserRefusedFirmwareUpdate"); +const UserRefusedAllowManager = createCustomErrorClass("UserRefusedAllowManager"); +const UserRefusedOnDevice = createCustomErrorClass("UserRefusedOnDevice"); // TODO rename because it's just for transaction refusal + +const TransportOpenUserCancelled = createCustomErrorClass("TransportOpenUserCancelled"); +const TransportInterfaceNotAvailable = createCustomErrorClass("TransportInterfaceNotAvailable"); +const TransportWebUSBGestureRequired = createCustomErrorClass("TransportWebUSBGestureRequired"); +const DeviceShouldStayInApp = createCustomErrorClass("DeviceShouldStayInApp"); +const WebsocketConnectionError = createCustomErrorClass("WebsocketConnectionError"); +const WebsocketConnectionFailed = createCustomErrorClass("WebsocketConnectionFailed"); +const WrongDeviceForAccount = createCustomErrorClass("WrongDeviceForAccount"); +const WrongAppForCurrency = createCustomErrorClass("WrongAppForCurrency"); +const ETHAddressNonEIP = createCustomErrorClass("ETHAddressNonEIP"); +const CantScanQRCode = createCustomErrorClass("CantScanQRCode"); +const FeeNotLoaded = createCustomErrorClass("FeeNotLoaded"); +const FeeRequired = createCustomErrorClass("FeeRequired"); +const FeeTooHigh = createCustomErrorClass("FeeTooHigh"); +const SyncError = createCustomErrorClass("SyncError"); +const PairingFailed = createCustomErrorClass("PairingFailed"); +const GenuineCheckFailed = createCustomErrorClass("GenuineCheckFailed"); +const LedgerAPI4xx = createCustomErrorClass("LedgerAPI4xx"); +const LedgerAPI5xx = createCustomErrorClass("LedgerAPI5xx"); +const FirmwareOrAppUpdateRequired = createCustomErrorClass("FirmwareOrAppUpdateRequired"); // db stuff, no need to translate + +const NoDBPathGiven = createCustomErrorClass("NoDBPathGiven"); +const DBWrongPassword = createCustomErrorClass("DBWrongPassword"); +const DBNotReset = createCustomErrorClass("DBNotReset"); +/** + * TransportError is used for any generic transport errors. + * e.g. Error thrown when data received by exchanges are incorrect or if exchanged failed to communicate with the device for various reason. + */ + +function TransportError(message, id) { + this.name = "TransportError"; + this.message = message; + this.stack = new Error().stack; + this.id = id; +} //$FlowFixMe + +TransportError.prototype = new Error(); +addCustomErrorDeserializer("TransportError", e => new TransportError(e.message, e.id)); +const StatusCodes = { + PIN_REMAINING_ATTEMPTS: 0x63c0, + INCORRECT_LENGTH: 0x6700, + COMMAND_INCOMPATIBLE_FILE_STRUCTURE: 0x6981, + SECURITY_STATUS_NOT_SATISFIED: 0x6982, + CONDITIONS_OF_USE_NOT_SATISFIED: 0x6985, + INCORRECT_DATA: 0x6a80, + NOT_ENOUGH_MEMORY_SPACE: 0x6a84, + REFERENCED_DATA_NOT_FOUND: 0x6a88, + FILE_ALREADY_EXISTS: 0x6a89, + INCORRECT_P1_P2: 0x6b00, + INS_NOT_SUPPORTED: 0x6d00, + CLA_NOT_SUPPORTED: 0x6e00, + TECHNICAL_PROBLEM: 0x6f00, + OK: 0x9000, + MEMORY_PROBLEM: 0x9240, + NO_EF_SELECTED: 0x9400, + INVALID_OFFSET: 0x9402, + FILE_NOT_FOUND: 0x9404, + INCONSISTENT_FILE: 0x9408, + ALGORITHM_NOT_SUPPORTED: 0x9484, + INVALID_KCV: 0x9485, + CODE_NOT_INITIALIZED: 0x9802, + ACCESS_CONDITION_NOT_FULFILLED: 0x9804, + CONTRADICTION_SECRET_CODE_STATUS: 0x9808, + CONTRADICTION_INVALIDATION: 0x9810, + CODE_BLOCKED: 0x9840, + MAX_VALUE_REACHED: 0x9850, + GP_AUTH_FAILED: 0x6300, + LICENSING: 0x6f42, + HALTED: 0x6faa +}; +function getAltStatusMessage(code) { + switch (code) { + // improve text of most common errors + case 0x6700: + return "Incorrect length"; + + case 0x6982: + return "Security not satisfied (dongle locked or have invalid access rights)"; + + case 0x6985: + return "Condition of use not satisfied (denied by the user?)"; + + case 0x6a80: + return "Invalid data received"; + + case 0x6b00: + return "Invalid parameter received"; + } + + if (0x6f00 <= code && code <= 0x6fff) { + return "Internal error, please report"; + } +} +/** + * Error thrown when a device returned a non success status. + * the error.statusCode is one of the `StatusCodes` exported by this library. + */ + +function TransportStatusError(statusCode) { + this.name = "TransportStatusError"; + const statusText = Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR"; + const smsg = getAltStatusMessage(statusCode) || statusText; + const statusCodeStr = statusCode.toString(16); + this.message = `Ledger device: ${smsg} (0x${statusCodeStr})`; + this.stack = new Error().stack; + this.statusCode = statusCode; + this.statusText = statusText; +} //$FlowFixMe + +TransportStatusError.prototype = new Error(); +addCustomErrorDeserializer("TransportStatusError", e => new TransportStatusError(e.statusCode)); + +const remapTransactionRelatedErrors = e => { + if (e && e.statusCode === 0x6a80) { + return new EthAppPleaseEnableContractData("Please enable Contract data on the Ethereum app Settings"); + } + + return e; +}; +/** + * Ethereum API + * + * @example + * import Eth from "@ledgerhq/hw-app-eth"; + * const eth = new Eth(transport) + */ + + +class Eth { + constructor(transport, scrambleKey = "w0w") { + this.transport = void 0; + this.transport = transport; + transport.decorateAppAPIMethods(this, ["getAddress", "provideERC20TokenInformation", "signTransaction", "signPersonalMessage", "getAppConfiguration"], scrambleKey); + } + /** + * get Ethereum address for a given BIP 32 path. + * @param path a path in BIP 32 format + * @option boolDisplay optionally enable or not the display + * @option boolChaincode optionally enable or not the chaincode request + * @return an object with a publicKey, address and (optionally) chainCode + * @example + * eth.getAddress("44'/60'/0'/0/0").then(o => o.address) + */ + + + getAddress(path, boolDisplay, boolChaincode) { + let paths = splitPath(path); + let buffer = Buffer.alloc(1 + paths.length * 4); + buffer[0] = paths.length; + paths.forEach((element, index) => { + buffer.writeUInt32BE(element, 1 + 4 * index); + }); + return this.transport.send(0xe0, 0x02, boolDisplay ? 0x01 : 0x00, boolChaincode ? 0x01 : 0x00, buffer).then(response => { + let result = {}; + let publicKeyLength = response[0]; + let addressLength = response[1 + publicKeyLength]; + result.publicKey = response.slice(1, 1 + publicKeyLength).toString("hex"); + result.address = "0x" + response.slice(1 + publicKeyLength + 1, 1 + publicKeyLength + 1 + addressLength).toString("ascii"); + + if (boolChaincode) { + result.chainCode = response.slice(1 + publicKeyLength + 1 + addressLength, 1 + publicKeyLength + 1 + addressLength + 32).toString("hex"); + } + + return result; + }); + } + /** + * This commands provides a trusted description of an ERC 20 token + * to associate a contract address with a ticker and number of decimals. + * + * It shall be run immediately before performing a transaction involving a contract + * calling this contract address to display the proper token information to the user if necessary. + * + * @param {*} info: a blob from "erc20.js" utilities that contains all token information. + * + * @example + * import { byContractAddress } from "@ledgerhq/hw-app-eth/erc20" + * const zrxInfo = byContractAddress("0xe41d2489571d322189246dafa5ebde1f4699f498") + * if (zrxInfo) await appEth.provideERC20TokenInformation(zrxInfo) + * const signed = await appEth.signTransaction(path, rawTxHex) + */ + + + provideERC20TokenInformation({ + data + }) { + return this.transport.send(0xe0, 0x0a, 0x00, 0x00, data).then(() => true, e => { + if (e && e.statusCode === 0x6d00) { + // this case happen for older version of ETH app, since older app version had the ERC20 data hardcoded, it's fine to assume it worked. + // we return a flag to know if the call was effective or not + return false; + } + + throw e; + }); + } + /** + * You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign + * @example + eth.signTransaction("44'/60'/0'/0/0", "e8018504e3b292008252089428ee52a8f3d6e5d15f8b131996950d7f296c7952872bd72a2487400080").then(result => ...) + */ + + + signTransaction(path, rawTxHex) { + let paths = splitPath(path); + let offset = 0; + let rawTx = Buffer.from(rawTxHex, "hex"); + let toSend = []; + let response; + + while (offset !== rawTx.length) { + let maxChunkSize = offset === 0 ? 150 - 1 - paths.length * 4 : 150; + let chunkSize = offset + maxChunkSize > rawTx.length ? rawTx.length - offset : maxChunkSize; + let buffer = Buffer.alloc(offset === 0 ? 1 + paths.length * 4 + chunkSize : chunkSize); + + if (offset === 0) { + buffer[0] = paths.length; + paths.forEach((element, index) => { + buffer.writeUInt32BE(element, 1 + 4 * index); + }); + rawTx.copy(buffer, 1 + 4 * paths.length, offset, offset + chunkSize); + } else { + rawTx.copy(buffer, 0, offset, offset + chunkSize); + } + + toSend.push(buffer); + offset += chunkSize; + } + + return foreach(toSend, (data, i) => this.transport.send(0xe0, 0x04, i === 0 ? 0x00 : 0x80, 0x00, data).then(apduResponse => { + response = apduResponse; + })).then(() => { + const v = response.slice(0, 1).toString("hex"); + const r = response.slice(1, 1 + 32).toString("hex"); + const s = response.slice(1 + 32, 1 + 32 + 32).toString("hex"); + return { + v, + r, + s + }; + }, e => { + throw remapTransactionRelatedErrors(e); + }); + } + /** + */ + + + getAppConfiguration() { + return this.transport.send(0xe0, 0x06, 0x00, 0x00).then(response => { + let result = {}; + result.arbitraryDataEnabled = response[0] & 0x01; + result.version = "" + response[1] + "." + response[2] + "." + response[3]; + return result; + }); + } + /** + * You can sign a message according to eth_sign RPC call and retrieve v, r, s given the message and the BIP 32 path of the account to sign. + * @example + eth.signPersonalMessage("44'/60'/0'/0/0", Buffer.from("test").toString("hex")).then(result => { + var v = result['v'] - 27; + v = v.toString(16); + if (v.length < 2) { + v = "0" + v; + } + console.log("Signature 0x" + result['r'] + result['s'] + v); + }) + */ + + + signPersonalMessage(path, messageHex) { + let paths = splitPath(path); + let offset = 0; + let message = Buffer.from(messageHex, "hex"); + let toSend = []; + let response; + + while (offset !== message.length) { + let maxChunkSize = offset === 0 ? 150 - 1 - paths.length * 4 - 4 : 150; + let chunkSize = offset + maxChunkSize > message.length ? message.length - offset : maxChunkSize; + let buffer = Buffer.alloc(offset === 0 ? 1 + paths.length * 4 + 4 + chunkSize : chunkSize); + + if (offset === 0) { + buffer[0] = paths.length; + paths.forEach((element, index) => { + buffer.writeUInt32BE(element, 1 + 4 * index); + }); + buffer.writeUInt32BE(message.length, 1 + 4 * paths.length); + message.copy(buffer, 1 + 4 * paths.length + 4, offset, offset + chunkSize); + } else { + message.copy(buffer, 0, offset, offset + chunkSize); + } + + toSend.push(buffer); + offset += chunkSize; + } + + return foreach(toSend, (data, i) => this.transport.send(0xe0, 0x08, i === 0 ? 0x00 : 0x80, 0x00, data).then(apduResponse => { + response = apduResponse; + })).then(() => { + const v = response[0]; + const r = response.slice(1, 1 + 32).toString("hex"); + const s = response.slice(1 + 32, 1 + 32 + 32).toString("hex"); + return { + v, + r, + s + }; + }); + } + +} + +// Copyright 2014 Google Inc. All rights reserved +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +/** + * @fileoverview The U2F api. + */ + +'use strict'; + +/** Namespace for the U2F api. + * @type {Object} + */ +var u2f = u2f || {}; + +var googleU2fApi = u2f; // Adaptation for u2f-api package + +/** + * The U2F extension id + * @type {string} + * @const + */ +u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd'; + +/** + * Message types for messsages to/from the extension + * @const + * @enum {string} + */ +u2f.MessageTypes = { + 'U2F_REGISTER_REQUEST': 'u2f_register_request', + 'U2F_SIGN_REQUEST': 'u2f_sign_request', + 'U2F_REGISTER_RESPONSE': 'u2f_register_response', + 'U2F_SIGN_RESPONSE': 'u2f_sign_response' +}; + +/** + * Response status codes + * @const + * @enum {number} + */ +u2f.ErrorCodes = { + 'OK': 0, + 'OTHER_ERROR': 1, + 'BAD_REQUEST': 2, + 'CONFIGURATION_UNSUPPORTED': 3, + 'DEVICE_INELIGIBLE': 4, + 'TIMEOUT': 5 +}; + +/** + * A message type for registration requests + * @typedef {{ + * type: u2f.MessageTypes, + * signRequests: Array., + * registerRequests: ?Array., + * timeoutSeconds: ?number, + * requestId: ?number + * }} + */ +u2f.Request; + +/** + * A message for registration responses + * @typedef {{ + * type: u2f.MessageTypes, + * responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse), + * requestId: ?number + * }} + */ +u2f.Response; + +/** + * An error object for responses + * @typedef {{ + * errorCode: u2f.ErrorCodes, + * errorMessage: ?string + * }} + */ +u2f.Error; + +/** + * Data object for a single sign request. + * @typedef {{ + * version: string, + * challenge: string, + * keyHandle: string, + * appId: string + * }} + */ +u2f.SignRequest; + +/** + * Data object for a sign response. + * @typedef {{ + * keyHandle: string, + * signatureData: string, + * clientData: string + * }} + */ +u2f.SignResponse; + +/** + * Data object for a registration request. + * @typedef {{ + * version: string, + * challenge: string, + * appId: string + * }} + */ +u2f.RegisterRequest; + +/** + * Data object for a registration response. + * @typedef {{ + * registrationData: string, + * clientData: string + * }} + */ +u2f.RegisterResponse; + + +// Low level MessagePort API support + +/** + * Call MessagePort disconnect + */ +u2f.disconnect = function() { + if (u2f.port_ && u2f.port_.port_) { + u2f.port_.port_.disconnect(); + u2f.port_ = null; + } +}; + +/** + * Sets up a MessagePort to the U2F extension using the + * available mechanisms. + * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback + */ +u2f.getMessagePort = function(callback) { + if (typeof chrome != 'undefined' && chrome.runtime) { + // The actual message here does not matter, but we need to get a reply + // for the callback to run. Thus, send an empty signature request + // in order to get a failure response. + var msg = { + type: u2f.MessageTypes.U2F_SIGN_REQUEST, + signRequests: [] + }; + chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function() { + if (!chrome.runtime.lastError) { + // We are on a whitelisted origin and can talk directly + // with the extension. + u2f.getChromeRuntimePort_(callback); + } else { + // chrome.runtime was available, but we couldn't message + // the extension directly, use iframe + u2f.getIframePort_(callback); + } + }); + } else { + // chrome.runtime was not available at all, which is normal + // when this origin doesn't have access to any extensions. + u2f.getIframePort_(callback); + } +}; + +/** + * Connects directly to the extension via chrome.runtime.connect + * @param {function(u2f.WrappedChromeRuntimePort_)} callback + * @private + */ +u2f.getChromeRuntimePort_ = function(callback) { + var port = chrome.runtime.connect(u2f.EXTENSION_ID, + {'includeTlsChannelId': true}); + setTimeout(function() { + callback(null, new u2f.WrappedChromeRuntimePort_(port)); + }, 0); +}; + +/** + * A wrapper for chrome.runtime.Port that is compatible with MessagePort. + * @param {Port} port + * @constructor + * @private + */ +u2f.WrappedChromeRuntimePort_ = function(port) { + this.port_ = port; +}; + +/** + * Posts a message on the underlying channel. + * @param {Object} message + */ +u2f.WrappedChromeRuntimePort_.prototype.postMessage = function(message) { + this.port_.postMessage(message); +}; + +/** + * Emulates the HTML 5 addEventListener interface. Works only for the + * onmessage event, which is hooked up to the chrome.runtime.Port.onMessage. + * @param {string} eventName + * @param {function({data: Object})} handler + */ +u2f.WrappedChromeRuntimePort_.prototype.addEventListener = + function(eventName, handler) { + var name = eventName.toLowerCase(); + if (name == 'message' || name == 'onmessage') { + this.port_.onMessage.addListener(function(message) { + // Emulate a minimal MessageEvent object + handler({'data': message}); + }); + } else { + console.error('WrappedChromeRuntimePort only supports onMessage'); + } +}; + +/** + * Sets up an embedded trampoline iframe, sourced from the extension. + * @param {function(MessagePort)} callback + * @private + */ +u2f.getIframePort_ = function(callback) { + // Create the iframe + var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID; + var iframe = document.createElement('iframe'); + iframe.src = iframeOrigin + '/u2f-comms.html'; + iframe.setAttribute('style', 'display:none'); + document.body.appendChild(iframe); + + var hasCalledBack = false; + + var channel = new MessageChannel(); + var ready = function(message) { + if (message.data == 'ready') { + channel.port1.removeEventListener('message', ready); + if (!hasCalledBack) + { + hasCalledBack = true; + callback(null, channel.port1); + } + } else { + console.error('First event on iframe port was not "ready"'); + } + }; + channel.port1.addEventListener('message', ready); + channel.port1.start(); + + iframe.addEventListener('load', function() { + // Deliver the port to the iframe and initialize + iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]); + }); + + // Give this 200ms to initialize, after that, we treat this method as failed + setTimeout(function() { + if (!hasCalledBack) + { + hasCalledBack = true; + callback(new Error("IFrame extension not supported")); + } + }, 200); +}; + + +// High-level JS API + +/** + * Default extension response timeout in seconds. + * @const + */ +u2f.EXTENSION_TIMEOUT_SEC = 30; + +/** + * A singleton instance for a MessagePort to the extension. + * @type {MessagePort|u2f.WrappedChromeRuntimePort_} + * @private + */ +u2f.port_ = null; + +/** + * Callbacks waiting for a port + * @type {Array.} + * @private + */ +u2f.waitingForPort_ = []; + +/** + * A counter for requestIds. + * @type {number} + * @private + */ +u2f.reqCounter_ = 0; + +/** + * A map from requestIds to client callbacks + * @type {Object.} + * @private + */ +u2f.callbackMap_ = {}; + +/** + * Creates or retrieves the MessagePort singleton to use. + * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback + * @private + */ +u2f.getPortSingleton_ = function(callback) { + if (u2f.port_) { + callback(null, u2f.port_); + } else { + if (u2f.waitingForPort_.length == 0) { + u2f.getMessagePort(function(err, port) { + if (!err) { + u2f.port_ = port; + u2f.port_.addEventListener('message', + /** @type {function(Event)} */ (u2f.responseHandler_)); + } + + // Careful, here be async callbacks. Maybe. + while (u2f.waitingForPort_.length) + u2f.waitingForPort_.shift()(err, port); + }); + } + u2f.waitingForPort_.push(callback); + } +}; + +/** + * Handles response messages from the extension. + * @param {MessageEvent.} message + * @private + */ +u2f.responseHandler_ = function(message) { + var response = message.data; + var reqId = response['requestId']; + if (!reqId || !u2f.callbackMap_[reqId]) { + console.error('Unknown or missing requestId in response.'); + return; + } + var cb = u2f.callbackMap_[reqId]; + delete u2f.callbackMap_[reqId]; + cb(null, response['responseData']); +}; + +/** + * Calls the callback with true or false as first and only argument + * @param {Function} callback + */ +u2f.isSupported = function(callback) { + u2f.getPortSingleton_(function(err, port) { + callback(!err); + }); +}; + +/** + * Dispatches an array of sign requests to available U2F tokens. + * @param {Array.} signRequests + * @param {function((u2f.Error|u2f.SignResponse))} callback + * @param {number=} opt_timeoutSeconds + */ +u2f.sign = function(signRequests, callback, opt_timeoutSeconds) { + u2f.getPortSingleton_(function(err, port) { + if (err) + return callback(err); + + var reqId = ++u2f.reqCounter_; + u2f.callbackMap_[reqId] = callback; + var req = { + type: u2f.MessageTypes.U2F_SIGN_REQUEST, + signRequests: signRequests, + timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ? + opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC), + requestId: reqId + }; + port.postMessage(req); + }); +}; + +/** + * Dispatches register requests to available U2F tokens. An array of sign + * requests identifies already registered tokens. + * @param {Array.} registerRequests + * @param {Array.} signRequests + * @param {function((u2f.Error|u2f.RegisterResponse))} callback + * @param {number=} opt_timeoutSeconds + */ +u2f.register = function(registerRequests, signRequests, + callback, opt_timeoutSeconds) { + u2f.getPortSingleton_(function(err, port) { + if (err) + return callback(err); + + var reqId = ++u2f.reqCounter_; + u2f.callbackMap_[reqId] = callback; + var req = { + type: u2f.MessageTypes.U2F_REGISTER_REQUEST, + signRequests: signRequests, + registerRequests: registerRequests, + timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ? + opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC), + requestId: reqId + }; + port.postMessage(req); + }); +}; + +'use strict'; + +var u2fApi = API; + + + +// Feature detection (yes really) +var isBrowser = ( typeof navigator !== 'undefined' ) && !!navigator.userAgent; +var isSafari = isBrowser && navigator.userAgent.match( /Safari\// ) + && !navigator.userAgent.match( /Chrome\// ); +var isEDGE = isBrowser && navigator.userAgent.match( /Edge\/1[2345]/ ); + +var _backend = null; +function getBackend( Promise ) +{ + if ( !_backend ) + _backend = new Promise( function( resolve, reject ) + { + function notSupported( ) + { + // Note; {native: true} means *not* using Google's hack + resolve( { u2f: null, native: true } ); + } + + if ( !isBrowser ) + return notSupported( ); + + if ( isSafari ) + // Safari doesn't support U2F, and the Safari-FIDO-U2F + // extension lacks full support (Multi-facet apps), so we + // block it until proper support. + return notSupported( ); + + var hasNativeSupport = + ( typeof window.u2f !== 'undefined' ) && + ( typeof window.u2f.sign === 'function' ); + + if ( hasNativeSupport ) + resolve( { u2f: window.u2f, native: true } ); + + if ( isEDGE ) + // We don't want to check for Google's extension hack on EDGE + // as it'll cause trouble (popups, etc) + return notSupported( ); + + if ( location.protocol === 'http:' ) + // U2F isn't supported over http, only https + return notSupported( ); + + if ( typeof MessageChannel === 'undefined' ) + // Unsupported browser, the chrome hack would throw + return notSupported( ); + + // Test for google extension support + googleU2fApi.isSupported( function( ok ) + { + if ( ok ) + resolve( { u2f: googleU2fApi, native: false } ); + else + notSupported( ); + } ); + } ); + + return _backend; +} + +function API( Promise ) +{ + return { + isSupported : isSupported.bind( Promise ), + ensureSupport : ensureSupport.bind( Promise ), + register : register.bind( Promise ), + sign : sign.bind( Promise ), + ErrorCodes : API.ErrorCodes, + ErrorNames : API.ErrorNames + }; +} + +API.ErrorCodes = { + CANCELLED: -1, + OK: 0, + OTHER_ERROR: 1, + BAD_REQUEST: 2, + CONFIGURATION_UNSUPPORTED: 3, + DEVICE_INELIGIBLE: 4, + TIMEOUT: 5 +}; +API.ErrorNames = { + "-1": "CANCELLED", + "0": "OK", + "1": "OTHER_ERROR", + "2": "BAD_REQUEST", + "3": "CONFIGURATION_UNSUPPORTED", + "4": "DEVICE_INELIGIBLE", + "5": "TIMEOUT" +}; + +function makeError( msg, err ) +{ + var code = err != null ? err.errorCode : 1; // Default to OTHER_ERROR + var type = API.ErrorNames[ '' + code ]; + var error = new Error( msg ); + error.metaData = { + type: type, + code: code + }; + return error; +} + +function deferPromise( Promise, promise ) +{ + var ret = { }; + ret.promise = new Promise( function( resolve, reject ) { + ret.resolve = resolve; + ret.reject = reject; + promise.then( resolve, reject ); + } ); + /** + * Reject request promise and disconnect port if 'disconnect' flag is true + * @param {string} msg + * @param {boolean} disconnect + */ + ret.promise.cancel = function( msg, disconnect ) + { + getBackend( Promise ) + .then( function( backend ) + { + if ( disconnect && !backend.native ) + backend.u2f.disconnect( ); + + ret.reject( makeError( msg, { errorCode: -1 } ) ); + } ); + }; + return ret; +} + +function defer$1( Promise, fun ) +{ + return deferPromise( Promise, new Promise( function( resolve, reject ) + { + try + { + fun && fun( resolve, reject ); + } + catch ( err ) + { + reject( err ); + } + } ) ); +} + +function isSupported( ) +{ + var Promise = this; + + return getBackend( Promise ) + .then( function( backend ) + { + return !!backend.u2f; + } ); +} + +function _ensureSupport( backend ) +{ + if ( !backend.u2f ) + { + if ( location.protocol === 'http:' ) + throw new Error( "U2F isn't supported over http, only https" ); + throw new Error( "U2F not supported" ); + } +} + +function ensureSupport( ) +{ + var Promise = this; + + return getBackend( Promise ) + .then( _ensureSupport ); +} + +function register( registerRequests, signRequests /* = null */, timeout ) +{ + var Promise = this; + + if ( !Array.isArray( registerRequests ) ) + registerRequests = [ registerRequests ]; + + if ( typeof signRequests === 'number' && typeof timeout === 'undefined' ) + { + timeout = signRequests; + signRequests = null; + } + + if ( !signRequests ) + signRequests = [ ]; + + return deferPromise( Promise, getBackend( Promise ) + .then( function( backend ) + { + _ensureSupport( backend ); + + var native = backend.native; + var u2f = backend.u2f; + + return new Promise( function( resolve, reject ) + { + function cbNative( response ) + { + if ( response.errorCode ) + reject( makeError( "Registration failed", response ) ); + else + { + delete response.errorCode; + resolve( response ); + } + } + + function cbChrome( err, response ) + { + if ( err ) + reject( err ); + else if ( response.errorCode ) + reject( makeError( "Registration failed", response ) ); + else + resolve( response ); + } + + if ( native ) + { + var appId = registerRequests[ 0 ].appId; + + u2f.register( + appId, registerRequests, signRequests, cbNative, timeout ); + } + else + { + u2f.register( + registerRequests, signRequests, cbChrome, timeout ); + } + } ); + } ) ).promise; +} + +function sign( signRequests, timeout ) +{ + var Promise = this; + + if ( !Array.isArray( signRequests ) ) + signRequests = [ signRequests ]; + + return deferPromise( Promise, getBackend( Promise ) + .then( function( backend ) + { + _ensureSupport( backend ); + + var native = backend.native; + var u2f = backend.u2f; + + return new Promise( function( resolve, reject ) + { + function cbNative( response ) + { + if ( response.errorCode ) + reject( makeError( "Sign failed", response ) ); + else + { + delete response.errorCode; + resolve( response ); + } + } + + function cbChrome( err, response ) + { + if ( err ) + reject( err ); + else if ( response.errorCode ) + reject( makeError( "Sign failed", response ) ); + else + resolve( response ); + } + + if ( native ) + { + var appId = signRequests[ 0 ].appId; + var challenge = signRequests[ 0 ].challenge; + + u2f.sign( appId, challenge, signRequests, cbNative, timeout ); + } + else + { + u2f.sign( signRequests, cbChrome, timeout ); + } + } ); + } ) ).promise; +} + +function makeDefault( func ) +{ + API[ func ] = function( ) + { + if ( !commonjsGlobal.Promise ) + // This is very unlikely to ever happen, since browsers + // supporting U2F will most likely support Promises. + throw new Error( "The platform doesn't natively support promises" ); + + var args = [ ].slice.call( arguments ); + return API( commonjsGlobal.Promise )[ func ].apply( null, args ); + }; +} + +// Provide default functions using the built-in Promise if available. +makeDefault( 'isSupported' ); +makeDefault( 'ensureSupport' ); +makeDefault( 'register' ); +makeDefault( 'sign' ); + +'use strict'; +var u2fApi$1 = u2fApi; +var u2fApi_1 = u2fApi$1.isSupported; +var u2fApi_2 = u2fApi$1.sign; + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +var R = typeof Reflect === 'object' ? Reflect : null; +var ReflectApply = R && typeof R.apply === 'function' + ? R.apply + : function ReflectApply(target, receiver, args) { + return Function.prototype.apply.call(target, receiver, args); + }; + +var ReflectOwnKeys; +if (R && typeof R.ownKeys === 'function') { + ReflectOwnKeys = R.ownKeys; +} else if (Object.getOwnPropertySymbols) { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target) + .concat(Object.getOwnPropertySymbols(target)); + }; +} else { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target); + }; +} + +function ProcessEmitWarning(warning) { + if (console && console.warn) console.warn(warning); +} + +var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { + return value !== value; +}; + +function EventEmitter() { + EventEmitter.init.call(this); +} +var events = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._eventsCount = 0; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +var defaultMaxListeners = 10; + +function checkListener(listener) { + if (typeof listener !== 'function') { + throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); + } +} + +Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: true, + get: function() { + return defaultMaxListeners; + }, + set: function(arg) { + if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { + throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); + } + defaultMaxListeners = arg; + } +}); + +EventEmitter.init = function() { + + if (this._events === undefined || + this._events === Object.getPrototypeOf(this)._events) { + this._events = Object.create(null); + this._eventsCount = 0; + } + + this._maxListeners = this._maxListeners || undefined; +}; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { + if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { + throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); + } + this._maxListeners = n; + return this; +}; + +function _getMaxListeners(that) { + if (that._maxListeners === undefined) + return EventEmitter.defaultMaxListeners; + return that._maxListeners; +} + +EventEmitter.prototype.getMaxListeners = function getMaxListeners() { + return _getMaxListeners(this); +}; + +EventEmitter.prototype.emit = function emit(type) { + var args = []; + for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); + var doError = (type === 'error'); + + var events = this._events; + if (events !== undefined) + doError = (doError && events.error === undefined); + else if (!doError) + return false; + + // If there is no 'error' event listener then throw. + if (doError) { + var er; + if (args.length > 0) + er = args[0]; + if (er instanceof Error) { + // Note: The comments on the `throw` lines are intentional, they show + // up in Node's output if this results in an unhandled exception. + throw er; // Unhandled 'error' event + } + // At least give some kind of context to the user + var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); + err.context = er; + throw err; // Unhandled 'error' event + } + + var handler = events[type]; + + if (handler === undefined) + return false; + + if (typeof handler === 'function') { + ReflectApply(handler, this, args); + } else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + ReflectApply(listeners[i], this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + checkListener(listener); + + events = target._events; + if (events === undefined) { + events = target._events = Object.create(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener !== undefined) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (existing === undefined) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + // If we've already got an array, just append. + } else if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + + // Check for listener leak + m = _getMaxListeners(target); + if (m > 0 && existing.length > m && !existing.warned) { + existing.warned = true; + // No error code for this since it is a Warning + // eslint-disable-next-line no-restricted-syntax + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' ' + String(type) + ' listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + ProcessEmitWarning(w); + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + if (arguments.length === 0) + return this.listener.call(this.target); + return this.listener.apply(this.target, arguments); + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = onceWrapper.bind(state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + checkListener(listener); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + checkListener(listener); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + checkListener(listener); + + events = this._events; + if (events === undefined) + return this; + + list = events[type]; + if (list === undefined) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = Object.create(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else { + spliceOne(list, position); + } + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener !== undefined) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (events === undefined) + return this; + + // not listening for removeListener, no need to emit + if (events.removeListener === undefined) { + if (arguments.length === 0) { + this._events = Object.create(null); + this._eventsCount = 0; + } else if (events[type] !== undefined) { + if (--this._eventsCount === 0) + this._events = Object.create(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = Object.keys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = Object.create(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners !== undefined) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (events === undefined) + return []; + + var evlistener = events[type]; + if (evlistener === undefined) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? + unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events !== undefined) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener !== undefined) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; +}; + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function spliceOne(list, index) { + for (; index + 1 < list.length; index++) + list[index] = list[index + 1]; + list.pop(); +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +/** + */ + +/** + * Transport defines the generic interface to share between node/u2f impl + * A **Descriptor** is a parametric type that is up to be determined for the implementation. + * it can be for instance an ID, an file path, a URL,... + */ +class Transport { + constructor() { + this.exchangeTimeout = 30000; + this._events = new events(); + + this.send = async (cla, ins, p1, p2, data = Buffer.alloc(0), statusList = [StatusCodes.OK]) => { + if (data.length >= 256) { + throw new TransportError("data.length exceed 256 bytes limit. Got: " + data.length, "DataLengthTooBig"); + } + + const response = await this.exchange(Buffer.concat([Buffer.from([cla, ins, p1, p2]), Buffer.from([data.length]), data])); + const sw = response.readUInt16BE(response.length - 2); + + if (!statusList.some(s => s === sw)) { + throw new TransportStatusError(sw); + } + + return response; + }; + + this.exchangeBusyPromise = void 0; + + this.exchangeAtomicImpl = async f => { + if (this.exchangeBusyPromise) { + throw new TransportError("Transport race condition", "RaceCondition"); + } + + let resolveBusy; + const busyPromise = new Promise(r => { + resolveBusy = r; + }); + this.exchangeBusyPromise = busyPromise; + + try { + const res = await f(); + return res; + } finally { + if (resolveBusy) resolveBusy(); + this.exchangeBusyPromise = null; + } + }; + + this._appAPIlock = null; + } + + /** + * low level api to communicate with the device + * This method is for implementations to implement but should not be directly called. + * Instead, the recommanded way is to use send() method + * @param apdu the data to send + * @return a Promise of response data + */ + exchange(_apdu) { + throw new Error("exchange not implemented"); + } + /** + * set the "scramble key" for the next exchanges with the device. + * Each App can have a different scramble key and they internally will set it at instanciation. + * @param key the scramble key + */ + + + setScrambleKey(_key) {} + /** + * close the exchange with the device. + * @return a Promise that ends when the transport is closed. + */ + + + close() { + return Promise.resolve(); + } + + /** + * Listen to an event on an instance of transport. + * Transport implementation can have specific events. Here is the common events: + * * `"disconnect"` : triggered if Transport is disconnected + */ + on(eventName, cb) { + this._events.on(eventName, cb); + } + /** + * Stop listening to an event on an instance of transport. + */ + + + off(eventName, cb) { + this._events.removeListener(eventName, cb); + } + + emit(event, ...args) { + this._events.emit(event, ...args); + } + /** + * Enable or not logs of the binary exchange + */ + + + setDebugMode() { + console.warn("setDebugMode is deprecated. use @ledgerhq/logs instead. No logs are emitted in this anymore."); + } + /** + * Set a timeout (in milliseconds) for the exchange call. Only some transport might implement it. (e.g. U2F) + */ + + + setExchangeTimeout(exchangeTimeout) { + this.exchangeTimeout = exchangeTimeout; + } + /** + * wrapper on top of exchange to simplify work of the implementation. + * @param cla + * @param ins + * @param p1 + * @param p2 + * @param data + * @param statusList is a list of accepted status code (shorts). [0x9000] by default + * @return a Promise of response buffer + */ + + + /** + * create() allows to open the first descriptor available or + * throw if there is none or if timeout is reached. + * This is a light helper, alternative to using listen() and open() (that you may need for any more advanced usecase) + * @example + TransportFoo.create().then(transport => ...) + */ + static create(openTimeout = 3000, listenTimeout) { + return new Promise((resolve, reject) => { + let found = false; + const sub = this.listen({ + next: e => { + found = true; + if (sub) sub.unsubscribe(); + if (listenTimeoutId) clearTimeout(listenTimeoutId); + this.open(e.descriptor, openTimeout).then(resolve, reject); + }, + error: e => { + if (listenTimeoutId) clearTimeout(listenTimeoutId); + reject(e); + }, + complete: () => { + if (listenTimeoutId) clearTimeout(listenTimeoutId); + + if (!found) { + reject(new TransportError(this.ErrorMessage_NoDeviceFound, "NoDeviceFound")); + } + } + }); + const listenTimeoutId = listenTimeout ? setTimeout(() => { + sub.unsubscribe(); + reject(new TransportError(this.ErrorMessage_ListenTimeout, "ListenTimeout")); + }, listenTimeout) : null; + }); + } + + decorateAppAPIMethods(self, methods, scrambleKey) { + for (let methodName of methods) { + self[methodName] = this.decorateAppAPIMethod(methodName, self[methodName], self, scrambleKey); + } + } + + decorateAppAPIMethod(methodName, f, ctx, scrambleKey) { + return async (...args) => { + const { + _appAPIlock + } = this; + + if (_appAPIlock) { + return Promise.reject(new TransportError("Ledger Device is busy (lock " + _appAPIlock + ")", "TransportLocked")); + } + + try { + this._appAPIlock = methodName; + this.setScrambleKey(scrambleKey); + return await f.apply(ctx, args); + } finally { + this._appAPIlock = null; + } + }; + } + +} +Transport.isSupported = void 0; +Transport.list = void 0; +Transport.listen = void 0; +Transport.open = void 0; +Transport.ErrorMessage_ListenTimeout = "No Ledger device found (timeout)"; +Transport.ErrorMessage_NoDeviceFound = "No Ledger device found"; + +/** + * A Log object + */ +let id = 0; +const subscribers = []; +/** + * log something + * @param type a namespaced identifier of the log (it is not a level like "debug", "error" but more like "apdu-in", "apdu-out", etc...) + * @param message a clear message of the log associated to the type + */ + +const log = (type, message, data) => { + const obj = { + type, + id: String(++id), + date: new Date() + }; + if (message) obj.message = message; + if (data) obj.data = data; + dispatch(obj); +}; +/** + * listen to logs. + * @param cb that is called for each future log() with the Log object + * @return a function that can be called to unsubscribe the listener + */ + +const listen = cb => { + subscribers.push(cb); + return () => { + const i = subscribers.indexOf(cb); + + if (i !== -1) { + // equivalent of subscribers.splice(i, 1) // https://twitter.com/Rich_Harris/status/1125850391155965952 + subscribers[i] = subscribers[subscribers.length - 1]; + subscribers.pop(); + } + }; +}; + +function dispatch(log) { + for (let i = 0; i < subscribers.length; i++) { + try { + subscribers[i](log); + } catch (e) { + console.error(e); + } + } +} // for debug purpose + + +global$1.__ledgerLogsListen = listen; + +function wrapU2FTransportError(originalError, message, id) { + const err = new TransportError(message, id); // $FlowFixMe + + err.originalError = originalError; + return err; +} + +function wrapApdu(apdu, key) { + const result = Buffer.alloc(apdu.length); + + for (let i = 0; i < apdu.length; i++) { + result[i] = apdu[i] ^ key[i % key.length]; + } + + return result; +} // Convert from normal to web-safe, strip trailing "="s + + +const webSafe64 = base64 => base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); // Convert from web-safe to normal, add trailing "="s + + +const normal64 = base64 => base64.replace(/-/g, "+").replace(/_/g, "/") + "==".substring(0, 3 * base64.length % 4); + +function attemptExchange(apdu, timeoutMillis, scrambleKey, unwrap) { + const keyHandle = wrapApdu(apdu, scrambleKey); + const challenge = Buffer.from("0000000000000000000000000000000000000000000000000000000000000000", "hex"); + const signRequest = { + version: "U2F_V2", + keyHandle: webSafe64(keyHandle.toString("base64")), + challenge: webSafe64(challenge.toString("base64")), + appId: location.origin + }; + log("apdu", "=> " + apdu.toString("hex")); + return u2fApi_2(signRequest, timeoutMillis / 1000).then(response => { + const { + signatureData + } = response; + + if (typeof signatureData === "string") { + const data = Buffer.from(normal64(signatureData), "base64"); + let result; + + if (!unwrap) { + result = data; + } else { + result = data.slice(5); + } + + log("apdu", "<= " + result.toString("hex")); + return result; + } else { + throw response; + } + }); +} + +let transportInstances = []; + +function emitDisconnect() { + transportInstances.forEach(t => t.emit("disconnect")); + transportInstances = []; +} + +function isTimeoutU2FError(u2fError) { + return u2fError.metaData.code === 5; +} +/** + * U2F web Transport implementation + * @example + * import TransportU2F from "@ledgerhq/hw-transport-u2f"; + * ... + * TransportU2F.create().then(transport => ...) + */ + + +class TransportU2F extends Transport { + /* + */ + + /* + */ + + /** + * static function to create a new Transport from a connected Ledger device discoverable via U2F (browser support) + */ + static async open(_, _openTimeout = 5000) { + return new TransportU2F(); + } + + constructor() { + super(); + this.scrambleKey = void 0; + this.unwrap = true; + transportInstances.push(this); + } + /** + * Exchange with the device using APDU protocol. + * @param apdu + * @returns a promise of apdu response + */ + + + async exchange(apdu) { + try { + return await attemptExchange(apdu, this.exchangeTimeout, this.scrambleKey, this.unwrap); + } catch (e) { + const isU2FError = typeof e.metaData === "object"; + + if (isU2FError) { + if (isTimeoutU2FError(e)) { + emitDisconnect(); + } // the wrapping make error more usable and "printable" to the end user. + + + throw wrapU2FTransportError(e, "Failed to sign with Ledger device: U2F " + e.metaData.type, "U2F_" + e.metaData.code); + } else { + throw e; + } + } + } + /** + */ + + + setScrambleKey(scrambleKey) { + this.scrambleKey = Buffer.from(scrambleKey, "ascii"); + } + /** + */ + + + setUnwrap(unwrap) { + this.unwrap = unwrap; + } + + close() { + // u2f have no way to clean things up + return Promise.resolve(); + } + +} +TransportU2F.isSupported = u2fApi_1; + +TransportU2F.list = () => // this transport is not discoverable but we are going to guess if it is here with isSupported() +u2fApi_1().then(supported => supported ? [null] : []); + +TransportU2F.listen = observer => { + let unsubscribed = false; + u2fApi_1().then(supported => { + if (unsubscribed) return; + + if (supported) { + observer.next({ + type: "add", + descriptor: null + }); + observer.complete(); + } else { + observer.error(new TransportError("U2F browser support is needed for Ledger. " + "Please use Chrome, Opera or Firefox with a U2F extension. " + "Also make sure you're on an HTTPS connection", "U2FNotSupported")); + } + }); + return { + unsubscribe: () => { + unsubscribed = true; + } + }; +}; + +var browserLedgerTransport = createCommonjsModule(function (module, exports) { +"use strict"; +var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var hw_transport_u2f_1 = __importDefault(TransportU2F); +exports.transports = { + "u2f": hw_transport_u2f_1.default, + "default": hw_transport_u2f_1.default +}; +}); + +var browserLedgerTransport$1 = unwrapExports(browserLedgerTransport); +var browserLedgerTransport_1 = browserLedgerTransport.transports; + +"use strict"; +var __awaiter = (window && window.__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()); + }); +}; +const logger = new browserEthers_1.utils.Logger(version); +const defaultPath = "m/44'/60'/0'/0/0"; +function waiter(duration) { + return new Promise((resolve) => { + setTimeout(resolve, duration); + }); +} +class LedgerSigner extends browserEthers_1.Signer { + constructor(provider, type, path) { + super(); + if (path == null) { + path = defaultPath; + } + if (type == null) { + type = "default"; + } + browserEthers_1.utils.defineReadOnly(this, "path", path); + browserEthers_1.utils.defineReadOnly(this, "type", type); + browserEthers_1.utils.defineReadOnly(this, "provider", provider || null); + const transport = browserLedgerTransport_1[type]; + if (!transport) { + logger.throwArgumentError("unknown or unsupport type", "type", type); + } + browserEthers_1.utils.defineReadOnly(this, "_eth", transport.create().then((transport) => { + const eth = new Eth(transport); + return eth.getAppConfiguration().then((config) => { + return eth; + }, (error) => { + return Promise.reject(error); + }); + }, (error) => { + return Promise.reject(error); + })); + } + _retry(callback, timeout) { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + if (timeout && timeout > 0) { + setTimeout(() => { reject(new Error("timeout")); }, timeout); + } + const eth = yield this._eth; + // Wait up to 5 seconds + for (let i = 0; i < 50; i++) { + try { + const result = yield callback(eth); + return resolve(result); + } + catch (error) { + if (error.id !== "TransportLocked") { + return reject(error); + } + } + yield waiter(100); + } + return reject(new Error("timeout")); + })); + } + getAddress() { + return __awaiter(this, void 0, void 0, function* () { + const account = yield this._retry((eth) => eth.getAddress(this.path)); + return browserEthers_1.utils.getAddress(account.address); + }); + } + signMessage(message) { + return __awaiter(this, void 0, void 0, function* () { + if (typeof (message) === 'string') { + message = browserEthers_1.utils.toUtf8Bytes(message); + } + const messageHex = browserEthers_1.utils.hexlify(message).substring(2); + const sig = yield this._retry((eth) => eth.signPersonalMessage(this.path, messageHex)); + sig.r = '0x' + sig.r; + sig.s = '0x' + sig.s; + return browserEthers_1.utils.joinSignature(sig); + }); + } + signTransaction(transaction) { + return __awaiter(this, void 0, void 0, function* () { + const tx = transaction = yield browserEthers_1.utils.resolveProperties(transaction); + const unsignedTx = browserEthers_1.utils.serializeTransaction(tx).substring(2); + const sig = yield this._retry((eth) => eth.signTransaction(this.path, unsignedTx)); + return browserEthers_1.utils.serializeTransaction(tx, { + v: sig.v, + r: ("0x" + sig.r), + s: ("0x" + sig.s), + }); + }); + } + connect(provider) { + return new LedgerSigner(provider, this.type, this.path); + } +} + +"use strict"; + +export { LedgerSigner }; diff --git a/packages/hardware-wallets/dist/hardware-wallets.esm.min.js b/packages/hardware-wallets/dist/hardware-wallets.esm.min.js new file mode 100644 index 0000000000..0490156865 --- /dev/null +++ b/packages/hardware-wallets/dist/hardware-wallets.esm.min.js @@ -0,0 +1 @@ +var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function r(e,t){return e(t={exports:{}},t.exports),t.exports}var n=r((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r={};t.ethers=r;var n=window;null==n._ethers?console.log("WARNING: @ethersproject/hardware-wallet requires ethers loaded first"):t.ethers=r=n._ethers})),o=(t(n),n.ethers);var i="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},s=[],a=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array,h=!1;function f(){h=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,r=e.length;t>18&63]+s[o>>12&63]+s[o>>6&63]+s[63&o]);return i.join("")}function l(e){var t;h||f();for(var r=e.length,n=r%3,o="",i=[],a=0,u=r-n;au?u:a+16383));return 1===n?(t=e[r-1],o+=s[t>>2],o+=s[t<<4&63],o+="=="):2===n&&(t=(e[r-2]<<8)+e[r-1],o+=s[t>>10],o+=s[t>>4&63],o+=s[t<<2&63],o+="="),i.push(o),i.join("")}function p(e,t,r,n,o){var i,s,a=8*o-n-1,u=(1<>1,f=-7,c=r?o-1:0,l=r?-1:1,p=e[t+c];for(c+=l,i=p&(1<<-f)-1,p>>=-f,f+=a;f>0;i=256*i+e[t+c],c+=l,f-=8);for(s=i&(1<<-f)-1,i>>=-f,f+=n;f>0;s=256*s+e[t+c],c+=l,f-=8);if(0===i)i=1-h;else{if(i===u)return s?NaN:1/0*(p?-1:1);s+=Math.pow(2,n),i-=h}return(p?-1:1)*s*Math.pow(2,i-n)}function d(e,t,r,n,o,i){var s,a,u,h=8*i-o-1,f=(1<>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:i-1,d=n?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=f):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),(t+=s+c>=1?l/u:l*Math.pow(2,1-c))*u>=2&&(s++,u/=2),s+c>=f?(a=0,s=f):s+c>=1?(a=(t*u-1)*Math.pow(2,o),s+=c):(a=t*Math.pow(2,c-1)*Math.pow(2,o),s=0));o>=8;e[r+p]=255&a,p+=d,a/=256,o-=8);for(s=s<0;e[r+p]=255&s,p+=d,s/=256,h-=8);e[r+p-d]|=128*g}var g={}.toString,v=Array.isArray||function(e){return"[object Array]"==g.call(e)};w.TYPED_ARRAY_SUPPORT=void 0===i.TYPED_ARRAY_SUPPORT||i.TYPED_ARRAY_SUPPORT;y();function y(){return w.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function E(e,t){if(y()=y())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+y().toString(16)+" bytes");return 0|e}function I(e){return!(null==e||!e._isBuffer)}function b(e,t){if(I(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return J(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return ee(e).length;default:if(n)return J(e).length;t=(""+t).toLowerCase(),n=!0}}function S(e,t,r){var n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return G(this,t,r);case"utf8":case"utf-8":return F(this,t,r);case"ascii":return Y(this,t,r);case"latin1":case"binary":return j(this,t,r);case"base64":return B(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return q(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function P(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function C(e,t,r,n,o){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=o?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(o)return-1;r=e.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof t&&(t=w.from(t,n)),I(t))return 0===t.length?-1:O(e,t,r,n,o);if("number"==typeof t)return t&=255,w.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):O(e,[t],r,n,o);throw new TypeError("val must be string, number or Buffer")}function O(e,t,r,n,o){var i,s=1,a=e.length,u=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;s=2,a/=2,u/=2,r/=2}function h(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(o){var f=-1;for(i=r;ia&&(r=a-u),i=r;i>=0;i--){for(var c=!0,l=0;lo&&(n=o):n=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");n>i/2&&(n=i/2);for(var s=0;s>8,o=r%256,i.push(o),i.push(n);return i}(t,e.length-r),e,r,n)}function B(e,t,r){return 0===t&&r===e.length?l(e):l(e.slice(t,r))}function F(e,t,r){r=Math.min(e.length,r);for(var n=[],o=t;o239?4:h>223?3:h>191?2:1;if(o+c<=r)switch(c){case 1:h<128&&(f=h);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&h)<<6|63&i)>127&&(f=u);break;case 3:i=e[o+1],s=e[o+2],128==(192&i)&&128==(192&s)&&(u=(15&h)<<12|(63&i)<<6|63&s)>2047&&(u<55296||u>57343)&&(f=u);break;case 4:i=e[o+1],s=e[o+2],a=e[o+3],128==(192&i)&&128==(192&s)&&128==(192&a)&&(u=(15&h)<<18|(63&i)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(f=u)}null===f?(f=65533,c=1):f>65535&&(f-=65536,n.push(f>>>10&1023|55296),f=56320|1023&f),n.push(f),o+=c}return function(e){var t=e.length;if(t<=k)return String.fromCharCode.apply(String,e);var r="",n=0;for(;n0&&(e=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(e+=" ... ")),""},w.prototype.compare=function(e,t,r,n,o){if(!I(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||r>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&t>=r)return 0;if(n>=o)return-1;if(t>=r)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0),a=Math.min(i,s),u=this.slice(n,o),h=e.slice(t,r),f=0;fo)&&(r=o),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return N(this,e,t,r);case"utf8":case"utf-8":return U(this,e,t,r);case"ascii":return L(this,e,t,r);case"latin1":case"binary":return D(this,e,t,r);case"base64":return M(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,r);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},w.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var k=4096;function Y(e,t,r){var n="";r=Math.min(e.length,r);for(var o=t;on)&&(r=n);for(var o="",i=t;ir)throw new RangeError("Trying to access beyond buffer length")}function K(e,t,r,n,o,i){if(!I(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function W(e,t,r,n){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-r,2);o>>8*(n?o:1-o)}function z(e,t,r,n){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-r,4);o>>8*(n?o:3-o)&255}function V(e,t,r,n,o,i){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function X(e,t,r,n,o){return o||V(e,0,r,4),d(e,t,r,n,23,4),r+4}function Q(e,t,r,n,o){return o||V(e,0,r,8),d(e,t,r,n,52,8),r+8}w.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t0&&(o*=256);)n+=this[e+--t]*o;return n},w.prototype.readUInt8=function(e,t){return t||H(e,1,this.length),this[e]},w.prototype.readUInt16LE=function(e,t){return t||H(e,2,this.length),this[e]|this[e+1]<<8},w.prototype.readUInt16BE=function(e,t){return t||H(e,2,this.length),this[e]<<8|this[e+1]},w.prototype.readUInt32LE=function(e,t){return t||H(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},w.prototype.readUInt32BE=function(e,t){return t||H(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},w.prototype.readIntLE=function(e,t,r){e|=0,t|=0,r||H(e,t,this.length);for(var n=this[e],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*t)),n},w.prototype.readIntBE=function(e,t,r){e|=0,t|=0,r||H(e,t,this.length);for(var n=t,o=1,i=this[e+--n];n>0&&(o*=256);)i+=this[e+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},w.prototype.readInt8=function(e,t){return t||H(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},w.prototype.readInt16LE=function(e,t){t||H(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},w.prototype.readInt16BE=function(e,t){t||H(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},w.prototype.readInt32LE=function(e,t){return t||H(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},w.prototype.readInt32BE=function(e,t){return t||H(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},w.prototype.readFloatLE=function(e,t){return t||H(e,4,this.length),p(this,e,!0,23,4)},w.prototype.readFloatBE=function(e,t){return t||H(e,4,this.length),p(this,e,!1,23,4)},w.prototype.readDoubleLE=function(e,t){return t||H(e,8,this.length),p(this,e,!0,52,8)},w.prototype.readDoubleBE=function(e,t){return t||H(e,8,this.length),p(this,e,!1,52,8)},w.prototype.writeUIntLE=function(e,t,r,n){(e=+e,t|=0,r|=0,n)||K(this,e,t,r,Math.pow(2,8*r)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+r},w.prototype.writeUInt8=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,1,255,0),w.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},w.prototype.writeUInt16LE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,2,65535,0),w.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):W(this,e,t,!0),t+2},w.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,2,65535,0),w.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):W(this,e,t,!1),t+2},w.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,4,4294967295,0),w.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):z(this,e,t,!0),t+4},w.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,4,4294967295,0),w.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):z(this,e,t,!1),t+4},w.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var o=Math.pow(2,8*r-1);K(this,e,t,r,o-1,-o)}var i=0,s=1,a=0;for(this[t]=255&e;++i>0)-a&255;return t+r},w.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t|=0,!n){var o=Math.pow(2,8*r-1);K(this,e,t,r,o-1,-o)}var i=r-1,s=1,a=0;for(this[t+i]=255&e;--i>=0&&(s*=256);)e<0&&0===a&&0!==this[t+i+1]&&(a=1),this[t+i]=(e/s>>0)-a&255;return t+r},w.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,1,127,-128),w.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},w.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,2,32767,-32768),w.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):W(this,e,t,!0),t+2},w.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,2,32767,-32768),w.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):W(this,e,t,!1),t+2},w.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,4,2147483647,-2147483648),w.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):z(this,e,t,!0),t+4},w.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||K(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),w.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):z(this,e,t,!1),t+4},w.prototype.writeFloatLE=function(e,t,r){return X(this,e,t,!0,r)},w.prototype.writeFloatBE=function(e,t,r){return X(this,e,t,!1,r)},w.prototype.writeDoubleLE=function(e,t,r){return Q(this,e,t,!0,r)},w.prototype.writeDoubleBE=function(e,t,r){return Q(this,e,t,!1,r)},w.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t=0;--o)e[o+t]=this[o+r];else if(i<1e3||!w.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&r<57344){if(!o){if(r>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===n){(t-=3)>-1&&i.push(239,191,189);continue}o=r;continue}if(r<56320){(t-=3)>-1&&i.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,r<128){if((t-=1)<0)break;i.push(r)}else if(r<2048){if((t-=2)<0)break;i.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function ee(e){return function(e){var t,r,n,o,i,s;h||f();var c=e.length;if(c%4>0)throw new Error("Invalid string. Length must be a multiple of 4");i="="===e[c-2]?2:"="===e[c-1]?1:0,s=new u(3*c/4-i),n=i>0?c-4:c;var l=0;for(t=0,r=0;t>16&255,s[l++]=o>>8&255,s[l++]=255&o;return 2===i?(o=a[e.charCodeAt(t)]<<2|a[e.charCodeAt(t+1)]>>4,s[l++]=255&o):1===i&&(o=a[e.charCodeAt(t)]<<10|a[e.charCodeAt(t+1)]<<4|a[e.charCodeAt(t+2)]>>2,s[l++]=o>>8&255,s[l++]=255&o),s}(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace($,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function te(e,t,r,n){for(var o=0;o=t.length||o>=e.length);++o)t[o+r]=e[o];return o}function re(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function ne(e){let t=[];return e.split("/").forEach(e=>{let r=parseInt(e,10);isNaN(r)||(e.length>1&&"'"===e[e.length-1]&&(r+=2147483648),t.push(r))}),t}function oe(e,t){return Promise.resolve().then(()=>(function e(r,n,o){return r>=n.length?o:t(n[r],r).then((function(t){return o.push(t),e(r+1,n,o)}))})(0,e,[]))}const ie={},se={},ae=(e,t)=>{se[e]=t},ue=e=>{const t=function(t,r){Object.assign(this,r),this.name=e,this.message=t||e,this.stack=(new Error).stack};return t.prototype=new Error,ie[e]=t,t};ue("AccountNameRequired"),ue("AccountNotSupported"),ue("AmountRequired"),ue("BluetoothRequired"),ue("BtcUnmatchedApp"),ue("CantOpenDevice"),ue("CashAddrNotSupported"),ue("CurrencyNotSupported"),ue("DeviceAppVerifyNotSupported"),ue("DeviceGenuineSocketEarlyClose"),ue("DeviceNotGenuine"),ue("DeviceOnDashboardExpected"),ue("DeviceOnDashboardUnexpected"),ue("DeviceInOSUExpected"),ue("DeviceHalted"),ue("DeviceNameInvalid"),ue("DeviceSocketFail"),ue("DeviceSocketNoBulkStatus"),ue("DisconnectedDevice"),ue("DisconnectedDeviceDuringOperation"),ue("EnpointConfig");const he=ue("EthAppPleaseEnableContractData");ue("FeeEstimationFailed"),ue("HardResetFail"),ue("InvalidXRPTag"),ue("InvalidAddress"),ue("InvalidAddressBecauseDestinationIsAlsoSource"),ue("LatestMCUInstalledError"),ue("UnknownMCU"),ue("LedgerAPIError"),ue("LedgerAPIErrorWithMessage"),ue("LedgerAPINotAvailable"),ue("ManagerAppAlreadyInstalled"),ue("ManagerAppRelyOnBTC"),ue("ManagerAppDepInstallRequired"),ue("ManagerAppDepUninstallRequired"),ue("ManagerDeviceLocked"),ue("ManagerFirmwareNotEnoughSpace"),ue("ManagerNotEnoughSpace"),ue("ManagerUninstallBTCDep"),ue("NetworkDown"),ue("NoAddressesFound"),ue("NotEnoughBalance"),ue("NotEnoughBalanceToDelegate"),ue("NotEnoughBalanceInParentAccount"),ue("NotEnoughSpendableBalance"),ue("NotEnoughBalanceBecauseDestinationNotCreated"),ue("NoAccessToCamera"),ue("NotEnoughGas"),ue("NotSupportedLegacyAddress"),ue("GasLessThanEstimate"),ue("PasswordsDontMatch"),ue("PasswordIncorrect"),ue("RecommendSubAccountsToEmpty"),ue("RecommendUndelegation"),ue("TimeoutTagged"),ue("UnexpectedBootloader"),ue("MCUNotGenuineToDashboard"),ue("RecipientRequired"),ue("UnavailableTezosOriginatedAccountReceive"),ue("UnavailableTezosOriginatedAccountSend"),ue("UpdateYourApp"),ue("UserRefusedDeviceNameChange"),ue("UserRefusedAddress"),ue("UserRefusedFirmwareUpdate"),ue("UserRefusedAllowManager"),ue("UserRefusedOnDevice"),ue("TransportOpenUserCancelled"),ue("TransportInterfaceNotAvailable"),ue("TransportWebUSBGestureRequired"),ue("DeviceShouldStayInApp"),ue("WebsocketConnectionError"),ue("WebsocketConnectionFailed"),ue("WrongDeviceForAccount"),ue("WrongAppForCurrency"),ue("ETHAddressNonEIP"),ue("CantScanQRCode"),ue("FeeNotLoaded"),ue("FeeRequired"),ue("FeeTooHigh"),ue("SyncError"),ue("PairingFailed"),ue("GenuineCheckFailed"),ue("LedgerAPI4xx"),ue("LedgerAPI5xx"),ue("FirmwareOrAppUpdateRequired"),ue("NoDBPathGiven"),ue("DBWrongPassword"),ue("DBNotReset");function fe(e,t){this.name="TransportError",this.message=e,this.stack=(new Error).stack,this.id=t}fe.prototype=new Error,ae("TransportError",e=>new fe(e.message,e.id));const ce={PIN_REMAINING_ATTEMPTS:25536,INCORRECT_LENGTH:26368,COMMAND_INCOMPATIBLE_FILE_STRUCTURE:27009,SECURITY_STATUS_NOT_SATISFIED:27010,CONDITIONS_OF_USE_NOT_SATISFIED:27013,INCORRECT_DATA:27264,NOT_ENOUGH_MEMORY_SPACE:27268,REFERENCED_DATA_NOT_FOUND:27272,FILE_ALREADY_EXISTS:27273,INCORRECT_P1_P2:27392,INS_NOT_SUPPORTED:27904,CLA_NOT_SUPPORTED:28160,TECHNICAL_PROBLEM:28416,OK:36864,MEMORY_PROBLEM:37440,NO_EF_SELECTED:37888,INVALID_OFFSET:37890,FILE_NOT_FOUND:37892,INCONSISTENT_FILE:37896,ALGORITHM_NOT_SUPPORTED:38020,INVALID_KCV:38021,CODE_NOT_INITIALIZED:38914,ACCESS_CONDITION_NOT_FULFILLED:38916,CONTRADICTION_SECRET_CODE_STATUS:38920,CONTRADICTION_INVALIDATION:38928,CODE_BLOCKED:38976,MAX_VALUE_REACHED:38992,GP_AUTH_FAILED:25344,LICENSING:28482,HALTED:28586};function le(e){this.name="TransportStatusError";const t=Object.keys(ce).find(t=>ce[t]===e)||"UNKNOWN_ERROR",r=function(e){switch(e){case 26368:return"Incorrect length";case 27010:return"Security not satisfied (dongle locked or have invalid access rights)";case 27013:return"Condition of use not satisfied (denied by the user?)";case 27264:return"Invalid data received";case 27392:return"Invalid parameter received"}if(28416<=e&&e<=28671)return"Internal error, please report"}(e)||t,n=e.toString(16);this.message=`Ledger device: ${r} (0x${n})`,this.stack=(new Error).stack,this.statusCode=e,this.statusText=t}le.prototype=new Error,ae("TransportStatusError",e=>new le(e.statusCode));const pe=e=>e&&27264===e.statusCode?new he("Please enable Contract data on the Ethereum app Settings"):e;class de{constructor(e,t="w0w"){this.transport=void 0,this.transport=e,e.decorateAppAPIMethods(this,["getAddress","provideERC20TokenInformation","signTransaction","signPersonalMessage","getAppConfiguration"],t)}getAddress(e,t,r){let n=ne(e),o=w.alloc(1+4*n.length);return o[0]=n.length,n.forEach((e,t)=>{o.writeUInt32BE(e,1+4*t)}),this.transport.send(224,2,t?1:0,r?1:0,o).then(e=>{let t={},n=e[0],o=e[1+n];return t.publicKey=e.slice(1,1+n).toString("hex"),t.address="0x"+e.slice(1+n+1,1+n+1+o).toString("ascii"),r&&(t.chainCode=e.slice(1+n+1+o,1+n+1+o+32).toString("hex")),t})}provideERC20TokenInformation({data:e}){return this.transport.send(224,10,0,0,e).then(()=>!0,e=>{if(e&&27904===e.statusCode)return!1;throw e})}signTransaction(e,t){let r,n=ne(e),o=0,i=w.from(t,"hex"),s=[];for(;o!==i.length;){let e=0===o?149-4*n.length:150,t=o+e>i.length?i.length-o:e,r=w.alloc(0===o?1+4*n.length+t:t);0===o?(r[0]=n.length,n.forEach((e,t)=>{r.writeUInt32BE(e,1+4*t)}),i.copy(r,1+4*n.length,o,o+t)):i.copy(r,0,o,o+t),s.push(r),o+=t}return oe(s,(e,t)=>this.transport.send(224,4,0===t?0:128,0,e).then(e=>{r=e})).then(()=>{return{v:r.slice(0,1).toString("hex"),r:r.slice(1,33).toString("hex"),s:r.slice(33,65).toString("hex")}},e=>{throw pe(e)})}getAppConfiguration(){return this.transport.send(224,6,0,0).then(e=>{let t={};return t.arbitraryDataEnabled=1&e[0],t.version=e[1]+"."+e[2]+"."+e[3],t})}signPersonalMessage(e,t){let r,n=ne(e),o=0,i=w.from(t,"hex"),s=[];for(;o!==i.length;){let e=0===o?149-4*n.length-4:150,t=o+e>i.length?i.length-o:e,r=w.alloc(0===o?1+4*n.length+4+t:t);0===o?(r[0]=n.length,n.forEach((e,t)=>{r.writeUInt32BE(e,1+4*t)}),r.writeUInt32BE(i.length,1+4*n.length),i.copy(r,1+4*n.length+4,o,o+t)):i.copy(r,0,o,o+t),s.push(r),o+=t}return oe(s,(e,t)=>this.transport.send(224,8,0===t?0:128,0,e).then(e=>{r=e})).then(()=>{return{v:r[0],r:r.slice(1,33).toString("hex"),s:r.slice(33,65).toString("hex")}})}}var ge=ge||{},ve=ge;ge.EXTENSION_ID="kmendfapggjehodndflmmgagdbamhnfd",ge.MessageTypes={U2F_REGISTER_REQUEST:"u2f_register_request",U2F_SIGN_REQUEST:"u2f_sign_request",U2F_REGISTER_RESPONSE:"u2f_register_response",U2F_SIGN_RESPONSE:"u2f_sign_response"},ge.ErrorCodes={OK:0,OTHER_ERROR:1,BAD_REQUEST:2,CONFIGURATION_UNSUPPORTED:3,DEVICE_INELIGIBLE:4,TIMEOUT:5},ge.Request,ge.Response,ge.Error,ge.SignRequest,ge.SignResponse,ge.RegisterRequest,ge.RegisterResponse,ge.disconnect=function(){ge.port_&&ge.port_.port_&&(ge.port_.port_.disconnect(),ge.port_=null)},ge.getMessagePort=function(e){if("undefined"!=typeof chrome&&chrome.runtime){var t={type:ge.MessageTypes.U2F_SIGN_REQUEST,signRequests:[]};chrome.runtime.sendMessage(ge.EXTENSION_ID,t,(function(){chrome.runtime.lastError?ge.getIframePort_(e):ge.getChromeRuntimePort_(e)}))}else ge.getIframePort_(e)},ge.getChromeRuntimePort_=function(e){var t=chrome.runtime.connect(ge.EXTENSION_ID,{includeTlsChannelId:!0});setTimeout((function(){e(null,new ge.WrappedChromeRuntimePort_(t))}),0)},ge.WrappedChromeRuntimePort_=function(e){this.port_=e},ge.WrappedChromeRuntimePort_.prototype.postMessage=function(e){this.port_.postMessage(e)},ge.WrappedChromeRuntimePort_.prototype.addEventListener=function(e,t){var r=e.toLowerCase();"message"==r||"onmessage"==r?this.port_.onMessage.addListener((function(e){t({data:e})})):console.error("WrappedChromeRuntimePort only supports onMessage")},ge.getIframePort_=function(e){var t="chrome-extension://"+ge.EXTENSION_ID,r=document.createElement("iframe");r.src=t+"/u2f-comms.html",r.setAttribute("style","display:none"),document.body.appendChild(r);var n=!1,o=new MessageChannel,i=function(t){"ready"==t.data?(o.port1.removeEventListener("message",i),n||(n=!0,e(null,o.port1))):console.error('First event on iframe port was not "ready"')};o.port1.addEventListener("message",i),o.port1.start(),r.addEventListener("load",(function(){r.contentWindow.postMessage("init",t,[o.port2])})),setTimeout((function(){n||(n=!0,e(new Error("IFrame extension not supported")))}),200)},ge.EXTENSION_TIMEOUT_SEC=30,ge.port_=null,ge.waitingForPort_=[],ge.reqCounter_=0,ge.callbackMap_={},ge.getPortSingleton_=function(e){ge.port_?e(null,ge.port_):(0==ge.waitingForPort_.length&&ge.getMessagePort((function(e,t){for(e||(ge.port_=t,ge.port_.addEventListener("message",ge.responseHandler_));ge.waitingForPort_.length;)ge.waitingForPort_.shift()(e,t)})),ge.waitingForPort_.push(e))},ge.responseHandler_=function(e){var t=e.data,r=t.requestId;if(r&&ge.callbackMap_[r]){var n=ge.callbackMap_[r];delete ge.callbackMap_[r],n(null,t.responseData)}else console.error("Unknown or missing requestId in response.")},ge.isSupported=function(e){ge.getPortSingleton_((function(t,r){e(!t)}))},ge.sign=function(e,t,r){ge.getPortSingleton_((function(n,o){if(n)return t(n);var i=++ge.reqCounter_;ge.callbackMap_[i]=t;var s={type:ge.MessageTypes.U2F_SIGN_REQUEST,signRequests:e,timeoutSeconds:void 0!==r?r:ge.EXTENSION_TIMEOUT_SEC,requestId:i};o.postMessage(s)}))},ge.register=function(e,t,r,n){ge.getPortSingleton_((function(o,i){if(o)return r(o);var s=++ge.reqCounter_;ge.callbackMap_[s]=r;var a={type:ge.MessageTypes.U2F_REGISTER_REQUEST,signRequests:t,registerRequests:e,timeoutSeconds:void 0!==n?n:ge.EXTENSION_TIMEOUT_SEC,requestId:s};i.postMessage(a)}))};var ye=Ae,Ee="undefined"!=typeof navigator&&!!navigator.userAgent,we=Ee&&navigator.userAgent.match(/Safari\//)&&!navigator.userAgent.match(/Chrome\//),me=Ee&&navigator.userAgent.match(/Edge\/1[2345]/),_e=null;function Te(e){return _e||(_e=new e((function(e,t){function r(){e({u2f:null,native:!0})}return Ee?we?r():(void 0!==window.u2f&&"function"==typeof window.u2f.sign&&e({u2f:window.u2f,native:!0}),me?r():"http:"===location.protocol?r():"undefined"==typeof MessageChannel?r():void ve.isSupported((function(t){t?e({u2f:ve,native:!1}):r()}))):r()}))),_e}function Ae(e){return{isSupported:be.bind(e),ensureSupport:Pe.bind(e),register:Ce.bind(e),sign:Oe.bind(e),ErrorCodes:Ae.ErrorCodes,ErrorNames:Ae.ErrorNames}}function Re(e,t){var r=null!=t?t.errorCode:1,n=Ae.ErrorNames[""+r],o=new Error(e);return o.metaData={type:n,code:r},o}function Ie(e,t){var r={};return r.promise=new e((function(e,n){r.resolve=e,r.reject=n,t.then(e,n)})),r.promise.cancel=function(t,n){Te(e).then((function(e){n&&!e.native&&e.u2f.disconnect(),r.reject(Re(t,{errorCode:-1}))}))},r}function be(){return Te(this).then((function(e){return!!e.u2f}))}function Se(e){if(!e.u2f){if("http:"===location.protocol)throw new Error("U2F isn't supported over http, only https");throw new Error("U2F not supported")}}function Pe(){return Te(this).then(Se)}function Ce(e,t,r){var n=this;return Array.isArray(e)||(e=[e]),"number"==typeof t&&void 0===r&&(r=t,t=null),t||(t=[]),Ie(n,Te(n).then((function(o){Se(o);var i=o.native,s=o.u2f;return new n((function(n,o){if(i){var a=e[0].appId;s.register(a,e,t,(function(e){e.errorCode?o(Re("Registration failed",e)):(delete e.errorCode,n(e))}),r)}else s.register(e,t,(function(e,t){e?o(e):t.errorCode?o(Re("Registration failed",t)):n(t)}),r)}))}))).promise}function Oe(e,t){var r=this;return Array.isArray(e)||(e=[e]),Ie(r,Te(r).then((function(n){Se(n);var o=n.native,i=n.u2f;return new r((function(r,n){if(o){var s=e[0].appId,a=e[0].challenge;i.sign(s,a,e,(function(e){e.errorCode?n(Re("Sign failed",e)):(delete e.errorCode,r(e))}),t)}else i.sign(e,(function(e,t){e?n(e):t.errorCode?n(Re("Sign failed",t)):r(t)}),t)}))}))).promise}function Ne(t){Ae[t]=function(){if(!e.Promise)throw new Error("The platform doesn't natively support promises");var r=[].slice.call(arguments);return Ae(e.Promise)[t].apply(null,r)}}Ae.ErrorCodes={CANCELLED:-1,OK:0,OTHER_ERROR:1,BAD_REQUEST:2,CONFIGURATION_UNSUPPORTED:3,DEVICE_INELIGIBLE:4,TIMEOUT:5},Ae.ErrorNames={"-1":"CANCELLED",0:"OK",1:"OTHER_ERROR",2:"BAD_REQUEST",3:"CONFIGURATION_UNSUPPORTED",4:"DEVICE_INELIGIBLE",5:"TIMEOUT"},Ne("isSupported"),Ne("ensureSupport"),Ne("register"),Ne("sign");var Ue,Le=ye,De=Le.isSupported,Me=Le.sign,xe="object"==typeof Reflect?Reflect:null,Be=xe&&"function"==typeof xe.apply?xe.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};Ue=xe&&"function"==typeof xe.ownKeys?xe.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var Fe=Number.isNaN||function(e){return e!=e};function ke(){ke.init.call(this)}var Ye=ke;ke.EventEmitter=ke,ke.prototype._events=void 0,ke.prototype._eventsCount=0,ke.prototype._maxListeners=void 0;var je=10;function Ge(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function qe(e){return void 0===e._maxListeners?ke.defaultMaxListeners:e._maxListeners}function He(e,t,r,n){var o,i,s,a;if(Ge(r),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),i=e._events),s=i[t]),void 0===s)s=i[t]=r,++e._eventsCount;else if("function"==typeof s?s=i[t]=n?[r,s]:[s,r]:n?s.unshift(r):s.push(r),(o=qe(e))>0&&s.length>o&&!s.warned){s.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=s.length,a=u,console&&console.warn&&console.warn(a)}return e}function Ke(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function We(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},o=Ke.bind(n);return o.listener=r,n.wrapFn=o,o}function ze(e,t,r){var n=e._events;if(void 0===n)return[];var o=n[t];return void 0===o?[]:"function"==typeof o?r?[o.listener||o]:[o]:r?function(e){for(var t=new Array(e.length),r=0;r0&&(i=t[0]),i instanceof Error)throw i;var s=new Error("Unhandled error."+(i?" ("+i.message+")":""));throw s.context=i,s}var a=o[e];if(void 0===a)return!1;if("function"==typeof a)Be(a,this,t);else{var u=a.length,h=Xe(a,u);for(r=0;r=0;i--)if(r[i]===t||r[i].listener===t){s=r[i].listener,o=i;break}if(o<0)return this;0===o?r.shift():function(e,t){for(;t+1=0;n--)this.removeListener(e,t[n]);return this},ke.prototype.listeners=function(e){return ze(this,e,!0)},ke.prototype.rawListeners=function(e){return ze(this,e,!1)},ke.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):Ve.call(e,t)},ke.prototype.listenerCount=Ve,ke.prototype.eventNames=function(){return this._eventsCount>0?Ue(this._events):[]};class Qe{constructor(){this.exchangeTimeout=3e4,this._events=new Ye,this.send=async(e,t,r,n,o=w.alloc(0),i=[ce.OK])=>{if(o.length>=256)throw new fe("data.length exceed 256 bytes limit. Got: "+o.length,"DataLengthTooBig");const s=await this.exchange(w.concat([w.from([e,t,r,n]),w.from([o.length]),o])),a=s.readUInt16BE(s.length-2);if(!i.some(e=>e===a))throw new le(a);return s},this.exchangeBusyPromise=void 0,this.exchangeAtomicImpl=async e=>{if(this.exchangeBusyPromise)throw new fe("Transport race condition","RaceCondition");let t;const r=new Promise(e=>{t=e});this.exchangeBusyPromise=r;try{return await e()}finally{t&&t(),this.exchangeBusyPromise=null}},this._appAPIlock=null}exchange(e){throw new Error("exchange not implemented")}setScrambleKey(e){}close(){return Promise.resolve()}on(e,t){this._events.on(e,t)}off(e,t){this._events.removeListener(e,t)}emit(e,...t){this._events.emit(e,...t)}setDebugMode(){console.warn("setDebugMode is deprecated. use @ledgerhq/logs instead. No logs are emitted in this anymore.")}setExchangeTimeout(e){this.exchangeTimeout=e}static create(e=3e3,t){return new Promise((r,n)=>{let o=!1;const i=this.listen({next:t=>{o=!0,i&&i.unsubscribe(),s&&clearTimeout(s),this.open(t.descriptor,e).then(r,n)},error:e=>{s&&clearTimeout(s),n(e)},complete:()=>{s&&clearTimeout(s),o||n(new fe(this.ErrorMessage_NoDeviceFound,"NoDeviceFound"))}}),s=t?setTimeout(()=>{i.unsubscribe(),n(new fe(this.ErrorMessage_ListenTimeout,"ListenTimeout"))},t):null})}decorateAppAPIMethods(e,t,r){for(let n of t)e[n]=this.decorateAppAPIMethod(n,e[n],e,r)}decorateAppAPIMethod(e,t,r,n){return async(...o)=>{const{_appAPIlock:i}=this;if(i)return Promise.reject(new fe("Ledger Device is busy (lock "+i+")","TransportLocked"));try{return this._appAPIlock=e,this.setScrambleKey(n),await t.apply(r,o)}finally{this._appAPIlock=null}}}}Qe.isSupported=void 0,Qe.list=void 0,Qe.listen=void 0,Qe.open=void 0,Qe.ErrorMessage_ListenTimeout="No Ledger device found (timeout)",Qe.ErrorMessage_NoDeviceFound="No Ledger device found";let $e=0;const Ze=[],Je=(e,t,r)=>{const n={type:e,id:String(++$e),date:new Date};t&&(n.message=t),r&&(n.data=r),function(e){for(let t=0;t(Ze.push(e),()=>{const t=Ze.indexOf(e);-1!==t&&(Ze[t]=Ze[Ze.length-1],Ze.pop())});const et=e=>e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""),tt=e=>e.replace(/-/g,"+").replace(/_/g,"/")+"==".substring(0,3*e.length%4);function rt(e,t,r,n){const o=function(e,t){const r=w.alloc(e.length);for(let n=0;n "+e.toString("hex")),Me(s,t/1e3).then(e=>{const{signatureData:t}=e;if("string"==typeof t){const e=w.from(tt(t),"base64");let r;return r=n?e.slice(5):e,Je("apdu","<= "+r.toString("hex")),r}throw e})}let nt=[];class ot extends Qe{static async open(e,t=5e3){return new ot}constructor(){super(),this.scrambleKey=void 0,this.unwrap=!0,nt.push(this)}async exchange(e){try{return await rt(e,this.exchangeTimeout,this.scrambleKey,this.unwrap)}catch(e){throw"object"==typeof e.metaData?(5===e.metaData.code&&(nt.forEach(e=>e.emit("disconnect")),nt=[]),function(e,t,r){const n=new fe(t,r);return n.originalError=e,n}(e,"Failed to sign with Ledger device: U2F "+e.metaData.type,"U2F_"+e.metaData.code)):e}}setScrambleKey(e){this.scrambleKey=w.from(e,"ascii")}setUnwrap(e){this.unwrap=e}close(){return Promise.resolve()}}ot.isSupported=De,ot.list=()=>De().then(e=>e?[null]:[]),ot.listen=e=>{let t=!1;return De().then(r=>{t||(r?(e.next({type:"add",descriptor:null}),e.complete()):e.error(new fe("U2F browser support is needed for Ledger. Please use Chrome, Opera or Firefox with a U2F extension. Also make sure you're on an HTTPS connection","U2FNotSupported")))}),{unsubscribe:()=>{t=!0}}};var it,st=(it=Object.freeze({default:ot}))&&it.default||it,at=r((function(t,r){var n=e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:!0});var o=n(st);r.transports={u2f:o.default,default:o.default}})),ut=(t(at),at.transports),ht=window&&window.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(o,i){function s(e){try{u(n.next(e))}catch(e){i(e)}}function a(e){try{u(n.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(s,a)}u((n=n.apply(e,t||[])).next())}))};const ft=new o.utils.Logger("hardware-wallets/5.0.0-beta.2"),ct="m/44'/60'/0'/0/0";function lt(e){return new Promise(t=>{setTimeout(t,e)})}class pt extends o.Signer{constructor(e,t,r){super(),null==r&&(r=ct),null==t&&(t="default"),o.utils.defineReadOnly(this,"path",r),o.utils.defineReadOnly(this,"type",t),o.utils.defineReadOnly(this,"provider",e||null);const n=ut[t];n||ft.throwArgumentError("unknown or unsupport type","type",t),o.utils.defineReadOnly(this,"_eth",n.create().then(e=>{const t=new de(e);return t.getAppConfiguration().then(e=>t,e=>Promise.reject(e))},e=>Promise.reject(e)))}_retry(e,t){return new Promise((r,n)=>ht(this,void 0,void 0,(function*(){t&&t>0&&setTimeout(()=>{n(new Error("timeout"))},t);const o=yield this._eth;for(let t=0;t<50;t++){try{const t=yield e(o);return r(t)}catch(e){if("TransportLocked"!==e.id)return n(e)}yield lt(100)}return n(new Error("timeout"))})))}getAddress(){return ht(this,void 0,void 0,(function*(){const e=yield this._retry(e=>e.getAddress(this.path));return o.utils.getAddress(e.address)}))}signMessage(e){return ht(this,void 0,void 0,(function*(){"string"==typeof e&&(e=o.utils.toUtf8Bytes(e));const t=o.utils.hexlify(e).substring(2),r=yield this._retry(e=>e.signPersonalMessage(this.path,t));return r.r="0x"+r.r,r.s="0x"+r.s,o.utils.joinSignature(r)}))}signTransaction(e){return ht(this,void 0,void 0,(function*(){const t=e=yield o.utils.resolveProperties(e),r=o.utils.serializeTransaction(t).substring(2),n=yield this._retry(e=>e.signTransaction(this.path,r));return o.utils.serializeTransaction(t,{v:n.v,r:"0x"+n.r,s:"0x"+n.s})}))}connect(e){return new pt(e,this.type,this.path)}}export{pt as LedgerSigner}; diff --git a/packages/hardware-wallets/lib.esm/_version.d.ts b/packages/hardware-wallets/lib.esm/_version.d.ts new file mode 100644 index 0000000000..7ee8c196f2 --- /dev/null +++ b/packages/hardware-wallets/lib.esm/_version.d.ts @@ -0,0 +1 @@ +export declare const version = "hardware-wallets/5.0.0-beta.2"; diff --git a/packages/hardware-wallets/lib.esm/_version.js b/packages/hardware-wallets/lib.esm/_version.js new file mode 100644 index 0000000000..8cb75f90b2 --- /dev/null +++ b/packages/hardware-wallets/lib.esm/_version.js @@ -0,0 +1 @@ +export const version = "hardware-wallets/5.0.0-beta.2"; diff --git a/packages/hardware-wallets/lib.esm/browser-ethers.d.ts b/packages/hardware-wallets/lib.esm/browser-ethers.d.ts new file mode 100644 index 0000000000..68f61a70fe --- /dev/null +++ b/packages/hardware-wallets/lib.esm/browser-ethers.d.ts @@ -0,0 +1,2 @@ +declare let ethers: any; +export { ethers }; diff --git a/packages/hardware-wallets/lib.esm/browser-ethers.js b/packages/hardware-wallets/lib.esm/browser-ethers.js new file mode 100644 index 0000000000..c5f670265e --- /dev/null +++ b/packages/hardware-wallets/lib.esm/browser-ethers.js @@ -0,0 +1,10 @@ +"use strict"; +let ethers = {}; +const w = window; +if (w._ethers == null) { + console.log("WARNING: @ethersproject/hardware-wallet requires ethers loaded first"); +} +else { + ethers = w._ethers; +} +export { ethers }; diff --git a/packages/hardware-wallets/lib.esm/browser-ledger-transport.d.ts b/packages/hardware-wallets/lib.esm/browser-ledger-transport.d.ts new file mode 100644 index 0000000000..c46d3a1061 --- /dev/null +++ b/packages/hardware-wallets/lib.esm/browser-ledger-transport.d.ts @@ -0,0 +1,6 @@ +export declare type TransportCreator = { + create: () => Promise; +}; +export declare const transports: { + [name: string]: TransportCreator; +}; diff --git a/packages/hardware-wallets/lib.esm/browser-ledger-transport.js b/packages/hardware-wallets/lib.esm/browser-ledger-transport.js new file mode 100644 index 0000000000..3d20a13527 --- /dev/null +++ b/packages/hardware-wallets/lib.esm/browser-ledger-transport.js @@ -0,0 +1,6 @@ +"use strict"; +import u2f from "@ledgerhq/hw-transport-u2f"; +export const transports = { + "u2f": u2f, + "default": u2f +}; diff --git a/packages/hardware-wallets/lib.esm/ledger.d.ts b/packages/hardware-wallets/lib.esm/ledger.d.ts index d7946fbdd0..a67ba489b3 100644 --- a/packages/hardware-wallets/lib.esm/ledger.d.ts +++ b/packages/hardware-wallets/lib.esm/ledger.d.ts @@ -1,14 +1,13 @@ -import { Bytes } from "@ethersproject/bytes"; -import { Signer } from "@ethersproject/abstract-signer"; -import { Provider, TransactionRequest } from "@ethersproject/abstract-provider"; +import { ethers } from "ethers"; import Eth from "@ledgerhq/hw-app-eth"; -export declare class LedgerSigner extends Signer { +export declare class LedgerSigner extends ethers.Signer { readonly type: string; readonly path: string; readonly _eth: Promise; - constructor(provider?: Provider, type?: string, path?: string); + constructor(provider?: ethers.providers.Provider, type?: string, path?: string); + _retry(callback: (eth: Eth) => Promise, timeout?: number): Promise; getAddress(): Promise; - signMessage(message: Bytes | string): Promise; - signTransaction(transaction: TransactionRequest): Promise; - connect(provider: Provider): Signer; + signMessage(message: ethers.utils.Bytes | string): Promise; + signTransaction(transaction: ethers.providers.TransactionRequest): Promise; + connect(provider: ethers.providers.Provider): ethers.Signer; } diff --git a/packages/hardware-wallets/lib.esm/ledger.js b/packages/hardware-wallets/lib.esm/ledger.js index 310f6b942e..a30d4aa541 100644 --- a/packages/hardware-wallets/lib.esm/ledger.js +++ b/packages/hardware-wallets/lib.esm/ledger.js @@ -8,19 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -import { getAddress } from "@ethersproject/address"; -import { hexlify, joinSignature } from "@ethersproject/bytes"; -import { Signer } from "@ethersproject/abstract-signer"; -import { defineReadOnly, resolveProperties } from "@ethersproject/properties"; -import { toUtf8Bytes } from "@ethersproject/strings"; -import { serialize as serializeTransaction } from "@ethersproject/transactions"; +import { ethers } from "ethers"; +import { version } from "./_version"; +const logger = new ethers.utils.Logger(version); import Eth from "@ledgerhq/hw-app-eth"; // We store these in a separated import so it is easier to swap them out // at bundle time; browsers do not get HID, for example. This maps a string // "type" to a Transport with create. import { transports } from "./ledger-transport"; const defaultPath = "m/44'/60'/0'/0/0"; -export class LedgerSigner extends Signer { +function waiter(duration) { + return new Promise((resolve) => { + setTimeout(resolve, duration); + }); +} +export class LedgerSigner extends ethers.Signer { constructor(provider, type, path) { super(); if (path == null) { @@ -29,14 +31,14 @@ export class LedgerSigner extends Signer { if (type == null) { type = "default"; } - defineReadOnly(this, "path", path); - defineReadOnly(this, "type", type); - defineReadOnly(this, "provider", provider || null); + ethers.utils.defineReadOnly(this, "path", path); + ethers.utils.defineReadOnly(this, "type", type); + ethers.utils.defineReadOnly(this, "provider", provider || null); const transport = transports[type]; if (!transport) { - throw new Error("unknown or unsupport type"); + logger.throwArgumentError("unknown or unsupport type", "type", type); } - defineReadOnly(this, "_eth", transport.create().then((transport) => { + ethers.utils.defineReadOnly(this, "_eth", transport.create().then((transport) => { const eth = new Eth(transport); return eth.getAppConfiguration().then((config) => { return eth; @@ -47,41 +49,55 @@ export class LedgerSigner extends Signer { return Promise.reject(error); })); } - getAddress() { - return __awaiter(this, void 0, void 0, function* () { + _retry(callback, timeout) { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + if (timeout && timeout > 0) { + setTimeout(() => { reject(new Error("timeout")); }, timeout); + } const eth = yield this._eth; - if (eth == null) { - throw new Error("failed to connect"); + // Wait up to 5 seconds + for (let i = 0; i < 50; i++) { + try { + const result = yield callback(eth); + return resolve(result); + } + catch (error) { + if (error.id !== "TransportLocked") { + return reject(error); + } + } + yield waiter(100); } - const o = yield eth.getAddress(this.path); - return getAddress(o.address); + return reject(new Error("timeout")); + })); + } + getAddress() { + return __awaiter(this, void 0, void 0, function* () { + const account = yield this._retry((eth) => eth.getAddress(this.path)); + return ethers.utils.getAddress(account.address); }); } signMessage(message) { return __awaiter(this, void 0, void 0, function* () { if (typeof (message) === 'string') { - message = toUtf8Bytes(message); + message = ethers.utils.toUtf8Bytes(message); } - const messageHex = hexlify(message).substring(2); - const eth = yield this._eth; - const sig = yield eth.signPersonalMessage(this.path, messageHex); + const messageHex = ethers.utils.hexlify(message).substring(2); + const sig = yield this._retry((eth) => eth.signPersonalMessage(this.path, messageHex)); sig.r = '0x' + sig.r; sig.s = '0x' + sig.s; - return joinSignature(sig); + return ethers.utils.joinSignature(sig); }); } signTransaction(transaction) { return __awaiter(this, void 0, void 0, function* () { - const eth = yield this._eth; - return resolveProperties(transaction).then((tx) => { - const unsignedTx = serializeTransaction(tx).substring(2); - return eth.signTransaction(this.path, unsignedTx).then((sig) => { - return serializeTransaction(tx, { - v: sig.v, - r: ("0x" + sig.r), - s: ("0x" + sig.s), - }); - }); + const tx = transaction = yield ethers.utils.resolveProperties(transaction); + const unsignedTx = ethers.utils.serializeTransaction(tx).substring(2); + const sig = yield this._retry((eth) => eth.signTransaction(this.path, unsignedTx)); + return ethers.utils.serializeTransaction(tx, { + v: sig.v, + r: ("0x" + sig.r), + s: ("0x" + sig.s), }); }); } @@ -89,16 +105,3 @@ export class LedgerSigner extends Signer { return new LedgerSigner(provider, this.type, this.path); } } -(function () { - return __awaiter(this, void 0, void 0, function* () { - const signer = new LedgerSigner(); - console.log(signer); - try { - const sig = yield signer.signMessage("Hello World"); - console.log(sig); - } - catch (error) { - console.log("ERR", error); - } - }); -})(); diff --git a/packages/hardware-wallets/lib/_version.d.ts b/packages/hardware-wallets/lib/_version.d.ts new file mode 100644 index 0000000000..7ee8c196f2 --- /dev/null +++ b/packages/hardware-wallets/lib/_version.d.ts @@ -0,0 +1 @@ +export declare const version = "hardware-wallets/5.0.0-beta.2"; diff --git a/packages/hardware-wallets/lib/_version.js b/packages/hardware-wallets/lib/_version.js new file mode 100644 index 0000000000..e9765b5cb1 --- /dev/null +++ b/packages/hardware-wallets/lib/_version.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.version = "hardware-wallets/5.0.0-beta.2"; diff --git a/packages/hardware-wallets/lib/browser-ethers.d.ts b/packages/hardware-wallets/lib/browser-ethers.d.ts new file mode 100644 index 0000000000..68f61a70fe --- /dev/null +++ b/packages/hardware-wallets/lib/browser-ethers.d.ts @@ -0,0 +1,2 @@ +declare let ethers: any; +export { ethers }; diff --git a/packages/hardware-wallets/lib/browser-ethers.js b/packages/hardware-wallets/lib/browser-ethers.js new file mode 100644 index 0000000000..9dc5186831 --- /dev/null +++ b/packages/hardware-wallets/lib/browser-ethers.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ethers = {}; +exports.ethers = ethers; +var w = window; +if (w._ethers == null) { + console.log("WARNING: @ethersproject/hardware-wallet requires ethers loaded first"); +} +else { + exports.ethers = ethers = w._ethers; +} diff --git a/packages/hardware-wallets/lib/browser-ledger-transport.d.ts b/packages/hardware-wallets/lib/browser-ledger-transport.d.ts new file mode 100644 index 0000000000..c46d3a1061 --- /dev/null +++ b/packages/hardware-wallets/lib/browser-ledger-transport.d.ts @@ -0,0 +1,6 @@ +export declare type TransportCreator = { + create: () => Promise; +}; +export declare const transports: { + [name: string]: TransportCreator; +}; diff --git a/packages/hardware-wallets/lib/browser-ledger-transport.js b/packages/hardware-wallets/lib/browser-ledger-transport.js new file mode 100644 index 0000000000..f8bfd715e3 --- /dev/null +++ b/packages/hardware-wallets/lib/browser-ledger-transport.js @@ -0,0 +1,10 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var hw_transport_u2f_1 = __importDefault(require("@ledgerhq/hw-transport-u2f")); +exports.transports = { + "u2f": hw_transport_u2f_1.default, + "default": hw_transport_u2f_1.default +}; diff --git a/packages/hardware-wallets/lib/ledger.d.ts b/packages/hardware-wallets/lib/ledger.d.ts index d7946fbdd0..a67ba489b3 100644 --- a/packages/hardware-wallets/lib/ledger.d.ts +++ b/packages/hardware-wallets/lib/ledger.d.ts @@ -1,14 +1,13 @@ -import { Bytes } from "@ethersproject/bytes"; -import { Signer } from "@ethersproject/abstract-signer"; -import { Provider, TransactionRequest } from "@ethersproject/abstract-provider"; +import { ethers } from "ethers"; import Eth from "@ledgerhq/hw-app-eth"; -export declare class LedgerSigner extends Signer { +export declare class LedgerSigner extends ethers.Signer { readonly type: string; readonly path: string; readonly _eth: Promise; - constructor(provider?: Provider, type?: string, path?: string); + constructor(provider?: ethers.providers.Provider, type?: string, path?: string); + _retry(callback: (eth: Eth) => Promise, timeout?: number): Promise; getAddress(): Promise; - signMessage(message: Bytes | string): Promise; - signTransaction(transaction: TransactionRequest): Promise; - connect(provider: Provider): Signer; + signMessage(message: ethers.utils.Bytes | string): Promise; + signTransaction(transaction: ethers.providers.TransactionRequest): Promise; + connect(provider: ethers.providers.Provider): ethers.Signer; } diff --git a/packages/hardware-wallets/lib/ledger.js b/packages/hardware-wallets/lib/ledger.js index a1343ae0df..fb0309f6ba 100644 --- a/packages/hardware-wallets/lib/ledger.js +++ b/packages/hardware-wallets/lib/ledger.js @@ -52,18 +52,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var address_1 = require("@ethersproject/address"); -var bytes_1 = require("@ethersproject/bytes"); -var abstract_signer_1 = require("@ethersproject/abstract-signer"); -var properties_1 = require("@ethersproject/properties"); -var strings_1 = require("@ethersproject/strings"); -var transactions_1 = require("@ethersproject/transactions"); +var ethers_1 = require("ethers"); +var _version_1 = require("./_version"); +var logger = new ethers_1.ethers.utils.Logger(_version_1.version); var hw_app_eth_1 = __importDefault(require("@ledgerhq/hw-app-eth")); // We store these in a separated import so it is easier to swap them out // at bundle time; browsers do not get HID, for example. This maps a string // "type" to a Transport with create. var ledger_transport_1 = require("./ledger-transport"); var defaultPath = "m/44'/60'/0'/0/0"; +function waiter(duration) { + return new Promise(function (resolve) { + setTimeout(resolve, duration); + }); +} var LedgerSigner = /** @class */ (function (_super) { __extends(LedgerSigner, _super); function LedgerSigner(provider, type, path) { @@ -74,14 +76,14 @@ var LedgerSigner = /** @class */ (function (_super) { if (type == null) { type = "default"; } - properties_1.defineReadOnly(_this, "path", path); - properties_1.defineReadOnly(_this, "type", type); - properties_1.defineReadOnly(_this, "provider", provider || null); + ethers_1.ethers.utils.defineReadOnly(_this, "path", path); + ethers_1.ethers.utils.defineReadOnly(_this, "type", type); + ethers_1.ethers.utils.defineReadOnly(_this, "provider", provider || null); var transport = ledger_transport_1.transports[type]; if (!transport) { - throw new Error("unknown or unsupport type"); + logger.throwArgumentError("unknown or unsupport type", "type", type); } - properties_1.defineReadOnly(_this, "_eth", transport.create().then(function (transport) { + ethers_1.ethers.utils.defineReadOnly(_this, "_eth", transport.create().then(function (transport) { var eth = new hw_app_eth_1.default(transport); return eth.getAppConfiguration().then(function (config) { return eth; @@ -93,66 +95,100 @@ var LedgerSigner = /** @class */ (function (_super) { })); return _this; } - LedgerSigner.prototype.getAddress = function () { - return __awaiter(this, void 0, void 0, function () { - var eth, o; + LedgerSigner.prototype._retry = function (callback, timeout) { + var _this = this; + return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { + var eth, i, result, error_1; return __generator(this, function (_a) { switch (_a.label) { - case 0: return [4 /*yield*/, this._eth]; + case 0: + if (timeout && timeout > 0) { + setTimeout(function () { reject(new Error("timeout")); }, timeout); + } + return [4 /*yield*/, this._eth]; case 1: eth = _a.sent(); - if (eth == null) { - throw new Error("failed to connect"); - } - return [4 /*yield*/, eth.getAddress(this.path)]; + i = 0; + _a.label = 2; case 2: - o = _a.sent(); - return [2 /*return*/, address_1.getAddress(o.address)]; + if (!(i < 50)) return [3 /*break*/, 9]; + _a.label = 3; + case 3: + _a.trys.push([3, 5, , 6]); + return [4 /*yield*/, callback(eth)]; + case 4: + result = _a.sent(); + return [2 /*return*/, resolve(result)]; + case 5: + error_1 = _a.sent(); + if (error_1.id !== "TransportLocked") { + return [2 /*return*/, reject(error_1)]; + } + return [3 /*break*/, 6]; + case 6: return [4 /*yield*/, waiter(100)]; + case 7: + _a.sent(); + _a.label = 8; + case 8: + i++; + return [3 /*break*/, 2]; + case 9: return [2 /*return*/, reject(new Error("timeout"))]; + } + }); + }); }); + }; + LedgerSigner.prototype.getAddress = function () { + return __awaiter(this, void 0, void 0, function () { + var account; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this._retry(function (eth) { return eth.getAddress(_this.path); })]; + case 1: + account = _a.sent(); + return [2 /*return*/, ethers_1.ethers.utils.getAddress(account.address)]; } }); }); }; LedgerSigner.prototype.signMessage = function (message) { return __awaiter(this, void 0, void 0, function () { - var messageHex, eth, sig; + var messageHex, sig; + var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (typeof (message) === 'string') { - message = strings_1.toUtf8Bytes(message); + message = ethers_1.ethers.utils.toUtf8Bytes(message); } - messageHex = bytes_1.hexlify(message).substring(2); - return [4 /*yield*/, this._eth]; + messageHex = ethers_1.ethers.utils.hexlify(message).substring(2); + return [4 /*yield*/, this._retry(function (eth) { return eth.signPersonalMessage(_this.path, messageHex); })]; case 1: - eth = _a.sent(); - return [4 /*yield*/, eth.signPersonalMessage(this.path, messageHex)]; - case 2: sig = _a.sent(); sig.r = '0x' + sig.r; sig.s = '0x' + sig.s; - return [2 /*return*/, bytes_1.joinSignature(sig)]; + return [2 /*return*/, ethers_1.ethers.utils.joinSignature(sig)]; } }); }); }; LedgerSigner.prototype.signTransaction = function (transaction) { return __awaiter(this, void 0, void 0, function () { - var eth; + var tx, unsignedTx, sig; var _this = this; return __generator(this, function (_a) { switch (_a.label) { - case 0: return [4 /*yield*/, this._eth]; + case 0: return [4 /*yield*/, ethers_1.ethers.utils.resolveProperties(transaction)]; case 1: - eth = _a.sent(); - return [2 /*return*/, properties_1.resolveProperties(transaction).then(function (tx) { - var unsignedTx = transactions_1.serialize(tx).substring(2); - return eth.signTransaction(_this.path, unsignedTx).then(function (sig) { - return transactions_1.serialize(tx, { - v: sig.v, - r: ("0x" + sig.r), - s: ("0x" + sig.s), - }); - }); + tx = transaction = _a.sent(); + unsignedTx = ethers_1.ethers.utils.serializeTransaction(tx).substring(2); + return [4 /*yield*/, this._retry(function (eth) { return eth.signTransaction(_this.path, unsignedTx); })]; + case 2: + sig = _a.sent(); + return [2 /*return*/, ethers_1.ethers.utils.serializeTransaction(tx, { + v: sig.v, + r: ("0x" + sig.r), + s: ("0x" + sig.s), })]; } }); @@ -162,30 +198,5 @@ var LedgerSigner = /** @class */ (function (_super) { return new LedgerSigner(provider, this.type, this.path); }; return LedgerSigner; -}(abstract_signer_1.Signer)); +}(ethers_1.ethers.Signer)); exports.LedgerSigner = LedgerSigner; -(function () { - return __awaiter(this, void 0, void 0, function () { - var signer, sig, error_1; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - signer = new LedgerSigner(); - console.log(signer); - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, signer.signMessage("Hello World")]; - case 2: - sig = _a.sent(); - console.log(sig); - return [3 /*break*/, 4]; - case 3: - error_1 = _a.sent(); - console.log("ERR", error_1); - return [3 /*break*/, 4]; - case 4: return [2 /*return*/]; - } - }); - }); -})(); diff --git a/packages/hardware-wallets/package.json b/packages/hardware-wallets/package.json index 75656e6863..64fb3212e9 100644 --- a/packages/hardware-wallets/package.json +++ b/packages/hardware-wallets/package.json @@ -1,8 +1,8 @@ { "author": "Richard Moore ", "browser": { - "./lib.esm/ledger-transport.js": "./lib.esm/browser-ledger-transport.js", - "ethers": "./lib.esm/browser-ethers.js" + "./lib.esm/ledger-transport.js": "./lib/browser-ledger-transport.js", + "ethers": "./lib/browser-ethers.js" }, "dependencies": { "@ledgerhq/hw-app-eth": "5.3.0", @@ -35,7 +35,7 @@ "scripts": { "test": "exit 1" }, - "tarballHash": "0x7ae47cbae54f4c1489bffc6d606055c372a098f38e8821b42d7cbfb2dcc22014", + "tarballHash": "0xa37070ed42f6da545b3a6d5bb1678a9a4c0fb0e9f76726b36c8b197d685b6a01", "types": "./lib/index.d.ts", - "version": "5.0.0-beta.1" + "version": "5.0.0-beta.2" } diff --git a/packages/hardware-wallets/src.ts/_version.ts b/packages/hardware-wallets/src.ts/_version.ts new file mode 100644 index 0000000000..8cb75f90b2 --- /dev/null +++ b/packages/hardware-wallets/src.ts/_version.ts @@ -0,0 +1 @@ +export const version = "hardware-wallets/5.0.0-beta.2"; diff --git a/packages/hardware-wallets/test.html b/packages/hardware-wallets/test.html new file mode 100644 index 0000000000..98ae20ef1c --- /dev/null +++ b/packages/hardware-wallets/test.html @@ -0,0 +1,31 @@ + + + Browser Test - Ledger + + + + + diff --git a/packages/hardware-wallets/test.js b/packages/hardware-wallets/test.js new file mode 100644 index 0000000000..418170cc45 --- /dev/null +++ b/packages/hardware-wallets/test.js @@ -0,0 +1,14 @@ +"use strict"; + +const { LedgerSigner } = require("./lib"); + +(async function() { + const signer = new LedgerSigner(); + console.log(signer); + try { + const sig = await signer.signMessage("Hello World"); + console.log(sig); + } catch (error) { + console.log("ERR", error); + } +})(); diff --git a/tsconfig.project.json b/tsconfig.project.json index 52016b2531..183cde0bed 100644 --- a/tsconfig.project.json +++ b/tsconfig.project.json @@ -87,9 +87,6 @@ { "path": "./packages/contracts" }, - { - "path": "./packages/hardware-wallets" - }, { "path": "./packages/providers" }, @@ -114,6 +111,9 @@ { "path": "./packages/experimental" }, + { + "path": "./packages/hardware-wallets" + }, { "path": "./packages/testcases" },