diff --git a/example/multisig.js b/example/multisig.js new file mode 100644 index 00000000..e170f0bf --- /dev/null +++ b/example/multisig.js @@ -0,0 +1,109 @@ +const { v4 } = require('uuid'); +const { MixinApi, buildMultiSigsTransaction, sleep, encodeScript } = require('..'); +const keystore = require('../keystore.json'); + +keystore.user_id = keystore.client_id; +const client = MixinApi({ + requestConfig: { + responseCallback: err => { + console.log(err); + }, + }, + keystore, +}); + +const readOutput = async (hash, members, threshold, offset = '') => { + let new_offset = offset; + const outputs = await client.multisig.outputs({ + members, + threshold, + offset, + limit: 10, + }); + + // eslint-disable-next-line no-restricted-syntax + for (const output of outputs) { + new_offset = output.updated_at; + if (output.transaction_hash === hash) return output; + } + + await sleep(1000 * 5); + return readOutput(hash, members, threshold, new_offset); +}; + +const main = async () => { + const bot = await client.user.profile(); + const asset_id = '965e5c6e-434c-3fa9-b780-c50f43cd955c'; + const amount = '0.0001'; + const members = [bot.app.creator_id, keystore.user_id]; + const threshold = 1; + + // 1. send to multisig account + // should have balance in your bot + const sendTxReceipt = await client.transfer.toAddress(keystore.pin, { + asset_id, + amount, + trace_id: v4(), + memo: 'send to multisig', + opponent_multisig: { + threshold, + receivers: members, + }, + }); + console.log('send to multi-signature account'); + console.log('transaction hash:', sendTxReceipt.transaction_hash); + + // 2. wait tx complete + console.log('read transaction output...'); + const utxo = await readOutput(sendTxReceipt.transaction_hash, members, threshold, ''); + console.log(utxo); + + // 3. refund + console.log('refund to bot:'); + const asset = await client.asset.fetch(asset_id); + const receivers = await client.transfer.outputs([ + { + receivers: [keystore.user_id], + index: 0, + }, + ]); + console.log('generate raw transaction'); + const raw = buildMultiSigsTransaction({ + version: 2, + asset: asset.mixin_id, + inputs: [ + { + hash: utxo.transaction_hash, + index: utxo.output_index, + }, + ], + outputs: [ + { + amount, + mask: receivers[0].mask, + keys: receivers[0].keys, + script: encodeScript(threshold), + }, + ], + extra: 'refund', + }); + + // Generate a multi-signature + console.log('generate a multi-signature request...'); + const multisig = await client.multisig.create('sign', raw); + + // Sign a multi-signature + console.log('sign...'); + const signed = await client.multisig.sign(keystore.pin, multisig.request_id); + console.log(signed); + + // Send signed tx to mainnet + console.log('send to mainnet...'); + const res = await client.external.proxy({ + method: 'sendrawtransaction', + params: [signed.raw_transaction], + }); + console.log(res); +}; + +main(); diff --git a/package.json b/package.json index 4ea3f91e..fcfc5d85 100644 --- a/package.json +++ b/package.json @@ -81,8 +81,6 @@ "@ethersproject/abi": "^5.6.3", "@ethersproject/providers": "^5.6.8", "@types/axios": "^0.14.0", - "@types/bn.js": "^5.1.0", - "@types/jsonwebtoken": "^8.5.8", "@types/node-forge": "^1.0.2", "@types/serialize-javascript": "^5.0.2", "@types/uuid": "^8.3.4", diff --git a/src/client/external.ts b/src/client/external.ts index 70acf26d..27f92691 100644 --- a/src/client/external.ts +++ b/src/client/external.ts @@ -20,6 +20,13 @@ export const ExternalKeystoreClient = (axiosInstance: AxiosInstance) => ({ */ exchangeRates: (): Promise => axiosInstance.get('/external/fiats'), + /** + * Submit a raw transaction to a random mainnet node + * { + * method: 'sendrawtransaction', + * params: array of transaction hash + * } + * */ proxy: (params: ProxyRequest): Promise => axiosInstance.post('/external/proxy', params), }); diff --git a/src/client/message.ts b/src/client/message.ts index 212d6e8e..c2a36538 100644 --- a/src/client/message.ts +++ b/src/client/message.ts @@ -19,9 +19,7 @@ import { TransferMessageRequest, RecallMessageRequest, } from './types/message'; -import { base64url } from '../mixin/sign'; -import { uniqueConversationID } from './utils/uniq'; -import { buildClient } from './utils/client'; +import { uniqueConversationID, base64RawURLEncode, buildClient } from './utils'; /** * Methods to send messages @@ -41,7 +39,7 @@ export const MessageKeystoreClient = (axiosInstance: AxiosInstance, keystore: Ke recipient_id: recipientID, conversation_id: uniqueConversationID(keystore!.user_id, recipientID), message_id: uuid(), - data: base64url(Buffer.from(data)), + data: base64RawURLEncode(Buffer.from(data)), }; await send(messageRequest); return messageRequest; diff --git a/src/client/types/multisig.ts b/src/client/types/multisig.ts index 188c3e6a..b5ab3928 100644 --- a/src/client/types/multisig.ts +++ b/src/client/types/multisig.ts @@ -1,3 +1,5 @@ +import { Input, Output } from '../../mvm'; + export type UTXOState = 'unspent' | 'signed' | 'spent'; export type MultisigInitAction = 'sign' | 'unlock'; @@ -55,3 +57,13 @@ export interface MultisigRequestResponse { updated_at: string; code_id: string; } + +export interface MultisigTransaction { + /** 2 */ + version: number; + /** mixin_id of asset */ + asset: string; + inputs: Input[]; + outputs: Output[]; + extra: string; +} diff --git a/src/client/types/transaction.ts b/src/client/types/transaction.ts index 286e3465..e26026b9 100644 --- a/src/client/types/transaction.ts +++ b/src/client/types/transaction.ts @@ -16,7 +16,7 @@ export interface RawTransactionRequest { export interface GhostInputRequest { receivers: string[]; index: number; - hint: string; + hint?: string; } export interface GhostKeysResponse { diff --git a/src/client/utils/index.ts b/src/client/utils/index.ts index 5dd6297c..c596f57c 100644 --- a/src/client/utils/index.ts +++ b/src/client/utils/index.ts @@ -1,6 +1,7 @@ export * from './auth'; export * from './base64'; export * from './client'; +export * from './multisigs'; export * from './nfo'; export * from './pin'; export * from './sleep'; diff --git a/src/client/utils/multisigs.ts b/src/client/utils/multisigs.ts new file mode 100644 index 00000000..54226e04 --- /dev/null +++ b/src/client/utils/multisigs.ts @@ -0,0 +1,54 @@ +import { MultisigTransaction } from '../types'; +import { Encoder, magic } from '../../mvm'; + +export const TxVersion = 0x02; + +export const encodeScript = (threshold: number) => { + let s = threshold.toString(16); + if (s.length === 1) s = `0${s}`; + if (s.length > 2) throw new Error(`INVALID THRESHOLD ${threshold}`); + + return `fffe${s}`; +}; + +export const encodeTx = (tx: MultisigTransaction) => { + const enc = new Encoder(Buffer.from([])); + + enc.write(magic); + enc.write(Buffer.from([0x00, tx.version])); + enc.write(Buffer.from(tx.asset, 'hex')); + + enc.writeInt(tx.inputs.length); + tx.inputs.forEach(input => { + enc.encodeInput(input); + }); + + enc.writeInt(tx.outputs.length); + tx.outputs.forEach(output => { + enc.encodeOutput(output); + }); + + const extra = Buffer.from(tx.extra); + enc.writeInt(extra.byteLength); + enc.write(extra); + + enc.writeInt(0); + enc.write(Buffer.from([])); + + return enc.buf.toString('hex'); +}; + +/** + * Generate raw for multi-signature transaction. + * The total amount of input utxos should be equal to the total amount of output utxos. + * */ +export const buildMultiSigsTransaction = (transaction: MultisigTransaction) => { + if (transaction.version !== TxVersion) throw new Error('Invalid Version!'); + + const tx = { + ...transaction, + outputs: transaction.outputs.filter(output => !!output.mask), + extra: Buffer.from(transaction.extra).toString('hex'), + }; + return encodeTx(tx); +}; diff --git a/src/client/utils/nfo.ts b/src/client/utils/nfo.ts index f9795a76..d03c9937 100644 --- a/src/client/utils/nfo.ts +++ b/src/client/utils/nfo.ts @@ -1,7 +1,7 @@ import { parse as UUIDParse, stringify } from 'uuid'; import { NFOMemo } from '../types'; -import { newHash } from './uniq'; import { base64RawURLEncode } from './base64'; +import { newHash } from './uniq'; import { Encoder, Decoder } from '../../mvm'; const Prefix = 'NFO'; diff --git a/src/index.ts b/src/index.ts index 831ffe2a..201ed2e3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,4 @@ export * from './client'; export * from './mvm'; export * from './webview'; -export * from './mixin/dump_transacion'; export * from './constant'; diff --git a/src/mixin/dump_transacion.ts b/src/mixin/dump_transacion.ts deleted file mode 100644 index 9decbaba..00000000 --- a/src/mixin/dump_transacion.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Transaction } from '../mvm'; -import { GhostKeysResponse } from '../client'; -import { Encoder, magic, maxEcodingInt, OperatorCmp, OperatorSum } from './encoder'; - -export function dumpTransaction(signed: Transaction): string { - const enc = new Encoder(magic); - enc.write(Buffer.from([0x00, signed.version!])); - enc.write(Buffer.from(signed.asset, 'hex')); - - const il = signed.inputs!.length; - enc.writeInt(il); - signed.inputs!.forEach(i => enc.encodeInput(i)); - - const ol = signed.outputs!.length; - enc.writeInt(ol); - signed.outputs!.forEach(o => enc.encodeOutput(o)); - - const e = Buffer.from(signed.extra!, 'base64'); - enc.writeInt(e.byteLength); - enc.write(e); - - if (signed.aggregated) { - enc.encodeAggregatedSignature(signed.aggregated); - } else { - const sl = signed.signatures ? Object.keys(signed.signatures).length : 0; - if (sl === maxEcodingInt) throw new Error('signatures overflow'); - enc.writeInt(sl); - if (sl > 0) { - enc.encodeSignature(signed.signatures!); - } - } - return enc.buf.toString('hex'); -} - -export function DumpOutputFromGhostKey(gi: GhostKeysResponse, amount: string, threshold: number) { - const { mask, keys } = gi; - return { - mask, - keys, - amount: Number(amount).toFixed(8), - script: Buffer.from([OperatorCmp, OperatorSum, threshold]).toString('hex'), - }; -} diff --git a/src/mixin/encoder.ts b/src/mixin/encoder.ts deleted file mode 100644 index 2fa87978..00000000 --- a/src/mixin/encoder.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { BN } from 'bn.js'; -import { parse } from 'uuid'; -import { Aggregated, Input, Output } from '../mvm'; - -const aggregatedSignaturePrefix = 0xff01; -const empty = Buffer.from([0x00, 0x00]); - -export const magic = Buffer.from([0x77, 0x77]); -export const maxEcodingInt = 0xffff; - -export const TxVersion = 0x02; - -export const OperatorSum = 0xfe; -export const OperatorCmp = 0xff; - -export class Encoder { - buf: Buffer; - - constructor(buf: Buffer) { - this.buf = buf; - } - - write(buf: Buffer) { - this.buf = Buffer.concat([this.buf, buf]); - } - - writeBytes(buf: Buffer) { - const len = buf.byteLength; - if (len > 65 * 21) { - throw new Error(`bytes too long. max length is 21 * 65, current length is ${len}`); - } - - this.writeInt(len); - this.write(buf); - } - - writeInt(i: number) { - if (i > maxEcodingInt) { - throw new Error('int overflow'); - } - const buf = Buffer.alloc(2); - buf.writeUInt16BE(i); - this.write(buf); - } - - writeUint64(i: bigint) { - const buf = Buffer.alloc(8); - buf.writeBigUInt64BE(i); - this.write(buf); - } - - writeUint16(i: number) { - const buf = Buffer.alloc(2); - buf.writeUInt16BE(i); - this.write(buf); - } - - writeInteger(i: number) { - const b = getIntBytes(i); - this.writeInt(b.length); - this.write(Buffer.from(b)); - } - - writeSlice(str: Buffer) { - const l = str.length; - if (l > 128) throw new Error('slice too long'); - this.write(Buffer.from([l])); - this.write(str); - } - - writeUUID(id: string) { - const uuid: any = parse(id); - for (let i = 0; i < uuid.length; i++) this.write(Buffer.from([uuid[i]])); - } - - encodeInput(i: Input) { - this.write(Buffer.from(i.hash!, 'hex')); - this.writeInt(i.index!); - - if (!i.genesis) i.genesis = ''; - this.writeInt(i.genesis.length); - this.write(Buffer.from(i.genesis)); - const d = i.deposit; - if (typeof d === 'undefined') { - this.write(empty); - } else { - // TODO... to test... - this.write(magic); - this.write(Buffer.from(d.chain, 'hex')); - - const asset = Buffer.from(d.asset); - this.writeInt(asset.byteLength); - this.write(asset); - - const tx = Buffer.from(d.transaction); - this.writeInt(tx.byteLength); - this.write(tx); - - this.writeUint64(d.index); - this.writeInteger(d.amount); - } - const m = i.mint; - if (typeof m === 'undefined') { - this.write(empty); - } else { - this.write(magic); - if (!m.group) m.group = ''; - this.writeInt(m.group.length); - this.write(Buffer.from(m.group)); - - this.writeUint64(m.batch); - this.writeInteger(m.amount); - } - } - - encodeOutput(o: Output) { - if (!o.type) o.type = 0; - this.write(Buffer.from([0x00, o.type])); - this.writeInteger(new BN(1e8).mul(new BN(o.amount!)).toNumber()); - this.writeInt(o.keys!.length); - - o.keys!.forEach(k => this.write(Buffer.from(k, 'hex'))); - - this.write(Buffer.from(o.mask!, 'hex')); - - const s = Buffer.from(o.script!, 'hex'); - this.writeInt(s.byteLength); - this.write(s); - - const w = o.withdrawal; - if (typeof w === 'undefined') { - this.write(empty); - } else { - // TODO... not check... - this.write(magic); - this.write(Buffer.from(w.chain, 'hex')); - - const asset = Buffer.from(w.asset); - this.writeInt(asset.byteLength); - this.write(asset); - - if (!w.address) w.address = ''; - - const addr = Buffer.from(w.address); - this.writeInt(addr.byteLength); - this.write(addr); - - const tag = Buffer.from(w.tag); - this.writeInt(tag.byteLength); - this.write(tag); - } - } - - encodeAggregatedSignature(js: Aggregated) { - this.writeInt(maxEcodingInt); - this.writeInt(aggregatedSignaturePrefix); - this.write(Buffer.from(js.signature, 'hex')); - - if (js.signers.length === 0) { - this.write(Buffer.from([0x00])); - this.writeInt(0); - return; - } - - js.signers.forEach((m, i) => { - if (i > 0 && m <= js.signers[i - 1]) { - throw new Error('signers not sorted'); - } - if (m > maxEcodingInt) { - throw new Error('signer overflow'); - } - }); - - const max = js.signers[js.signers.length - 1]; - - if (((((max / 8) | 0) + 1) | 0) > js.signature.length * 2) { - // TODO... not check... - this.write(Buffer.from([0x01])); - this.writeInt(js.signature.length); - js.signers.forEach(m => this.writeInt(m)); - return; - } - - const masks = Buffer.alloc((((max / 8) | 0) + 1) | 0); - // eslint-disable-next-line no-return-assign - js.signers.forEach(m => (masks[(m / 8) | 0] ^= 1 << (m % 8 | 0))); - this.write(Buffer.from([0x00])); - this.writeInt(masks.length); - this.write(masks); - } - - encodeSignature(sm: { [key: number]: string }) { - const ss = Object.keys(sm) - .map((j, i) => ({ index: j, sig: sm[i] })) - .sort((a, b) => Number(a.index) - Number(b.index)); - - this.writeInt(ss.length); - ss.forEach(s => { - this.writeUint16(Number(s.index)); - this.write(Buffer.from(s.sig, 'hex')); - }); - } -} - -function getIntBytes(x: number) { - const bytes = []; - do { - bytes.unshift(x & 255); - x = (x / 2 ** 8) | 0; - } while (x !== 0); - return bytes; -} diff --git a/src/mixin/keystore.ts b/src/mixin/keystore.ts deleted file mode 100644 index c1925f8e..00000000 --- a/src/mixin/keystore.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { sign } from 'jsonwebtoken'; -import { v4 } from 'uuid'; -import { getEd25519Sign, toBuffer } from './sign'; -import { Keystore } from '../client'; - -export class KeystoreAuth { - keystore?: Keystore; - - constructor(keystore?: Keystore) { - this.keystore = keystore; - } - - signToken(signature: string, requestID: string): string { - const { user_id: client_id, session_id, private_key, scope } = this.keystore!; - const issuedAt = Math.floor(Date.now() / 1000); - if (!requestID) requestID = v4(); - const payload = { - uid: client_id, - sid: session_id, - iat: issuedAt, - exp: issuedAt + 3600, - jti: requestID, - sig: signature, - scp: scope || 'FULL', - }; - const _privateKey = toBuffer(private_key, 'base64'); - return _privateKey.length === 64 ? getEd25519Sign(payload, _privateKey) : sign(payload, private_key, { algorithm: 'RS512' }); - } -} diff --git a/src/mixin/mvm_registry.ts b/src/mixin/mvm_registry.ts deleted file mode 100644 index 591cf6b6..00000000 --- a/src/mixin/mvm_registry.ts +++ /dev/null @@ -1,368 +0,0 @@ -export const registryAddress = '0x65ccF8d1B92AfC6aF2915Cb61e72d93ACdD16556'; - -export const registryProcess = '86c58765-ec81-3ca4-a35b-875f35a0ad7d'; - -export const registryAbi = [ - { - inputs: [ - { - internalType: 'bytes', - name: 'raw', - type: 'bytes', - }, - { - internalType: 'uint128', - name: 'pid', - type: 'uint128', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'at', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'id', - type: 'uint256', - }, - ], - name: 'AssetCreated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - components: [ - { - internalType: 'uint64', - name: 'nonce', - type: 'uint64', - }, - { - internalType: 'address', - name: 'user', - type: 'address', - }, - { - internalType: 'address', - name: 'asset', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'extra', - type: 'bytes', - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64', - }, - { - internalType: 'uint256[2]', - name: 'sig', - type: 'uint256[2]', - }, - ], - indexed: false, - internalType: 'struct Registry.Event', - name: 'evt', - type: 'tuple', - }, - ], - name: 'MixinEvent', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'bytes', - name: '', - type: 'bytes', - }, - ], - name: 'MixinTransaction', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'at', - type: 'address', - }, - { - indexed: false, - internalType: 'bytes', - name: 'members', - type: 'bytes', - }, - ], - name: 'UserCreated', - type: 'event', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'GROUP', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'INBOUND', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'OUTBOUND', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PID', - outputs: [ - { - internalType: 'uint128', - name: '', - type: 'uint128', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'VERSION', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'assets', - outputs: [ - { - internalType: 'uint128', - name: '', - type: 'uint128', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'user', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'burn', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'asset', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'claim', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'contracts', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes', - name: 'raw', - type: 'bytes', - }, - ], - name: 'iterate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes', - name: 'raw', - type: 'bytes', - }, - ], - name: 'mixin', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'users', - outputs: [ - { - internalType: 'bytes', - name: '', - type: 'bytes', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'values', - outputs: [ - { - internalType: 'bytes', - name: '', - type: 'bytes', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_key', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'raw', - type: 'bytes', - }, - ], - name: 'writeValue', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, -]; diff --git a/src/mixin/sign.ts b/src/mixin/sign.ts deleted file mode 100644 index 8788153f..00000000 --- a/src/mixin/sign.ts +++ /dev/null @@ -1,736 +0,0 @@ -/* eslint-disable prefer-destructuring */ -import { randomBytes, createCipheriv, createHash } from 'crypto'; -import { pki, util, md } from 'node-forge'; -import { Uint64LE } from 'int64-buffer'; -import { Keystore } from '../client'; - -export const getSignPIN = (keystore: Keystore, pin?: any, iterator?: any) => { - const { session_id, private_key, pin_token, pin: _pin } = keystore; - pin = pin || _pin; - if (!pin) throw new Error('PIN is required'); - const blockSize = 16; - - const _privateKey: any = toBuffer(private_key, 'base64'); - const pinKey = _privateKey.length === 64 ? signEncryptEd25519PIN(pin_token, _privateKey) : signPin(pin_token, private_key, session_id); - - const time = new Uint64LE((Date.now() / 1000) | 0).toBuffer(); - if (iterator === undefined || iterator === '') { - iterator = Date.now() * 1000000; - } - iterator = new Uint64LE(iterator).toBuffer(); - pin = Buffer.from(pin, 'utf8'); - let buf: any = Buffer.concat([pin, Buffer.from(time), Buffer.from(iterator)]); - const padding = blockSize - (buf.length % blockSize); - const paddingArray = []; - for (let i = 0; i < padding; i++) { - paddingArray.push(padding); - } - buf = Buffer.concat([buf, Buffer.from(paddingArray)]); - const iv16 = randomBytes(16); - const cipher = createCipheriv('aes-256-cbc', pinKey, iv16); - cipher.setAutoPadding(false); - let encrypted_pin_buff = cipher.update(buf, 'utf-8'); - encrypted_pin_buff = Buffer.concat([iv16, encrypted_pin_buff]); - return Buffer.from(encrypted_pin_buff).toString('base64'); -}; - -export function toBuffer(content: any, encoding: any = 'utf8') { - if (typeof content === 'object') { - content = JSON.stringify(content); - } - return Buffer.from(content, encoding); -} - -export function getEd25519Sign(payload: any, privateKey: any) { - const header = toBuffer({ alg: 'EdDSA', typ: 'JWT' }).toString('base64'); - payload = base64url(toBuffer(payload)); - const result = [header, payload]; - const sign = base64url(Buffer.from(pki.ed25519.sign({ message: result.join('.'), encoding: 'utf8', privateKey }))); - result.push(sign); - return result.join('.'); -} - -export const signRequest = (method: string, url: string, body: object | string = ''): string => { - const _method = method.toUpperCase(); - - const _url = new URL(url); - - let _body = body; - if (typeof body === 'object') _body = JSON.stringify(body); - return md.sha256 - .create() - .update(_method + _url.pathname + _url.search + _body, 'utf8') - .digest() - .toHex(); -}; -function signEncryptEd25519PIN(pinToken: any, privateKey: string) { - pinToken = Buffer.from(pinToken, 'base64'); - return scalarMulti(privateKeyToCurve25519(privateKey), pinToken.slice(0, 32)); -} - -function signPin(pin_token: any, private_key: any, session_id: any) { - pin_token = Buffer.from(pin_token, 'base64'); - private_key = pki.privateKeyFromPem(private_key); - const pinKey = private_key.decrypt(pin_token, 'RSA-OAEP', { - md: md.sha256.create(), - label: session_id, - }); - return hexToBytes(util.binary.hex.encode(pinKey)); -} - -function hexToBytes(hex: any) { - const bytes = new Uint8Array(32); - for (let c = 0; c < hex.length; c += 2) { - bytes[c / 2] = parseInt(hex.substr(c, 2), 16); - } - return bytes; -} - -function scalarMulti(curvePriv: any, publicKey: any) { - curvePriv[0] &= 248; - curvePriv[31] &= 127; - curvePriv[31] |= 64; - const sharedKey = new Uint8Array(32); - cryptoScalarMulti(sharedKey, curvePriv, publicKey); - return sharedKey; -} - -export function base64url(buffer: Buffer) { - return Buffer.from(buffer).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); -} - -function privateKeyToCurve25519(privateKey: any) { - const seed = privateKey.slice(0, 32); - const sha512 = createHash('sha512'); - sha512.write(seed, 'binary'); - const digest = sha512.digest(); - digest[0] &= 248; - digest[31] &= 127; - digest[31] |= 64; - return digest.slice(0, 32); -} - -function cryptoScalarMulti(q: any, n: any, p: any) { - const z = new Uint8Array(32); - const x = new Float64Array(80); - let r; - let i; - const a = gf(); - const b = gf(); - const c = gf(); - const d = gf(); - const e = gf(); - const f = gf(); - for (i = 0; i < 31; i++) { - z[i] = n[i]; - } - z[31] = (n[31] & 127) | 64; - z[0] &= 248; - unpack25519(x, p); - for (i = 0; i < 16; i++) { - b[i] = x[i]; - d[i] = 0; - a[i] = 0; - c[i] = 0; - } - a[0] = 1; - d[0] = 1; - for (i = 254; i >= 0; --i) { - r = (z[i >>> 3] >>> (i & 7)) & 1; - sel25519(a, b, r); - sel25519(c, d, r); - A(e, a, c); - Z(a, a, c); - A(c, b, d); - Z(b, b, d); - S(d, e); - S(f, a); - M(a, c, a); - M(c, b, e); - A(e, a, c); - Z(a, a, c); - S(b, a); - Z(c, d, f); - M(a, c, gf([0xdb41, 1])); - A(a, a, d); - M(c, c, a); - M(a, d, f); - M(d, b, x); - S(b, e); - sel25519(a, b, r); - sel25519(c, d, r); - } - for (i = 0; i < 16; i++) { - x[i + 16] = a[i]; - x[i + 32] = c[i]; - x[i + 48] = b[i]; - x[i + 64] = d[i]; - } - const x32 = x.subarray(32); - const x16 = x.subarray(16); - inv25519(x32, x32); - M(x16, x16, x32); - pack25519(q, x16); - return 0; -} - -function gf(init: any = undefined) { - let i; - const r = new Float64Array(16); - if (init) { - for (i = 0; i < init.length; i++) { - r[i] = init[i]; - } - } - return r; -} - -function unpack25519(o: any, n: any) { - let i; - for (i = 0; i < 16; i++) { - o[i] = n[2 * i] + (n[2 * i + 1] << 8); - } - o[15] &= 0x7fff; -} - -function sel25519(p: any, q: any, b: any) { - let t; - const c = ~(b - 1); - for (let i = 0; i < 16; i++) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } -} - -function A(o: any, a: any, b: any) { - for (let i = 0; i < 16; i++) { - o[i] = a[i] + b[i]; - } -} - -function Z(o: any, a: any, b: any) { - for (let i = 0; i < 16; i++) { - o[i] = a[i] - b[i]; - } -} - -function M(o: any, a: any, b: any) { - let v; - let c; - let t0 = 0; - let t1 = 0; - let t2 = 0; - let t3 = 0; - let t4 = 0; - let t5 = 0; - let t6 = 0; - let t7 = 0; - let t8 = 0; - let t9 = 0; - let t10 = 0; - let t11 = 0; - let t12 = 0; - let t13 = 0; - let t14 = 0; - let t15 = 0; - let t16 = 0; - let t17 = 0; - let t18 = 0; - let t19 = 0; - let t20 = 0; - let t21 = 0; - let t22 = 0; - let t23 = 0; - let t24 = 0; - let t25 = 0; - let t26 = 0; - let t27 = 0; - let t28 = 0; - let t29 = 0; - let t30 = 0; - const b0 = b[0]; - const b1 = b[1]; - const b2 = b[2]; - const b3 = b[3]; - const b4 = b[4]; - const b5 = b[5]; - const b6 = b[6]; - const b7 = b[7]; - const b8 = b[8]; - const b9 = b[9]; - const b10 = b[10]; - const b11 = b[11]; - const b12 = b[12]; - const b13 = b[13]; - const b14 = b[14]; - const b15 = b[15]; - v = a[0]; - t0 += v * b0; - t1 += v * b1; - t2 += v * b2; - t3 += v * b3; - t4 += v * b4; - t5 += v * b5; - t6 += v * b6; - t7 += v * b7; - t8 += v * b8; - t9 += v * b9; - t10 += v * b10; - t11 += v * b11; - t12 += v * b12; - t13 += v * b13; - t14 += v * b14; - t15 += v * b15; - v = a[1]; - t1 += v * b0; - t2 += v * b1; - t3 += v * b2; - t4 += v * b3; - t5 += v * b4; - t6 += v * b5; - t7 += v * b6; - t8 += v * b7; - t9 += v * b8; - t10 += v * b9; - t11 += v * b10; - t12 += v * b11; - t13 += v * b12; - t14 += v * b13; - t15 += v * b14; - t16 += v * b15; - v = a[2]; - t2 += v * b0; - t3 += v * b1; - t4 += v * b2; - t5 += v * b3; - t6 += v * b4; - t7 += v * b5; - t8 += v * b6; - t9 += v * b7; - t10 += v * b8; - t11 += v * b9; - t12 += v * b10; - t13 += v * b11; - t14 += v * b12; - t15 += v * b13; - t16 += v * b14; - t17 += v * b15; - v = a[3]; - t3 += v * b0; - t4 += v * b1; - t5 += v * b2; - t6 += v * b3; - t7 += v * b4; - t8 += v * b5; - t9 += v * b6; - t10 += v * b7; - t11 += v * b8; - t12 += v * b9; - t13 += v * b10; - t14 += v * b11; - t15 += v * b12; - t16 += v * b13; - t17 += v * b14; - t18 += v * b15; - v = a[4]; - t4 += v * b0; - t5 += v * b1; - t6 += v * b2; - t7 += v * b3; - t8 += v * b4; - t9 += v * b5; - t10 += v * b6; - t11 += v * b7; - t12 += v * b8; - t13 += v * b9; - t14 += v * b10; - t15 += v * b11; - t16 += v * b12; - t17 += v * b13; - t18 += v * b14; - t19 += v * b15; - v = a[5]; - t5 += v * b0; - t6 += v * b1; - t7 += v * b2; - t8 += v * b3; - t9 += v * b4; - t10 += v * b5; - t11 += v * b6; - t12 += v * b7; - t13 += v * b8; - t14 += v * b9; - t15 += v * b10; - t16 += v * b11; - t17 += v * b12; - t18 += v * b13; - t19 += v * b14; - t20 += v * b15; - v = a[6]; - t6 += v * b0; - t7 += v * b1; - t8 += v * b2; - t9 += v * b3; - t10 += v * b4; - t11 += v * b5; - t12 += v * b6; - t13 += v * b7; - t14 += v * b8; - t15 += v * b9; - t16 += v * b10; - t17 += v * b11; - t18 += v * b12; - t19 += v * b13; - t20 += v * b14; - t21 += v * b15; - v = a[7]; - t7 += v * b0; - t8 += v * b1; - t9 += v * b2; - t10 += v * b3; - t11 += v * b4; - t12 += v * b5; - t13 += v * b6; - t14 += v * b7; - t15 += v * b8; - t16 += v * b9; - t17 += v * b10; - t18 += v * b11; - t19 += v * b12; - t20 += v * b13; - t21 += v * b14; - t22 += v * b15; - v = a[8]; - t8 += v * b0; - t9 += v * b1; - t10 += v * b2; - t11 += v * b3; - t12 += v * b4; - t13 += v * b5; - t14 += v * b6; - t15 += v * b7; - t16 += v * b8; - t17 += v * b9; - t18 += v * b10; - t19 += v * b11; - t20 += v * b12; - t21 += v * b13; - t22 += v * b14; - t23 += v * b15; - v = a[9]; - t9 += v * b0; - t10 += v * b1; - t11 += v * b2; - t12 += v * b3; - t13 += v * b4; - t14 += v * b5; - t15 += v * b6; - t16 += v * b7; - t17 += v * b8; - t18 += v * b9; - t19 += v * b10; - t20 += v * b11; - t21 += v * b12; - t22 += v * b13; - t23 += v * b14; - t24 += v * b15; - v = a[10]; - t10 += v * b0; - t11 += v * b1; - t12 += v * b2; - t13 += v * b3; - t14 += v * b4; - t15 += v * b5; - t16 += v * b6; - t17 += v * b7; - t18 += v * b8; - t19 += v * b9; - t20 += v * b10; - t21 += v * b11; - t22 += v * b12; - t23 += v * b13; - t24 += v * b14; - t25 += v * b15; - v = a[11]; - t11 += v * b0; - t12 += v * b1; - t13 += v * b2; - t14 += v * b3; - t15 += v * b4; - t16 += v * b5; - t17 += v * b6; - t18 += v * b7; - t19 += v * b8; - t20 += v * b9; - t21 += v * b10; - t22 += v * b11; - t23 += v * b12; - t24 += v * b13; - t25 += v * b14; - t26 += v * b15; - v = a[12]; - t12 += v * b0; - t13 += v * b1; - t14 += v * b2; - t15 += v * b3; - t16 += v * b4; - t17 += v * b5; - t18 += v * b6; - t19 += v * b7; - t20 += v * b8; - t21 += v * b9; - t22 += v * b10; - t23 += v * b11; - t24 += v * b12; - t25 += v * b13; - t26 += v * b14; - t27 += v * b15; - v = a[13]; - t13 += v * b0; - t14 += v * b1; - t15 += v * b2; - t16 += v * b3; - t17 += v * b4; - t18 += v * b5; - t19 += v * b6; - t20 += v * b7; - t21 += v * b8; - t22 += v * b9; - t23 += v * b10; - t24 += v * b11; - t25 += v * b12; - t26 += v * b13; - t27 += v * b14; - t28 += v * b15; - v = a[14]; - t14 += v * b0; - t15 += v * b1; - t16 += v * b2; - t17 += v * b3; - t18 += v * b4; - t19 += v * b5; - t20 += v * b6; - t21 += v * b7; - t22 += v * b8; - t23 += v * b9; - t24 += v * b10; - t25 += v * b11; - t26 += v * b12; - t27 += v * b13; - t28 += v * b14; - t29 += v * b15; - v = a[15]; - t15 += v * b0; - t16 += v * b1; - t17 += v * b2; - t18 += v * b3; - t19 += v * b4; - t20 += v * b5; - t21 += v * b6; - t22 += v * b7; - t23 += v * b8; - t24 += v * b9; - t25 += v * b10; - t26 += v * b11; - t27 += v * b12; - t28 += v * b13; - t29 += v * b14; - t30 += v * b15; - t0 += 38 * t16; - t1 += 38 * t17; - t2 += 38 * t18; - t3 += 38 * t19; - t4 += 38 * t20; - t5 += 38 * t21; - t6 += 38 * t22; - t7 += 38 * t23; - t8 += 38 * t24; - t9 += 38 * t25; - t10 += 38 * t26; - t11 += 38 * t27; - t12 += 38 * t28; - t13 += 38 * t29; - t14 += 38 * t30; - // t15 left as is - // first car - c = 1; - v = t0 + c + 65535; - c = Math.floor(v / 65536); - t0 = v - c * 65536; - v = t1 + c + 65535; - c = Math.floor(v / 65536); - t1 = v - c * 65536; - v = t2 + c + 65535; - c = Math.floor(v / 65536); - t2 = v - c * 65536; - v = t3 + c + 65535; - c = Math.floor(v / 65536); - t3 = v - c * 65536; - v = t4 + c + 65535; - c = Math.floor(v / 65536); - t4 = v - c * 65536; - v = t5 + c + 65535; - c = Math.floor(v / 65536); - t5 = v - c * 65536; - v = t6 + c + 65535; - c = Math.floor(v / 65536); - t6 = v - c * 65536; - v = t7 + c + 65535; - c = Math.floor(v / 65536); - t7 = v - c * 65536; - v = t8 + c + 65535; - c = Math.floor(v / 65536); - t8 = v - c * 65536; - v = t9 + c + 65535; - c = Math.floor(v / 65536); - t9 = v - c * 65536; - v = t10 + c + 65535; - c = Math.floor(v / 65536); - t10 = v - c * 65536; - v = t11 + c + 65535; - c = Math.floor(v / 65536); - t11 = v - c * 65536; - v = t12 + c + 65535; - c = Math.floor(v / 65536); - t12 = v - c * 65536; - v = t13 + c + 65535; - c = Math.floor(v / 65536); - t13 = v - c * 65536; - v = t14 + c + 65535; - c = Math.floor(v / 65536); - t14 = v - c * 65536; - v = t15 + c + 65535; - c = Math.floor(v / 65536); - t15 = v - c * 65536; - t0 += c - 1 + 37 * (c - 1); - // second car - c = 1; - v = t0 + c + 65535; - c = Math.floor(v / 65536); - t0 = v - c * 65536; - v = t1 + c + 65535; - c = Math.floor(v / 65536); - t1 = v - c * 65536; - v = t2 + c + 65535; - c = Math.floor(v / 65536); - t2 = v - c * 65536; - v = t3 + c + 65535; - c = Math.floor(v / 65536); - t3 = v - c * 65536; - v = t4 + c + 65535; - c = Math.floor(v / 65536); - t4 = v - c * 65536; - v = t5 + c + 65535; - c = Math.floor(v / 65536); - t5 = v - c * 65536; - v = t6 + c + 65535; - c = Math.floor(v / 65536); - t6 = v - c * 65536; - v = t7 + c + 65535; - c = Math.floor(v / 65536); - t7 = v - c * 65536; - v = t8 + c + 65535; - c = Math.floor(v / 65536); - t8 = v - c * 65536; - v = t9 + c + 65535; - c = Math.floor(v / 65536); - t9 = v - c * 65536; - v = t10 + c + 65535; - c = Math.floor(v / 65536); - t10 = v - c * 65536; - v = t11 + c + 65535; - c = Math.floor(v / 65536); - t11 = v - c * 65536; - v = t12 + c + 65535; - c = Math.floor(v / 65536); - t12 = v - c * 65536; - v = t13 + c + 65535; - c = Math.floor(v / 65536); - t13 = v - c * 65536; - v = t14 + c + 65535; - c = Math.floor(v / 65536); - t14 = v - c * 65536; - v = t15 + c + 65535; - c = Math.floor(v / 65536); - t15 = v - c * 65536; - t0 += c - 1 + 37 * (c - 1); - o[0] = t0; - o[1] = t1; - o[2] = t2; - o[3] = t3; - o[4] = t4; - o[5] = t5; - o[6] = t6; - o[7] = t7; - o[8] = t8; - o[9] = t9; - o[10] = t10; - o[11] = t11; - o[12] = t12; - o[13] = t13; - o[14] = t14; - o[15] = t15; -} - -function S(o: any, a: any) { - M(o, a, a); -} - -function inv25519(o: any, i: any) { - const c = gf(); - let a; - for (a = 0; a < 16; a++) { - c[a] = i[a]; - } - for (a = 253; a >= 0; a--) { - S(c, c); - if (a !== 2 && a !== 4) { - M(c, c, i); - } - } - for (a = 0; a < 16; a++) { - o[a] = c[a]; - } -} - -function pack25519(o: any, n: any) { - let i; - let j; - let b; - const m = gf(); - const t = gf(); - for (i = 0; i < 16; i++) { - t[i] = n[i]; - } - car25519(t); - car25519(t); - car25519(t); - for (j = 0; j < 2; j++) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; i++) { - m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); - m[i - 1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); - b = (m[15] >> 16) & 1; - m[14] &= 0xffff; - sel25519(t, m, 1 - b); - } - for (i = 0; i < 16; i++) { - o[2 * i] = t[i] & 0xff; - o[2 * i + 1] = t[i] >> 8; - } -} - -function car25519(o: any) { - let i; - let v; - let c = 1; - for (i = 0; i < 16; i++) { - v = o[i] + c + 65535; - c = Math.floor(v / 65536); - o[i] = v - c * 65536; - } - o[0] += c - 1 + 37 * (c - 1); -} diff --git a/src/mixin/tools.ts b/src/mixin/tools.ts deleted file mode 100644 index 76d66fb2..00000000 --- a/src/mixin/tools.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function toBuffer(content: any, encoding: any = 'utf8') { - if (typeof content === 'object') { - content = JSON.stringify(content); - } - return Buffer.from(content, encoding); -} diff --git a/src/mvm/bridge/client.ts b/src/mvm/bridge/client.ts index c9d000bd..9e17c8ec 100644 --- a/src/mvm/bridge/client.ts +++ b/src/mvm/bridge/client.ts @@ -1,5 +1,5 @@ import axios, { AxiosResponse } from 'axios'; -import { GenerateExtraRequest, RegisteredUser, RegisterRequest } from 'mvm/types/bridge'; +import { GenerateExtraRequest, RegisteredUser, RegisterRequest } from '../types/bridge'; import ResponseError from '../../client/error'; export const BridgeApi = (uri: string = 'https://bridge.mvm.dev') => { diff --git a/src/mvm/encoder.ts b/src/mvm/encoder.ts index 1a024caa..dc369e28 100644 --- a/src/mvm/encoder.ts +++ b/src/mvm/encoder.ts @@ -1,4 +1,4 @@ -import BN from 'bn.js'; +import utils from 'ethers/lib/utils'; import { parse } from 'uuid'; import { Aggregated, Input, Output } from './types'; @@ -6,14 +6,14 @@ const MaximumEncodingInt = 0xffff; const AggregatedSignaturePrefix = 0xff01; -const magic = Buffer.from([0x77, 0x77]); +export const magic = Buffer.from([0x77, 0x77]); const empty = Buffer.from([0x00, 0x00]); export const integerToBytes = (x: number) => { const bytes = []; let i = x; do { - bytes.unshift(x & 255); + bytes.unshift(i & 255); i = (i / 2 ** 8) | 0; } while (i !== 0); return bytes; @@ -130,7 +130,7 @@ export class Encoder { const o = output; if (!o.type) o.type = 0; this.write(Buffer.from([0x00, o.type])); - this.writeInteger(new BN(1e8).mul(new BN(o.amount!)).toNumber()); + this.writeInteger(utils.parseUnits(Number(o.amount!).toFixed(8), 8).toNumber()); this.writeInt(o.keys!.length); o.keys!.forEach(k => this.write(Buffer.from(k, 'hex'))); @@ -140,7 +140,6 @@ export class Encoder { const s = Buffer.from(o.script!, 'hex'); this.writeInt(s.byteLength); this.write(s); - const w = o.withdrawal; if (typeof w === 'undefined') { this.write(empty); diff --git a/src/mvm/index.ts b/src/mvm/index.ts index 39bba17f..42ed55a1 100644 --- a/src/mvm/index.ts +++ b/src/mvm/index.ts @@ -5,7 +5,7 @@ export * from './constant'; export * from './utils'; export { MVMApi } from './client'; -export { Encoder } from './encoder'; +export { Encoder, magic } from './encoder'; export { Decoder } from './decoder'; export { Registry } from './registry'; export { StorageContract } from './storage'; diff --git a/yarn.lock b/yarn.lock index 0639e032..af8287f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1895,13 +1895,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - "@types/eslint-plugin-prettier@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#451b5e1e5f148a38dc41e9c5b61d45cd2e97af2c" @@ -1992,13 +1985,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/jsonwebtoken@^8.5.8": - version "8.5.9" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" - integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== - dependencies: - "@types/node" "*" - "@types/lodash.merge@^4.6.7": version "4.6.7" resolved "https://registry.yarnpkg.com/@types/lodash.merge/-/lodash.merge-4.6.7.tgz#0af6555dd8bc6568ef73e5e0d820a027362946b1" @@ -2770,11 +2756,6 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-hrtime@^1.1.8: - version "1.1.8" - resolved "https://registry.npmmirror.com/browser-hrtime/-/browser-hrtime-1.1.8.tgz#6a17cc212c19bdaf60faa499b7ae10a0dfb65d5e" - integrity sha512-kzXheikaJsBtzUBlyVtPIY5r0soQePzjwVwT4IlDpU2RvfB5Py52gpU98M77rgqMCheoSSZvrcrdj3t6cZ3suA== - browser-process-hrtime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" @@ -2811,11 +2792,6 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== - buffer-from@1.x, buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -3324,13 +3300,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - electron-to-chromium@^1.4.164: version "1.4.168" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.168.tgz#8f6bda320a434ac963850d18e41d83220973cbdd" @@ -5680,22 +5649,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - jsprim@^1.2.2: version "1.4.2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" @@ -5719,23 +5672,6 @@ jssha@^3.2.0: array-includes "^3.1.5" object.assign "^4.1.2" -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -5835,36 +5771,6 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== - lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -5875,11 +5781,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -7088,9 +6989,9 @@ scrypt-js@3.0.1: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0: version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + resolved "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@6.x, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: