commit
ae55e8a3c1
@ -0,0 +1,24 @@ |
||||
const Config = require('./recipient-blacklist-config.json') |
||||
|
||||
/** @module*/ |
||||
module.exports = { |
||||
checkAccount, |
||||
} |
||||
|
||||
/** |
||||
* Checks if a specified account on a specified network is blacklisted. |
||||
@param networkId {number} |
||||
@param account {string} |
||||
*/ |
||||
function checkAccount (networkId, account) { |
||||
|
||||
const mainnetId = 1 |
||||
if (networkId !== mainnetId) { |
||||
return |
||||
} |
||||
|
||||
const accountToCheck = account.toLowerCase() |
||||
if (Config.blacklist.includes(accountToCheck)) { |
||||
throw new Error('Recipient is a public account') |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
{ |
||||
"blacklist": [ |
||||
"0x627306090abab3a6e1400e9345bc60c78a8bef57", |
||||
"0xf17f52151ebef6c7334fad080c5704d77216b732", |
||||
"0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef", |
||||
"0x821aea9a577a9b44299b9c15c88cf3087f3b5544", |
||||
"0x0d1d4e623d10f9fba5db95830f7d3839406c6af2", |
||||
"0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e", |
||||
"0x2191ef87e392377ec08e7c08eb105ef5448eced5", |
||||
"0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5", |
||||
"0x6330a553fc93768f612722bb8c2ec78ac90b3bbc", |
||||
"0x5aeda56215b167893e80b4fe645ba6d5bab767de" |
||||
] |
||||
} |
@ -1,22 +0,0 @@ |
||||
class BugNotifier { |
||||
notify (uri, message) { |
||||
return postData(uri, message) |
||||
} |
||||
} |
||||
|
||||
function postData(uri, data) { |
||||
return fetch(uri, { |
||||
body: JSON.stringify(data), // must match 'Content-Type' header
|
||||
credentials: 'same-origin', // include, same-origin, *omit
|
||||
headers: { |
||||
'content-type': 'application/json', |
||||
}, |
||||
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||
mode: 'cors', // no-cors, cors, *same-origin
|
||||
}) |
||||
} |
||||
|
||||
const notifier = new BugNotifier() |
||||
|
||||
module.exports = notifier |
||||
|
@ -0,0 +1,71 @@ |
||||
class DiagnosticsReporter { |
||||
|
||||
constructor ({ firstTimeInfo, version }) { |
||||
this.firstTimeInfo = firstTimeInfo |
||||
this.version = version |
||||
} |
||||
|
||||
async reportOrphans(orphans) { |
||||
try { |
||||
return await this.submit({ |
||||
accounts: Object.keys(orphans), |
||||
metadata: { |
||||
type: 'orphans', |
||||
}, |
||||
}) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "reportOrphans" encountered an error:') |
||||
console.error(err) |
||||
} |
||||
} |
||||
|
||||
async reportMultipleKeyrings(rawKeyrings) { |
||||
try { |
||||
const keyrings = await Promise.all(rawKeyrings.map(async (keyring, index) => { |
||||
return { |
||||
index, |
||||
type: keyring.type, |
||||
accounts: await keyring.getAccounts(), |
||||
} |
||||
})) |
||||
return await this.submit({ |
||||
accounts: [], |
||||
metadata: { |
||||
type: 'keyrings', |
||||
keyrings, |
||||
}, |
||||
}) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "reportMultipleKeyrings" encountered an error:') |
||||
console.error(err) |
||||
} |
||||
} |
||||
|
||||
async submit (message) { |
||||
try { |
||||
// add metadata
|
||||
message.metadata.version = this.version |
||||
message.metadata.firstTimeInfo = this.firstTimeInfo |
||||
return await postData(message) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "submit" encountered an error:') |
||||
throw err |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
function postData(data) { |
||||
const uri = 'https://diagnostics.metamask.io/v1/orphanedAccounts' |
||||
return fetch(uri, { |
||||
body: JSON.stringify(data), // must match 'Content-Type' header
|
||||
credentials: 'same-origin', // include, same-origin, *omit
|
||||
headers: { |
||||
'content-type': 'application/json', |
||||
}, |
||||
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||
mode: 'cors', // no-cors, cors, *same-origin
|
||||
}) |
||||
} |
||||
|
||||
module.exports = DiagnosticsReporter |
@ -0,0 +1,77 @@ |
||||
const assert = require('assert') |
||||
const recipientBlackListChecker = require('../../../../../app/scripts/controllers/transactions/lib/recipient-blacklist-checker') |
||||
const { |
||||
ROPSTEN_CODE, |
||||
RINKEYBY_CODE, |
||||
KOVAN_CODE, |
||||
} = require('../../../../../app/scripts/controllers/network/enums') |
||||
|
||||
const KeyringController = require('eth-keyring-controller') |
||||
|
||||
describe('Recipient Blacklist Checker', function () { |
||||
|
||||
let publicAccounts |
||||
|
||||
before(async function () { |
||||
const damnedMnemonic = 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat' |
||||
const keyringController = new KeyringController({}) |
||||
const Keyring = keyringController.getKeyringClassForType('HD Key Tree') |
||||
const opts = { |
||||
mnemonic: damnedMnemonic, |
||||
numberOfAccounts: 10, |
||||
} |
||||
const keyring = new Keyring(opts) |
||||
publicAccounts = await keyring.getAccounts() |
||||
}) |
||||
|
||||
describe('#checkAccount', function () { |
||||
it('does not fail on test networks', function () { |
||||
let callCount = 0 |
||||
const networks = [ROPSTEN_CODE, RINKEYBY_CODE, KOVAN_CODE] |
||||
for (let networkId in networks) { |
||||
publicAccounts.forEach((account) => { |
||||
recipientBlackListChecker.checkAccount(networkId, account) |
||||
callCount++ |
||||
}) |
||||
} |
||||
assert.equal(callCount, 30) |
||||
}) |
||||
|
||||
it('fails on mainnet', function () { |
||||
const mainnetId = 1 |
||||
let callCount = 0 |
||||
publicAccounts.forEach((account) => { |
||||
try { |
||||
recipientBlackListChecker.checkAccount(mainnetId, account) |
||||
assert.fail('function should have thrown an error') |
||||
} catch (err) { |
||||
assert.equal(err.message, 'Recipient is a public account') |
||||
} |
||||
callCount++ |
||||
}) |
||||
assert.equal(callCount, 10) |
||||
}) |
||||
|
||||
it('fails for public account - uppercase', function () { |
||||
const mainnetId = 1 |
||||
const publicAccount = '0X0D1D4E623D10F9FBA5DB95830F7D3839406C6AF2' |
||||
try { |
||||
recipientBlackListChecker.checkAccount(mainnetId, publicAccount) |
||||
assert.fail('function should have thrown an error') |
||||
} catch (err) { |
||||
assert.equal(err.message, 'Recipient is a public account') |
||||
} |
||||
})
|
||||
|
||||
it('fails for public account - lowercase', async function () { |
||||
const mainnetId = 1 |
||||
const publicAccount = '0x0d1d4e623d10f9fba5db95830f7d3839406c6af2' |
||||
try { |
||||
await recipientBlackListChecker.checkAccount(mainnetId, publicAccount) |
||||
assert.fail('function should have thrown an error') |
||||
} catch (err) { |
||||
assert.equal(err.message, 'Recipient is a public account') |
||||
} |
||||
})
|
||||
}) |
||||
}) |
@ -1,15 +0,0 @@ |
||||
const extend = require('xtend') |
||||
|
||||
module.exports = reduceIdentities |
||||
|
||||
function reduceIdentities (state, action) { |
||||
// clone + defaults
|
||||
var idState = extend({ |
||||
|
||||
}, state.identities) |
||||
|
||||
switch (action.type) { |
||||
default: |
||||
return idState |
||||
} |
||||
} |
Loading…
Reference in new issue