From 8d1a5db827dfa5444a9ac4adfca73b41c9853621 Mon Sep 17 00:00:00 2001 From: Asgeir Date: Fri, 28 Oct 2022 11:47:15 +0200 Subject: [PATCH] [Reality Module] Add monitoring for answers submitted for a proposal question at Reality.eth Fixes #149 --- .../RealityModule/service/monitoring.ts | 3 + .../RealityModule/service/setupService.ts | 1 + .../backend/api/monitoring/notification.ts | 108 ++++++------- .../autotasks/on_new_question_from_module.js | 95 +++++++++++ packages/backend/lib/defender/index.ts | 117 ++++++++++++++ packages/backend/lib/types.ts | 14 -- packages/backend/lib/util.ts | 22 +++ packages/backend/package.json | 1 + packages/backend/yarn.lock | 149 +++++++++++++++++- 9 files changed, 433 insertions(+), 77 deletions(-) create mode 100644 packages/backend/lib/defender/autotasks/on_new_question_from_module.js create mode 100644 packages/backend/lib/defender/index.ts diff --git a/packages/app/src/views/AddModule/wizards/RealityModule/service/monitoring.ts b/packages/app/src/views/AddModule/wizards/RealityModule/service/monitoring.ts index 7e9a8258..8422f80a 100644 --- a/packages/app/src/views/AddModule/wizards/RealityModule/service/monitoring.ts +++ b/packages/app/src/views/AddModule/wizards/RealityModule/service/monitoring.ts @@ -18,12 +18,14 @@ interface NotificationChannels { interface RequestType extends MonitoringCredentials { network: string realityModuleAddress: string + oracleAddress: string notificationChannels: NotificationChannels[] } export const setUpMonitoring = async ( network: string, realityModuleAddress: string, + oracleAddress: string, data: MonitoringSectionData, ) => { console.log() @@ -84,6 +86,7 @@ export const setUpMonitoring = async ( apiKey: data.apiKey, apiSecret: data.secretKey, network, + oracleAddress, realityModuleAddress, notificationChannels, } diff --git a/packages/app/src/views/AddModule/wizards/RealityModule/service/setupService.ts b/packages/app/src/views/AddModule/wizards/RealityModule/service/setupService.ts index dedb0512..ca01abbd 100644 --- a/packages/app/src/views/AddModule/wizards/RealityModule/service/setupService.ts +++ b/packages/app/src/views/AddModule/wizards/RealityModule/service/setupService.ts @@ -83,6 +83,7 @@ export const setup = async ( await setUpMonitoring( NETWORKS[safeInfo.chainId as NETWORK].name, realityModuleAddress, + setupData.oracle.instanceData.instanceAddress, setupData.monitoring, ).catch((e) => { statusCallback("Error when setting up monitoring.", e) diff --git a/packages/backend/api/monitoring/notification.ts b/packages/backend/api/monitoring/notification.ts index 5e3d1d0c..70aa4ba6 100644 --- a/packages/backend/api/monitoring/notification.ts +++ b/packages/backend/api/monitoring/notification.ts @@ -1,10 +1,27 @@ import type { VercelRequest, VercelResponse } from "@vercel/node" import { - CreateSentinelRequest, + setupSentinelClient, NotificationType, - SentinelClient, -} from "defender-sentinel-client" -import { Network, Body } from "../../lib/types" + setupNewNotificationChannel, + createSentinel, + createAutotask, + setupAutotaskClient, +} from "../../lib/defender" +import { Network } from "../../lib/types" + +export interface Body { + apiKey: string + apiSecret: string + network: Network + realityModuleAddress: string + oracleAddress: string + notificationChannels: [ + { + channel: NotificationType + config: any + }, + ] +} export default async (request: VercelRequest, response: VercelResponse) => { response.setHeader("Access-Control-Allow-Origin", "*") @@ -20,31 +37,41 @@ export default async (request: VercelRequest, response: VercelResponse) => { console.log("Incoming request at ", request.url) console.log("Request body", request.body) const body = request.body as Body - const { apiKey, apiSecret, notificationChannels, realityModuleAddress, network } = - body - const client = new SentinelClient({ apiKey, apiSecret }) + const { + apiKey, + apiSecret, + notificationChannels, + oracleAddress, + realityModuleAddress, + network, + } = body + const sentinelClient = setupSentinelClient({ apiKey, apiSecret }) console.log("Client is ready") const notificationChannelIds = await Promise.all( - notificationChannels.map(async ({ channel, config }) => { - const notificationChannelSetupResponds = await setupNewNotificationChannel( - client, - channel, - config, - ) - console.log( - "Notification channel set up responds", - notificationChannelSetupResponds, - ) - const { notificationId } = notificationChannelSetupResponds - return notificationId - }), + notificationChannels.map( + async ({ channel, config }) => + await setupNewNotificationChannel(sentinelClient, channel, config), + ), ) + + const autotaskClient = setupAutotaskClient({ apiKey, apiSecret }) + + const autotaskId = await createAutotask( + autotaskClient, + oracleAddress, + notificationChannelIds, + network, + apiKey, + apiSecret, + ) + const sentinelCreationResponds = await createSentinel( - client, + sentinelClient, notificationChannelIds, network, realityModuleAddress, + autotaskId, ) console.log("Sentinel creation responds", sentinelCreationResponds) return response @@ -66,42 +93,3 @@ export default async (request: VercelRequest, response: VercelResponse) => { }) } } - -const setupNewNotificationChannel = ( - client: SentinelClient, - channel: NotificationType, - config: any, -) => - client.createNotificationChannel({ - type: channel, - name: `ZodiacRealityModuleNotification-${channel}`, - config, - paused: false, - }) - -const createSentinel = ( - client: SentinelClient, - notificationChannels: string[], - network: Network, - realityModuleAddress: string, -) => { - const requestParameters: CreateSentinelRequest = { - type: "BLOCK", - network: network, - // optional - name: "New proposal added to the Reality Module", - addresses: [realityModuleAddress], - // optional - paused: false, - // optional - eventConditions: [ - { - eventSignature: "ProposalQuestionCreated(bytes32, string)", - }, - ], - // optional - notificationChannels: notificationChannels, - } - - return client.create(requestParameters) -} diff --git a/packages/backend/lib/defender/autotasks/on_new_question_from_module.js b/packages/backend/lib/defender/autotasks/on_new_question_from_module.js new file mode 100644 index 00000000..8f08d6e5 --- /dev/null +++ b/packages/backend/lib/defender/autotasks/on_new_question_from_module.js @@ -0,0 +1,95 @@ +const { SentinelClient } = require("defender-sentinel-client") + +const PROPOSAL_QUESTION_CREATED_EVENT_TOPIC = + "0xa1f5047031a658827550a2c4be07648493f3ac88a09c857b3961d1336429a31f" // Keccak-256("ProposalQuestionCreated(bytes32,string)") + +// @param event: AutotaskEvent +exports.handler = async function (event) { + // variable from the event + const evmEvent = event.request.body.transaction.logs.find( + (log) => log.topics[0] === PROPOSAL_QUESTION_CREATED_EVENT_TOPIC, + ) + const questionId = evmEvent.topics[1] + console.log("QuestionId to monitor for:", questionId) + const txHash = event.request.body.transaction.transactionHash + const txFrom = event.request.body.transaction.from + + // variables from autotask creation + const network = "{{network}}" + const oracleAddress = "{{oracleAddress}}" + const notificationChannels = "{{notificationChannels}}" + const apiKey = "{{apiKey}}" + const apiSecret = "{{apiSecret}}" + + const client = new SentinelClient({ + apiKey, + apiSecret, + }) + + const requestParameters = { + type: "BLOCK", + network, + name: `Answer submitted for a proposal question at Reality.eth for the Reality Module (on ${network})`, + addresses: [oracleAddress], + paused: false, + abi: `[{ + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "answer", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "history_hash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bond", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ts", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "is_commitment", + "type": "bool" + } + ], + "name": "LogNewAnswer", + "type": "event" + }]`, + eventConditions: [ + { + eventSignature: + "LogNewAnswer(bytes32,bytes32,bytes32,address,uint256,uint256,bool)", + expression: `$1 == "${questionId}"`, + }, + ], + notificationChannels: notificationChannels, + } + + return client.create(requestParameters) +} diff --git a/packages/backend/lib/defender/index.ts b/packages/backend/lib/defender/index.ts new file mode 100644 index 00000000..59623a50 --- /dev/null +++ b/packages/backend/lib/defender/index.ts @@ -0,0 +1,117 @@ +import { + CreateSentinelRequest, + NotificationType, + SentinelClient, +} from "defender-sentinel-client" +import { AutotaskClient } from "defender-autotask-client" +import { CreateAutotaskRequest } from "defender-autotask-client" +import { Network } from "../../lib/types" +import { packageCode, readFileAndReplace } from "../util" + +export { NotificationType } from "defender-sentinel-client" + +export const setupSentinelClient = ({ apiKey, apiSecret }) => + new SentinelClient({ apiKey, apiSecret }) + +export const setupAutotaskClient = ({ apiKey, apiSecret }) => + new AutotaskClient({ apiKey, apiSecret }) + +export const setupNewNotificationChannel = async ( + client: SentinelClient, + channel: NotificationType, + config: any, +) => { + const notificationChannel = await client.createNotificationChannel({ + type: channel, + name: `ZodiacRealityModuleNotification-${channel}`, + config, + paused: false, + }) + console.log( + "Created Notification Channel with ID: ", + notificationChannel.notificationId, + ) + + return notificationChannel.notificationId +} + +export const createSentinel = async ( + client: SentinelClient, + notificationChannels: string[], + network: Network, + realityModuleAddress: string, + autotaskId: string, +) => { + const requestParameters: CreateSentinelRequest = { + type: "BLOCK", + network, + name: `Proposal added to the Reality Module (${realityModuleAddress} on ${network})`, + addresses: [realityModuleAddress], + paused: false, + abi: `[{ + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "questionId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "string", + "name": "proposalId", + "type": "string" + } + ], + "name": "ProposalQuestionCreated", + "type": "event" + }]`, + eventConditions: [ + { + eventSignature: "ProposalQuestionCreated(bytes32,string)", + }, + ], + autotaskTrigger: autotaskId, + notificationChannels: notificationChannels, + } + + const sentinel = await client.create(requestParameters) + console.log("Created Sentinel with subscriber ID: ", sentinel.subscriberId) + + return sentinel.subscriberId +} + +export const createAutotask = async ( + client: AutotaskClient, + oracleAddress: string, + notificationChannels: string[], + network: string, + apiKey: string, + apiSecret: string, +) => { + const code = readFileAndReplace( + "lib/defender/autotasks/on_new_question_from_module.js", + { + "{{network}}": network, + "{{oracleAddress}}": oracleAddress, + '"{{notificationChannels}}"': JSON.stringify(notificationChannels), + "{{apiKey}}": apiKey, + "{{apiSecret}}": apiSecret, + }, + ) + + const params: CreateAutotaskRequest = { + name: "Setup Sentinel for new Reality.eth question", + encodedZippedCode: await packageCode(code), + trigger: { + type: "webhook", + }, + paused: false, + } + + const createdAutotask = await client.create(params) + console.log("Created Autotask with ID: ", createdAutotask.autotaskId) + + return createdAutotask.autotaskId +} diff --git a/packages/backend/lib/types.ts b/packages/backend/lib/types.ts index 6fb0e779..9f2b8343 100644 --- a/packages/backend/lib/types.ts +++ b/packages/backend/lib/types.ts @@ -1,21 +1,7 @@ -import { NotificationType } from "defender-sentinel-client" - export interface Query { apiKey: string apiSecret: string } -export interface Body { - apiKey: string - apiSecret: string - network: Network - realityModuleAddress: string - notificationChannels: [ - { - channel: NotificationType - config: any - }, - ] -} export type Network = | "mainnet" diff --git a/packages/backend/lib/util.ts b/packages/backend/lib/util.ts index 001f1f29..63366b4c 100644 --- a/packages/backend/lib/util.ts +++ b/packages/backend/lib/util.ts @@ -1,3 +1,6 @@ +import fs from "fs" +import JSZip from "jszip" + export const getEnv = (name: string) => { const val = process.env[name] if (val == null) { @@ -5,3 +8,22 @@ export const getEnv = (name: string) => { } return val } + +export const readFileAndReplace = ( + filePath: string, + replaceMap: { [toReplace: string]: string }, +) => { + const buffer = fs.readFileSync(filePath) + let fileContent = buffer.toString() + Object.keys(replaceMap).forEach((key) => { + fileContent = fileContent.replace(key, replaceMap[key]) + }) + return fileContent +} + +export const packageCode = async (code: string) => { + const zip = new JSZip() + zip.file("index.js", code, { binary: false }) + const zippedCode = await zip.generateAsync({ type: "nodebuffer" }) + return zippedCode.toString("base64") +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 58d0634e..fc36cbf5 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,6 +12,7 @@ "dependencies": { "@snapshot-labs/snapshot.js": "^0.4.36", "@vercel/node": "^2.5.21", + "defender-autotask-client": "^1.34.0", "defender-sentinel-client": "^1.33.0", "node-fetch": "2", "ramda": "^0.28.0" diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock index c055f18a..35fcc7d0 100644 --- a/packages/backend/yarn.lock +++ b/packages/backend/yarn.lock @@ -610,6 +610,11 @@ convert-hrtime@^3.0.0: resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-3.0.0.tgz#62c7593f5809ca10be8da858a6d2f702bcda00aa" integrity sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cross-fetch@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" @@ -622,6 +627,19 @@ crypto-js@^4.0.0: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== +defender-autotask-client@^1.34.0: + version "1.34.0" + resolved "https://registry.yarnpkg.com/defender-autotask-client/-/defender-autotask-client-1.34.0.tgz#616b8f955185bad75af2079502db4bffbdfc7242" + integrity sha512-Gvnk8WYmNvtJjX/VJc9krqFHnT2JtKYpeA76KU6ozNQEkMlndOC7tXBGv8LwhXFVbj9e38o7qg6mzqwC6vOtfw== + dependencies: + axios "^0.21.2" + defender-base-client "1.34.0" + dotenv "^10.0.0" + glob "^7.1.6" + jszip "^3.5.0" + lodash "^4.17.19" + node-fetch "^2.6.0" + defender-base-client@1.31.1: version "1.31.1" resolved "https://registry.yarnpkg.com/defender-base-client/-/defender-base-client-1.31.1.tgz#4f060e1911d07b1309a9424824bd2b69987a25c4" @@ -633,6 +651,17 @@ defender-base-client@1.31.1: lodash "^4.17.19" node-fetch "^2.6.0" +defender-base-client@1.34.0: + version "1.34.0" + resolved "https://registry.yarnpkg.com/defender-base-client/-/defender-base-client-1.34.0.tgz#8dcae9b56c2a5d5433054fd9bdf662b4049b4bc9" + integrity sha512-A4/7z0PYX3XwbohQQGIFXX0qP8TgrVNvIWKiq2h4Q9t/F4ejJgvSthi18f5cKaepBntsszIdcidI8Ci7cX0l2w== + dependencies: + amazon-cognito-identity-js "^4.3.3" + async-retry "^1.3.3" + axios "^0.21.2" + lodash "^4.17.19" + node-fetch "^2.6.0" + defender-sentinel-client@^1.33.0: version "1.33.0" resolved "https://registry.yarnpkg.com/defender-sentinel-client/-/defender-sentinel-client-1.33.0.tgz#77465dd7254216e5c856a96fe0c70d48188d755c" @@ -654,6 +683,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + edge-runtime@1.1.0-beta.32: version "1.1.0-beta.32" resolved "https://registry.yarnpkg.com/edge-runtime/-/edge-runtime-1.1.0-beta.32.tgz#e43fd53c57fdba3c567b3fef50743cba00ff5e49" @@ -862,6 +896,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -869,6 +908,18 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -896,7 +947,20 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -inherits@^2.0.3, inherits@^2.0.4: +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -918,7 +982,7 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -isarray@^1.0.0: +isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== @@ -959,6 +1023,23 @@ json-to-graphql-query@^2.2.4: resolved "https://registry.yarnpkg.com/json-to-graphql-query/-/json-to-graphql-query-2.2.4.tgz#ada9cfdbb9bf38589fd2661e1588d1edd0a882cc" integrity sha512-vNvsOKDSlEqYCzejI1xHS9Hm738dSnG4Upy09LUGqyybZXSIIb7NydDphB/6WxW2EEVpPU4JeU/Yo63Nw9dEJg== +jszip@^3.5.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -1009,7 +1090,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.4: +minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -1033,6 +1114,18 @@ node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parse-ms@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" @@ -1043,6 +1136,11 @@ path-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + picocolors@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -1065,6 +1163,11 @@ pretty-ms@7.0.1: dependencies: parse-ms "^2.1.0" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -1080,6 +1183,19 @@ ramda@^0.28.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== +readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -1102,11 +1218,21 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + scrypt-js@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + source-map-support@^0.5.17: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -1120,6 +1246,13 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + time-span@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/time-span/-/time-span-4.0.0.tgz#fe74cd50a54e7998712f90ddfe47109040c985c4" @@ -1180,6 +1313,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -1193,6 +1331,11 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + ws@7.4.6: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"