Add bot script to tip kudos recipients. Closes #21
This commit is contained in:
parent
8c701a61fa
commit
3f3282e19c
|
@ -25,7 +25,7 @@
|
|||
],
|
||||
"env": {
|
||||
"DEBUG": "true",
|
||||
"KUDOS_BOT_CONFIG": "{'options':{'process_whole_history':true},'slack':{'channel_id':'C8P4F6WTB'},'rules':{'tip_per_kudo_in_usd':0.02,'tip_per_reaction_in_usd':0.001,'reaction_threshold':3},'payments':{'STT':{'network_id':'ropsten','private_key':'0xaaaa','contract_address':'0xc55cF4B03948D7EBc8b9E8BAD92643703811d162'},'SNT':{'network_id':'homestead','private_key':'0xaaaa','contract_address':'0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'}}}",
|
||||
"KUDOS_BOT_CONFIG": "{'options':{'inter_transaction_delay':20},'slack':{'channel_id':'C8P4F6WTB'},'rules':{'tip_per_kudo_in_usd':2,'tip_per_reaction_in_usd':0.2,'reaction_threshold':3},'payments':{'STT':{'network_id':'ropsten','private_key':'0xef04012ca9314315db69e27c8cfc8b99f529775a1503605223449f5b7f0e334b','contract_address':'0xc55cF4B03948D7EBc8b9E8BAD92643703811d162'},'SNT':{'network_id':'homestead','private_key':'0xecf69ec4a078f7010667c72ad40d0aad35bbdf9289dd484961281b5f89e2f866','contract_address':'0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'}}}",
|
||||
"MEMCACHE_URL": "",
|
||||
"MEMCACHE_USERNAME": "",
|
||||
"MEMCACHE_PASSWORD": ""
|
||||
|
|
|
@ -0,0 +1,302 @@
|
|||
// Description:
|
||||
// Script that monitors #kudos Slack channel and sends
|
||||
// a tip for each star attributes to target users
|
||||
//
|
||||
// Dependencies:
|
||||
// axios: "^0.18.0"
|
||||
// memjs: "^1.2.0"
|
||||
//
|
||||
// Author:
|
||||
// PombeirP
|
||||
|
||||
const axios = require('axios')
|
||||
const tokenPayments = require('../lib/token-payments')
|
||||
|
||||
const options = getOptions(process.env.KUDOS_BOT_CONFIG)
|
||||
const botName = 'tip-kudos-recipients'
|
||||
const kudosChannelId = options.slack.channel_id
|
||||
const tipPerKudoInUsd = parseFloat(options.rules.tip_per_kudo_in_usd)
|
||||
const tipPerReactionInUsd = parseFloat(options.rules.tip_per_reaction_in_usd)
|
||||
const reactionThreshold = parseInt(options.rules.reaction_threshold)
|
||||
const interTransactionDelay = parseInt(options.options.inter_transaction_delay)
|
||||
|
||||
const tokenID = process.env.DEBUG ? 'STT' : 'SNT'
|
||||
const token = options.payments[tokenID]
|
||||
const privateKey = token.private_key
|
||||
const contractAddress = token.contract_address
|
||||
|
||||
const kudosBotDataMemcachedKey = 'tip-kudos-recipients-data'
|
||||
const userIdRegex = /@[A-Z0-9]+/gi
|
||||
var isCheckingUpdates = false
|
||||
|
||||
module.exports = robot => {
|
||||
if (!privateKey.startsWith('0x')) {
|
||||
robot.log.error(`${botName} - Private key must start with 0x. Disabling script`)
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(() => processKudosChannelUpdates(robot), process.env.DISABLE_DELAY ? 1 * 1000 : 30 * 1000)
|
||||
setInterval(() => processKudosChannelUpdates(robot), 24 * 60 * 60 * 1000)
|
||||
}
|
||||
|
||||
function getOptions (optionsString) {
|
||||
return JSON.parse(optionsString.split(`'`).join(`"`))
|
||||
}
|
||||
|
||||
async function processKudosChannelUpdates (robot) {
|
||||
if (isCheckingUpdates) {
|
||||
return
|
||||
}
|
||||
|
||||
isCheckingUpdates = true
|
||||
try {
|
||||
const mc = robot['memcache']
|
||||
const data = await getSavedData(mc)
|
||||
|
||||
await fetchPendingKudos(robot, data)
|
||||
|
||||
try {
|
||||
await processPendingPayments(robot, data, d => setSavedData(mc, d))
|
||||
} catch (error) {
|
||||
robot.log.warn(`${botName} - Failed to make payment: ${error.responseText}`)
|
||||
}
|
||||
} catch (error) {
|
||||
robot.log.error(`${botName} - Error while processing kudos: ${error}`)
|
||||
} finally {
|
||||
isCheckingUpdates = false
|
||||
}
|
||||
}
|
||||
|
||||
async function getSavedData (mc) {
|
||||
const json = await mc.get(kudosBotDataMemcachedKey)
|
||||
if (json.value) {
|
||||
const data = JSON.parse(json.value)
|
||||
if (!data.hasOwnProperty('lastMessageTimestamp') || !data.hasOwnProperty('userPendingPayouts')) {
|
||||
throw new Error(`${botName} - Invalid cached data`)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
return {
|
||||
lastMessageTimestamp: (new Date(2017, 1, 1)).getTime() / 1000,
|
||||
userPendingPayouts: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function setSavedData (mc, data) {
|
||||
if (!data.hasOwnProperty('lastMessageTimestamp') || !data.hasOwnProperty('userPendingPayouts')) {
|
||||
throw new Error(`${botName} - Invalid data, saving aborted`)
|
||||
}
|
||||
|
||||
return mc.set(kudosBotDataMemcachedKey, JSON.stringify(data, {}, 2), {})
|
||||
}
|
||||
|
||||
async function fetchPendingKudos (robot, data) {
|
||||
const slackWeb = robot.slackWeb
|
||||
const startTime = (new Date()).getTime()
|
||||
const thresholdTs = startTime / 1000 - 24 * 60 * 60
|
||||
let newMessagesProcessed = 0
|
||||
|
||||
while (true) {
|
||||
const historyPayload = await slackWeb.channels.history(kudosChannelId, { oldest: data.lastMessageTimestamp })
|
||||
if (historyPayload.ok) {
|
||||
if (!historyPayload.has_more && newMessagesProcessed === 0) {
|
||||
robot.log.debug(`${botName} - No new entries in ${kudosChannelId} channel history`)
|
||||
break
|
||||
}
|
||||
|
||||
for (const message of historyPayload.messages.reverse()) {
|
||||
const messageTs = parseFloat(message.ts)
|
||||
if (messageTs >= thresholdTs) {
|
||||
// If the kudos was given less than 24 hours ago, let's ignore it
|
||||
// and leave it for a later time, so that people have time to vote
|
||||
continue
|
||||
}
|
||||
if (message.type !== 'message' || message.subtype || !message.bot_id) {
|
||||
continue
|
||||
}
|
||||
|
||||
++newMessagesProcessed
|
||||
|
||||
const kudosReceivers = parseKudosReceivers(message.attachments[0].text)
|
||||
const kudosTimestamp = new Date(message.ts * 1000).toISOString()
|
||||
if (kudosReceivers.length > 0) {
|
||||
const reactionCount = countStarReactions(message, kudosReceivers)
|
||||
if (reactionCount >= reactionThreshold) {
|
||||
const additionalReactionCount = reactionCount - 1
|
||||
const totalTip = tipPerKudoInUsd + additionalReactionCount * tipPerReactionInUsd
|
||||
const tipPerUser = totalTip / kudosReceivers.length
|
||||
const kudosReceiversData = await fetchKudosReceiversData(robot, kudosReceivers, slackWeb)
|
||||
|
||||
robot.log.trace(`${botName} - ${kudosTimestamp}: ${JSON.stringify(kudosReceiversData)} received ${reactionCount} reactions (~${tipPerUser}$ each)`)
|
||||
|
||||
for (const userInfo of kudosReceiversData) {
|
||||
let userPendingPayout = data.userPendingPayouts[userInfo.user]
|
||||
if (!userPendingPayout) {
|
||||
userPendingPayout = { kudosCount: 0, reactionCount: 0, balanceInUsd: 0 }
|
||||
data.userPendingPayouts[userInfo.user] = userPendingPayout
|
||||
}
|
||||
|
||||
userPendingPayout.kudosCount++
|
||||
userPendingPayout.reactionCount += additionalReactionCount
|
||||
userPendingPayout.balanceInUsd += tipPerUser
|
||||
}
|
||||
} else {
|
||||
robot.log.trace(`${botName} - ${kudosTimestamp}: ${JSON.stringify(kudosReceivers)} only received ${reactionCount} reactions`)
|
||||
}
|
||||
} else {
|
||||
robot.log.trace(`${botName} - ${kudosTimestamp}: No receivers`)
|
||||
}
|
||||
|
||||
if (!data.lastMessageTimestamp || messageTs > data.lastMessageTimestamp) {
|
||||
data.lastMessageTimestamp = messageTs
|
||||
}
|
||||
}
|
||||
|
||||
if (!historyPayload.has_more) {
|
||||
robot.log.debug(`${botName} - Reached end of ${kudosChannelId} channel history`)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
robot.log.debug(`${botName} - Failed to fetch ${kudosChannelId} channel history`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
async function processPendingPayments (robot, data, saveStateAsyncFunc) {
|
||||
if (!process.env.DEBUG && !contractAddress) {
|
||||
return
|
||||
}
|
||||
|
||||
const tokenPrice = await getTokenPrice(tokenID)
|
||||
const slackProfileCache = robot['slackProfileCache']
|
||||
|
||||
const { contract, wallet } = tokenPayments.getContract(contractAddress, privateKey, token.network_id)
|
||||
|
||||
// Sort users from lowest to highest balance
|
||||
const sortedUsers = Object.keys(data.userPendingPayouts).sort((a, b) => compareBalances(data.userPendingPayouts, a, b))
|
||||
|
||||
// Print stats
|
||||
robot.log.debug(`User name\tAmount (${tokenID})\t# Kudos\t# Reactions\tPub key`)
|
||||
for (const slackUserId of sortedUsers) {
|
||||
const userPendingPayout = data.userPendingPayouts[slackUserId]
|
||||
const slackUsername = await slackProfileCache.getSlackUsernameFromSlackId(slackUserId)
|
||||
const pubkey = await slackProfileCache.getMainnetPubKeyFromSlackId(slackUserId)
|
||||
const tokenBalance = getTokenBalance(userPendingPayout.balanceInUsd, tokenPrice)
|
||||
|
||||
robot.log.debug(`@${slackUsername}\t${tokenBalance}\t${userPendingPayout.kudosCount}\t${userPendingPayout.reactionCount}\t${pubkey}`)
|
||||
}
|
||||
|
||||
// Make payments
|
||||
let totalPayments = 0
|
||||
for (const slackUserId of sortedUsers) {
|
||||
const userPendingPayout = data.userPendingPayouts[slackUserId]
|
||||
const slackUsername = await slackProfileCache.getSlackUsernameFromSlackId(slackUserId)
|
||||
const pubkey = await slackProfileCache.getMainnetPubKeyFromSlackId(slackUserId)
|
||||
|
||||
if (pubkey && userPendingPayout.balanceInUsd > 0) {
|
||||
const tokenBalance = getTokenBalance(userPendingPayout.balanceInUsd, tokenPrice)
|
||||
totalPayments += tokenBalance
|
||||
|
||||
try {
|
||||
const transaction = await tokenPayments.transfer(contract, wallet, pubkey, (process.env.DEBUG ? '0.0001' : tokenBalance.toString()))
|
||||
|
||||
// Reset the outstanding payout values
|
||||
delete data.userPendingPayouts[slackUserId]
|
||||
robot.log.info(`${botName} - Made payment to @${slackUsername} (https://etherscan.io/tx/${transaction.hash}): ${JSON.stringify(transaction)}`)
|
||||
|
||||
await saveStateAsyncFunc(data)
|
||||
} catch (error) {
|
||||
robot.log.warn(`${botName} - Failed to make payment to @${slackUsername}: ${error}`)
|
||||
}
|
||||
|
||||
// Need to wait for a bit between transactions, otherwise we start receiving errors
|
||||
if (interTransactionDelay > 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, interTransactionDelay * 1000))
|
||||
}
|
||||
}
|
||||
}
|
||||
robot.log.debug(`Total payments: ${totalPayments}`)
|
||||
}
|
||||
|
||||
function compareBalances (userToPendingPayouts, a, b) {
|
||||
const x = userToPendingPayouts[a]
|
||||
const y = userToPendingPayouts[b]
|
||||
|
||||
if (x.balanceInUsd > y.balanceInUsd) {
|
||||
return 1
|
||||
}
|
||||
if (x.balanceInUsd < y.balanceInUsd) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function getTokenBalance (balanceInUsd, tokenPrice) {
|
||||
return Math.round(balanceInUsd / tokenPrice * 100) / 100
|
||||
}
|
||||
|
||||
async function fetchKudosReceiversData (robot, kudosReceivers, slackWeb) {
|
||||
const slackProfileCache = robot['slackProfileCache']
|
||||
const result = []
|
||||
|
||||
for (const user of kudosReceivers) {
|
||||
const pubkey = await slackProfileCache.getMainnetPubKeyFromSlackId(user)
|
||||
|
||||
result.push({ user: user, pubkey: pubkey })
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function parseKudosReceivers (message) {
|
||||
const match = message.match(userIdRegex)
|
||||
|
||||
const result = []
|
||||
if (match) {
|
||||
for (const k of match) {
|
||||
result.push(k.substring(1))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function countStarReactions (message, kudosReceivers) {
|
||||
let reactionCount = 0
|
||||
if (message.reactions) {
|
||||
const starsRegex = /> \*(\d+) :star:s\s+\*/g
|
||||
reactionCount = getReactionCount(starsRegex, message.text)
|
||||
if (reactionCount === 0) {
|
||||
const reactionsRegex = /> \*`(\d+)` Reactions?\s+\*/g
|
||||
reactionCount = getReactionCount(reactionsRegex, message.text)
|
||||
}
|
||||
}
|
||||
|
||||
return reactionCount
|
||||
}
|
||||
|
||||
function getReactionCount (regex, text) {
|
||||
let reactionCount = 0
|
||||
let m
|
||||
|
||||
if ((m = regex.exec(text)) !== null) {
|
||||
reactionCount = parseInt(m[1])
|
||||
}
|
||||
|
||||
return reactionCount
|
||||
}
|
||||
|
||||
async function getTokenPrice (tokenID) {
|
||||
if (tokenID === 'STT') {
|
||||
tokenID = 'SNT'
|
||||
}
|
||||
|
||||
const currency = 'USD'
|
||||
const response = await axios.get(`https://min-api.cryptocompare.com/data/price?fsym=${tokenID}&tsyms=${currency}`)
|
||||
const tokenPrice = parseFloat(response.data[currency])
|
||||
return tokenPrice
|
||||
}
|
29
index.js
29
index.js
|
@ -1,4 +1,16 @@
|
|||
// Description:
|
||||
// Startup script
|
||||
//
|
||||
// Dependencies:
|
||||
// mem-cache: "0.0.5"
|
||||
// memjs: "^1.2.0"
|
||||
// @slack/client: "^3.16.0"
|
||||
//
|
||||
// Author:
|
||||
// PombeirP
|
||||
|
||||
const Slack = require('./lib/slack')
|
||||
const memjs = require('memjs')
|
||||
|
||||
module.exports = async (robot) => {
|
||||
console.log('Yay, the app was loaded!')
|
||||
|
@ -11,6 +23,7 @@ module.exports = async (robot) => {
|
|||
robot.log.trace = console.log
|
||||
}
|
||||
|
||||
setupMemcache(robot)
|
||||
await setupSlack(robot)
|
||||
|
||||
robot['slackProfileCache'] = require('./lib/slack-profile-cache')(robot)
|
||||
|
@ -23,6 +36,7 @@ module.exports = async (robot) => {
|
|||
require('./bot_scripts/trigger-automation-test-build')(robot)
|
||||
require('./bot_scripts/bounty-awaiting-approval-slack-ping')(robot)
|
||||
require('./bot_scripts/notify-reviewers-via-slack')(robot)
|
||||
require('./bot_scripts/tip-kudos-recipients')(robot)
|
||||
|
||||
// For more information on building apps:
|
||||
// https://probot.github.io/docs/
|
||||
|
@ -46,3 +60,18 @@ async function setupSlack (robot) {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
function setupMemcache (robot) {
|
||||
// Environment variables are defined in .env
|
||||
let MEMCACHE_URL = process.env.MEMCACHE_URL || '127.0.0.1:11211'
|
||||
if (process.env.USE_GAE_MEMCACHE) {
|
||||
MEMCACHE_URL = `${process.env.GAE_MEMCACHE_HOST}:${process.env.GAE_MEMCACHE_PORT}`
|
||||
}
|
||||
const mc = memjs.Client.create(MEMCACHE_URL, {
|
||||
username: process.env.MEMCACHE_USERNAME,
|
||||
password: process.env.MEMCACHE_PASSWORD
|
||||
})
|
||||
|
||||
// Copy memcache client to the robot object
|
||||
robot['memcache'] = mc
|
||||
}
|
||||
|
|
|
@ -3,29 +3,19 @@
|
|||
//
|
||||
// Dependencies:
|
||||
// mem-cache: "0.0.5"
|
||||
// memjs: "^1.2.0"
|
||||
// @slack/client: "^3.16.0"
|
||||
//
|
||||
// Author:
|
||||
// PombeirP
|
||||
|
||||
const MemCache = require('mem-cache')
|
||||
const memjs = require('memjs')
|
||||
const { WebClient } = require('@slack/client')
|
||||
|
||||
const token = process.env.SLACK_USER_TOKEN || ''
|
||||
const cacheMemcachedKey = 'slack-profile-cache-json'
|
||||
var allowLoadFromCache = true
|
||||
|
||||
// Environment variables are defined in app.yaml.
|
||||
let MEMCACHE_URL = process.env.MEMCACHE_URL || '127.0.0.1:11211'
|
||||
if (process.env.USE_GAE_MEMCACHE) {
|
||||
MEMCACHE_URL = `${process.env.GAE_MEMCACHE_HOST}:${process.env.GAE_MEMCACHE_PORT}`
|
||||
}
|
||||
const mc = memjs.Client.create(MEMCACHE_URL, {
|
||||
username: process.env.MEMCACHE_USERNAME,
|
||||
password: process.env.MEMCACHE_PASSWORD
|
||||
})
|
||||
|
||||
module.exports = (robot) => new GitHubSlackIdMapper(robot)
|
||||
|
||||
class GitHubSlackIdMapper {
|
||||
|
@ -68,20 +58,37 @@ class GitHubSlackIdMapper {
|
|||
}
|
||||
return `<@${id}>`
|
||||
}
|
||||
|
||||
async getMainnetPubKeyFromSlackId (slackUserId) {
|
||||
await this.buildPromise
|
||||
const profile = this.cache.get(getSlackId2ProfileCacheKeyName(slackUserId))
|
||||
if (profile) {
|
||||
return profile.pubkey
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function internalBuild (robot, cache) {
|
||||
if (allowLoadFromCache) {
|
||||
const mc = robot['memcache']
|
||||
|
||||
if (allowLoadFromCache && mc) {
|
||||
try {
|
||||
const json = await mc.get(cacheMemcachedKey)
|
||||
if (json.value) {
|
||||
const cacheFromFile = JSON.parse(json.value)
|
||||
for (const kvp of cacheFromFile) {
|
||||
if (kvp.k.startsWith('Slack-') && !kvp.v.hasOwnProperty('pubkey')) {
|
||||
cache.clean()
|
||||
break
|
||||
}
|
||||
cache.set(kvp.k, kvp.v)
|
||||
}
|
||||
robot.log.info(`Read Slack user cache from ${MEMCACHE_URL} (${cache.length} entries)`)
|
||||
allowLoadFromCache = false
|
||||
return
|
||||
if (cache.length > 0) {
|
||||
robot.log.info(`Read Slack user cache from Memcached (${cache.length} entries)`)
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore
|
||||
|
@ -97,8 +104,11 @@ async function internalBuild (robot, cache) {
|
|||
const activeUsersList = usersList.members.filter(u => !u.deleted && !u.is_bot && u.id !== 'USLACKBOT')
|
||||
|
||||
let gitHubFieldId = null
|
||||
let pubKeyFieldId = null
|
||||
let usersMissingGitHubInfo = []
|
||||
let usersMissingMainnetAddress = []
|
||||
let usersContainingGitHubInfo = []
|
||||
let usersWithMainnetPubkey = 0
|
||||
let rateLimitWait = 10000
|
||||
let profileFetchPreviousBatchCount = 3
|
||||
let profileFetchBatchCount = 0
|
||||
|
@ -107,17 +117,24 @@ async function internalBuild (robot, cache) {
|
|||
|
||||
try {
|
||||
++profileFetchBatchCount
|
||||
const { profile } = await slackWeb.users.profile.get({ user: user.id, include_labels: !gitHubFieldId })
|
||||
const { profile } = await slackWeb.users.profile.get({ user: user.id, include_labels: !gitHubFieldId || !pubKeyFieldId })
|
||||
const username = profile.display_name_normalized || profile.real_name_normalized
|
||||
|
||||
if (!gitHubFieldId) {
|
||||
// Find the field ID for the field with the 'Github ID' label
|
||||
gitHubFieldId = findProfileLabelId(profile, 'Github ID')
|
||||
}
|
||||
if (!pubKeyFieldId) {
|
||||
// Find the field ID for the field with the 'Mainnet Address' label
|
||||
pubKeyFieldId = findProfileLabelId(profile, 'Mainnet Address')
|
||||
}
|
||||
|
||||
if (!gitHubFieldId) {
|
||||
robot.log.warn(`No GitHub ID field found in @${username} (${user.id}) profile!`)
|
||||
}
|
||||
if (!pubKeyFieldId) {
|
||||
robot.log.warn(`No Mainnet Address field found in @${username} (${user.id}) profile!`)
|
||||
}
|
||||
|
||||
const gitHubUsername = gitHubFieldId && profile.fields && profile.fields[gitHubFieldId] ? profile.fields[gitHubFieldId].value.replace('https://github.com/', '') : null
|
||||
if (gitHubUsername) {
|
||||
|
@ -126,7 +143,14 @@ async function internalBuild (robot, cache) {
|
|||
usersMissingGitHubInfo = usersMissingGitHubInfo.concat(username)
|
||||
}
|
||||
|
||||
const data = { name: username, github_handle: gitHubUsername }
|
||||
const pubkey = profile.fields && profile.fields[pubKeyFieldId] ? profile.fields[pubKeyFieldId].value : null
|
||||
if (pubkey) {
|
||||
++usersWithMainnetPubkey
|
||||
} else {
|
||||
usersMissingMainnetAddress = usersMissingMainnetAddress.concat(username)
|
||||
}
|
||||
|
||||
const data = { name: username, github_handle: gitHubUsername, pubkey: pubkey }
|
||||
|
||||
robot.log.debug(`@${username} (${user.id}) -> ${JSON.stringify(data)}`)
|
||||
|
||||
|
@ -157,6 +181,10 @@ async function internalBuild (robot, cache) {
|
|||
if (usersMissingGitHubInfo) {
|
||||
robot.log.warn(`The following ${usersMissingGitHubInfo.length} Slack users have no GitHub info in their profiles: ${usersMissingGitHubInfo.map(s => '@' + s).join(', ')}`)
|
||||
}
|
||||
if (usersMissingMainnetAddress) {
|
||||
robot.log.warn(`The following ${usersMissingMainnetAddress.length} Slack users have no Mainnet address in their profiles: ${usersMissingMainnetAddress.map(s => '@' + s).join(', ')}`)
|
||||
}
|
||||
robot.log.info(`${usersWithMainnetPubkey} users in ${activeUsersList.length} have a mainnet public key address configured`)
|
||||
|
||||
// Write cache out to JSON file for faster startup next time
|
||||
const c = []
|
||||
|
@ -166,7 +194,7 @@ async function internalBuild (robot, cache) {
|
|||
|
||||
if (mc) {
|
||||
try {
|
||||
await mc.set(cacheMemcachedKey, c, {})
|
||||
await mc.set(cacheMemcachedKey, JSON.stringify(c, {}, 2), {})
|
||||
robot.log.info(`Saved cache to Memcached`)
|
||||
} catch (error) {
|
||||
robot.log.warn(`Error while saving cache to Memcached: ${error}`)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// Description:
|
||||
// Ethereum token payment logic
|
||||
//
|
||||
// Dependencies:
|
||||
// ethers: "^3.0.8",
|
||||
//
|
||||
// Author:
|
||||
// PombeirP
|
||||
|
||||
const ethers = require('ethers')
|
||||
const { Wallet, Contract, providers } = ethers
|
||||
|
||||
const ERC20_ABI = [
|
||||
{
|
||||
'constant': false,
|
||||
'inputs': [
|
||||
{
|
||||
'name': '_to',
|
||||
'type': 'address'
|
||||
},
|
||||
{
|
||||
'name': '_amount',
|
||||
'type': 'uint256'
|
||||
}
|
||||
],
|
||||
'name': 'transfer',
|
||||
'outputs': [
|
||||
{
|
||||
'name': 'success',
|
||||
'type': 'bool'
|
||||
}
|
||||
],
|
||||
'payable': false,
|
||||
'type': 'function'
|
||||
}
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
getContract: _getContract,
|
||||
transfer: _transfer
|
||||
}
|
||||
|
||||
let transaction = null
|
||||
let hash = null
|
||||
|
||||
function _getContract (contractAddress, privateKey, networkId) {
|
||||
const network = providers.Provider.getNetwork(networkId)
|
||||
const wallet = new Wallet(privateKey, ethers.providers.getDefaultProvider(network))
|
||||
|
||||
async function customSendTransaction (tx) {
|
||||
hash = await wallet.provider.sendTransaction(tx)
|
||||
return hash
|
||||
}
|
||||
async function customSignTransaction (tx) {
|
||||
transaction = tx
|
||||
return wallet.sign(tx)
|
||||
}
|
||||
|
||||
const customSigner = _getCustomSigner(wallet, customSignTransaction, customSendTransaction)
|
||||
const contract = new Contract(contractAddress, ERC20_ABI, customSigner)
|
||||
|
||||
return { contract: contract, wallet: wallet }
|
||||
}
|
||||
|
||||
async function _transfer (contract, wallet, pubkey, tokenAmount) {
|
||||
const bigNumberAmount = ethers.utils.parseUnits(tokenAmount.toString(), 'ether')
|
||||
|
||||
await contract.transfer(pubkey, bigNumberAmount)
|
||||
|
||||
transaction.hash = hash
|
||||
transaction.from = wallet.address
|
||||
transaction.value = bigNumberAmount
|
||||
|
||||
return transaction
|
||||
}
|
||||
|
||||
function _getCustomSigner (wallet, signTransaction, sendTransaction) {
|
||||
const provider = wallet.provider
|
||||
|
||||
async function getAddress () { return wallet.address }
|
||||
|
||||
async function resolveName (addressOrName) { return provider.resolveName(addressOrName) }
|
||||
async function estimateGas (transaction) { return provider.estimateGas(transaction) }
|
||||
async function getGasPrice () { return process.env.DEBUG ? 5000000 : provider.getGasPrice() }
|
||||
async function getTransactionCount (blockTag) { return provider.getTransactionCount(blockTag) }
|
||||
|
||||
const customSigner = {
|
||||
getAddress: getAddress,
|
||||
provider: {
|
||||
resolveName: resolveName,
|
||||
estimateGas: estimateGas,
|
||||
getGasPrice: getGasPrice,
|
||||
getTransactionCount: getTransactionCount,
|
||||
sendTransaction: sendTransaction
|
||||
},
|
||||
sign: signTransaction
|
||||
}
|
||||
|
||||
return customSigner
|
||||
}
|
|
@ -15,6 +15,59 @@
|
|||
"js-tokens": "3.0.2"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "15.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.2.0.tgz",
|
||||
"integrity": "sha512-Dn56HRk3445JiZOHIKNWyLjfm3DEWEOfomcfON8Fm6mV+aFtzntuEmcnUIHHdIL7RPuMAFF3aE74CXMW+JpA2w==",
|
||||
"requires": {
|
||||
"before-after-hook": "1.1.0",
|
||||
"btoa-lite": "1.0.0",
|
||||
"debug": "3.1.0",
|
||||
"http-proxy-agent": "2.1.0",
|
||||
"https-proxy-agent": "2.2.1",
|
||||
"lodash": "4.17.4",
|
||||
"node-fetch": "2.1.2",
|
||||
"url-template": "2.0.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
|
||||
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
|
||||
"requires": {
|
||||
"agent-base": "4.2.0",
|
||||
"debug": "3.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/webhooks": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-3.1.1.tgz",
|
||||
"integrity": "sha512-VqpGDClqhLw5sKV+or5AnkPmUyur/Oktr9paqiR+yH69Tew9QA/vXHjKP4zctxj5PVAsOdTQFhSzP53qbNLVOg==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"debug": "3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@slack/client": {
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@slack/client/-/client-3.16.0.tgz",
|
||||
|
@ -241,7 +294,6 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
|
||||
"integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "5.3.0"
|
||||
}
|
||||
|
@ -261,6 +313,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"aes-js": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
|
||||
"integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
|
||||
|
@ -432,8 +489,7 @@
|
|||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
|
@ -450,6 +506,33 @@
|
|||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
||||
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
|
||||
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
|
||||
"requires": {
|
||||
"follow-redirects": "1.4.1",
|
||||
"is-buffer": "1.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz",
|
||||
"integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==",
|
||||
"requires": {
|
||||
"debug": "3.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
|
@ -715,6 +798,11 @@
|
|||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz",
|
||||
"integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
|
||||
|
@ -728,6 +816,11 @@
|
|||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "4.11.8",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
||||
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||
|
@ -777,11 +870,15 @@
|
|||
"repeat-element": "1.1.2"
|
||||
}
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
|
||||
},
|
||||
"browser-process-hrtime": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
|
||||
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44="
|
||||
},
|
||||
"browser-resolve": {
|
||||
"version": "1.11.2",
|
||||
|
@ -806,6 +903,11 @@
|
|||
"node-int64": "0.4.0"
|
||||
}
|
||||
},
|
||||
"btoa-lite": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
|
||||
"integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc="
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
|
@ -915,6 +1017,11 @@
|
|||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
|
||||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
|
||||
},
|
||||
"charenc": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||
},
|
||||
"ci-info": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
|
||||
|
@ -1116,6 +1223,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"crypt": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
|
||||
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
|
||||
|
@ -1322,15 +1434,52 @@
|
|||
"esutils": "2.0.2"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
||||
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
|
||||
"requires": {
|
||||
"domelementtype": "1.1.3",
|
||||
"entities": "1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
|
||||
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
|
||||
}
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
|
||||
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
|
||||
},
|
||||
"domexception": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
|
||||
"integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"webidl-conversions": "4.0.2"
|
||||
}
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
|
||||
"integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
|
||||
"requires": {
|
||||
"domelementtype": "1.3.0"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
|
||||
"requires": {
|
||||
"dom-serializer": "0.1.0",
|
||||
"domelementtype": "1.3.0"
|
||||
}
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz",
|
||||
|
@ -1373,11 +1522,27 @@
|
|||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
|
||||
"integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
|
||||
"integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
|
||||
"requires": {
|
||||
"bn.js": "4.11.8",
|
||||
"brorand": "1.1.0",
|
||||
"hash.js": "1.1.3",
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
|
||||
"integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
|
||||
"integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz",
|
||||
|
@ -1549,9 +1714,9 @@
|
|||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "4.17.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.17.0.tgz",
|
||||
"integrity": "sha512-AyxBUCANU/o/xC0ijGMKavo5Ls3oK6xykiOITlMdjFjrKOsqLrA7Nf5cnrDgcKrHzBirclAZt63XO7YZlVUPwA==",
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
|
||||
"integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
|
||||
"requires": {
|
||||
"ajv": "5.5.2",
|
||||
"babel-code-frame": "6.26.0",
|
||||
|
@ -1562,13 +1727,13 @@
|
|||
"doctrine": "2.1.0",
|
||||
"eslint-scope": "3.7.1",
|
||||
"eslint-visitor-keys": "1.0.0",
|
||||
"espree": "3.5.2",
|
||||
"espree": "3.5.4",
|
||||
"esquery": "1.0.0",
|
||||
"esutils": "2.0.2",
|
||||
"file-entry-cache": "2.0.0",
|
||||
"functional-red-black-tree": "1.0.1",
|
||||
"glob": "7.1.2",
|
||||
"globals": "11.3.0",
|
||||
"globals": "11.4.0",
|
||||
"ignore": "3.3.7",
|
||||
"imurmurhash": "0.1.4",
|
||||
"inquirer": "3.3.0",
|
||||
|
@ -1584,6 +1749,7 @@
|
|||
"path-is-inside": "1.0.2",
|
||||
"pluralize": "7.0.0",
|
||||
"progress": "2.0.0",
|
||||
"regexpp": "1.0.1",
|
||||
"require-uncached": "1.0.3",
|
||||
"semver": "5.5.0",
|
||||
"strip-ansi": "4.0.0",
|
||||
|
@ -1592,6 +1758,11 @@
|
|||
"text-table": "0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
|
||||
"integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
|
@ -1600,6 +1771,15 @@
|
|||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"espree": {
|
||||
"version": "3.5.4",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
|
||||
"integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
|
||||
"requires": {
|
||||
"acorn": "5.5.3",
|
||||
"acorn-jsx": "3.0.1"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
|
@ -1614,9 +1794,9 @@
|
|||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz",
|
||||
"integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw=="
|
||||
"version": "11.4.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz",
|
||||
"integrity": "sha512-Dyzmifil8n/TmSqYDEXbm+C8yitzJQqQIlJQLNRMwa+BOUJpRC19pyVeN12JAjt61xonvXjtff+hJruTRXn5HA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1814,6 +1994,7 @@
|
|||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
|
||||
"integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "5.3.0",
|
||||
"acorn-jsx": "3.0.1"
|
||||
|
@ -1856,6 +2037,35 @@
|
|||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"ethers": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-3.0.8.tgz",
|
||||
"integrity": "sha512-SdPjKGd95/+oo/G+72dBUVO9A/z1LipcCr5keb8RFh8o7xUBsx+pwskUJKzup1E5oCqnrrYOt6g4ypx14/wUzA==",
|
||||
"requires": {
|
||||
"aes-js": "3.0.0",
|
||||
"bn.js": "4.11.8",
|
||||
"elliptic": "6.3.3",
|
||||
"hash.js": "1.1.3",
|
||||
"inherits": "2.0.1",
|
||||
"js-sha3": "0.5.7",
|
||||
"scrypt-js": "2.0.3",
|
||||
"setimmediate": "1.0.4",
|
||||
"uuid": "2.0.1",
|
||||
"xmlhttprequest": "1.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
|
||||
}
|
||||
}
|
||||
},
|
||||
"event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
|
@ -3216,6 +3426,15 @@
|
|||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||
"dev": true
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
||||
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
||||
"requires": {
|
||||
"inherits": "2.0.3",
|
||||
"minimalistic-assert": "1.0.0"
|
||||
}
|
||||
},
|
||||
"hashmap": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/hashmap/-/hashmap-2.3.0.tgz",
|
||||
|
@ -3276,6 +3495,19 @@
|
|||
"whatwg-encoding": "1.0.3"
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.9.2",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
|
||||
"integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
|
||||
"requires": {
|
||||
"domelementtype": "1.3.0",
|
||||
"domhandler": "2.4.1",
|
||||
"domutils": "1.7.0",
|
||||
"entities": "1.1.1",
|
||||
"inherits": "2.0.3",
|
||||
"readable-stream": "2.0.6"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
||||
|
@ -3299,6 +3531,25 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
|
||||
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
|
||||
"requires": {
|
||||
"agent-base": "4.2.0",
|
||||
"debug": "3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
|
@ -4209,6 +4460,11 @@
|
|||
"merge-stream": "1.0.1"
|
||||
}
|
||||
},
|
||||
"js-sha3": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
||||
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
|
@ -4233,7 +4489,6 @@
|
|||
"version": "11.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.6.2.tgz",
|
||||
"integrity": "sha512-pAeZhpbSlUp5yQcS6cBQJwkbzmv4tWFaYxHbFVSxzXefqjvtRA851Z5N2P+TguVG9YeUDcgb8pdeVQRJh0XR3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "1.0.4",
|
||||
"acorn": "5.3.0",
|
||||
|
@ -4266,14 +4521,12 @@
|
|||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
|
||||
"dev": true
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
},
|
||||
"ws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-4.0.0.tgz",
|
||||
"integrity": "sha512-QYslsH44bH8O7/W2815u5DpnCpXWpEK44FmaHffNwgJI4JMaSZONgPBTOfrxJ29mXKbXak+LsJ2uAkDTYq2ptQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
|
@ -4422,8 +4675,7 @@
|
|||
"left-pad": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz",
|
||||
"integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4="
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
|
@ -4513,8 +4765,7 @@
|
|||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
|
||||
},
|
||||
"longest": {
|
||||
"version": "1.0.1",
|
||||
|
@ -4551,6 +4802,16 @@
|
|||
"tmpl": "1.0.4"
|
||||
}
|
||||
},
|
||||
"md5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
|
||||
"integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
|
||||
"requires": {
|
||||
"charenc": "0.0.2",
|
||||
"crypt": "0.0.2",
|
||||
"is-buffer": "1.1.6"
|
||||
}
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -4641,6 +4902,11 @@
|
|||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
|
||||
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
|
||||
"integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
|
@ -4729,6 +4995,11 @@
|
|||
"resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz",
|
||||
"integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
|
||||
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
|
||||
},
|
||||
"node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
|
@ -4988,8 +5259,7 @@
|
|||
"parse5": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
|
||||
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.2",
|
||||
|
@ -5167,8 +5437,7 @@
|
|||
"pn": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
|
||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
|
@ -6114,6 +6383,11 @@
|
|||
"is-equal-shallow": "0.1.3"
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.0.1.tgz",
|
||||
"integrity": "sha512-8Ph721maXiOYSLtaDGKVmDn5wdsNaF6Px85qFNeMPQq0r8K5Y10tgP6YuR65Ws35n4DvzFcCxEnRNBIXQunzLw=="
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
|
@ -6177,7 +6451,6 @@
|
|||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
|
||||
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
|
@ -6186,7 +6459,6 @@
|
|||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
|
||||
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.1",
|
||||
"stealthy-require": "1.1.1",
|
||||
|
@ -6344,6 +6616,11 @@
|
|||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"scrypt-js": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
|
||||
"integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
|
@ -6385,6 +6662,11 @@
|
|||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
|
||||
"integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48="
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||
|
@ -6942,8 +7224,7 @@
|
|||
"stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"dev": true
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||
},
|
||||
"stream-consume": {
|
||||
"version": "0.1.0",
|
||||
|
@ -7137,7 +7418,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
|
||||
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "2.1.0"
|
||||
},
|
||||
|
@ -7145,8 +7425,7 @@
|
|||
"punycode": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
|
||||
"integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -7221,6 +7500,97 @@
|
|||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
|
||||
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
|
||||
},
|
||||
"unfurl": {
|
||||
"version": "github:probot/unfurl#2931ec3b8c16717fba76555b2ffdd30e3d3126e0",
|
||||
"requires": {
|
||||
"ejs": "2.5.7",
|
||||
"jsdom": "11.6.2",
|
||||
"probot": "6.1.0",
|
||||
"probot-attachments": "github:probot/attachments#c17f86a1bc9e3fc7c7dac1038d77f9ff0c7a5617",
|
||||
"unfurl.js": "1.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"bottleneck": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.2.2.tgz",
|
||||
"integrity": "sha512-2b24YzUWbbyTdUmCOvIZ8f7CTcVtRpYaFChq63RIZegxIrISTTHGtnK5GqxKS6h1lxUydUF/taMjQvn81gwKTQ=="
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
|
||||
"integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
|
||||
},
|
||||
"express-async-errors": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-2.1.1.tgz",
|
||||
"integrity": "sha512-iI7wKVK1SvmmEe368hWPkX25nOh3gTcgIlTqlre/m7iduLiSa4vCsYhlVlTtBFYl+nkLHRm8jOI+2/8jUceJJQ==",
|
||||
"requires": {
|
||||
"express": "4.16.2"
|
||||
}
|
||||
},
|
||||
"probot": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/probot/-/probot-6.1.0.tgz",
|
||||
"integrity": "sha512-yQwAB+KdTJLyO8jyke0s7CdR/PHqj9ySWn+6f4hCGcr0fLeVOBiTjnXVCrnf6+QdYJfKtoqlTovxgfBLMF9Xew==",
|
||||
"requires": {
|
||||
"@octokit/rest": "15.2.0",
|
||||
"@octokit/webhooks": "3.1.1",
|
||||
"bottleneck": "2.2.2",
|
||||
"bunyan": "1.8.12",
|
||||
"bunyan-format": "0.2.1",
|
||||
"bunyan-sentry-stream": "1.2.1",
|
||||
"cache-manager": "2.6.0",
|
||||
"commander": "2.13.0",
|
||||
"dotenv": "5.0.1",
|
||||
"express": "4.16.2",
|
||||
"express-async-errors": "2.1.1",
|
||||
"github-webhook-handler": "0.7.1",
|
||||
"hbs": "4.0.1",
|
||||
"js-yaml": "3.10.0",
|
||||
"jsonwebtoken": "8.1.0",
|
||||
"pkg-conf": "2.1.0",
|
||||
"promise-events": "0.1.4",
|
||||
"raven": "2.4.2",
|
||||
"resolve": "1.5.0",
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"probot-attachments": {
|
||||
"version": "github:probot/attachments#c17f86a1bc9e3fc7c7dac1038d77f9ff0c7a5617"
|
||||
},
|
||||
"raven": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/raven/-/raven-2.4.2.tgz",
|
||||
"integrity": "sha1-ASnircMHiGRv1TC2fQioziXU9tw=",
|
||||
"requires": {
|
||||
"cookie": "0.3.1",
|
||||
"md5": "2.2.1",
|
||||
"stack-trace": "0.0.9",
|
||||
"timed-out": "4.0.1",
|
||||
"uuid": "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"unfurl.js": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/unfurl.js/-/unfurl.js-1.1.6.tgz",
|
||||
"integrity": "sha1-L2Ycvov50xtvbsIv4eGnFKJFxN8=",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"htmlparser2": "3.9.2",
|
||||
"lodash": "4.17.4",
|
||||
"pify": "2.3.0",
|
||||
"request": "2.83.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
|
||||
}
|
||||
}
|
||||
},
|
||||
"uniq": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
||||
|
@ -7247,6 +7617,11 @@
|
|||
"requires-port": "1.0.0"
|
||||
}
|
||||
},
|
||||
"url-template": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||
"integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
|
||||
},
|
||||
"user-home": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
|
||||
|
@ -7309,7 +7684,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
||||
"integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-process-hrtime": "0.1.2"
|
||||
}
|
||||
|
@ -7363,7 +7737,6 @@
|
|||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz",
|
||||
"integrity": "sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.sortby": "4.7.0",
|
||||
"tr46": "1.0.1",
|
||||
|
@ -7409,6 +7782,71 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"wip-bot": {
|
||||
"version": "github:gr2m/wip-bot#0a9786db57d01f3c7c789fdf0d6f93ce11accbb1",
|
||||
"requires": {
|
||||
"probot": "6.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bottleneck": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.2.2.tgz",
|
||||
"integrity": "sha512-2b24YzUWbbyTdUmCOvIZ8f7CTcVtRpYaFChq63RIZegxIrISTTHGtnK5GqxKS6h1lxUydUF/taMjQvn81gwKTQ=="
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
|
||||
"integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
|
||||
},
|
||||
"express-async-errors": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-2.1.1.tgz",
|
||||
"integrity": "sha512-iI7wKVK1SvmmEe368hWPkX25nOh3gTcgIlTqlre/m7iduLiSa4vCsYhlVlTtBFYl+nkLHRm8jOI+2/8jUceJJQ==",
|
||||
"requires": {
|
||||
"express": "4.16.2"
|
||||
}
|
||||
},
|
||||
"probot": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/probot/-/probot-6.1.0.tgz",
|
||||
"integrity": "sha512-yQwAB+KdTJLyO8jyke0s7CdR/PHqj9ySWn+6f4hCGcr0fLeVOBiTjnXVCrnf6+QdYJfKtoqlTovxgfBLMF9Xew==",
|
||||
"requires": {
|
||||
"@octokit/rest": "15.2.0",
|
||||
"@octokit/webhooks": "3.1.1",
|
||||
"bottleneck": "2.2.2",
|
||||
"bunyan": "1.8.12",
|
||||
"bunyan-format": "0.2.1",
|
||||
"bunyan-sentry-stream": "1.2.1",
|
||||
"cache-manager": "2.6.0",
|
||||
"commander": "2.13.0",
|
||||
"dotenv": "5.0.1",
|
||||
"express": "4.16.2",
|
||||
"express-async-errors": "2.1.1",
|
||||
"github-webhook-handler": "0.7.1",
|
||||
"hbs": "4.0.1",
|
||||
"js-yaml": "3.10.0",
|
||||
"jsonwebtoken": "8.1.0",
|
||||
"pkg-conf": "2.1.0",
|
||||
"promise-events": "0.1.4",
|
||||
"raven": "2.4.2",
|
||||
"resolve": "1.5.0",
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"raven": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/raven/-/raven-2.4.2.tgz",
|
||||
"integrity": "sha1-ASnircMHiGRv1TC2fQioziXU9tw=",
|
||||
"requires": {
|
||||
"cookie": "0.3.1",
|
||||
"md5": "2.2.1",
|
||||
"stack-trace": "0.0.9",
|
||||
"timed-out": "4.0.1",
|
||||
"uuid": "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
|
@ -7494,8 +7932,12 @@
|
|||
"xml-name-validator": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
|
||||
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
|
||||
},
|
||||
"xmlhttprequest": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
|
||||
"integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "2.1.2",
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@slack/client": "^3.16.0",
|
||||
"eslint": "^4.17.0",
|
||||
"axios": "^0.18.0",
|
||||
"eslint": "^4.19.1",
|
||||
"ethers": "^3.0.8",
|
||||
"hashmap": "^2.3.0",
|
||||
"hashset": "0.0.6",
|
||||
"jenkins": "^0.20.1",
|
||||
|
|
Loading…
Reference in New Issue