From 6485018c428271f41f0616f2720f042c47edff90 Mon Sep 17 00:00:00 2001 From: James Zheng Date: Thu, 26 May 2022 13:57:39 -0700 Subject: [PATCH 01/12] init commit --- client-sdk/ts-web/package.json | 1 + client-sdk/ts-web/rt/package.json | 4 +++ client-sdk/ts-web/rt/src/callformat.ts | 45 +++++++++++++++++++++++++ client-sdk/ts-web/rt/src/mrae.ts | 26 ++++++++++++++ client-sdk/ts-web/rt/src/transaction.ts | 9 ----- client-sdk/ts-web/rt/src/types.ts | 10 ++++++ 6 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 client-sdk/ts-web/rt/src/mrae.ts diff --git a/client-sdk/ts-web/package.json b/client-sdk/ts-web/package.json index cbc6046d22..95bb942886 100644 --- a/client-sdk/ts-web/package.json +++ b/client-sdk/ts-web/package.json @@ -1,4 +1,5 @@ { + "private": true, "workspaces": [ "core", "ext-utils", diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 12e9d84608..0895da6186 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -16,6 +16,10 @@ "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", "elliptic": "^6.5.3", + "cborg": "^1.9.3", + "@noble/ed25519": "^1.6.0", + "js-sha512": "^0.8.0", + "deoxysii": "^0.0.2", "sha3": "^2.1.4" }, "devDependencies": { diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 2ad2146202..38d9e4b84a 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -1,4 +1,49 @@ +import * as ed from '@noble/ed25519'; +import * as types from './types'; +import * as mrae from './mrae'; +import * as cborg from 'cborg'; + +var deoxysii = require('deoxysii'); + /** * Call data key pair ID domain separation context base. */ export const CALL_DATA_KEY_PAIR_ID_CONTEXT_BASE = 'oasis-runtime-sdk/private: tx'; + +/** + * EncodeConfig is call encoding configuration. + */ +export interface EncodeConfig { + /** + * publicKey is an optional runtime's call data public key to use for encrypted call formats. + */ + publicKey?: types.KeyManagerSignedPublicKey; +} + +export interface metaEncryptedX25519DeoxysII { + sk: Uint8Array; + pk: Uint8Array; +} + +/** + * encodeCall encodes a call based on its configured call format. + * It returns the encoded call and any metadata needed to successfully decode the result. + */ +export async function encodeCall(call: types.Call, cf: types.CallFormat, cfg?: EncodeConfig): Promise<[types.Call, metaEncryptedX25519DeoxysII?]> { + switch (cf) { + case types.CALLFORMAT_PLAIN: + return [call, undefined]; + case types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: + if (cfg && cfg.publicKey) { + const privateKey = ed.utils.randomPrivateKey(); + const publicKey = await ed.getPublicKey(privateKey); + const nonce = new Uint8Array(deoxysii.NonceSize); + crypto.getRandomValues(nonce); + const rawCall = cborg.encode(call) as Uint8Array; + const sealedCall = mrae.boxSeal(nonce, rawCall, null, cfg.publicKey, privateKey) + } else { + throw new Error('callformat: runtime call data public key not set'); + } + + } +} diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts new file mode 100644 index 0000000000..1777fe960d --- /dev/null +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -0,0 +1,26 @@ + +import * as ed from '@noble/ed25519'; +import {sha512_256} from 'js-sha512'; +var oasis = require('@oasisprotocol/client'); +var deoxysii = require('deoxysii'); + +const BoxKDFTweak = "MRAE_Box_Deoxys-II-256-128"; + +function deriveSymmetricKey(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { + const pmk = ed.curve25519.scalarMult(oasis.misc.toHex(privateKey), oasis.misc.toHex(publicKey)); + var kdf = sha512_256.hmac.create(BoxKDFTweak); + kdf.update(pmk); + return oasis.misc.fromHex(kdf.hex()); +} + +export function boxSeal(nonce: Uint8Array, plainText: Uint8Array, associateData: Uint8Array, privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { + const sharedKey = deriveSymmetricKey(privateKey, publicKey); + var aead = new deoxysii.AEAD(sharedKey); + return aead.encrypt(nonce, plainText, associateData); +} + +export function boxOpen(nonce: Uint8Array, ciperText: Uint8Array, associateData: Uint8Array, privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { + const sharedKey = deriveSymmetricKey(privateKey, publicKey); + var aead = new deoxysii.AEAD(sharedKey); + return aead.decrypt(nonce, ciperText, associateData); +} diff --git a/client-sdk/ts-web/rt/src/transaction.ts b/client-sdk/ts-web/rt/src/transaction.ts index 4c9926b065..78663d83a9 100644 --- a/client-sdk/ts-web/rt/src/transaction.ts +++ b/client-sdk/ts-web/rt/src/transaction.ts @@ -13,15 +13,6 @@ export const SIGNATURE_CONTEXT_BASE = 'oasis-runtime-sdk/tx: v0'; */ export const LATEST_TRANSACTION_VERSION = 1; -/** - * Plain text call data. - */ -export const CALLFORMAT_PLAIN = 0; -/** - * Encrypted call data using X25519 for key exchange and Deoxys-II for symmetric encryption. - */ -export const CALLFORMAT_ENCRYPTED_X25519DEOXYSII = 1; - /** * A union of signer types from different algorithms. * Because they all tend to look the same (e.g. have a `sign` method), code diff --git a/client-sdk/ts-web/rt/src/types.ts b/client-sdk/ts-web/rt/src/types.ts index 5062528fda..c36c64c843 100644 --- a/client-sdk/ts-web/rt/src/types.ts +++ b/client-sdk/ts-web/rt/src/types.ts @@ -231,6 +231,16 @@ export interface AuthProof { */ export type BaseUnits = [amount: Uint8Array, denomination: Uint8Array]; +/** + * Plain text call data. + */ +export const CALLFORMAT_PLAIN = 0; + +/** + * Encrypted call data using X25519 for key exchange and Deoxys-II for symmetric encryption. + */ +export const CALLFORMAT_ENCRYPTED_X25519DEOXYSII = 1; + /** * Format used for encoding the call (and output) information. */ From 8af546db15a645792cd69e088d92007c5310471a Mon Sep 17 00:00:00 2001 From: James Zheng Date: Tue, 31 May 2022 09:07:00 -0700 Subject: [PATCH 02/12] add unittest for mrae functions --- client-sdk/ts-web/package-lock.json | 2136 +++++++++++++++++++++--- client-sdk/ts-web/rt/package.json | 1 - client-sdk/ts-web/rt/src/callformat.ts | 51 +- client-sdk/ts-web/rt/src/index.ts | 1 + client-sdk/ts-web/rt/src/mrae.ts | 29 +- client-sdk/ts-web/rt/test/mrae.test.ts | 16 + 6 files changed, 2023 insertions(+), 211 deletions(-) create mode 100644 client-sdk/ts-web/rt/test/mrae.test.ts diff --git a/client-sdk/ts-web/package-lock.json b/client-sdk/ts-web/package-lock.json index 77c2294db8..ad238e1140 100644 --- a/client-sdk/ts-web/package-lock.json +++ b/client-sdk/ts-web/package-lock.json @@ -1892,6 +1892,39 @@ "peerDependencies": { "acorn": "^8" } + "node_modules/@ledgerhq/logs": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.10.0.tgz", + "integrity": "sha512-lLseUPEhSFUXYTKj6q7s2O3s2vW2ebgA11vMAlKodXGf5AFw4zUoEbTz9CoFOC9jS6xY4Qr8BmRnxP/odT4Uuw==" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", + "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", + "dev": true + }, + "node_modules/@noble/ed25519": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.0.tgz", + "integrity": "sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@oasisprotocol/client": { + "resolved": "core", + "link": true + }, + "node_modules/@oasisprotocol/client-ext-utils": { + "resolved": "ext-utils", + "link": true + }, + "node_modules/@oasisprotocol/client-rt": { + "resolved": "rt", + "link": true }, "node_modules/acorn-jsx": { "version": "5.3.2", @@ -3040,10 +3073,25 @@ "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", "dev": true }, +<<<<<<< HEAD "node_modules/cypress/node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", +======= + "node_modules/bsaes": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/bsaes/-/bsaes-0.0.2.tgz", + "integrity": "sha512-iVxJFMOvCUG85sX2UVpZ9IgvH6Jjc5xpd/W8pALvFE7zfCqHkV7hW3M2XZtpg9biPS0K4Eka96bbNNgLohcpgQ==", + "dependencies": { + "uint32": "^0.2.1" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", +>>>>>>> add unittest for mrae functions "dev": true, "funding": [ { @@ -3695,6 +3743,7 @@ "node": ">=0.10" } }, +<<<<<<< HEAD "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -3702,6 +3751,22 @@ "dependencies": { "estraverse": "^5.2.0" }, +======= + "node_modules/deoxysii": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/deoxysii/-/deoxysii-0.0.2.tgz", + "integrity": "sha512-mMob/2wDZBatPC48g188hFt5xxrbfYMl9L+XQGOZuHPU4ScCHpAKkbZiAU1yg/kROj6nPKZp5eItuNI3LdU7vA==", + "dependencies": { + "bsaes": "0.0.2", + "uint32": "^0.2.1" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, +>>>>>>> add unittest for mrae functions "engines": { "node": ">=4.0" } @@ -7142,10 +7207,22 @@ "node": ">=8.10.0" } }, +<<<<<<< HEAD "node_modules/rechoir": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", +======= + "node_modules/uint32": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/uint32/-/uint32-0.2.1.tgz", + "integrity": "sha1-5hjYAtf//Si3CPzOzHMVYIusR/I=" + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", +>>>>>>> add unittest for mrae functions "dev": true, "dependencies": { "resolve": "^1.9.0" @@ -7635,11 +7712,20 @@ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "dependencies": { +<<<<<<< HEAD "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" +======= + "@noble/ed25519": "^1.6.0", + "@oasisprotocol/client": "^0.1.0-alpha9", + "deoxysii": "^0.0.2", + "elliptic": "^6.5.3", + "js-sha512": "^0.8.0", + "sha3": "^2.1.4" +>>>>>>> add unittest for mrae functions }, "engines": { "node": ">=6.0.0" @@ -9761,6 +9847,11 @@ "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", "dev": true }, + "@noble/ed25519": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.0.tgz", + "integrity": "sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q==" + }, "@oasisprotocol/client": { "version": "file:core", "requires": { @@ -9840,206 +9931,1835 @@ "integrity": "sha512-ITfF6JJIl9zbEi2k6NmhNE/BiDqfsI/ceqfvdaWaPbcrCpYyyRq4KtDQIWh6vQUru6SqwppODiom/Zhid+np6A==", "dev": true, "requires": { +<<<<<<< HEAD "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" +======= + "@jest/console": "^28.1.0", + "@jest/reporters": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.0.2", + "jest-config": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-resolve-dependencies": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "jest-watcher": "^28.1.0", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" } - } - } - }, - "@oasisprotocol/client-signer-ledger": { - "version": "file:signer-ledger", - "requires": { - "@ledgerhq/hw-transport-webusb": "^6.27.1", - "@oasisprotocol/client": "^0.1.1-alpha.1", - "@oasisprotocol/ledger": "^0.2.3", - "@types/w3c-web-usb": "^1.0.6", - "buffer": "^6.0.3", - "prettier": "^2.7.1", - "process": "^0.11.10", - "stream-browserify": "^3.0.0", - "typescript": "^4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" - } - }, - "@oasisprotocol/ledger": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@oasisprotocol/ledger/-/ledger-0.2.3.tgz", - "integrity": "sha512-OxPhwnz0SP8tU9zeRzrppfOxgvylOGllY0+Sj229WZbuLQeFPxgnAra0llW3u8lPT5FcoaMLLsgqRVI2QL9MRw==", - "requires": { - "@babel/eslint-parser": "^7.17.0", - "@babel/runtime": "^7.9.2", - "@ledgerhq/hw-transport": "^6.1.0", - "bech32": "^2.0.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@sinclair/typebox": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", - "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "dev": true, - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, + }, + "@jest/environment": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", + "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0" + } + }, + "@jest/fake-timers": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", + "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@sinonjs/fake-timers": "^9.1.1", + "@types/node": "*", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "@jest/globals": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", + "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/types": "^28.1.0" + } + }, + "@jest/reporters": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", + "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.0" + } + }, + "@jest/source-map": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", + "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", + "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + } + }, + "@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "babel-jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", + "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "dev": true, + "requires": { + "@jest/transform": "^28.1.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.0.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", + "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", + "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^28.0.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "diff-sequences": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", + "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", + "dev": true + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", + "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "import-local": "^3.0.2", + "jest-cli": "^28.1.0" + } + }, + "jest-changed-files": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", + "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", + "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-cli": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", + "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", + "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.0", + "@jest/types": "^28.1.0", + "babel-jest": "^28.1.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.0", + "jest-environment-node": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", + "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^28.0.2", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-docblock": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", + "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", + "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0" + } + }, + "jest-environment-node": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", + "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-leak-detector": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", + "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-matcher-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", + "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", + "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*" + } + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true + }, + "jest-resolve": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", + "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", + "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "dev": true, + "requires": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.0" + } + }, + "jest-runner": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", + "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/environment": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.0.2", + "jest-environment-node": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-leak-detector": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-resolve": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-util": "^28.1.0", + "jest-watcher": "^28.1.0", + "jest-worker": "^28.1.0", + "source-map-support": "0.5.13", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", + "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/globals": "^28.1.0", + "@jest/source-map": "^28.0.2", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", + "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.0", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", + "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.0" + } + }, + "jest-watcher": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", + "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ts-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.2.tgz", + "integrity": "sha512-IOZMb3D0gx6IHO9ywPgiQxJ3Zl4ECylEFwoVpENB55aTn5sdO0Ptyx/7noNBxAaUff708RqQL4XBNxxOVjY0vQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^20.x" + }, + "dependencies": { + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "v8-to-istanbul": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", + "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true + } + } + }, + "@oasisprotocol/client-ext-utils": { + "version": "file:ext-utils", + "requires": { + "@oasisprotocol/client": "^0.1.0-alpha9", + "@oasisprotocol/client-rt": "^0.2.0-alpha10", + "buffer": "^6.0.3", + "cypress": "^9.6.1", + "prettier": "^2.6.2", + "process": "^0.11.10", + "stream-browserify": "^3.0.0", + "typescript": "^4.6.4", + "webpack": "^5.72.1", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.9.0" + } + }, + "@oasisprotocol/client-rt": { + "version": "file:rt", + "requires": { + "@noble/ed25519": "^1.6.0", + "@oasisprotocol/client": "^0.1.0-alpha9", + "@types/elliptic": "^6.4.14", + "@types/jest": "^27.5.1", + "buffer": "^6.0.3", + "cypress": "^9.6.1", + "deoxysii": "^0.0.2", + "elliptic": "^6.5.3", + "jest": "^28.1.0", + "js-sha512": "^0.8.0", + "prettier": "^2.6.2", + "process": "^0.11.10", + "sha3": "^2.1.4", + "stream-browserify": "^3.0.0", + "ts-jest": "^28.0.2", + "typescript": "^4.6.4", + "webpack": "^5.72.1", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.9.0" + }, + "dependencies": { + "@jest/console": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", + "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", + "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/reporters": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.0.2", + "jest-config": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-resolve-dependencies": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "jest-watcher": "^28.1.0", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", + "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0" + } + }, + "@jest/fake-timers": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", + "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@sinonjs/fake-timers": "^9.1.1", + "@types/node": "*", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "@jest/globals": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", + "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/types": "^28.1.0" + } + }, + "@jest/reporters": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", + "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.0" + } + }, + "@jest/source-map": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", + "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", + "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + } + }, + "@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "babel-jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", + "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "dev": true, + "requires": { + "@jest/transform": "^28.1.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.0.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", + "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", + "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^28.0.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "diff-sequences": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", + "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", + "dev": true + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", + "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "import-local": "^3.0.2", + "jest-cli": "^28.1.0" + } + }, + "jest-changed-files": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", + "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", + "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-cli": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", + "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", + "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.0", + "@jest/types": "^28.1.0", + "babel-jest": "^28.1.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.0", + "jest-environment-node": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", + "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^28.0.2", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-docblock": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", + "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", + "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0" + } + }, + "jest-environment-node": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", + "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-leak-detector": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", + "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-matcher-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", + "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", + "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*" + } + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true + }, + "jest-resolve": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", + "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", + "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "dev": true, + "requires": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.0" + } + }, + "jest-runner": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", + "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/environment": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.0.2", + "jest-environment-node": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-leak-detector": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-resolve": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-util": "^28.1.0", + "jest-watcher": "^28.1.0", + "jest-worker": "^28.1.0", + "source-map-support": "0.5.13", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", + "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/globals": "^28.1.0", + "@jest/source-map": "^28.0.2", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", + "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.0", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", + "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.0" + } + }, + "jest-watcher": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", + "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ts-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.2.tgz", + "integrity": "sha512-IOZMb3D0gx6IHO9ywPgiQxJ3Zl4ECylEFwoVpENB55aTn5sdO0Ptyx/7noNBxAaUff708RqQL4XBNxxOVjY0vQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^20.x" + }, + "dependencies": { + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "v8-to-istanbul": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", + "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" +>>>>>>> add unittest for mrae functions + } + } + } + }, + "@oasisprotocol/client-signer-ledger": { + "version": "file:signer-ledger", + "requires": { + "@ledgerhq/hw-transport-webusb": "^6.27.1", + "@oasisprotocol/client": "^0.1.1-alpha.1", + "@oasisprotocol/ledger": "^0.2.3", + "@types/w3c-web-usb": "^1.0.6", + "buffer": "^6.0.3", + "prettier": "^2.7.1", + "process": "^0.11.10", + "stream-browserify": "^3.0.0", + "typescript": "^4.7.4", + "webpack": "^5.73.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.9.2" + } + }, + "@oasisprotocol/ledger": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@oasisprotocol/ledger/-/ledger-0.2.3.tgz", + "integrity": "sha512-OxPhwnz0SP8tU9zeRzrppfOxgvylOGllY0+Sj229WZbuLQeFPxgnAra0llW3u8lPT5FcoaMLLsgqRVI2QL9MRw==", + "requires": { + "@babel/eslint-parser": "^7.17.0", + "@babel/runtime": "^7.9.2", + "@ledgerhq/hw-transport": "^6.1.0", + "bech32": "^2.0.0" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@sinclair/typebox": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", + "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", + "dev": true + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", + "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, "@types/elliptic": { "version": "6.4.14", "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.14.tgz", @@ -10907,6 +12627,14 @@ "fast-json-stable-stringify": "2.x" } }, + "bsaes": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/bsaes/-/bsaes-0.0.2.tgz", + "integrity": "sha512-iVxJFMOvCUG85sX2UVpZ9IgvH6Jjc5xpd/W8pALvFE7zfCqHkV7hW3M2XZtpg9biPS0K4Eka96bbNNgLohcpgQ==", + "requires": { + "uint32": "^0.2.1" + } + }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -11467,6 +13195,15 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "deoxysii": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/deoxysii/-/deoxysii-0.0.2.tgz", + "integrity": "sha512-mMob/2wDZBatPC48g188hFt5xxrbfYMl9L+XQGOZuHPU4ScCHpAKkbZiAU1yg/kROj6nPKZp5eItuNI3LdU7vA==", + "requires": { + "bsaes": "0.0.2", + "uint32": "^0.2.1" + } + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -15262,6 +16999,11 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, + "uint32": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/uint32/-/uint32-0.2.1.tgz", + "integrity": "sha1-5hjYAtf//Si3CPzOzHMVYIusR/I=" + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 0895da6186..8c62236d15 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -16,7 +16,6 @@ "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", "elliptic": "^6.5.3", - "cborg": "^1.9.3", "@noble/ed25519": "^1.6.0", "js-sha512": "^0.8.0", "deoxysii": "^0.0.2", diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 38d9e4b84a..25ead25eb7 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -1,7 +1,8 @@ +import * as oasis from '@oasisprotocol/client'; + import * as ed from '@noble/ed25519'; import * as types from './types'; import * as mrae from './mrae'; -import * as cborg from 'cborg'; var deoxysii = require('deoxysii'); @@ -36,14 +37,52 @@ export async function encodeCall(call: types.Call, cf: types.CallFormat, cfg?: E case types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: if (cfg && cfg.publicKey) { const privateKey = ed.utils.randomPrivateKey(); - const publicKey = await ed.getPublicKey(privateKey); + const publicKey = ed.curve25519.scalarMultBase(privateKey) const nonce = new Uint8Array(deoxysii.NonceSize); crypto.getRandomValues(nonce); - const rawCall = cborg.encode(call) as Uint8Array; - const sealedCall = mrae.boxSeal(nonce, rawCall, null, cfg.publicKey, privateKey) + const rawCall = oasis.misc.toCBOR(call); + const sealedCall = mrae.boxSeal(nonce, rawCall, null, cfg.publicKey.key, privateKey); + const envolope: types.CallEnvelopeX25519DeoxysII = { + pk: publicKey, + nonce: nonce, + data: sealedCall, + } + const encoded: types.Call = { + format: types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: "", + body: oasis.misc.toCBOR(envolope), + }; + const meta: metaEncryptedX25519DeoxysII = { + sk: privateKey, + pk: cfg.publicKey.key, + }; + return [encoded, meta]; } else { throw new Error('callformat: runtime call data public key not set'); - } - + } + } +} + +/** + * decodeResult performs result decoding based on the specified call format metadata. + */ + +export function decodeResult(result: types.CallResult, meta?: metaEncryptedX25519DeoxysII): types.CallResult { + if (meta == undefined) { + /** + * In case of plain-text data format, we simply pass on the result unchanged. + */ + return result; + } else { + if (result.unknown) { + const envelop = oasis.misc.fromCBOR(result.unknown) as types.ResultEnvelopeX25519DeoxysII; + const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); + const output = oasis.misc.fromCBOR(pt) as types.CallResult; + return output; + } else if (result.fail) { + throw new Error(`callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`); + } else { + throw new Error(`callformat: unexpected result: ${result.ok}`); + } } } diff --git a/client-sdk/ts-web/rt/src/index.ts b/client-sdk/ts-web/rt/src/index.ts index f71d58304a..1ae2781bcf 100644 --- a/client-sdk/ts-web/rt/src/index.ts +++ b/client-sdk/ts-web/rt/src/index.ts @@ -7,6 +7,7 @@ export * as contracts from './contracts'; export * as core from './core'; export * as event from './event'; export * as evm from './evm'; +export * as mrae from './mrae'; export * as rewards from './rewards'; export * as signatureSecp256k1 from './signature_secp256k1'; export * as token from './token'; diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts index 1777fe960d..3d847b2c73 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -1,26 +1,41 @@ - +import * as oasis from '@oasisprotocol/client'; import * as ed from '@noble/ed25519'; import {sha512_256} from 'js-sha512'; -var oasis = require('@oasisprotocol/client'); + var deoxysii = require('deoxysii'); const BoxKDFTweak = "MRAE_Box_Deoxys-II-256-128"; -function deriveSymmetricKey(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { +/** + * deriveSymmetricKey derives a MRAE AEAD symmetric key suitable for use with the asymmetric + * box primitives from the provided X25519 public and private keys. + */ + +export function deriveSymmetricKey(publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { const pmk = ed.curve25519.scalarMult(oasis.misc.toHex(privateKey), oasis.misc.toHex(publicKey)); var kdf = sha512_256.hmac.create(BoxKDFTweak); kdf.update(pmk); return oasis.misc.fromHex(kdf.hex()); } -export function boxSeal(nonce: Uint8Array, plainText: Uint8Array, associateData: Uint8Array, privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { - const sharedKey = deriveSymmetricKey(privateKey, publicKey); +/** + * boxSeal boxes ("seals") the provided additional data and plaintext via + * Deoxys-II-256-128 using a symmetric key derived from the provided + * X25519 public and private keys. + */ +export function boxSeal(nonce: Uint8Array, plainText: Uint8Array, associateData: Uint8Array, publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { + const sharedKey = deriveSymmetricKey(publicKey, privateKey); var aead = new deoxysii.AEAD(sharedKey); return aead.encrypt(nonce, plainText, associateData); } -export function boxOpen(nonce: Uint8Array, ciperText: Uint8Array, associateData: Uint8Array, privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { - const sharedKey = deriveSymmetricKey(privateKey, publicKey); +/** + * boxOpen unboxes ("opens") the provided additional data and plaintext via + * Deoxys-II-256-128 using a symmetric key derived from the provided + * X25519 public and private keys. + */ +export function boxOpen(nonce: Uint8Array, ciperText: Uint8Array, associateData: Uint8Array, publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { + const sharedKey = deriveSymmetricKey(publicKey, privateKey); var aead = new deoxysii.AEAD(sharedKey); return aead.decrypt(nonce, ciperText, associateData); } diff --git a/client-sdk/ts-web/rt/test/mrae.test.ts b/client-sdk/ts-web/rt/test/mrae.test.ts new file mode 100644 index 0000000000..064325d5fa --- /dev/null +++ b/client-sdk/ts-web/rt/test/mrae.test.ts @@ -0,0 +1,16 @@ +import * as oasisRT from './../src'; +import * as ed from '@noble/ed25519'; +import * as oasis from '@oasisprotocol/client'; + +describe('mrae', () => { + describe('symmetricKey', () => { + it('Should drive symmetric key correctly', async () => { + const privateKeyHex = "c07b151fbc1e7a11dff926111188f8d872f62eba0396da97c0a24adb75161750"; + const privateKey = oasis.misc.fromHex(privateKeyHex); + const publicKey = ed.curve25519.scalarMultBase(privateKey); + expect(oasis.misc.toHex(publicKey)).toEqual("3046db3fa70ce605457dc47c48837ebd8bd0a26abfde5994d033e1ced68e2576"); + const sharedKey = oasisRT.mrae.deriveSymmetricKey(publicKey, privateKey); + expect(oasis.misc.toHex(sharedKey)).toEqual("e69ac21066a8c2284e8fdc690e579af4513547b9b31dd144792c1904b45cf586"); + }); + }); +}); From 084158faac820b15426c252fce5892f020e0d597 Mon Sep 17 00:00:00 2001 From: James Zheng Date: Tue, 31 May 2022 09:11:39 -0700 Subject: [PATCH 03/12] fmt --- client-sdk/ts-web/rt/src/callformat.ts | 129 ++++++++++++++----------- client-sdk/ts-web/rt/src/mrae.ts | 52 ++++++---- 2 files changed, 105 insertions(+), 76 deletions(-) diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 25ead25eb7..25fde26de2 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -15,74 +15,91 @@ export const CALL_DATA_KEY_PAIR_ID_CONTEXT_BASE = 'oasis-runtime-sdk/private: tx * EncodeConfig is call encoding configuration. */ export interface EncodeConfig { - /** - * publicKey is an optional runtime's call data public key to use for encrypted call formats. - */ - publicKey?: types.KeyManagerSignedPublicKey; + /** + * publicKey is an optional runtime's call data public key to use for encrypted call formats. + */ + publicKey?: types.KeyManagerSignedPublicKey; } export interface metaEncryptedX25519DeoxysII { - sk: Uint8Array; - pk: Uint8Array; + sk: Uint8Array; + pk: Uint8Array; } /** - * encodeCall encodes a call based on its configured call format. - * It returns the encoded call and any metadata needed to successfully decode the result. + * encodeCall encodes a call based on its configured call format. + * It returns the encoded call and any metadata needed to successfully decode the result. */ -export async function encodeCall(call: types.Call, cf: types.CallFormat, cfg?: EncodeConfig): Promise<[types.Call, metaEncryptedX25519DeoxysII?]> { - switch (cf) { - case types.CALLFORMAT_PLAIN: - return [call, undefined]; - case types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: - if (cfg && cfg.publicKey) { - const privateKey = ed.utils.randomPrivateKey(); - const publicKey = ed.curve25519.scalarMultBase(privateKey) - const nonce = new Uint8Array(deoxysii.NonceSize); - crypto.getRandomValues(nonce); - const rawCall = oasis.misc.toCBOR(call); - const sealedCall = mrae.boxSeal(nonce, rawCall, null, cfg.publicKey.key, privateKey); - const envolope: types.CallEnvelopeX25519DeoxysII = { - pk: publicKey, - nonce: nonce, - data: sealedCall, - } - const encoded: types.Call = { - format: types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, - method: "", - body: oasis.misc.toCBOR(envolope), - }; - const meta: metaEncryptedX25519DeoxysII = { - sk: privateKey, - pk: cfg.publicKey.key, - }; - return [encoded, meta]; - } else { - throw new Error('callformat: runtime call data public key not set'); - } - } +export async function encodeCall( + call: types.Call, + cf: types.CallFormat, + cfg?: EncodeConfig, +): Promise<[types.Call, metaEncryptedX25519DeoxysII?]> { + switch (cf) { + case types.CALLFORMAT_PLAIN: + return [call, undefined]; + case types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: + if (cfg && cfg.publicKey) { + const privateKey = ed.utils.randomPrivateKey(); + const publicKey = ed.curve25519.scalarMultBase(privateKey); + const nonce = new Uint8Array(deoxysii.NonceSize); + crypto.getRandomValues(nonce); + const rawCall = oasis.misc.toCBOR(call); + const sealedCall = mrae.boxSeal( + nonce, + rawCall, + null, + cfg.publicKey.key, + privateKey, + ); + const envolope: types.CallEnvelopeX25519DeoxysII = { + pk: publicKey, + nonce: nonce, + data: sealedCall, + }; + const encoded: types.Call = { + format: types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: '', + body: oasis.misc.toCBOR(envolope), + }; + const meta: metaEncryptedX25519DeoxysII = { + sk: privateKey, + pk: cfg.publicKey.key, + }; + return [encoded, meta]; + } else { + throw new Error('callformat: runtime call data public key not set'); + } + } } /** * decodeResult performs result decoding based on the specified call format metadata. */ -export function decodeResult(result: types.CallResult, meta?: metaEncryptedX25519DeoxysII): types.CallResult { - if (meta == undefined) { - /** - * In case of plain-text data format, we simply pass on the result unchanged. - */ - return result; - } else { - if (result.unknown) { - const envelop = oasis.misc.fromCBOR(result.unknown) as types.ResultEnvelopeX25519DeoxysII; - const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); - const output = oasis.misc.fromCBOR(pt) as types.CallResult; - return output; - } else if (result.fail) { - throw new Error(`callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`); +export function decodeResult( + result: types.CallResult, + meta?: metaEncryptedX25519DeoxysII, +): types.CallResult { + if (meta == undefined) { + /** + * In case of plain-text data format, we simply pass on the result unchanged. + */ + return result; } else { - throw new Error(`callformat: unexpected result: ${result.ok}`); - } - } + if (result.unknown) { + const envelop = oasis.misc.fromCBOR( + result.unknown, + ) as types.ResultEnvelopeX25519DeoxysII; + const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); + const output = oasis.misc.fromCBOR(pt) as types.CallResult; + return output; + } else if (result.fail) { + throw new Error( + `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, + ); + } else { + throw new Error(`callformat: unexpected result: ${result.ok}`); + } + } } diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts index 3d847b2c73..21d8ba2832 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -4,38 +4,50 @@ import {sha512_256} from 'js-sha512'; var deoxysii = require('deoxysii'); -const BoxKDFTweak = "MRAE_Box_Deoxys-II-256-128"; +const BoxKDFTweak = 'MRAE_Box_Deoxys-II-256-128'; /** * deriveSymmetricKey derives a MRAE AEAD symmetric key suitable for use with the asymmetric - * box primitives from the provided X25519 public and private keys. + * box primitives from the provided X25519 public and private keys. */ export function deriveSymmetricKey(publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { - const pmk = ed.curve25519.scalarMult(oasis.misc.toHex(privateKey), oasis.misc.toHex(publicKey)); - var kdf = sha512_256.hmac.create(BoxKDFTweak); - kdf.update(pmk); - return oasis.misc.fromHex(kdf.hex()); + const pmk = ed.curve25519.scalarMult(oasis.misc.toHex(privateKey), oasis.misc.toHex(publicKey)); + var kdf = sha512_256.hmac.create(BoxKDFTweak); + kdf.update(pmk); + return oasis.misc.fromHex(kdf.hex()); } /** - * boxSeal boxes ("seals") the provided additional data and plaintext via - * Deoxys-II-256-128 using a symmetric key derived from the provided - * X25519 public and private keys. + * boxSeal boxes ("seals") the provided additional data and plaintext via + * Deoxys-II-256-128 using a symmetric key derived from the provided + * X25519 public and private keys. */ -export function boxSeal(nonce: Uint8Array, plainText: Uint8Array, associateData: Uint8Array, publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { - const sharedKey = deriveSymmetricKey(publicKey, privateKey); - var aead = new deoxysii.AEAD(sharedKey); - return aead.encrypt(nonce, plainText, associateData); +export function boxSeal( + nonce: Uint8Array, + plainText: Uint8Array, + associateData: Uint8Array, + publicKey: Uint8Array, + privateKey: Uint8Array, +): Uint8Array { + const sharedKey = deriveSymmetricKey(publicKey, privateKey); + var aead = new deoxysii.AEAD(sharedKey); + return aead.encrypt(nonce, plainText, associateData); } /** - * boxOpen unboxes ("opens") the provided additional data and plaintext via - * Deoxys-II-256-128 using a symmetric key derived from the provided - * X25519 public and private keys. + * boxOpen unboxes ("opens") the provided additional data and plaintext via + * Deoxys-II-256-128 using a symmetric key derived from the provided + * X25519 public and private keys. */ -export function boxOpen(nonce: Uint8Array, ciperText: Uint8Array, associateData: Uint8Array, publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { - const sharedKey = deriveSymmetricKey(publicKey, privateKey); - var aead = new deoxysii.AEAD(sharedKey); - return aead.decrypt(nonce, ciperText, associateData); +export function boxOpen( + nonce: Uint8Array, + ciperText: Uint8Array, + associateData: Uint8Array, + publicKey: Uint8Array, + privateKey: Uint8Array, +): Uint8Array { + const sharedKey = deriveSymmetricKey(publicKey, privateKey); + var aead = new deoxysii.AEAD(sharedKey); + return aead.decrypt(nonce, ciperText, associateData); } From 07cb480030a0d10cf3590a7b003de5d799c41bfa Mon Sep 17 00:00:00 2001 From: James Zheng Date: Tue, 21 Jun 2022 08:53:25 -0700 Subject: [PATCH 04/12] use tweetnacl and address other comments --- client-sdk/ts-web/package.json | 1 - client-sdk/ts-web/rt/package.json | 5 +- client-sdk/ts-web/rt/src/callformat.ts | 107 +++++++++++------------- client-sdk/ts-web/rt/src/mrae.ts | 10 +-- client-sdk/ts-web/rt/src/transaction.ts | 10 +++ client-sdk/ts-web/rt/src/types.ts | 10 --- client-sdk/ts-web/rt/test/mrae.test.ts | 1 + 7 files changed, 65 insertions(+), 79 deletions(-) diff --git a/client-sdk/ts-web/package.json b/client-sdk/ts-web/package.json index 95bb942886..cbc6046d22 100644 --- a/client-sdk/ts-web/package.json +++ b/client-sdk/ts-web/package.json @@ -1,5 +1,4 @@ { - "private": true, "workspaces": [ "core", "ext-utils", diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 8c62236d15..9d89dd7e11 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -16,10 +16,9 @@ "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", "elliptic": "^6.5.3", - "@noble/ed25519": "^1.6.0", "js-sha512": "^0.8.0", - "deoxysii": "^0.0.2", - "sha3": "^2.1.4" + "sha3": "^2.1.4", + "tweetnacl": "^1.0.3" }, "devDependencies": { "@types/elliptic": "^6.4.14", diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 25fde26de2..76adb4c610 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -1,10 +1,9 @@ import * as oasis from '@oasisprotocol/client'; - import * as ed from '@noble/ed25519'; -import * as types from './types'; -import * as mrae from './mrae'; -var deoxysii = require('deoxysii'); +import * as transaction from './transaction'; +import * as mrae from './mrae'; +import * as types from './types'; /** * Call data key pair ID domain separation context base. @@ -13,6 +12,8 @@ export const CALL_DATA_KEY_PAIR_ID_CONTEXT_BASE = 'oasis-runtime-sdk/private: tx /** * EncodeConfig is call encoding configuration. + * golang: oasis-sdk/client-sdk/go/callformat/callformat.go + * rust: */ export interface EncodeConfig { /** @@ -21,7 +22,7 @@ export interface EncodeConfig { publicKey?: types.KeyManagerSignedPublicKey; } -export interface metaEncryptedX25519DeoxysII { +export interface MetaEncryptedX25519DeoxysII { sk: Uint8Array; pk: Uint8Array; } @@ -31,75 +32,61 @@ export interface metaEncryptedX25519DeoxysII { * It returns the encoded call and any metadata needed to successfully decode the result. */ export async function encodeCall( + nonce: Uint8Array, + sk: Uint8Array, + pk: Uint8Array, call: types.Call, - cf: types.CallFormat, - cfg?: EncodeConfig, -): Promise<[types.Call, metaEncryptedX25519DeoxysII?]> { - switch (cf) { - case types.CALLFORMAT_PLAIN: + format: types.CallFormat, + config?: EncodeConfig, +): Promise<[types.Call, MetaEncryptedX25519DeoxysII?]> { + switch (format) { + case transaction.CALLFORMAT_PLAIN: return [call, undefined]; - case types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: - if (cfg && cfg.publicKey) { - const privateKey = ed.utils.randomPrivateKey(); - const publicKey = ed.curve25519.scalarMultBase(privateKey); - const nonce = new Uint8Array(deoxysii.NonceSize); - crypto.getRandomValues(nonce); - const rawCall = oasis.misc.toCBOR(call); - const sealedCall = mrae.boxSeal( - nonce, - rawCall, - null, - cfg.publicKey.key, - privateKey, - ); - const envolope: types.CallEnvelopeX25519DeoxysII = { - pk: publicKey, - nonce: nonce, - data: sealedCall, - }; - const encoded: types.Call = { - format: types.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, - method: '', - body: oasis.misc.toCBOR(envolope), - }; - const meta: metaEncryptedX25519DeoxysII = { - sk: privateKey, - pk: cfg.publicKey.key, - }; - return [encoded, meta]; - } else { + case transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: + if (config?.publicKey === undefined) { throw new Error('callformat: runtime call data public key not set'); } + const rawCall = oasis.misc.toCBOR(call); + const sealedCall = mrae.boxSeal(nonce, rawCall, null, config.publicKey.key, sk); + const envelope: types.CallEnvelopeX25519DeoxysII = { + pk: pk, + nonce: nonce, + data: sealedCall, + }; + const encoded: types.Call = { + format: transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: '', + body: oasis.misc.toCBOR(envelope), + }; + const meta: MetaEncryptedX25519DeoxysII = { + sk: sk, + pk: config.publicKey.key, + }; + return [encoded, meta]; } } /** * decodeResult performs result decoding based on the specified call format metadata. */ - export function decodeResult( result: types.CallResult, - meta?: metaEncryptedX25519DeoxysII, + meta?: MetaEncryptedX25519DeoxysII, ): types.CallResult { if (meta == undefined) { - /** - * In case of plain-text data format, we simply pass on the result unchanged. - */ + // In case of plain-text data format, we simply pass on the result unchanged. return result; - } else { - if (result.unknown) { - const envelop = oasis.misc.fromCBOR( - result.unknown, - ) as types.ResultEnvelopeX25519DeoxysII; - const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); - const output = oasis.misc.fromCBOR(pt) as types.CallResult; - return output; - } else if (result.fail) { - throw new Error( - `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, - ); - } else { - throw new Error(`callformat: unexpected result: ${result.ok}`); - } } + + if (result.unknown) { + const envelop = oasis.misc.fromCBOR(result.unknown) as types.ResultEnvelopeX25519DeoxysII; + const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); + return oasis.misc.fromCBOR(pt) as types.CallResult; + } else if (result.fail) { + throw new Error( + `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, + ); + } + + throw new Error(`callformat: unexpected result: ${result.ok}`); } diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts index 21d8ba2832..93e2f44ae0 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -1,10 +1,10 @@ import * as oasis from '@oasisprotocol/client'; -import * as ed from '@noble/ed25519'; +import * as nacl from 'tweetnacl'; import {sha512_256} from 'js-sha512'; var deoxysii = require('deoxysii'); -const BoxKDFTweak = 'MRAE_Box_Deoxys-II-256-128'; +const BOX_KDF_TWEAK = 'MRAE_Box_Deoxys-II-256-128'; /** * deriveSymmetricKey derives a MRAE AEAD symmetric key suitable for use with the asymmetric @@ -12,15 +12,15 @@ const BoxKDFTweak = 'MRAE_Box_Deoxys-II-256-128'; */ export function deriveSymmetricKey(publicKey: Uint8Array, privateKey: Uint8Array): Uint8Array { - const pmk = ed.curve25519.scalarMult(oasis.misc.toHex(privateKey), oasis.misc.toHex(publicKey)); - var kdf = sha512_256.hmac.create(BoxKDFTweak); + const pmk = nacl.scalarMult(privateKey, publicKey); + var kdf = sha512_256.hmac.create(BOX_KDF_TWEAK); kdf.update(pmk); return oasis.misc.fromHex(kdf.hex()); } /** * boxSeal boxes ("seals") the provided additional data and plaintext via - * Deoxys-II-256-128 using a symmetric key derived from the provided + * Deoxys-II-256-128 using a symmetcaric key derived from the provided * X25519 public and private keys. */ export function boxSeal( diff --git a/client-sdk/ts-web/rt/src/transaction.ts b/client-sdk/ts-web/rt/src/transaction.ts index 78663d83a9..02de9e25e4 100644 --- a/client-sdk/ts-web/rt/src/transaction.ts +++ b/client-sdk/ts-web/rt/src/transaction.ts @@ -13,6 +13,16 @@ export const SIGNATURE_CONTEXT_BASE = 'oasis-runtime-sdk/tx: v0'; */ export const LATEST_TRANSACTION_VERSION = 1; +/** + * Plain text call data. + */ +export const CALLFORMAT_PLAIN = 0; + +/** + * Encrypted call data using X25519 for key exchange and Deoxys-II for symmetric encryption. + */ +export const CALLFORMAT_ENCRYPTED_X25519DEOXYSII = 1; + /** * A union of signer types from different algorithms. * Because they all tend to look the same (e.g. have a `sign` method), code diff --git a/client-sdk/ts-web/rt/src/types.ts b/client-sdk/ts-web/rt/src/types.ts index c36c64c843..5062528fda 100644 --- a/client-sdk/ts-web/rt/src/types.ts +++ b/client-sdk/ts-web/rt/src/types.ts @@ -231,16 +231,6 @@ export interface AuthProof { */ export type BaseUnits = [amount: Uint8Array, denomination: Uint8Array]; -/** - * Plain text call data. - */ -export const CALLFORMAT_PLAIN = 0; - -/** - * Encrypted call data using X25519 for key exchange and Deoxys-II for symmetric encryption. - */ -export const CALLFORMAT_ENCRYPTED_X25519DEOXYSII = 1; - /** * Format used for encoding the call (and output) information. */ diff --git a/client-sdk/ts-web/rt/test/mrae.test.ts b/client-sdk/ts-web/rt/test/mrae.test.ts index 064325d5fa..b553fb9625 100644 --- a/client-sdk/ts-web/rt/test/mrae.test.ts +++ b/client-sdk/ts-web/rt/test/mrae.test.ts @@ -1,6 +1,7 @@ import * as oasisRT from './../src'; import * as ed from '@noble/ed25519'; import * as oasis from '@oasisprotocol/client'; +import * as nacl from 'tweetnacl'; describe('mrae', () => { describe('symmetricKey', () => { From 18956b1717e41a4efbd4ffe123bcb4675841f13e Mon Sep 17 00:00:00 2001 From: James Zheng Date: Fri, 24 Jun 2022 09:31:10 -0700 Subject: [PATCH 05/12] address more comments --- client-sdk/ts-web/rt/package.json | 4 ++-- client-sdk/ts-web/rt/src/callformat.ts | 14 +++++++------- client-sdk/ts-web/rt/src/mrae.ts | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 9d89dd7e11..fdee3a9c1e 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -16,9 +16,9 @@ "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", "elliptic": "^6.5.3", - "js-sha512": "^0.8.0", + "js-sha512": "^0.8.0", "sha3": "^2.1.4", - "tweetnacl": "^1.0.3" + "tweetnacl": "^1.0.3" }, "devDependencies": { "@types/elliptic": "^6.4.14", diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 76adb4c610..87d15a9f26 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -1,5 +1,4 @@ import * as oasis from '@oasisprotocol/client'; -import * as ed from '@noble/ed25519'; import * as transaction from './transaction'; import * as mrae from './mrae'; @@ -38,7 +37,7 @@ export async function encodeCall( call: types.Call, format: types.CallFormat, config?: EncodeConfig, -): Promise<[types.Call, MetaEncryptedX25519DeoxysII?]> { +): Promise<[types.Call, unknown]> { switch (format) { case transaction.CALLFORMAT_PLAIN: return [call, undefined]; @@ -55,15 +54,16 @@ export async function encodeCall( }; const encoded: types.Call = { format: transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, - method: '', body: oasis.misc.toCBOR(envelope), }; const meta: MetaEncryptedX25519DeoxysII = { sk: sk, pk: config.publicKey.key, }; - return [encoded, meta]; - } + return [encoded, meta]; + default: + throw new Error(`callformat: unsupported call format: ${format}`) + } } /** @@ -73,7 +73,7 @@ export function decodeResult( result: types.CallResult, meta?: MetaEncryptedX25519DeoxysII, ): types.CallResult { - if (meta == undefined) { + if (meta === undefined) { // In case of plain-text data format, we simply pass on the result unchanged. return result; } @@ -84,7 +84,7 @@ export function decodeResult( return oasis.misc.fromCBOR(pt) as types.CallResult; } else if (result.fail) { throw new Error( - `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, + `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}` ); } diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts index 93e2f44ae0..769320dd52 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -20,7 +20,7 @@ export function deriveSymmetricKey(publicKey: Uint8Array, privateKey: Uint8Array /** * boxSeal boxes ("seals") the provided additional data and plaintext via - * Deoxys-II-256-128 using a symmetcaric key derived from the provided + * Deoxys-II-256-128 using a symmetric key derived from the provided * X25519 public and private keys. */ export function boxSeal( From f3567d507956978bc50ec7da622dc002decf7c4e Mon Sep 17 00:00:00 2001 From: James Zheng Date: Mon, 27 Jun 2022 07:50:51 -0700 Subject: [PATCH 06/12] use arrayBuffer and ignore declaration error --- client-sdk/ts-web/rt/src/callformat.ts | 11 ++++++----- client-sdk/ts-web/rt/src/mrae.ts | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 87d15a9f26..c934f256c3 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -54,16 +54,17 @@ export async function encodeCall( }; const encoded: types.Call = { format: transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: '', body: oasis.misc.toCBOR(envelope), }; const meta: MetaEncryptedX25519DeoxysII = { sk: sk, pk: config.publicKey.key, }; - return [encoded, meta]; - default: - throw new Error(`callformat: unsupported call format: ${format}`) - } + return [encoded, meta]; + default: + throw new Error(`callformat: unsupported call format: ${format}`); + } } /** @@ -84,7 +85,7 @@ export function decodeResult( return oasis.misc.fromCBOR(pt) as types.CallResult; } else if (result.fail) { throw new Error( - `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}` + `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, ); } diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae.ts index 769320dd52..4407c4cfbd 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae.ts @@ -1,8 +1,8 @@ import * as oasis from '@oasisprotocol/client'; import * as nacl from 'tweetnacl'; import {sha512_256} from 'js-sha512'; - -var deoxysii = require('deoxysii'); +// @ts-expect-error missing declaration +import * as deoxysii from 'deoxysii'; const BOX_KDF_TWEAK = 'MRAE_Box_Deoxys-II-256-128'; @@ -15,7 +15,7 @@ export function deriveSymmetricKey(publicKey: Uint8Array, privateKey: Uint8Array const pmk = nacl.scalarMult(privateKey, publicKey); var kdf = sha512_256.hmac.create(BOX_KDF_TWEAK); kdf.update(pmk); - return oasis.misc.fromHex(kdf.hex()); + return new Uint8Array(kdf.arrayBuffer()); } /** From 8fb3f0a5fa04628884e504226b38683f8acb73de Mon Sep 17 00:00:00 2001 From: James Zheng Date: Fri, 1 Jul 2022 19:51:45 -0700 Subject: [PATCH 07/12] add one more unittest and address more comments --- client-sdk/ts-web/rt/package.json | 1 + client-sdk/ts-web/rt/src/callformat.ts | 79 ++++++++++++++----- client-sdk/ts-web/rt/src/index.ts | 2 +- .../rt/src/{mrae.ts => mrae/deoxysii.ts} | 4 +- client-sdk/ts-web/rt/test/mrae.test.ts | 11 ++- 5 files changed, 68 insertions(+), 29 deletions(-) rename client-sdk/ts-web/rt/src/{mrae.ts => mrae/deoxysii.ts} (100%) diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index fdee3a9c1e..597360d3c0 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -17,6 +17,7 @@ "@oasisprotocol/client": "^0.1.1-alpha.1", "elliptic": "^6.5.3", "js-sha512": "^0.8.0", + "randombytes": "^2.0.1", "sha3": "^2.1.4", "tweetnacl": "^1.0.3" }, diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index c934f256c3..384cda156a 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -1,7 +1,12 @@ import * as oasis from '@oasisprotocol/client'; +// @ts-expect-error missing declaration +import * as deoxysii from 'deoxysii'; +import * as nacl from 'tweetnacl'; +// @ts-expect-error missing declaration +import * as randomBytes from 'randombytes'; +import * as mraeDeoxysii from './mrae/deoxysii'; import * as transaction from './transaction'; -import * as mrae from './mrae'; import * as types from './types'; /** @@ -27,17 +32,17 @@ export interface MetaEncryptedX25519DeoxysII { } /** - * encodeCall encodes a call based on its configured call format. + * encodeCallWithNonceAndKeys encodes a call based on its configured call format. * It returns the encoded call and any metadata needed to successfully decode the result. */ -export async function encodeCall( +export function encodeCallWithNonceAndKeys( nonce: Uint8Array, sk: Uint8Array, pk: Uint8Array, call: types.Call, format: types.CallFormat, config?: EncodeConfig, -): Promise<[types.Call, unknown]> { +): [types.Call, unknown] { switch (format) { case transaction.CALLFORMAT_PLAIN: return [call, undefined]; @@ -46,7 +51,7 @@ export async function encodeCall( throw new Error('callformat: runtime call data public key not set'); } const rawCall = oasis.misc.toCBOR(call); - const sealedCall = mrae.boxSeal(nonce, rawCall, null, config.publicKey.key, sk); + const sealedCall = mraeDeoxysii.boxSeal(nonce, rawCall, null, config.publicKey.key, sk); const envelope: types.CallEnvelopeX25519DeoxysII = { pk: pk, nonce: nonce, @@ -67,27 +72,61 @@ export async function encodeCall( } } +/** + * encodeCall randomly generates nonce and keyPair and then call encodeCallWithNonceAndKeys + * It returns the encoded call and any metadata needed to successfully decode the result. + */ +export function encodeCall( + call: types.Call, + format: types.CallFormat, + config?: EncodeConfig, +): [types.Call, unknown] { + const nonce = randomBytes(deoxysii.NonceSize); + const keyPair = nacl.box.keyPair(); + return encodeCallWithNonceAndKeys( + nonce, + keyPair.secretKey, + keyPair.publicKey, + call, + format, + config, + ); +} + /** * decodeResult performs result decoding based on the specified call format metadata. */ export function decodeResult( result: types.CallResult, + format: types.CallFormat, meta?: MetaEncryptedX25519DeoxysII, ): types.CallResult { - if (meta === undefined) { - // In case of plain-text data format, we simply pass on the result unchanged. - return result; - } - - if (result.unknown) { - const envelop = oasis.misc.fromCBOR(result.unknown) as types.ResultEnvelopeX25519DeoxysII; - const pt = mrae.boxOpen(envelop.nonce, envelop.data, null, meta.pk, meta.sk); - return oasis.misc.fromCBOR(pt) as types.CallResult; - } else if (result.fail) { - throw new Error( - `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, - ); + switch (format) { + case transaction.CALLFORMAT_PLAIN: + // In case of plain-text data format, we simply pass on the result unchanged. + return result; + case transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: + if (result.unknown) { + const envelop = oasis.misc.fromCBOR( + result.unknown, + ) as types.ResultEnvelopeX25519DeoxysII; + const pt = mraeDeoxysii.boxOpen( + envelop.nonce, + envelop.data, + null, + meta.pk, + meta.sk, + ); + return oasis.misc.fromCBOR(pt) as types.CallResult; + } else if (result.fail) { + throw new Error( + `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, + ); + } + throw Object.assign(new Error(`callformat: unexpected result: ${result.ok}`), { + source: result, + }); + default: + throw new Error(`callformat: unsupported call format: ${format}`); } - - throw new Error(`callformat: unexpected result: ${result.ok}`); } diff --git a/client-sdk/ts-web/rt/src/index.ts b/client-sdk/ts-web/rt/src/index.ts index 1ae2781bcf..0b5454fdd2 100644 --- a/client-sdk/ts-web/rt/src/index.ts +++ b/client-sdk/ts-web/rt/src/index.ts @@ -7,7 +7,7 @@ export * as contracts from './contracts'; export * as core from './core'; export * as event from './event'; export * as evm from './evm'; -export * as mrae from './mrae'; +export * as mraeDeoxysii from './mrae/deoxysii'; export * as rewards from './rewards'; export * as signatureSecp256k1 from './signature_secp256k1'; export * as token from './token'; diff --git a/client-sdk/ts-web/rt/src/mrae.ts b/client-sdk/ts-web/rt/src/mrae/deoxysii.ts similarity index 100% rename from client-sdk/ts-web/rt/src/mrae.ts rename to client-sdk/ts-web/rt/src/mrae/deoxysii.ts index 4407c4cfbd..d408fbe38a 100644 --- a/client-sdk/ts-web/rt/src/mrae.ts +++ b/client-sdk/ts-web/rt/src/mrae/deoxysii.ts @@ -1,8 +1,8 @@ import * as oasis from '@oasisprotocol/client'; -import * as nacl from 'tweetnacl'; -import {sha512_256} from 'js-sha512'; // @ts-expect-error missing declaration import * as deoxysii from 'deoxysii'; +import {sha512_256} from 'js-sha512'; +import * as nacl from 'tweetnacl'; const BOX_KDF_TWEAK = 'MRAE_Box_Deoxys-II-256-128'; diff --git a/client-sdk/ts-web/rt/test/mrae.test.ts b/client-sdk/ts-web/rt/test/mrae.test.ts index b553fb9625..9f78df03a4 100644 --- a/client-sdk/ts-web/rt/test/mrae.test.ts +++ b/client-sdk/ts-web/rt/test/mrae.test.ts @@ -1,17 +1,16 @@ import * as oasisRT from './../src'; -import * as ed from '@noble/ed25519'; import * as oasis from '@oasisprotocol/client'; import * as nacl from 'tweetnacl'; describe('mrae', () => { describe('symmetricKey', () => { - it('Should drive symmetric key correctly', async () => { - const privateKeyHex = "c07b151fbc1e7a11dff926111188f8d872f62eba0396da97c0a24adb75161750"; + it('Should drive symmetric key correctly', () => { + const privateKeyHex = "c07b151fbc1e7a11dff926111188f8d872f62eba0396da97c0a24adb75161750"; const privateKey = oasis.misc.fromHex(privateKeyHex); - const publicKey = ed.curve25519.scalarMultBase(privateKey); + const publicKey = nacl.scalarMult.base(privateKey); expect(oasis.misc.toHex(publicKey)).toEqual("3046db3fa70ce605457dc47c48837ebd8bd0a26abfde5994d033e1ced68e2576"); - const sharedKey = oasisRT.mrae.deriveSymmetricKey(publicKey, privateKey); - expect(oasis.misc.toHex(sharedKey)).toEqual("e69ac21066a8c2284e8fdc690e579af4513547b9b31dd144792c1904b45cf586"); + const sharedKey = oasisRT.mraeDeoxysii.deriveSymmetricKey(publicKey, privateKey); + expect(oasis.misc.toHex(sharedKey)).toEqual("e69ac21066a8c2284e8fdc690e579af4513547b9b31dd144792c1904b45cf586"); }); }); }); From 6a271c98cdb00b713f9a8d402aa1d0eaef5f03d7 Mon Sep 17 00:00:00 2001 From: James Zheng Date: Fri, 1 Jul 2022 19:58:13 -0700 Subject: [PATCH 08/12] add the callformat unit test --- client-sdk/ts-web/rt/test/callformat.test.ts | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 client-sdk/ts-web/rt/test/callformat.test.ts diff --git a/client-sdk/ts-web/rt/test/callformat.test.ts b/client-sdk/ts-web/rt/test/callformat.test.ts new file mode 100644 index 0000000000..389a446517 --- /dev/null +++ b/client-sdk/ts-web/rt/test/callformat.test.ts @@ -0,0 +1,34 @@ +import * as oasisRT from './../src'; +import * as nacl from 'tweetnacl'; + +describe('callformat', () => { + describe('encodeCall/DecodeResult', () => { + it('Should encode and decode the message correctly', () => { + const message = "I will find some random message here" + const pairs = nacl.box.keyPair() + const publicKey = pairs.publicKey + const rawCall: oasisRT.types.Call = { + format: oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: '', + body: message + } + const dummy = new Uint8Array() + const keyManagerPk: oasisRT.types.KeyManagerSignedPublicKey = { + key: publicKey, + checksum: dummy, + signature: dummy + } + const config: oasisRT.callformat.EncodeConfig = { + publicKey: keyManagerPk + } + const [sealedCall, meta] = oasisRT.callformat.encodeCall(rawCall, oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, config) + + const fakedResult: oasisRT.types.CallResult = { + unknown: sealedCall.body as Uint8Array + } + + var decodedResult = oasisRT.callformat.decodeResult(fakedResult, oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, meta as oasisRT.callformat.MetaEncryptedX25519DeoxysII) as oasisRT.types.Call + expect(decodedResult.body).toEqual(message) + }); + }); +}); From 59d8bebdfa018eae3dc47979218cfb89abdde6e2 Mon Sep 17 00:00:00 2001 From: James Zheng Date: Wed, 6 Jul 2022 09:12:23 -0700 Subject: [PATCH 09/12] small format changes --- client-sdk/ts-web/rt/src/callformat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 384cda156a..145b4938f8 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -120,7 +120,7 @@ export function decodeResult( return oasis.misc.fromCBOR(pt) as types.CallResult; } else if (result.fail) { throw new Error( - `callformat: failed call: module :${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, + `callformat: failed call: module: ${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, ); } throw Object.assign(new Error(`callformat: unexpected result: ${result.ok}`), { From 8ca5ecbb50686f536a24e3cb3c8378e79f7a01ab Mon Sep 17 00:00:00 2001 From: James Zheng Date: Wed, 6 Jul 2022 10:07:09 -0700 Subject: [PATCH 10/12] fix npm install issues --- client-sdk/ts-web/package-lock.json | 1754 +----------------------- client-sdk/ts-web/rt/package.json | 1 + client-sdk/ts-web/rt/src/callformat.ts | 38 +- 3 files changed, 59 insertions(+), 1734 deletions(-) diff --git a/client-sdk/ts-web/package-lock.json b/client-sdk/ts-web/package-lock.json index ad238e1140..fbfb33403d 100644 --- a/client-sdk/ts-web/package-lock.json +++ b/client-sdk/ts-web/package-lock.json @@ -1892,39 +1892,6 @@ "peerDependencies": { "acorn": "^8" } - "node_modules/@ledgerhq/logs": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.10.0.tgz", - "integrity": "sha512-lLseUPEhSFUXYTKj6q7s2O3s2vW2ebgA11vMAlKodXGf5AFw4zUoEbTz9CoFOC9jS6xY4Qr8BmRnxP/odT4Uuw==" - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", - "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", - "dev": true - }, - "node_modules/@noble/ed25519": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.0.tgz", - "integrity": "sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@oasisprotocol/client": { - "resolved": "core", - "link": true - }, - "node_modules/@oasisprotocol/client-ext-utils": { - "resolved": "ext-utils", - "link": true - }, - "node_modules/@oasisprotocol/client-rt": { - "resolved": "rt", - "link": true }, "node_modules/acorn-jsx": { "version": "5.3.2", @@ -2492,6 +2459,14 @@ "node": ">= 6" } }, + "node_modules/bsaes": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/bsaes/-/bsaes-0.0.2.tgz", + "integrity": "sha512-iVxJFMOvCUG85sX2UVpZ9IgvH6Jjc5xpd/W8pALvFE7zfCqHkV7hW3M2XZtpg9biPS0K4Eka96bbNNgLohcpgQ==", + "dependencies": { + "uint32": "^0.2.1" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -3073,25 +3048,10 @@ "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", "dev": true }, -<<<<<<< HEAD "node_modules/cypress/node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", -======= - "node_modules/bsaes": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/bsaes/-/bsaes-0.0.2.tgz", - "integrity": "sha512-iVxJFMOvCUG85sX2UVpZ9IgvH6Jjc5xpd/W8pALvFE7zfCqHkV7hW3M2XZtpg9biPS0K4Eka96bbNNgLohcpgQ==", - "dependencies": { - "uint32": "^0.2.1" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", ->>>>>>> add unittest for mrae functions "dev": true, "funding": [ { @@ -3241,6 +3201,15 @@ "node": ">=0.4.0" } }, + "node_modules/deoxysii": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/deoxysii/-/deoxysii-0.0.2.tgz", + "integrity": "sha512-mMob/2wDZBatPC48g188hFt5xxrbfYMl9L+XQGOZuHPU4ScCHpAKkbZiAU1yg/kROj6nPKZp5eItuNI3LdU7vA==", + "dependencies": { + "bsaes": "0.0.2", + "uint32": "^0.2.1" + } + }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -3743,7 +3712,6 @@ "node": ">=0.10" } }, -<<<<<<< HEAD "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -3751,22 +3719,6 @@ "dependencies": { "estraverse": "^5.2.0" }, -======= - "node_modules/deoxysii": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/deoxysii/-/deoxysii-0.0.2.tgz", - "integrity": "sha512-mMob/2wDZBatPC48g188hFt5xxrbfYMl9L+XQGOZuHPU4ScCHpAKkbZiAU1yg/kROj6nPKZp5eItuNI3LdU7vA==", - "dependencies": { - "bsaes": "0.0.2", - "uint32": "^0.2.1" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true, ->>>>>>> add unittest for mrae functions "engines": { "node": ">=4.0" } @@ -7207,22 +7159,10 @@ "node": ">=8.10.0" } }, -<<<<<<< HEAD "node_modules/rechoir": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", -======= - "node_modules/uint32": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/uint32/-/uint32-0.2.1.tgz", - "integrity": "sha1-5hjYAtf//Si3CPzOzHMVYIusR/I=" - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", ->>>>>>> add unittest for mrae functions "dev": true, "dependencies": { "resolve": "^1.9.0" @@ -7712,20 +7652,11 @@ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "dependencies": { -<<<<<<< HEAD "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" -======= - "@noble/ed25519": "^1.6.0", - "@oasisprotocol/client": "^0.1.0-alpha9", - "deoxysii": "^0.0.2", - "elliptic": "^6.5.3", - "js-sha512": "^0.8.0", - "sha3": "^2.1.4" ->>>>>>> add unittest for mrae functions }, "engines": { "node": ">=6.0.0" @@ -8245,6 +8176,11 @@ "node": ">=4.2.0" } }, + "node_modules/uint32": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/uint32/-/uint32-0.2.1.tgz", + "integrity": "sha512-d3i8kc/4s1CFW5g3FctmF1Bu2GVXGBMTn82JY2BW0ZtTtI8pRx1YWGPCFBwRF4uYVSJ7ua4y+qYEPqS+x+3w7Q==" + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -8876,8 +8812,12 @@ "version": "0.2.1-alpha.1", "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", + "deoxysii": "^0.0.2", "elliptic": "^6.5.3", - "sha3": "^2.1.4" + "js-sha512": "^0.8.0", + "randombytes": "^2.0.1", + "sha3": "^2.1.4", + "tweetnacl": "^1.0.3" }, "devDependencies": { "@types/elliptic": "^6.4.14", @@ -9847,11 +9787,6 @@ "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", "dev": true }, - "@noble/ed25519": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.0.tgz", - "integrity": "sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q==" - }, "@oasisprotocol/client": { "version": "file:core", "requires": { @@ -9912,13 +9847,17 @@ "@types/jest": "^28.1.0", "buffer": "^6.0.3", "cypress": "^10.2.0", + "deoxysii": "^0.0.2", "elliptic": "^6.5.3", "jest": "^28.1.0", + "js-sha512": "^0.8.0", "prettier": "^2.7.1", "process": "^0.11.10", + "randombytes": "^2.0.1", "sha3": "^2.1.4", "stream-browserify": "^3.0.0", "ts-jest": "^28.0.5", + "tweetnacl": "^1.0.3", "typescript": "^4.7.4", "webpack": "^5.73.0", "webpack-cli": "^4.10.0", @@ -9931,1637 +9870,8 @@ "integrity": "sha512-ITfF6JJIl9zbEi2k6NmhNE/BiDqfsI/ceqfvdaWaPbcrCpYyyRq4KtDQIWh6vQUru6SqwppODiom/Zhid+np6A==", "dev": true, "requires": { -<<<<<<< HEAD "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" -======= - "@jest/console": "^28.1.0", - "@jest/reporters": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.0.2", - "jest-config": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-resolve-dependencies": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "jest-watcher": "^28.1.0", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "jest-mock": "^28.1.0" - } - }, - "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", - "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "@jest/globals": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", - "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/types": "^28.1.0" - } - }, - "@jest/reporters": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", - "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.0" - } - }, - "@jest/source-map": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", - "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.7", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", - "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", - "dev": true, - "requires": { - "@jest/console": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", - "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", - "dev": true, - "requires": { - "@jest/test-result": "^28.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", - "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - } - }, - "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", - "dev": true, - "requires": { - "@jest/schemas": "^28.0.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "babel-jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", - "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", - "dev": true, - "requires": { - "@jest/transform": "^28.1.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.0.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", - "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", - "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^28.0.2", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true - }, - "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", - "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", - "dev": true, - "requires": { - "@jest/core": "^28.1.0", - "import-local": "^3.0.2", - "jest-cli": "^28.1.0" - } - }, - "jest-changed-files": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", - "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", - "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", - "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", - "dev": true, - "requires": { - "@jest/core": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", - "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.0", - "@jest/types": "^28.1.0", - "babel-jest": "^28.1.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.0", - "jest-environment-node": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-docblock": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", - "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", - "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0" - } - }, - "jest-environment-node": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", - "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-haste-map": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", - "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-leak-detector": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", - "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", - "dev": true, - "requires": { - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-matcher-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", - "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.0", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/node": "*" - } - }, - "jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "dev": true - }, - "jest-resolve": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", - "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", - "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", - "dev": true, - "requires": { - "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.0" - } - }, - "jest-runner": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", - "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", - "dev": true, - "requires": { - "@jest/console": "^28.1.0", - "@jest/environment": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "graceful-fs": "^4.2.9", - "jest-docblock": "^28.0.2", - "jest-environment-node": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-leak-detector": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-resolve": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-util": "^28.1.0", - "jest-watcher": "^28.1.0", - "jest-worker": "^28.1.0", - "source-map-support": "0.5.13", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", - "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/globals": "^28.1.0", - "@jest/source-map": "^28.0.2", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", - "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^28.1.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", - "natural-compare": "^1.4.0", - "pretty-format": "^28.1.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", - "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "leven": "^3.1.0", - "pretty-format": "^28.1.0" - } - }, - "jest-watcher": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", - "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", - "dev": true, - "requires": { - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", - "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "pretty-format": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", - "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.0.2", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "ts-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.2.tgz", - "integrity": "sha512-IOZMb3D0gx6IHO9ywPgiQxJ3Zl4ECylEFwoVpENB55aTn5sdO0Ptyx/7noNBxAaUff708RqQL4XBNxxOVjY0vQ==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^20.x" - }, - "dependencies": { - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.7", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - } - }, - "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "yargs": { - "version": "17.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", - "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - } - }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true - } - } - }, - "@oasisprotocol/client-ext-utils": { - "version": "file:ext-utils", - "requires": { - "@oasisprotocol/client": "^0.1.0-alpha9", - "@oasisprotocol/client-rt": "^0.2.0-alpha10", - "buffer": "^6.0.3", - "cypress": "^9.6.1", - "prettier": "^2.6.2", - "process": "^0.11.10", - "stream-browserify": "^3.0.0", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" - } - }, - "@oasisprotocol/client-rt": { - "version": "file:rt", - "requires": { - "@noble/ed25519": "^1.6.0", - "@oasisprotocol/client": "^0.1.0-alpha9", - "@types/elliptic": "^6.4.14", - "@types/jest": "^27.5.1", - "buffer": "^6.0.3", - "cypress": "^9.6.1", - "deoxysii": "^0.0.2", - "elliptic": "^6.5.3", - "jest": "^28.1.0", - "js-sha512": "^0.8.0", - "prettier": "^2.6.2", - "process": "^0.11.10", - "sha3": "^2.1.4", - "stream-browserify": "^3.0.0", - "ts-jest": "^28.0.2", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" - }, - "dependencies": { - "@jest/console": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", - "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", - "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", - "dev": true, - "requires": { - "@jest/console": "^28.1.0", - "@jest/reporters": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.0.2", - "jest-config": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-resolve-dependencies": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "jest-watcher": "^28.1.0", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", - "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "jest-mock": "^28.1.0" - } - }, - "@jest/fake-timers": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", - "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@sinonjs/fake-timers": "^9.1.1", - "@types/node": "*", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "@jest/globals": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", - "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/types": "^28.1.0" - } - }, - "@jest/reporters": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", - "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.0" - } - }, - "@jest/source-map": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", - "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.7", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", - "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", - "dev": true, - "requires": { - "@jest/console": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", - "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", - "dev": true, - "requires": { - "@jest/test-result": "^28.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", - "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^28.1.0", - "@jridgewell/trace-mapping": "^0.3.7", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - } - }, - "@jest/types": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", - "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", - "dev": true, - "requires": { - "@jest/schemas": "^28.0.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "babel-jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", - "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", - "dev": true, - "requires": { - "@jest/transform": "^28.1.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.0.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", - "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", - "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^28.0.2", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "diff-sequences": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", - "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", - "dev": true - }, - "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "expect": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", - "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "jest": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", - "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", - "dev": true, - "requires": { - "@jest/core": "^28.1.0", - "import-local": "^3.0.2", - "jest-cli": "^28.1.0" - } - }, - "jest-changed-files": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", - "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", - "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/expect": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", - "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", - "dev": true, - "requires": { - "@jest/core": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", - "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.0", - "@jest/types": "^28.1.0", - "babel-jest": "^28.1.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.0", - "jest-environment-node": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-runner": "^28.1.0", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", - "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.0.2", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-docblock": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", - "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", - "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "jest-util": "^28.1.0", - "pretty-format": "^28.1.0" - } - }, - "jest-environment-node": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", - "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "jest-mock": "^28.1.0", - "jest-util": "^28.1.0" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-haste-map": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", - "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.0", - "jest-worker": "^28.1.0", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-leak-detector": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", - "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", - "dev": true, - "requires": { - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-matcher-utils": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", - "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.0", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.0" - } - }, - "jest-message-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", - "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", - "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/node": "*" - } - }, - "jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "dev": true - }, - "jest-resolve": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", - "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.0", - "jest-validate": "^28.1.0", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", - "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", - "dev": true, - "requires": { - "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.0" - } - }, - "jest-runner": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", - "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", - "dev": true, - "requires": { - "@jest/console": "^28.1.0", - "@jest/environment": "^28.1.0", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "graceful-fs": "^4.2.9", - "jest-docblock": "^28.0.2", - "jest-environment-node": "^28.1.0", - "jest-haste-map": "^28.1.0", - "jest-leak-detector": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-resolve": "^28.1.0", - "jest-runtime": "^28.1.0", - "jest-util": "^28.1.0", - "jest-watcher": "^28.1.0", - "jest-worker": "^28.1.0", - "source-map-support": "0.5.13", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", - "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.0", - "@jest/fake-timers": "^28.1.0", - "@jest/globals": "^28.1.0", - "@jest/source-map": "^28.0.2", - "@jest/test-result": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-mock": "^28.1.0", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.0", - "jest-snapshot": "^28.1.0", - "jest-util": "^28.1.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", - "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.0", - "@jest/transform": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^28.1.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.0", - "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.0", - "jest-matcher-utils": "^28.1.0", - "jest-message-util": "^28.1.0", - "jest-util": "^28.1.0", - "natural-compare": "^1.4.0", - "pretty-format": "^28.1.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", - "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", - "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "leven": "^3.1.0", - "pretty-format": "^28.1.0" - } - }, - "jest-watcher": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", - "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", - "dev": true, - "requires": { - "@jest/test-result": "^28.1.0", - "@jest/types": "^28.1.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", - "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "pretty-format": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", - "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.0.2", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "ts-jest": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.2.tgz", - "integrity": "sha512-IOZMb3D0gx6IHO9ywPgiQxJ3Zl4ECylEFwoVpENB55aTn5sdO0Ptyx/7noNBxAaUff708RqQL4XBNxxOVjY0vQ==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^20.x" - }, - "dependencies": { - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.7", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - } - }, - "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "yargs": { - "version": "17.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", - "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" ->>>>>>> add unittest for mrae functions } } } @@ -17002,7 +15312,7 @@ "uint32": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/uint32/-/uint32-0.2.1.tgz", - "integrity": "sha1-5hjYAtf//Si3CPzOzHMVYIusR/I=" + "integrity": "sha512-d3i8kc/4s1CFW5g3FctmF1Bu2GVXGBMTn82JY2BW0ZtTtI8pRx1YWGPCFBwRF4uYVSJ7ua4y+qYEPqS+x+3w7Q==" }, "universalify": { "version": "2.0.0", diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 597360d3c0..92316e5993 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@oasisprotocol/client": "^0.1.1-alpha.1", + "deoxysii": "^0.0.2", "elliptic": "^6.5.3", "js-sha512": "^0.8.0", "randombytes": "^2.0.1", diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 145b4938f8..6098b98af6 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -51,7 +51,14 @@ export function encodeCallWithNonceAndKeys( throw new Error('callformat: runtime call data public key not set'); } const rawCall = oasis.misc.toCBOR(call); - const sealedCall = mraeDeoxysii.boxSeal(nonce, rawCall, null, config.publicKey.key, sk); + const zeroBuffer = new Uint8Array(0); + const sealedCall = mraeDeoxysii.boxSeal( + nonce, + rawCall, + zeroBuffer, + config.publicKey.key, + sk, + ); const envelope: types.CallEnvelopeX25519DeoxysII = { pk: pk, nonce: nonce, @@ -107,17 +114,24 @@ export function decodeResult( return result; case transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII: if (result.unknown) { - const envelop = oasis.misc.fromCBOR( - result.unknown, - ) as types.ResultEnvelopeX25519DeoxysII; - const pt = mraeDeoxysii.boxOpen( - envelop.nonce, - envelop.data, - null, - meta.pk, - meta.sk, - ); - return oasis.misc.fromCBOR(pt) as types.CallResult; + if (meta) { + const envelop = oasis.misc.fromCBOR( + result.unknown, + ) as types.ResultEnvelopeX25519DeoxysII; + const zeroBuffer = new Uint8Array(0); + const pt = mraeDeoxysii.boxOpen( + envelop?.nonce, + envelop?.data, + zeroBuffer, + meta.pk, + meta.sk, + ); + return oasis.misc.fromCBOR(pt) as types.CallResult; + } else { + throw new Error( + `callformat: MetaEncryptedX25519DeoxysII data is required for callformat: CALLFORMAT_ENCRYPTED_X25519DEOXYSII`, + ); + } } else if (result.fail) { throw new Error( `callformat: failed call: module: ${result.fail.module} code: ${result.fail.code} message: ${result.fail.message}`, From bc5d02ef75807404b4efcca5b218ee16e281dacf Mon Sep 17 00:00:00 2001 From: James Zheng Date: Wed, 6 Jul 2022 11:28:46 -0700 Subject: [PATCH 11/12] change encodeCall/decodeCall signatures to be async --- client-sdk/ts-web/rt/package.json | 4 +- client-sdk/ts-web/rt/src/callformat.ts | 14 ++--- client-sdk/ts-web/rt/test/address.test.ts | 8 ++- client-sdk/ts-web/rt/test/callformat.test.ts | 60 +++++++++++--------- client-sdk/ts-web/rt/test/mrae.test.ts | 23 +++++--- 5 files changed, 63 insertions(+), 46 deletions(-) diff --git a/client-sdk/ts-web/rt/package.json b/client-sdk/ts-web/rt/package.json index 92316e5993..3e71b80452 100644 --- a/client-sdk/ts-web/rt/package.json +++ b/client-sdk/ts-web/rt/package.json @@ -8,8 +8,8 @@ "scripts": { "prepare": "tsc", "check-playground": "cd playground && tsc -p jsconfig.json", - "fmt": "prettier --write playground/src src", - "lint": "prettier --check playground/src src", + "fmt": "prettier --write playground/src src test", + "lint": "prettier --check playground/src src test", "playground": "cd playground && webpack s -c webpack.config.js", "test": "jest" }, diff --git a/client-sdk/ts-web/rt/src/callformat.ts b/client-sdk/ts-web/rt/src/callformat.ts index 6098b98af6..61edf2d25a 100644 --- a/client-sdk/ts-web/rt/src/callformat.ts +++ b/client-sdk/ts-web/rt/src/callformat.ts @@ -35,14 +35,14 @@ export interface MetaEncryptedX25519DeoxysII { * encodeCallWithNonceAndKeys encodes a call based on its configured call format. * It returns the encoded call and any metadata needed to successfully decode the result. */ -export function encodeCallWithNonceAndKeys( +export async function encodeCallWithNonceAndKeys( nonce: Uint8Array, sk: Uint8Array, pk: Uint8Array, call: types.Call, format: types.CallFormat, config?: EncodeConfig, -): [types.Call, unknown] { +): Promise<[types.Call, unknown]> { switch (format) { case transaction.CALLFORMAT_PLAIN: return [call, undefined]; @@ -83,14 +83,14 @@ export function encodeCallWithNonceAndKeys( * encodeCall randomly generates nonce and keyPair and then call encodeCallWithNonceAndKeys * It returns the encoded call and any metadata needed to successfully decode the result. */ -export function encodeCall( +export async function encodeCall( call: types.Call, format: types.CallFormat, config?: EncodeConfig, -): [types.Call, unknown] { +): Promise<[types.Call, unknown]> { const nonce = randomBytes(deoxysii.NonceSize); const keyPair = nacl.box.keyPair(); - return encodeCallWithNonceAndKeys( + return await encodeCallWithNonceAndKeys( nonce, keyPair.secretKey, keyPair.publicKey, @@ -103,11 +103,11 @@ export function encodeCall( /** * decodeResult performs result decoding based on the specified call format metadata. */ -export function decodeResult( +export async function decodeResult( result: types.CallResult, format: types.CallFormat, meta?: MetaEncryptedX25519DeoxysII, -): types.CallResult { +): Promise { switch (format) { case transaction.CALLFORMAT_PLAIN: // In case of plain-text data format, we simply pass on the result unchanged. diff --git a/client-sdk/ts-web/rt/test/address.test.ts b/client-sdk/ts-web/rt/test/address.test.ts index 6e63a452e9..0361945223 100644 --- a/client-sdk/ts-web/rt/test/address.test.ts +++ b/client-sdk/ts-web/rt/test/address.test.ts @@ -5,7 +5,9 @@ describe('address', () => { it('Should derive the address correctly', async () => { const pk = Buffer.from('utrdHlX///////////////////////////////////8=', 'base64'); const address = await oasisRT.address.fromSigspec({ed25519: new Uint8Array(pk)}); - expect(oasisRT.address.toBech32(address)).toEqual('oasis1qryqqccycvckcxp453tflalujvlf78xymcdqw4vz'); + expect(oasisRT.address.toBech32(address)).toEqual( + 'oasis1qryqqccycvckcxp453tflalujvlf78xymcdqw4vz', + ); }); }); @@ -13,7 +15,9 @@ describe('address', () => { it('Should derive the address correctly', async () => { const pk = Buffer.from('Arra3R5V////////////////////////////////////', 'base64'); const address = await oasisRT.address.fromSigspec({secp256k1eth: new Uint8Array(pk)}); - expect(oasisRT.address.toBech32(address)).toEqual('oasis1qzd7akz24n6fxfhdhtk977s5857h3c6gf5583mcg'); + expect(oasisRT.address.toBech32(address)).toEqual( + 'oasis1qzd7akz24n6fxfhdhtk977s5857h3c6gf5583mcg', + ); }); }); }); diff --git a/client-sdk/ts-web/rt/test/callformat.test.ts b/client-sdk/ts-web/rt/test/callformat.test.ts index 389a446517..4bf7314a45 100644 --- a/client-sdk/ts-web/rt/test/callformat.test.ts +++ b/client-sdk/ts-web/rt/test/callformat.test.ts @@ -2,33 +2,41 @@ import * as oasisRT from './../src'; import * as nacl from 'tweetnacl'; describe('callformat', () => { - describe('encodeCall/DecodeResult', () => { - it('Should encode and decode the message correctly', () => { - const message = "I will find some random message here" - const pairs = nacl.box.keyPair() - const publicKey = pairs.publicKey - const rawCall: oasisRT.types.Call = { - format: oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, - method: '', - body: message - } - const dummy = new Uint8Array() - const keyManagerPk: oasisRT.types.KeyManagerSignedPublicKey = { - key: publicKey, - checksum: dummy, - signature: dummy - } - const config: oasisRT.callformat.EncodeConfig = { - publicKey: keyManagerPk - } - const [sealedCall, meta] = oasisRT.callformat.encodeCall(rawCall, oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, config) + describe('encodeCall/DecodeResult', () => { + it('Should encode and decode the message correctly', async () => { + const message = 'I will find some random message here'; + const pairs = nacl.box.keyPair(); + const publicKey = pairs.publicKey; + const rawCall: oasisRT.types.Call = { + format: oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + method: '', + body: message, + }; + const dummy = new Uint8Array(); + const keyManagerPk: oasisRT.types.KeyManagerSignedPublicKey = { + key: publicKey, + checksum: dummy, + signature: dummy, + }; + const config: oasisRT.callformat.EncodeConfig = { + publicKey: keyManagerPk, + }; + const [sealedCall, meta] = await oasisRT.callformat.encodeCall( + rawCall, + oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + config, + ); - const fakedResult: oasisRT.types.CallResult = { - unknown: sealedCall.body as Uint8Array - } + const fakedResult: oasisRT.types.CallResult = { + unknown: sealedCall.body as Uint8Array, + }; - var decodedResult = oasisRT.callformat.decodeResult(fakedResult, oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, meta as oasisRT.callformat.MetaEncryptedX25519DeoxysII) as oasisRT.types.Call - expect(decodedResult.body).toEqual(message) + var decodedResult = await oasisRT.callformat.decodeResult( + fakedResult, + oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, + meta as oasisRT.callformat.MetaEncryptedX25519DeoxysII, + ) as oasisRT.types.Call; + expect(decodedResult.body).toEqual(message); + }); }); - }); }); diff --git a/client-sdk/ts-web/rt/test/mrae.test.ts b/client-sdk/ts-web/rt/test/mrae.test.ts index 9f78df03a4..ce7af7701b 100644 --- a/client-sdk/ts-web/rt/test/mrae.test.ts +++ b/client-sdk/ts-web/rt/test/mrae.test.ts @@ -3,14 +3,19 @@ import * as oasis from '@oasisprotocol/client'; import * as nacl from 'tweetnacl'; describe('mrae', () => { - describe('symmetricKey', () => { - it('Should drive symmetric key correctly', () => { - const privateKeyHex = "c07b151fbc1e7a11dff926111188f8d872f62eba0396da97c0a24adb75161750"; - const privateKey = oasis.misc.fromHex(privateKeyHex); - const publicKey = nacl.scalarMult.base(privateKey); - expect(oasis.misc.toHex(publicKey)).toEqual("3046db3fa70ce605457dc47c48837ebd8bd0a26abfde5994d033e1ced68e2576"); - const sharedKey = oasisRT.mraeDeoxysii.deriveSymmetricKey(publicKey, privateKey); - expect(oasis.misc.toHex(sharedKey)).toEqual("e69ac21066a8c2284e8fdc690e579af4513547b9b31dd144792c1904b45cf586"); + describe('symmetricKey', () => { + it('Should drive symmetric key correctly', () => { + const privateKeyHex = + 'c07b151fbc1e7a11dff926111188f8d872f62eba0396da97c0a24adb75161750'; + const privateKey = oasis.misc.fromHex(privateKeyHex); + const publicKey = nacl.scalarMult.base(privateKey); + expect(oasis.misc.toHex(publicKey)).toEqual( + '3046db3fa70ce605457dc47c48837ebd8bd0a26abfde5994d033e1ced68e2576', + ); + const sharedKey = oasisRT.mraeDeoxysii.deriveSymmetricKey(publicKey, privateKey); + expect(oasis.misc.toHex(sharedKey)).toEqual( + 'e69ac21066a8c2284e8fdc690e579af4513547b9b31dd144792c1904b45cf586', + ); + }); }); - }); }); From ed84b41527ed16c4af954e110f1941e96c81768e Mon Sep 17 00:00:00 2001 From: James Zheng Date: Wed, 6 Jul 2022 12:15:37 -0700 Subject: [PATCH 12/12] fix the lint issue on test code --- client-sdk/ts-web/rt/test/callformat.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client-sdk/ts-web/rt/test/callformat.test.ts b/client-sdk/ts-web/rt/test/callformat.test.ts index 4bf7314a45..7ff086f131 100644 --- a/client-sdk/ts-web/rt/test/callformat.test.ts +++ b/client-sdk/ts-web/rt/test/callformat.test.ts @@ -31,11 +31,11 @@ describe('callformat', () => { unknown: sealedCall.body as Uint8Array, }; - var decodedResult = await oasisRT.callformat.decodeResult( + var decodedResult = (await oasisRT.callformat.decodeResult( fakedResult, oasisRT.transaction.CALLFORMAT_ENCRYPTED_X25519DEOXYSII, meta as oasisRT.callformat.MetaEncryptedX25519DeoxysII, - ) as oasisRT.types.Call; + )) as oasisRT.types.Call; expect(decodedResult.body).toEqual(message); }); });