Merge pull request #145 from gnosis/development

v0.1.0
This commit is contained in:
Germán Martínez 2019-07-26 12:01:00 +02:00 committed by GitHub
commit 1bfa8ad88d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
441 changed files with 24919 additions and 236843 deletions

View File

@ -1,25 +0,0 @@
{
"presets": [
"@babel/react",
"@babel/preset-flow",
[
"@babel/env",
{
"forceAllTransforms": true
}
],
["@babel/preset-stage-0", { "decoratorsLegacy": true }]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"transform-es3-member-expression-literals",
"transform-es3-property-literals"
],
"env": {
"test": {
"plugins": [
"dynamic-import-node"
]
}
}
}

View File

@ -1,8 +1,5 @@
{
"extends": [
"airbnb",
"plugin:flowtype/recommended"
],
"extends": ["airbnb", "plugin:flowtype/recommended"],
"parser": "babel-eslint",
"plugins": ["jest", "flowtype"],
"rules": {
@ -27,19 +24,23 @@
"import/extensions": 0,
"import/prefer-default-export": 0,
"jsx-a11y/label-has-for": 0,
"indent": ["error", 2],
"indent": ["error", 2, { "SwitchCase": 1 }],
"no-console": ["error", { "allow": ["warn", "error"] }],
"flowtype/require-valid-file-annotation": [
2,
"always", {
"always",
{
"annotationStyle": "line"
}
],
"jsx-a11y/anchor-is-valid": [ "error", {
"components": [ "Link" ],
"specialLink": [ "to", "hrefLeft", "hrefRight" ],
"aspects": [ "noHref", "invalidHref", "preferButton" ]
}],
"jsx-a11y/anchor-is-valid": [
"error",
{
"components": ["Link"],
"specialLink": ["to", "hrefLeft", "hrefRight"],
"aspects": ["noHref", "invalidHref", "preferButton"]
}
],
"react/require-default-props": 0,
"react/no-array-index-key": 0
},

4
.gitignore vendored
View File

@ -1,4 +1,6 @@
node_modules/
build_webpack/
build_storybook/
.DS_Store
.DS_Store
build/
yarn-error.log

View File

@ -1,10 +1,11 @@
if: (branch = development) OR (branch = master) OR (type = pull_request) OR (tag IS present)
sudo: required
dist: xenial
services:
- docker
language: node_js
node_js:
- "9"
- "10"
os:
- linux
env:
@ -23,6 +24,8 @@ before_install:
# Needed to deploy pull request and releases
- sudo apt-get -y install python-pip python-dev
- pip install awscli --upgrade --user
# Install truffle
- yarn global add truffle
before_script:
# Used in the tests of the project
- export NODE_ENV=testing

49
babel.config.js Normal file
View File

@ -0,0 +1,49 @@
// @flow
module.exports = {
presets: [
'@babel/react',
'@babel/preset-flow',
[
'@babel/env',
{
forceAllTransforms: true,
},
],
],
plugins: [
'react-hot-loader/babel',
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-member-expression-literals',
'@babel/plugin-transform-property-literals',
'@babel/plugin-syntax-import-meta',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-json-strings',
[
'@babel/plugin-proposal-decorators',
{
legacy: true,
},
],
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-logical-assignment-operators',
'@babel/plugin-proposal-optional-chaining',
[
'@babel/plugin-proposal-pipeline-operator',
{
proposal: 'minimal',
},
],
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-do-expressions',
'@babel/plugin-proposal-function-bind',
],
env: {
test: {
plugins: ['dynamic-import-node'],
},
},
}

View File

@ -1,12 +1,13 @@
// @flow
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/tutorial-webpack.html
module.exports = {
process() {
return 'module.exports = {};';
return 'module.exports = {};'
},
getCacheKey(fileData, filename) {
// The output is always the same.
return 'cssTransform';
return 'cssTransform'
},
};
}

View File

@ -1,10 +1,11 @@
const path = require('path');
// @flow
const path = require('path')
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/tutorial-webpack.html
module.exports = {
process(src, filename) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
return `module.exports = ${JSON.stringify(path.basename(filename))};`
},
};
}

View File

@ -1,14 +1,15 @@
// @flow
if (typeof Promise === 'undefined') {
// Rejection tracking prevents a common issue where React gets into an
// inconsistent state due to an error, but it gets swallowed by a Promise,
// and the user has no idea what causes React's erratic future behavior.
require('promise/lib/rejection-tracking').enable();
window.Promise = require('promise/lib/es6-extensions.js');
require('promise/lib/rejection-tracking').enable()
window.Promise = require('promise/lib/es6-extensions.js')
}
// fetch() polyfill for making API calls.
require('whatwg-fetch');
require('whatwg-fetch')
// Object.assign() is commonly used with React.
// It will use the native implementation if it's present and isn't buggy.
Object.assign = require('object-assign');
Object.assign = require('object-assign')

View File

@ -1,47 +1,47 @@
/*eslint-disable*/
const autoprefixer = require('autoprefixer');
const cssmixins = require('postcss-mixins');
const cssvars = require('postcss-simple-vars');
const webpack = require('webpack');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const autoprefixer = require('autoprefixer')
const cssmixins = require('postcss-mixins')
const cssvars = require('postcss-simple-vars')
const webpack = require('webpack')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const paths = require('./paths');
const getClientEnvironment = require('./env');
const paths = require('./paths')
const getClientEnvironment = require('./env')
const publicPath = '/';
const publicPath = '/'
// `publicUrl` we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var publicUrl = '';
var publicUrl = ''
// Get environment variables to inject into our app.
var env = getClientEnvironment(publicUrl);
var env = getClientEnvironment(publicUrl)
const cssvariables = require(paths.appSrc + '/theme/variables');
const cssvariables = require(paths.appSrc + '/theme/variables')
const postcssPlugins = [
autoprefixer({
browsers: [
overrideBrowserslist: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
]
],
}),
cssmixins,
cssvars({
variables: function () {
return Object.assign({}, cssvariables);
variables: function() {
return Object.assign({}, cssvariables)
},
silent: false
silent: false,
}),
];
]
module.exports = {
devtool: 'eval-source-map',
mode: 'development',
entry: [
"babel-polyfill",
'babel-polyfill',
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
@ -56,17 +56,13 @@ module.exports = {
// We ship a few polyfills by default:
require.resolve('./polyfills'),
// Finally, this is your app's code:
paths.appIndexJs
paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
],
resolve: {
modules: [
paths.appSrc,
'node_modules',
paths.appContracts,
],
modules: [paths.appSrc, 'node_modules', paths.appContracts],
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
@ -75,7 +71,7 @@ module.exports = {
alias: {
'~': paths.appSrc,
'#': paths.appContracts,
}
},
},
output: {
// Next line is not used in dev but WebpackDevServer crashes without it:
@ -87,28 +83,29 @@ module.exports = {
// containing code from all our entry points, and the Webpack runtime.
filename: 'static/js/bundle.js',
// This is the URL that app is served from. We use "/" in development.
publicPath: publicPath
},
publicPath: publicPath,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
loader: 'babel-loader',
},
},
{
test: /\.(scss|css)$/,
use: [
'style-loader',
{ loader: 'css-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
minimize: false,
localIdentName: '[name]__[local]___[hash:base64:5]',
}
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
},
{
loader: 'postcss-loader',
@ -123,22 +120,24 @@ module.exports = {
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: false }
}
]
loader: 'html-loader',
options: { minimize: false },
},
],
},
{
test: /\.(jpe?g|png|svg)$/i,
exclude: /node_modules/,
use: [{
loader: "file-loader",
options: {
name: 'img/[hash].[ext]'
}
}]
use: [
{
loader: 'file-loader',
options: {
name: 'img/[hash].[ext]',
},
},
],
},
]
],
},
plugins: [
new HtmlWebPackPlugin({
@ -152,6 +151,6 @@ module.exports = {
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
tls: 'empty',
},
}

View File

@ -1,7 +1,7 @@
/*eslint-disable*/
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const autoprefixer = require('autoprefixer')
const cssmixins = require('postcss-mixins');
const cssmixins = require('postcss-mixins')
const cssvars = require('postcss-simple-vars')
const webpack = require('webpack')
@ -9,8 +9,10 @@ const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')
const url = require('url')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const url = require('url')
const paths = require('./paths')
const getClientEnvironment = require('./env')
@ -18,7 +20,7 @@ const cssvariables = require(`${paths.appSrc}/theme/variables`)
const postcssPlugins = [
autoprefixer({
browsers: [
overrideBrowserslist: [
'>1%',
'last 4 versions',
'Firefox ESR',
@ -77,7 +79,7 @@ module.exports = {
bail: true,
optimization: {
splitChunks: {
chunks: "all",
chunks: 'all',
/* https://stackoverflow.com/questions/48985780/webpack-4-create-vendor-chunk
cacheGroups: {
vendor: {
@ -90,11 +92,9 @@ module.exports = {
},
*/
},
minimizer: [new OptimizeCSSAssetsPlugin({})],
},
entry: [
require.resolve('./polyfills'),
paths.appIndexJs,
],
entry: [require.resolve('./polyfills'), paths.appIndexJs],
output: {
// The build folder.
path: paths.appBuild,
@ -107,11 +107,7 @@ module.exports = {
publicPath,
},
resolve: {
modules: [
paths.appSrc,
'node_modules',
paths.appContracts,
],
modules: [paths.appSrc, 'node_modules', paths.appContracts],
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
@ -134,36 +130,35 @@ module.exports = {
},
{
test: /\.(scss|css)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
minimize: true,
},
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: postcssPlugins,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: postcssPlugins,
},
],
}),
},
],
},
{
test: /\.(jpe?g|png|svg)$/i,
exclude: /node_modules/,
use: [{
loader: "file-loader",
options: {
name: 'img/[hash].[ext]'
}
}]
use: [
{
loader: 'file-loader',
options: {
name: 'img/[hash].[ext]',
},
},
],
},
],
},
@ -190,10 +185,9 @@ module.exports = {
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin({
new MiniCssExtractPlugin({
filename: 'static/css/[name].[hash:8].css',
allChunks: true
allChunks: 'static/css/[id].[hash:8].css',
}),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without

View File

@ -0,0 +1,6 @@
pragma solidity ^0.5.2;
import "../src/test/contracts/TokenOMG.sol";
import "../src/test/contracts/TokenRDN.sol";
contract DevDependenciesGetter {}

23
contracts/Migrations.sol Normal file
View File

@ -0,0 +1,23 @@
pragma solidity ^0.5.2;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor () public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

28
jest.config.js Normal file
View File

@ -0,0 +1,28 @@
// @flow
const esModules = ['immortal-db'].join('|')
module.exports = {
collectCoverageFrom: ['src/**/*.{js,jsx}'],
moduleNameMapper: {
'~(.*)$': '<rootDir>/src/$1',
'#(.*)$': '<rootDir>/safe-contracts/build/contracts/$1',
'^react-native$': 'react-native-web',
},
setupFiles: [
'<rootDir>/config/webpack.config.test.js',
'<rootDir>/config/polyfills.js',
'<rootDir>/config/jest/LocalStorageMock.js',
'<rootDir>/config/jest/Web3Mock.js',
],
setupFilesAfterEnv: ['<rootDir>/config/jest/jest.setup.js', '@testing-library/react/cleanup-after-each'],
testEnvironment: 'node',
testMatch: ['<rootDir>/src/**/__tests__/**/*.js?(x)', '<rootDir>/src/**/?(*.)(spec|test).js?(x)'],
testURL: 'http://localhost:8000',
transform: {
'^.+\\.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
'^.+\\.(css|scss)$': '<rootDir>/config/jest/cssTransform.js',
'^(?!.*\\.(js|jsx|css|json)$)': '<rootDir>/config/jest/fileTransform.js',
},
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
verbose: true,
}

View File

@ -0,0 +1,4 @@
// @flow
const Migrations = artifacts.require('./Migrations.sol')
module.exports = deployer => deployer.deploy(Migrations)

View File

@ -0,0 +1,21 @@
// @flow
/* eslint-disable no-console */
const TokenOMG = artifacts.require('TokenOMG')
const TokenRDN = artifacts.require('TokenRDN')
module.exports = (deployer, network) => {
let toBN
if (typeof web3.version === 'string') {
// 1.X.xx Web3
({ toBN } = web3.utils)
} else {
toBN = web3.toBigNumber
}
if (network === 'development') {
return deployer
.deploy(TokenOMG, toBN(50000).mul(toBN(10).pow(toBN(18))))
.then(() => deployer.deploy(TokenRDN, toBN(50000).mul(toBN(10).pow(toBN(18)))))
}
return console.log('Not running on development, skipping.')
}

View File

@ -2,147 +2,142 @@
"name": "safe-react",
"version": "0.3.2",
"description": "Allowing crypto users manage funds in a safer way",
"directories": {
"test": "test"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"precommit": "./precommit.sh",
"flow": "flow",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook -o build_storybook"
"homepage": "https://github.com/gnosis/safe-react#readme",
"bugs": {
"url": "https://github.com/gnosis/safe-react/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/gnosis/safe-react"
},
"author": "Gnosis Team",
"license": "MIT",
"bugs": {
"url": "https://github.com/gnosis/safe-react/issues"
"author": "Gnosis Team",
"directories": {
"test": "test"
},
"scripts": {
"build": "node scripts/build.js",
"build-storybook": "build-storybook -o build_storybook",
"flow": "flow",
"precommit": "./precommit.sh",
"start": "node scripts/start.js",
"storybook": "start-storybook -p 6006",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"format": "prettier-eslint \"src/**/*.js\" --write"
},
"homepage": "https://github.com/gnosis/safe-react#readme",
"pre-commit": [
"precommit"
],
"devDependencies": {
"@babel/cli": "^7.0.0-beta.40",
"@babel/core": "^7.0.0-beta.40",
"@babel/plugin-syntax-dynamic-import": "^7.0.0-beta.40",
"@babel/polyfill": "^7.0.0-beta.40",
"@babel/preset-env": "^7.0.0-beta.40",
"@babel/preset-flow": "^7.0.0-beta.40",
"@babel/preset-react": "^7.0.0-beta.40",
"@babel/preset-stage-0": "^7.0.0-beta.40",
"@sambego/storybook-state": "^1.0.7",
"@storybook/addon-actions": "^3.3.15",
"@storybook/addon-knobs": "^3.3.15",
"@storybook/addon-links": "^3.3.15",
"@storybook/react": "^3.3.15",
"autoprefixer": "^8.1.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "8",
"babel-jest": "^22.4.1",
"babel-loader": "^8.0.0-beta.0",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"bignumber.js": "^7.2.1",
"classnames": "^2.2.5",
"css-loader": "^0.28.10",
"detect-port": "^1.2.2",
"dotenv": "^5.0.1",
"eslint": "^4.18.2",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-flowtype": "^2.46.1",
"eslint-plugin-import": "^2.9.0",
"eslint-plugin-jest": "^21.13.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"ethereumjs-abi": "^0.6.5",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"flow-bin": "^0.79.1",
"fs-extra": "^5.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.0.4",
"dependencies": {
"@gnosis.pm/safe-contracts": "^1.0.0",
"@gnosis.pm/util-contracts": "2.0.1",
"@material-ui/core": "4.2.0",
"@material-ui/icons": "4.2.1",
"@testing-library/jest-dom": "^4.0.0",
"@welldone-software/why-did-you-render": "3.2.1",
"axios": "0.19.0",
"bignumber.js": "9.0.0",
"connected-react-router": "6.5.2",
"date-fns": "1.30.1",
"final-form": "4.18.2",
"history": "^4.7.2",
"immortal-db": "^1.0.2",
"immutable": "^4.0.0-rc.9",
"jest": "^22.4.2",
"json-loader": "^0.5.7",
"material-ui-search-bar": "^1.0.0-beta.13",
"postcss-loader": "^2.1.1",
"postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^4.1.0",
"pre-commit": "^1.2.2",
"react": "^16.4.0",
"react-dev-utils": "^5.0.1",
"react-dom": "^16.4.0",
"react-redux": "^5.0.7",
"react-router-redux": "^5.0.0-alpha.9",
"redux": "^3.7.2",
"optimize-css-assets-webpack-plugin": "5.0.3",
"qrcode.react": "^0.9.3",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-final-form": "6.3.0",
"react-final-form-listeners": "^1.0.2",
"react-hot-loader": "4.12.7",
"react-infinite-scroll-component": "^4.5.2",
"react-redux": "7.1.0",
"react-router-dom": "^5.0.1",
"recompose": "^0.30.0",
"redux": "4.0.4",
"redux-actions": "^2.3.0",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1",
"run-with-testrpc": "^0.3.0",
"storybook-host": "^4.1.5",
"reselect": "^4.0.0",
"web3": "1.0.0-beta.37"
},
"devDependencies": {
"@babel/cli": "7.5.0",
"@babel/core": "7.5.4",
"@babel/plugin-proposal-class-properties": "7.5.0",
"@babel/plugin-proposal-decorators": "7.4.4",
"@babel/plugin-proposal-do-expressions": "7.5.0",
"@babel/plugin-proposal-export-default-from": "7.5.2",
"@babel/plugin-proposal-export-namespace-from": "7.5.2",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "7.5.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.4.4",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "7.5.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-member-expression-literals": "^7.2.0",
"@babel/plugin-transform-property-literals": "^7.2.0",
"@babel/polyfill": "7.4.4",
"@babel/preset-env": "7.5.4",
"@babel/preset-flow": "^7.0.0-beta.40",
"@babel/preset-react": "^7.0.0-beta.40",
"@sambego/storybook-state": "^1.0.7",
"@storybook/addon-actions": "5.1.9",
"@storybook/addon-knobs": "5.1.9",
"@storybook/addon-links": "5.1.9",
"@storybook/react": "5.1.9",
"@testing-library/react": "8.0.5",
"autoprefixer": "9.6.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "10.0.2",
"babel-jest": "24.8.0",
"babel-loader": "8.0.6",
"babel-plugin-dynamic-import-node": "^2.2.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"classnames": "^2.2.5",
"css-loader": "3.0.0",
"detect-port": "^1.2.2",
"eslint": "5.16.0",
"eslint-config-airbnb": "17.1.1",
"eslint-plugin-flowtype": "3.11.1",
"eslint-plugin-import": "2.18.0",
"eslint-plugin-jest": "22.9.0",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.14.2",
"ethereumjs-abi": "^0.6.7",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "4.0.0",
"flow-bin": "0.102.0",
"fs-extra": "8.1.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.0.4",
"jest": "24.8.0",
"jest-dom": "4.0.0",
"json-loader": "^0.5.7",
"mini-css-extract-plugin": "0.8.0",
"postcss-loader": "^3.0.0",
"postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^5.0.2",
"pre-commit": "^1.2.2",
"prettier-eslint-cli": "5.0.0",
"run-with-testrpc": "0.3.1",
"storybook-host": "5.1.0",
"storybook-router": "^0.3.3",
"style-loader": "^0.20.2",
"truffle": "^4.1.11",
"truffle-contract": "^1.1.8",
"truffle-solidity-loader": "0.0.8",
"uglifyjs-webpack-plugin": "^1.2.2",
"web3": "0.18.4",
"webpack": "^4.1.1",
"webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.8",
"webpack-dev-server": "^3.1.0",
"style-loader": "^0.23.1",
"truffle": "5.0.27",
"truffle-contract": "4.0.24",
"truffle-solidity-loader": "0.1.26",
"uglifyjs-webpack-plugin": "2.1.3",
"webpack": "4.35.3",
"webpack-bundle-analyzer": "3.3.2",
"webpack-cli": "3.3.6",
"webpack-dev-server": "3.7.2",
"webpack-manifest-plugin": "^2.0.0-rc.2"
},
"dependencies": {
"@gnosis.pm/util-contracts": "^0.2.14",
"@material-ui/core": "^3.0.1",
"@material-ui/icons": "^3.0.1",
"final-form": "^4.2.1",
"history": "^4.7.2",
"react-final-form": "^3.1.2",
"react-loadable": "^5.3.1",
"react-router-dom": "^4.2.2",
"recompose": "^0.27.1"
},
"jest": {
"verbose": true,
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"setupTestFrameworkScriptFile": "<rootDir>/config/jest/jest.setup.js",
"setupFiles": [
"<rootDir>/config/webpack.config.test.js",
"<rootDir>/config/polyfills.js",
"<rootDir>/config/jest/LocalStorageMock.js",
"<rootDir>/config/jest/Web3Mock.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"testEnvironment": "node",
"testURL": "http://localhost:8000",
"transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$",
"[/\\\\]flow-typed[/\\\\].+\\.(js|jsx)$"
],
"moduleNameMapper": {
"~(.*)$": "<rootDir>/src/$1",
"#(.*)$": "<rootDir>/safe-contracts/build/contracts/$1",
"^react-native$": "react-native-web"
}
}
}

View File

@ -11,12 +11,13 @@ These instructions will get you a copy of the project up and running on your loc
What things you need to install the software and how to install them
```
npm install truffle // recommended usage of -g flag
npm install ganache-cli // recommended usage of -g flag
npm install flow-type // recommended usage of -g flag
git clone https://github.com/gnosis/safe-contracts.git
yarn add truffle // recommended usage of -g flag
yarn add ganache-cli // recommended usage of -g flag
yarn add flow-type // recommended usage of -g flag
```
We use [yarn](https://yarnpkg.com) in our infrastacture, so we decided to go with yarn in the README
### Installing
A step by step series of examples that tell you have to get a development env running
@ -28,15 +29,37 @@ ganache-cli -b 3
Start the project in the other one
```
cd safe-contracts && truffle compile && truffle migrate && cd ..
npm install
npm start
yarn install
yarn start
```
## Running the tests
1. Run `transaction-history-service`
```
npm test
git clone https://github.com/gnosis/safe-transaction-service.git
cd safe-transaction-history
git checkout develop
docker-compose build
docker-compose up -d
```
Check that the service is running at https://localhost:8000
2. Migrate Safe Contracts:
```
git clone https://github.com/gnosis/safe-contracts.git
cd safe-contracts
yarn
npx truffle migrate
```
3. Migrate Token Contracts for the tests:
Inside `safe-react` directory
```
npx truffle migrate
```
4. Run the tests:
```
yarn test
```

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,666 +0,0 @@
{
"contractName": "DelegateConstructorProxy",
"abi": [
{
"constant": true,
"inputs": [],
"name": "proxyType",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "implementation",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "_masterCopy",
"type": "address"
},
{
"name": "initializer",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x608060405234801561001057600080fd5b506040516102fc3803806102fc83398101806040528101908080519060200190929190805182019291905050508160008173ffffffffffffffffffffffffffffffffffffffff16141515156100f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000815111156101805773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e600082141561017c573d81fd5b5050505b505061016b806101916000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820b2de5726e0943c0fae0f20300b651ccee9090eab24beaf21fd7dbc55f5eef5970029",
"deployedBytecode": "0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820b2de5726e0943c0fae0f20300b651ccee9090eab24beaf21fd7dbc55f5eef5970029",
"sourceMap": "355:882:21:-;;;610:625;8:9:-1;5:2;;;30:1;27;20:12;5:2;610:625:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;668:11;593:1:23;578:11;:16;;;;570:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;658:11;645:10;;:24;;;;;;;;;;;;;;;;;;508:168;735:1:21;714:11;:18;:22;710:519;;;879:42;875:1;869:8;865:57;1043:1;1040;1026:11;1020:18;1013:4;1000:11;996:22;984:10;976:5;971:3;967:15;954:91;1079:4;1073:11;1124:14;1121:1;1116:3;1101:38;1171:1;1162:7;1159:14;1156:2;;;1188:14;1183:3;1176:27;1156:2;829:390;;;;610:625;;355:882;;;;;;",
"deployedSourceMap": "355:882:21:-;;;;;;;;;;;;;;;;;;;;;;;;;;955:42:23;951:1;945:8;941:57;1030:14;1027:1;1024;1011:34;1125:1;1122;1106:14;1103:1;1091:10;1086:3;1073:54;1161:16;1158:1;1155;1140:38;1206:1;1197:7;1194:14;1191:2;;;1221:16;1218:1;1211:27;1191:2;1263:16;1260:1;1253:27;1426:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1426:104:23;;;;;;;;;;;;;;;;;;;;;;;1302:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1302:118:23;;;;;;;;;;;;;;;;;;;;;;;;;;;1426:104;1492:7;1522:1;1515:8;;1426:104;:::o;1302:118::-;1373:7;1403:10;;;;;;;;;;;1396:17;;1302:118;:::o",
"source": "pragma solidity 0.4.24;\nimport \"./Proxy.sol\";\n\n\n/// @title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n/// @author Stefan George - <stefan@gnosis.pm>\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract DelegateConstructorProxy is Proxy {\n\n /// @dev Constructor function sets address of master copy contract.\n /// @param _masterCopy Master copy address.\n /// @param initializer Data used for a delegate call to initialize the contract.\n constructor(address _masterCopy, bytes initializer) Proxy(_masterCopy)\n public\n {\n if (initializer.length > 0) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas, 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize)\n if eq(success, 0) { revert(ptr, returndatasize) }\n }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
"exportedSymbols": {
"DelegateConstructorProxy": [
2740
]
},
"id": 2741,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2718,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:21"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/Proxy.sol",
"file": "./Proxy.sol",
"id": 2719,
"nodeType": "ImportDirective",
"scope": 2741,
"sourceUnit": 2841,
"src": "24:21:21",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 2720,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2840,
"src": "392:5:21",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2840",
"typeString": "contract Proxy"
}
},
"id": 2721,
"nodeType": "InheritanceSpecifier",
"src": "392:5:21"
}
],
"contractDependencies": [
2840
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 2740,
"linearizedBaseContracts": [
2740,
2840
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2738,
"nodeType": "Block",
"src": "700:535:21",
"statements": [
{
"condition": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 2734,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 2731,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2725,
"src": "714:11:21",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 2732,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "length",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "714:18:21",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 2733,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "735:1:21",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "714:22:21",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"falseBody": null,
"id": 2737,
"nodeType": "IfStatement",
"src": "710:519:21",
"trueBody": {
"id": 2736,
"nodeType": "Block",
"src": "738:491:21",
"statements": [
{
"externalReferences": [
{
"initializer": {
"declaration": 2725,
"isOffset": false,
"isSlot": false,
"src": "1026:11:21",
"valueSize": 1
}
},
{
"initializer": {
"declaration": 2725,
"isOffset": false,
"isSlot": false,
"src": "1000:11:21",
"valueSize": 1
}
}
],
"id": 2735,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas(), 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n if eq(success, 0)\n {\n revert(ptr, returndatasize())\n }\n}",
"src": "820:409:21"
}
]
}
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 2739,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 2728,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2723,
"src": "668:11:21",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
}
],
"id": 2729,
"modifierName": {
"argumentTypes": null,
"id": 2727,
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2840,
"src": "662:5:21",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$2840_$",
"typeString": "type(contract Proxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "662:18:21"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2726,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2723,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2739,
"src": "622:19:21",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 2722,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "622:7:21",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 2725,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 2739,
"src": "643:17:21",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 2724,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "643:5:21",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "621:40:21"
},
"payable": false,
"returnParameters": {
"id": 2730,
"nodeType": "ParameterList",
"parameters": [],
"src": "700:0:21"
},
"scope": 2740,
"src": "610:625:21",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2741,
"src": "355:882:21"
}
],
"src": "0:1238:21"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
"exportedSymbols": {
"DelegateConstructorProxy": [
2740
]
},
"id": 2741,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2718,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:21"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/Proxy.sol",
"file": "./Proxy.sol",
"id": 2719,
"nodeType": "ImportDirective",
"scope": 2741,
"sourceUnit": 2841,
"src": "24:21:21",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 2720,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2840,
"src": "392:5:21",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2840",
"typeString": "contract Proxy"
}
},
"id": 2721,
"nodeType": "InheritanceSpecifier",
"src": "392:5:21"
}
],
"contractDependencies": [
2840
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 2740,
"linearizedBaseContracts": [
2740,
2840
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2738,
"nodeType": "Block",
"src": "700:535:21",
"statements": [
{
"condition": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 2734,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 2731,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2725,
"src": "714:11:21",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 2732,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "length",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "714:18:21",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 2733,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "735:1:21",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "714:22:21",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"falseBody": null,
"id": 2737,
"nodeType": "IfStatement",
"src": "710:519:21",
"trueBody": {
"id": 2736,
"nodeType": "Block",
"src": "738:491:21",
"statements": [
{
"externalReferences": [
{
"initializer": {
"declaration": 2725,
"isOffset": false,
"isSlot": false,
"src": "1026:11:21",
"valueSize": 1
}
},
{
"initializer": {
"declaration": 2725,
"isOffset": false,
"isSlot": false,
"src": "1000:11:21",
"valueSize": 1
}
}
],
"id": 2735,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas(), 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n if eq(success, 0)\n {\n revert(ptr, returndatasize())\n }\n}",
"src": "820:409:21"
}
]
}
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 2739,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 2728,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2723,
"src": "668:11:21",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
}
],
"id": 2729,
"modifierName": {
"argumentTypes": null,
"id": 2727,
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2840,
"src": "662:5:21",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$2840_$",
"typeString": "type(contract Proxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "662:18:21"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2726,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2723,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2739,
"src": "622:19:21",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 2722,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "622:7:21",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 2725,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 2739,
"src": "643:17:21",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 2724,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "643:5:21",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "621:40:21"
},
"payable": false,
"returnParameters": {
"id": 2730,
"nodeType": "ParameterList",
"parameters": [],
"src": "700:0:21"
},
"scope": 2740,
"src": "610:625:21",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2741,
"src": "355:882:21"
}
],
"src": "0:1238:21"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.944Z"
}

View File

@ -1,151 +0,0 @@
{
"contractName": "Enum",
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820e8f35ac07bd2a835eacbee7ba38b086a012b371f6bdc0da93abfb72fe3b38ec20029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820e8f35ac07bd2a835eacbee7ba38b086a012b371f6bdc0da93abfb72fe3b38ec20029",
"sourceMap": "115:95:7:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:7;;;;;;;",
"deployedSourceMap": "115:95:7:-;;;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Enum {\n enum Operation {\n Call,\n DelegateCall,\n Create\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
"exportedSymbols": {
"Enum": [
1659
]
},
"id": 1660,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1654,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:7"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1659,
"linearizedBaseContracts": [
1659
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 1658,
"members": [
{
"id": 1655,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:7"
},
{
"id": 1656,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:7"
},
{
"id": 1657,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:7"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:7"
}
],
"scope": 1660,
"src": "115:95:7"
}
],
"src": "0:211:7"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
"exportedSymbols": {
"Enum": [
1659
]
},
"id": 1660,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1654,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:7"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1659,
"linearizedBaseContracts": [
1659
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 1658,
"members": [
{
"id": 1655,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:7"
},
{
"id": 1656,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:7"
},
{
"id": 1657,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:7"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:7"
}
],
"scope": 1660,
"src": "115:95:7"
}
],
"src": "0:211:7"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.921Z"
}

View File

@ -1,171 +0,0 @@
{
"contractName": "EtherPaymentFallback",
"abi": [
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x6080604052348015600f57600080fd5b50603280601d6000396000f30060806040520000a165627a7a723058200c4d2e3a714c9a462ec30383030f16e7035d8647c8e18373ebc02f115b5a1d690029",
"deployedBytecode": "0x60806040520000a165627a7a723058200c4d2e3a714c9a462ec30383030f16e7035d8647c8e18373ebc02f115b5a1d690029",
"sourceMap": "167:155:8:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;167:155:8;;;;;;;",
"deployedSourceMap": "167:155:8:-;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract EtherPaymentFallback {\n\n /// @dev Fallback function accepts Ether transactions.\n function ()\n external\n payable\n {\n\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
"exportedSymbols": {
"EtherPaymentFallback": [
1666
]
},
"id": 1667,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1661,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:8"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1666,
"linearizedBaseContracts": [
1666
],
"name": "EtherPaymentFallback",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1664,
"nodeType": "Block",
"src": "312:8:8",
"statements": []
},
"documentation": "@dev Fallback function accepts Ether transactions.",
"id": 1665,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1662,
"nodeType": "ParameterList",
"parameters": [],
"src": "272:2:8"
},
"payable": true,
"returnParameters": {
"id": 1663,
"nodeType": "ParameterList",
"parameters": [],
"src": "312:0:8"
},
"scope": 1666,
"src": "263:57:8",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1667,
"src": "167:155:8"
}
],
"src": "0:323:8"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
"exportedSymbols": {
"EtherPaymentFallback": [
1666
]
},
"id": 1667,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1661,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:8"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1666,
"linearizedBaseContracts": [
1666
],
"name": "EtherPaymentFallback",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1664,
"nodeType": "Block",
"src": "312:8:8",
"statements": []
},
"documentation": "@dev Fallback function accepts Ether transactions.",
"id": 1665,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1662,
"nodeType": "ParameterList",
"parameters": [],
"src": "272:2:8"
},
"payable": true,
"returnParameters": {
"id": 1663,
"nodeType": "ParameterList",
"parameters": [],
"src": "312:0:8"
},
"scope": 1666,
"src": "263:57:8",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1667,
"src": "167:155:8"
}
],
"src": "0:323:8"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.922Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,339 +0,0 @@
{
"contractName": "ISignatureValidator",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_data",
"type": "bytes"
},
{
"name": "_signature",
"type": "bytes"
}
],
"name": "isValidSignature",
"outputs": [
{
"name": "isValid",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x",
"deployedBytecode": "0x",
"sourceMap": "",
"deployedSourceMap": "",
"source": "pragma solidity 0.4.24;\n\ncontract ISignatureValidator {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return a bool upon valid or invalid signature with corresponding _data\n * MUST take (bytes, bytes) as arguments\n */ \n function isValidSignature(\n bytes _data, \n bytes _signature)\n public\n returns (bool isValid); \n}",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
"exportedSymbols": {
"ISignatureValidator": [
1803
]
},
"id": 1804,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1793,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:13"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": false,
"id": 1803,
"linearizedBaseContracts": [
1803
],
"name": "ISignatureValidator",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": null,
"documentation": "@dev Should return whether the signature provided is valid for the provided data\n@param _data Arbitrary length data signed on the behalf of address(this)\n@param _signature Signature byte array associated with _data\n * MUST return a bool upon valid or invalid signature with corresponding _data\nMUST take (bytes, bytes) as arguments",
"id": 1802,
"implemented": false,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "isValidSignature",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1798,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1795,
"name": "_data",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "476:11:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1794,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "476:5:13",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1797,
"name": "_signature",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "498:16:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1796,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "498:5:13",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "466:49:13"
},
"payable": false,
"returnParameters": {
"id": 1801,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1800,
"name": "isValid",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "548:12:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1799,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "548:4:13",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "547:14:13"
},
"scope": 1803,
"src": "441:121:13",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1804,
"src": "25:540:13"
}
],
"src": "0:565:13"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
"exportedSymbols": {
"ISignatureValidator": [
1803
]
},
"id": 1804,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1793,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:13"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": false,
"id": 1803,
"linearizedBaseContracts": [
1803
],
"name": "ISignatureValidator",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": null,
"documentation": "@dev Should return whether the signature provided is valid for the provided data\n@param _data Arbitrary length data signed on the behalf of address(this)\n@param _signature Signature byte array associated with _data\n * MUST return a bool upon valid or invalid signature with corresponding _data\nMUST take (bytes, bytes) as arguments",
"id": 1802,
"implemented": false,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "isValidSignature",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1798,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1795,
"name": "_data",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "476:11:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1794,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "476:5:13",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1797,
"name": "_signature",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "498:16:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1796,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "498:5:13",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "466:49:13"
},
"payable": false,
"returnParameters": {
"id": 1801,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1800,
"name": "isValid",
"nodeType": "VariableDeclaration",
"scope": 1802,
"src": "548:12:13",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1799,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "548:4:13",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "547:14:13"
},
"scope": 1803,
"src": "441:121:13",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1804,
"src": "25:540:13"
}
],
"src": "0:565:13"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.938Z"
}

View File

@ -1,718 +0,0 @@
{
"contractName": "MasterCopy",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_masterCopy",
"type": "address"
}
],
"name": "changeMasterCopy",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582035e9d5d611938f796affd4397aed671c5c4079783e0a67a874440cb154a411440029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582035e9d5d611938f796affd4397aed671c5c4079783e0a67a874440cb154a411440029",
"sourceMap": "203:673:9:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:9;;;;;;;",
"deployedSourceMap": "203:673:9:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:11;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:9;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
"source": "pragma solidity 0.4.24;\nimport \"./SelfAuthorized.sol\";\n\n\n/// @title MasterCopy - Base for master copy contracts (should always be first super contract)\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract MasterCopy is SelfAuthorized {\n // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address masterCopy;\n\n /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n /// @param _masterCopy New contract address.\n function changeMasterCopy(address _masterCopy)\n public\n authorized\n {\n // Master copy address cannot be null.\n require(_masterCopy != 0, \"Invalid master copy address provided\");\n masterCopy = _masterCopy;\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
1693
]
},
"id": 1694,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1668,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 1669,
"nodeType": "ImportDirective",
"scope": 1694,
"sourceUnit": 1736,
"src": "24:30:9",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1670,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1735,
"src": "226:14:9",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
},
"id": 1671,
"nodeType": "InheritanceSpecifier",
"src": "226:14:9"
}
],
"contractDependencies": [
1735
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1693,
"linearizedBaseContracts": [
1693,
1735
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1673,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1693,
"src": "465:18:9",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1672,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 1691,
"nodeType": "Block",
"src": "711:163:9",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1683,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1681,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1675,
"src": "776:11:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1682,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "776:16:9",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 1684,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
"typeString": "literal_string \"Invalid master copy address provided\""
},
"value": "Invalid master copy address provided"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 1680,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4018,
4019
],
"referencedDeclaration": 4019,
"src": "768:7:9",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1685,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:9",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1686,
"nodeType": "ExpressionStatement",
"src": "768:65:9"
},
{
"expression": {
"argumentTypes": null,
"id": 1689,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1687,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1673,
"src": "843:10:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1688,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1675,
"src": "856:11:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1690,
"nodeType": "ExpressionStatement",
"src": "843:24:9"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 1692,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 1678,
"modifierName": {
"argumentTypes": null,
"id": 1677,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1734,
"src": "696:10:9",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:9"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1676,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1675,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1692,
"src": "652:19:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1674,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "651:21:9"
},
"payable": false,
"returnParameters": {
"id": 1679,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:9"
},
"scope": 1693,
"src": "626:248:9",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1694,
"src": "203:673:9"
}
],
"src": "0:877:9"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
1693
]
},
"id": 1694,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1668,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 1669,
"nodeType": "ImportDirective",
"scope": 1694,
"sourceUnit": 1736,
"src": "24:30:9",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1670,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1735,
"src": "226:14:9",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
},
"id": 1671,
"nodeType": "InheritanceSpecifier",
"src": "226:14:9"
}
],
"contractDependencies": [
1735
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1693,
"linearizedBaseContracts": [
1693,
1735
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1673,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1693,
"src": "465:18:9",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1672,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 1691,
"nodeType": "Block",
"src": "711:163:9",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1683,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1681,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1675,
"src": "776:11:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1682,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "776:16:9",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 1684,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:9",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
"typeString": "literal_string \"Invalid master copy address provided\""
},
"value": "Invalid master copy address provided"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 1680,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4018,
4019
],
"referencedDeclaration": 4019,
"src": "768:7:9",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1685,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:9",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1686,
"nodeType": "ExpressionStatement",
"src": "768:65:9"
},
{
"expression": {
"argumentTypes": null,
"id": 1689,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1687,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1673,
"src": "843:10:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1688,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1675,
"src": "856:11:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1690,
"nodeType": "ExpressionStatement",
"src": "843:24:9"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 1692,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 1678,
"modifierName": {
"argumentTypes": null,
"id": 1677,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1734,
"src": "696:10:9",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:9"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1676,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1675,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1692,
"src": "652:19:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1674,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:9",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "651:21:9"
},
"payable": false,
"returnParameters": {
"id": 1679,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:9"
},
"scope": 1693,
"src": "626:248:9",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1694,
"src": "203:673:9"
}
],
"src": "0:877:9"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.937Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,373 +0,0 @@
{
"contractName": "MultiSend",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "transactions",
"type": "bytes"
}
],
"name": "multiSend",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b50610169806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
"sourceMap": "253:1424:15:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1424:15;;;;;;;",
"deployedSourceMap": "253:1424:15:-;;;;;;;;;;;;;;;;;;;;;;;;695:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;695:980:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;870:12;864:19;905:4;922:737;936:6;933:1;930:13;922:737;;;1007:1;993:12;989:20;983:27;1068:4;1065:1;1061:12;1047;1043:31;1037:38;1136:4;1133:1;1129:12;1115;1111:31;1105:38;1209:4;1206:1;1202:12;1188;1184:31;1178:38;1270:4;1267:1;1263:12;1249;1245:31;1308:1;1333:9;1365:1;1360:66;;;;1448:1;1443:67;;;;1326:184;;1360:66;1422:1;1419;1407:10;1401:4;1394:5;1390:2;1385:3;1380:44;1369:55;;1360:66;;1443:67;1506:1;1503;1491:10;1485:4;1481:2;1476:3;1463:45;1452:56;;1326:184;;1542:1;1533:7;1530:14;1527:2;;;1557:1;1554;1547:12;1527:2;1638:4;1631;1624;1612:10;1608:21;1604:32;1600:43;1594:4;1590:54;1587:1;1583:62;1578:67;;948:711;;;;;;922:737;;;836:833;;;:::o",
"source": "pragma solidity 0.4.24;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - <nick.dodson@consensys.net>\n/// @author Gonçalo Sá - <goncalo.sa@consensys.net>\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a \n /// tuple(operation,address,uint256,bytes), where operation \n /// can be 0 for a call or 1 for a delegatecall. The bytes \n /// of all encoded transactions are concatenated to form the input.\n function multiSend(bytes transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation \n case 0 { success := call(gas, to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas, to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
1858
]
},
"id": 1859,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1850,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:15"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1858,
"linearizedBaseContracts": [
1858
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1856,
"nodeType": "Block",
"src": "753:922:15",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "870:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "993:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1047:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1188:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1115:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1249:12:15",
"valueSize": 1
}
}
],
"id": 1855,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:15"
}
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 1857,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1853,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1852,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 1857,
"src": "714:18:15",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1851,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "714:5:15",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "713:20:15"
},
"payable": false,
"returnParameters": {
"id": 1854,
"nodeType": "ParameterList",
"parameters": [],
"src": "753:0:15"
},
"scope": 1858,
"src": "695:980:15",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1859,
"src": "253:1424:15"
}
],
"src": "0:1678:15"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
1858
]
},
"id": 1859,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1850,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:15"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1858,
"linearizedBaseContracts": [
1858
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1856,
"nodeType": "Block",
"src": "753:922:15",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "870:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "993:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1047:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1188:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1115:12:15",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1852,
"isOffset": false,
"isSlot": false,
"src": "1249:12:15",
"valueSize": 1
}
}
],
"id": 1855,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:15"
}
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 1857,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1853,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1852,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 1857,
"src": "714:18:15",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1851,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "714:5:15",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "713:20:15"
},
"payable": false,
"returnParameters": {
"id": 1854,
"nodeType": "ParameterList",
"parameters": [],
"src": "753:0:15"
},
"scope": 1858,
"src": "695:980:15",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1859,
"src": "253:1424:15"
}
],
"src": "0:1678:15"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {
"4": {
"events": {},
"links": {},
"address": "0x6f6f431429fb15bb2ca4bb55bf353c15f044df9e",
"transactionHash": "0xeaf5db265940b81d6fe881ebf0b05aa9dde905851a966a9cda08dcabd7dc10bd"
},
"1538739975997": {
"events": {},
"links": {},
"address": "0x26b4afb60d6c903165150c6f0aa14f8016be4aec",
"transactionHash": "0x4a85e63a3968cc7f7aaa5303f6ed331cf782929fc758645b44145286ad4076a6"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:43:41.420Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,783 +0,0 @@
{
"contractName": "SecuredTokenTransfer",
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820ba27992b3b19c83b563b2634ef4e6e4b21311676e3d2a13b83cfd34834dfb8510029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820ba27992b3b19c83b563b2634ef4e6e4b21311676e3d2a13b83cfd34834dfb8510029",
"sourceMap": "133:1051:10:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;133:1051:10;;;;;;;",
"deployedSourceMap": "133:1051:10:-;;;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SecuredTokenTransfer {\n\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken (\n address token, \n address receiver,\n uint256 amount\n )\n internal\n returns (bool transferred)\n {\n bytes memory data = abi.encodeWithSignature(\"transfer(address,uint256)\", receiver, amount);\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let success := call(sub(gas, 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize)\n switch returndatasize \n case 0 { transferred := success }\n case 0x20 { transferred := iszero(or(iszero(success), iszero(mload(ptr)))) }\n default { transferred := 0 }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
"exportedSymbols": {
"SecuredTokenTransfer": [
1718
]
},
"id": 1719,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1695,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:10"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1718,
"linearizedBaseContracts": [
1718
],
"name": "SecuredTokenTransfer",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1716,
"nodeType": "Block",
"src": "590:592:10",
"statements": [
{
"assignments": [
1707
],
"declarations": [
{
"constant": false,
"id": 1707,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "600:17:10",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1706,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "600:5:10",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"id": 1714,
"initialValue": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
"id": 1710,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "644:27:10",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
"typeString": "literal_string \"transfer(address,uint256)\""
},
"value": "transfer(address,uint256)"
},
{
"argumentTypes": null,
"id": 1711,
"name": "receiver",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1699,
"src": "673:8:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
{
"argumentTypes": null,
"id": 1712,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1701,
"src": "683:6:10",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
"typeString": "literal_string \"transfer(address,uint256)\""
},
{
"typeIdentifier": "t_address",
"typeString": "address"
},
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"expression": {
"argumentTypes": null,
"id": 1708,
"name": "abi",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4002,
"src": "620:3:10",
"typeDescriptions": {
"typeIdentifier": "t_magic_abi",
"typeString": "abi"
}
},
"id": 1709,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"memberName": "encodeWithSignature",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "620:23:10",
"typeDescriptions": {
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
"typeString": "function (string memory) pure returns (bytes memory)"
}
},
"id": 1713,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "620:70:10",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"nodeType": "VariableDeclarationStatement",
"src": "600:90:10"
},
{
"externalReferences": [
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1061:11:10",
"valueSize": 1
}
},
{
"data": {
"declaration": 1707,
"isOffset": false,
"isSlot": false,
"src": "857:4:10",
"valueSize": 1
}
},
{
"token": {
"declaration": 1697,
"isOffset": false,
"isSlot": false,
"src": "824:5:10",
"valueSize": 1
}
},
{
"data": {
"declaration": 1707,
"isOffset": false,
"isSlot": false,
"src": "838:4:10",
"valueSize": 1
}
},
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1012:11:10",
"valueSize": 1
}
},
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1148:11:10",
"valueSize": 1
}
}
],
"id": 1715,
"nodeType": "InlineAssembly",
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
"src": "764:418:10"
}
]
},
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
"id": 1717,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "transferToken",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1702,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1697,
"name": "token",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "463:13:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1696,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "463:7:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1699,
"name": "receiver",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "487:16:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1698,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "487:7:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1701,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "513:14:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1700,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "513:7:10",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "453:80:10"
},
"payable": false,
"returnParameters": {
"id": 1705,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1704,
"name": "transferred",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "568:16:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1703,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "568:4:10",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "567:18:10"
},
"scope": 1718,
"src": "430:752:10",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "internal"
}
],
"scope": 1719,
"src": "133:1051:10"
}
],
"src": "0:1185:10"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
"exportedSymbols": {
"SecuredTokenTransfer": [
1718
]
},
"id": 1719,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1695,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:10"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1718,
"linearizedBaseContracts": [
1718
],
"name": "SecuredTokenTransfer",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1716,
"nodeType": "Block",
"src": "590:592:10",
"statements": [
{
"assignments": [
1707
],
"declarations": [
{
"constant": false,
"id": 1707,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "600:17:10",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1706,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "600:5:10",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"id": 1714,
"initialValue": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
"id": 1710,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "644:27:10",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
"typeString": "literal_string \"transfer(address,uint256)\""
},
"value": "transfer(address,uint256)"
},
{
"argumentTypes": null,
"id": 1711,
"name": "receiver",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1699,
"src": "673:8:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
{
"argumentTypes": null,
"id": 1712,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1701,
"src": "683:6:10",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
"typeString": "literal_string \"transfer(address,uint256)\""
},
{
"typeIdentifier": "t_address",
"typeString": "address"
},
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"expression": {
"argumentTypes": null,
"id": 1708,
"name": "abi",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4002,
"src": "620:3:10",
"typeDescriptions": {
"typeIdentifier": "t_magic_abi",
"typeString": "abi"
}
},
"id": 1709,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"memberName": "encodeWithSignature",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "620:23:10",
"typeDescriptions": {
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
"typeString": "function (string memory) pure returns (bytes memory)"
}
},
"id": 1713,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "620:70:10",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"nodeType": "VariableDeclarationStatement",
"src": "600:90:10"
},
{
"externalReferences": [
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1061:11:10",
"valueSize": 1
}
},
{
"data": {
"declaration": 1707,
"isOffset": false,
"isSlot": false,
"src": "857:4:10",
"valueSize": 1
}
},
{
"token": {
"declaration": 1697,
"isOffset": false,
"isSlot": false,
"src": "824:5:10",
"valueSize": 1
}
},
{
"data": {
"declaration": 1707,
"isOffset": false,
"isSlot": false,
"src": "838:4:10",
"valueSize": 1
}
},
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1012:11:10",
"valueSize": 1
}
},
{
"transferred": {
"declaration": 1704,
"isOffset": false,
"isSlot": false,
"src": "1148:11:10",
"valueSize": 1
}
}
],
"id": 1715,
"nodeType": "InlineAssembly",
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
"src": "764:418:10"
}
]
},
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
"id": 1717,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "transferToken",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1702,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1697,
"name": "token",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "463:13:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1696,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "463:7:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1699,
"name": "receiver",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "487:16:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1698,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "487:7:10",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1701,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "513:14:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1700,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "513:7:10",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "453:80:10"
},
"payable": false,
"returnParameters": {
"id": 1705,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1704,
"name": "transferred",
"nodeType": "VariableDeclaration",
"scope": 1717,
"src": "568:16:10",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1703,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "568:4:10",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "567:18:10"
},
"scope": 1718,
"src": "430:752:10",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "internal"
}
],
"scope": 1719,
"src": "133:1051:10"
}
],
"src": "0:1185:10"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.937Z"
}

View File

@ -1,479 +0,0 @@
{
"contractName": "SelfAuthorized",
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a7230582089be6830aa63b2ce4480c1565e02c1d4e7d28bdf01f3f1cfbca1af4fc2fd06f50029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a7230582089be6830aa63b2ce4480c1565e02c1d4e7d28bdf01f3f1cfbca1af4fc2fd06f50029",
"sourceMap": "152:166:11:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:11;;;;;;;",
"deployedSourceMap": "152:166:11:-;;;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SelfAuthorized {\n modifier authorized() {\n require(msg.sender == address(this), \"Method can only be called from this contract\");\n _;\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
1735
]
},
"id": 1736,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1720,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:11"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1735,
"linearizedBaseContracts": [
1735
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1733,
"nodeType": "Block",
"src": "204:112:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1728,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1723,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4015,
"src": "222:3:11",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1724,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1726,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4028,
"src": "244:4:11",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
],
"id": 1725,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:11",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1727,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:11",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 1729,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "251:46:11",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
"typeString": "literal_string \"Method can only be called from this contract\""
},
"value": "Method can only be called from this contract"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 1722,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4018,
4019
],
"referencedDeclaration": 4019,
"src": "214:7:11",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1730,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:84:11",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1731,
"nodeType": "ExpressionStatement",
"src": "214:84:11"
},
{
"id": 1732,
"nodeType": "PlaceholderStatement",
"src": "308:1:11"
}
]
},
"documentation": null,
"id": 1734,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1721,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:11"
},
"src": "182:134:11",
"visibility": "internal"
}
],
"scope": 1736,
"src": "152:166:11"
}
],
"src": "0:319:11"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
1735
]
},
"id": 1736,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1720,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:11"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1735,
"linearizedBaseContracts": [
1735
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1733,
"nodeType": "Block",
"src": "204:112:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1728,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1723,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4015,
"src": "222:3:11",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1724,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1726,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4028,
"src": "244:4:11",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
"typeString": "contract SelfAuthorized"
}
],
"id": 1725,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:11",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1727,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:11",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 1729,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "251:46:11",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
"typeString": "literal_string \"Method can only be called from this contract\""
},
"value": "Method can only be called from this contract"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 1722,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4018,
4019
],
"referencedDeclaration": 4019,
"src": "214:7:11",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1730,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:84:11",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1731,
"nodeType": "ExpressionStatement",
"src": "214:84:11"
},
{
"id": 1732,
"nodeType": "PlaceholderStatement",
"src": "308:1:11"
}
]
},
"documentation": null,
"id": 1734,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1721,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:11"
},
"src": "182:134:11",
"visibility": "internal"
}
],
"scope": 1736,
"src": "152:166:11"
}
],
"src": "0:319:11"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.938Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,363 +0,0 @@
{
"contractName": "Token",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x",
"deployedBytecode": "0x",
"sourceMap": "",
"deployedSourceMap": "",
"source": "pragma solidity ^0.4.23;\nimport \"@gnosis.pm/mock-contract/contracts/MockContract.sol\";\ncontract Token {\n\tfunction transfer(address _to, uint value) public returns (bool);\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
"exportedSymbols": {
"Token": [
1871
]
},
"id": 1872,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1860,
"literals": [
"solidity",
"^",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:24:16"
},
{
"absolutePath": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
"file": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
"id": 1861,
"nodeType": "ImportDirective",
"scope": 1872,
"sourceUnit": 4001,
"src": "25:61:16",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": false,
"id": 1871,
"linearizedBaseContracts": [
1871
],
"name": "Token",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": null,
"documentation": null,
"id": 1870,
"implemented": false,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "transfer",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1866,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1863,
"name": "_to",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "123:11:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1862,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "123:7:16",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1865,
"name": "value",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "136:10:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1864,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "136:4:16",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "122:25:16"
},
"payable": false,
"returnParameters": {
"id": 1869,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1868,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "164:4:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1867,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "164:4:16",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "163:6:16"
},
"scope": 1871,
"src": "105:65:16",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1872,
"src": "87:85:16"
}
],
"src": "0:173:16"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
"exportedSymbols": {
"Token": [
1871
]
},
"id": 1872,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1860,
"literals": [
"solidity",
"^",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:24:16"
},
{
"absolutePath": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
"file": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
"id": 1861,
"nodeType": "ImportDirective",
"scope": 1872,
"sourceUnit": 4001,
"src": "25:61:16",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": false,
"id": 1871,
"linearizedBaseContracts": [
1871
],
"name": "Token",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": null,
"documentation": null,
"id": 1870,
"implemented": false,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "transfer",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1866,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1863,
"name": "_to",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "123:11:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1862,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "123:7:16",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1865,
"name": "value",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "136:10:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1864,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "136:4:16",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "122:25:16"
},
"payable": false,
"returnParameters": {
"id": 1869,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1868,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1870,
"src": "164:4:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
},
"typeName": {
"id": 1867,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "164:4:16",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "163:6:16"
},
"scope": 1871,
"src": "105:65:16",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1872,
"src": "87:85:16"
}
],
"src": "0:173:16"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-10-05T14:25:58.939Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,180 +1,174 @@
/*eslint-disable*/
process.env.NODE_ENV = 'development';
process.env.NODE_ENV = 'development'
// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({silent: true});
require('dotenv').config({ silent: true })
var chalk = require('chalk');
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var historyApiFallback = require('connect-history-api-fallback');
var httpProxyMiddleware = require('http-proxy-middleware');
var detect = require('detect-port');
var clearConsole = require('react-dev-utils/clearConsole');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var getProcessForPort = require('react-dev-utils/getProcessForPort');
var openBrowser = require('react-dev-utils/openBrowser');
var pathExists = require('path-exists');
var config = require('../config/webpack.config.dev');
var paths = require('../config/paths');
var chalk = require('chalk')
var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var historyApiFallback = require('connect-history-api-fallback')
var httpProxyMiddleware = require('http-proxy-middleware')
var detect = require('detect-port')
var clearConsole = require('react-dev-utils/clearConsole')
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles')
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages')
var getProcessForPort = require('react-dev-utils/getProcessForPort')
var openBrowser = require('react-dev-utils/openBrowser')
var pathExists = require('path-exists')
var config = require('../config/webpack.config.dev')
var paths = require('../config/paths')
var useYarn = pathExists.sync(paths.yarnLockFile);
var cli = useYarn ? 'yarn' : 'npm';
var isInteractive = process.stdout.isTTY;
var useYarn = pathExists.sync(paths.yarnLockFile)
var cli = useYarn ? 'yarn' : 'npm'
var isInteractive = process.stdout.isTTY
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
process.exit(1)
}
// Tools like Cloud9 rely on this.
var DEFAULT_PORT = process.env.PORT || 3000;
var compiler;
var handleCompile;
// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
if (isSmokeTest) {
handleCompile = function (err, stats) {
if (err || stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
}
};
}
var DEFAULT_PORT = process.env.PORT || 3000
var compiler
var handleCompile
function setupCompiler(host, port, protocol) {
// "Compiler" is a low-level interface to Webpack.
// It lets us listen to some events and provide our own custom messages.
compiler = webpack(config, handleCompile);
compiler = webpack(config, handleCompile)
// "invalid" event fires when you have changed a file, and Webpack is
// recompiling a bundle. WebpackDevServer takes care to pause serving the
// bundle, so if you refresh, it'll wait instead of serving the old one.
// "invalid" is short for "bundle invalidated", it doesn't imply any errors.
compiler.plugin('invalid', function() {
compiler.hooks.invalid.tap('invalid', () => {
if (isInteractive) {
clearConsole();
clearConsole()
}
console.log('Compiling...');
});
console.log('Compiling...')
})
var isFirstCompile = true;
var isFirstCompile = true
// "done" event fires when Webpack has finished recompiling the bundle.
// Whether or not you have warnings or errors, you will get this event.
compiler.plugin('done', function(stats) {
compiler.hooks.done.tap('done', function(stats) {
if (isInteractive) {
clearConsole();
clearConsole()
}
// We have switched off the default Webpack output in WebpackDevServer
// options so we are going to "massage" the warnings and errors and present
// them in a readable focused way.
var messages = formatWebpackMessages(stats.toJson({}, true));
var isSuccessful = !messages.errors.length && !messages.warnings.length;
var showInstructions = isSuccessful && (isInteractive || isFirstCompile);
var messages = formatWebpackMessages(stats.toJson({}, true))
var isSuccessful = !messages.errors.length && !messages.warnings.length
var showInstructions = isSuccessful && (isInteractive || isFirstCompile)
if (isSuccessful) {
console.log(chalk.green('Compiled successfully!'));
console.log(chalk.green('Compiled successfully!'))
}
if (showInstructions) {
console.log();
console.log('The app is running at:');
console.log();
console.log(' ' + chalk.cyan(protocol + '://' + host + ':' + port + '/'));
console.log();
console.log('Note that the development build is not optimized.');
console.log('To create a production build, use ' + chalk.cyan(cli + ' run build') + '.');
console.log();
isFirstCompile = false;
console.log()
console.log('The app is running at:')
console.log()
console.log(' ' + chalk.cyan(protocol + '://' + host + ':' + port + '/'))
console.log()
console.log('Note that the development build is not optimized.')
console.log('To create a production build, use ' + chalk.cyan(cli + ' run build') + '.')
console.log()
isFirstCompile = false
}
// If errors exist, only show errors.
if (messages.errors.length) {
console.log(chalk.red('Failed to compile.'));
console.log();
console.log(chalk.red('Failed to compile.'))
console.log()
messages.errors.forEach(message => {
console.log(message);
console.log();
});
return;
console.log(message)
console.log()
})
return
}
// Show warnings if no errors were found.
if (messages.warnings.length) {
console.log(chalk.yellow('Compiled with warnings.'));
console.log();
console.log(chalk.yellow('Compiled with warnings.'))
console.log()
messages.warnings.forEach(message => {
console.log(message);
console.log();
});
console.log(message)
console.log()
})
// Teach some ESLint tricks.
console.log('You may use special comments to disable some warnings.');
console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
console.log('You may use special comments to disable some warnings.')
console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.')
console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.')
}
});
})
}
// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError(proxy) {
return function(err, req, res){
var host = req.headers && req.headers.host;
return function(err, req, res) {
var host = req.headers && req.headers.host
console.log(
chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) +
' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.'
);
chalk.red('Proxy error:') +
' Could not proxy request ' +
chalk.cyan(req.url) +
' from ' +
chalk.cyan(host) +
' to ' +
chalk.cyan(proxy) +
'.',
)
console.log(
'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
chalk.cyan(err.code) + ').'
);
console.log();
chalk.cyan(err.code) +
').',
)
console.log()
// And immediately send the proper error response to the client.
// Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
if (res.writeHead && !res.headersSent) {
res.writeHead(500);
res.writeHead(500)
}
res.end('Proxy error: Could not proxy request ' + req.url + ' from ' +
host + ' to ' + proxy + ' (' + err.code + ').'
);
res.end(
'Proxy error: Could not proxy request ' + req.url + ' from ' + host + ' to ' + proxy + ' (' + err.code + ').',
)
}
}
function addMiddleware(devServer) {
// `proxy` lets you to specify a fallback server during development.
// Every unrecognized request will be forwarded to it.
var proxy = require(paths.appPackageJson).proxy;
devServer.use(historyApiFallback({
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
// For single page apps, we generally want to fallback to /index.html.
// However we also want to respect `proxy` for API calls.
// So if `proxy` is specified, we need to decide which fallback to use.
// We use a heuristic: if request `accept`s text/html, we pick /index.html.
// Modern browsers include text/html into `accept` header when navigating.
// However API calls like `fetch()` wont generally accept text/html.
// If this heuristic doesnt work well for you, dont use `proxy`.
htmlAcceptHeaders: proxy ?
['text/html'] :
['text/html', '*/*']
}));
var proxy = require(paths.appPackageJson).proxy
devServer.use(
historyApiFallback({
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
// For single page apps, we generally want to fallback to /index.html.
// However we also want to respect `proxy` for API calls.
// So if `proxy` is specified, we need to decide which fallback to use.
// We use a heuristic: if request `accept`s text/html, we pick /index.html.
// Modern browsers include text/html into `accept` header when navigating.
// However API calls like `fetch()` wont generally accept text/html.
// If this heuristic doesnt work well for you, dont use `proxy`.
htmlAcceptHeaders: proxy ? ['text/html'] : ['text/html', '*/*'],
}),
)
if (proxy) {
if (typeof proxy !== 'string') {
console.log(chalk.red('When specified, "proxy" in package.json must be a string.'));
console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".'));
console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.'));
process.exit(1);
console.log(chalk.red('When specified, "proxy" in package.json must be a string.'))
console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".'))
console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.'))
process.exit(1)
}
// Otherwise, if proxy is specified, we will let it handle any request.
@ -183,7 +177,7 @@ function addMiddleware(devServer) {
// - /*.hot-update.json (WebpackDevServer uses this too for hot reloading)
// - /sockjs-node/* (WebpackDevServer uses this for hot reloading)
// Tip: use https://jex.im/regulex/ to visualize the regex
var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/;
var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/
// Pass the scope regex both to Express and to the middleware for proxying
// of both HTTP and WebSockets to work without false positives.
@ -195,25 +189,25 @@ function addMiddleware(devServer) {
// requests. To prevent CORS issues, we have to change
// the Origin to match the target URL.
if (proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', proxy);
proxyReq.setHeader('origin', proxy)
}
},
onError: onProxyError(proxy),
secure: false,
changeOrigin: true,
ws: true
});
devServer.use(mayProxy, hpm);
ws: true,
})
devServer.use(mayProxy, hpm)
// Listen for the websocket 'upgrade' event and upgrade the connection.
// If this is not done, httpProxyMiddleware will not try to upgrade until
// an initial plain HTTP request is made.
devServer.listeningApp.on('upgrade', hpm.upgrade);
devServer.listeningApp.on('upgrade', hpm.upgrade)
}
// Finally, by now we have certainly resolved the URL.
// It may be /index.html, so let the dev server try serving it again.
devServer.use(devServer.middleware);
devServer.use(devServer.middleware)
}
function runDevServer(host, port, protocol) {
@ -253,54 +247,54 @@ function runDevServer(host, port, protocol) {
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebookincubator/create-react-app/issues/293
watchOptions: {
ignored: /node_modules/
ignored: /node_modules/,
},
// Enable HTTPS if the HTTPS environment variable is set to 'true'
https: protocol === "https",
host: host
});
https: protocol === 'https',
host: host,
})
// Our custom middleware proxies requests to /index.html or a remote API.
addMiddleware(devServer);
addMiddleware(devServer)
// Launch WebpackDevServer.
devServer.listen(port, (err, result) => {
if (err) {
return console.log(err);
return console.log(err)
}
if (isInteractive) {
clearConsole();
clearConsole()
}
console.log(chalk.cyan('Starting the development server...'));
console.log();
console.log(chalk.cyan('Starting the development server...'))
console.log()
if (isInteractive) {
openBrowser(protocol + '://' + host + ':' + port + '/');
openBrowser(protocol + '://' + host + ':' + port + '/')
}
});
})
}
function run(port) {
var protocol = process.env.HTTPS === 'true' ? "https" : "http";
var host = process.env.HOST || 'localhost';
setupCompiler(host, port, protocol);
runDevServer(host, port, protocol);
var protocol = process.env.HTTPS === 'true' ? 'https' : 'http'
var host = process.env.HOST || 'localhost'
setupCompiler(host, port, protocol)
runDevServer(host, port, protocol)
}
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `detect()` Promise resolves to the next free port.
detect(DEFAULT_PORT).then(port => {
if (port === DEFAULT_PORT) {
run(port);
return;
run(port)
return
}
if (isInteractive) {
clearConsole();
var existingProcess = getProcessForPort(DEFAULT_PORT);
run(port);
clearConsole()
var existingProcess = getProcessForPort(DEFAULT_PORT)
run(port)
} else {
console.log(chalk.red('Something is already running on port ' + DEFAULT_PORT + '.'));
console.log(chalk.red('Something is already running on port ' + DEFAULT_PORT + '.'))
}
});
})

View File

@ -1,18 +1,20 @@
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
// @flow
process.env.NODE_ENV = 'test'
process.env.PUBLIC_URL = ''
// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({silent: true});
require('dotenv').config({ silent: true })
const jest = require('jest');
const argv = process.argv.slice(2);
const jest = require('jest')
const argv = process.argv.slice(2)
// Watch unless on CI or in coverage mode
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
argv.push('--watch');
argv.push('--watch')
}
jest.run(argv);
jest.run(argv)

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,31 @@
// @flow
import React from 'react'
import { connect } from 'react-redux'
import OpenInNew from '@material-ui/icons/OpenInNew'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { secondary } from '~/theme/variables'
import { networkSelector } from '~/logic/wallets/store/selectors'
const openIconStyle = {
height: '13px',
color: secondary,
}
type EtherscanLinkProps = {
type: 'tx' | 'address',
value: string,
currentNetwork: string,
}
const EtherscanLink = ({ type, value, currentNetwork }: EtherscanLinkProps) => (
<a href={getEtherScanLink(type, value, currentNetwork)} target="_blank" rel="noopener noreferrer">
{shortVersionOf(value, 4)}
<OpenInNew style={openIconStyle} />
</a>
)
export default connect<Object, Object, ?Function, ?Object>(
state => ({ currentNetwork: networkSelector(state) }),
null,
)(EtherscanLink)

View File

@ -9,7 +9,7 @@ import styles from './index.scss'
const Footer = () => (
<Block className={styles.footer}>
<Link to={WELCOME_ADDRESS}>
<Paragraph size="sm" color="primary" noMargin>Welcome</Paragraph>
<Paragraph size="sm" color="primary" noMargin>Add Safe</Paragraph>
</Link>
<Link to={SAFELIST_ADDRESS}>
<Paragraph size="sm" color="primary" noMargin>Safe List</Paragraph>

View File

@ -7,6 +7,7 @@
align-items: center;
border: solid 0.5px $border;
background-color: white;
margin-top: 50px;
}
@media only screen and (max-width: $(screenXs)px) {

View File

@ -7,7 +7,7 @@ import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
<div style={{ flex: '1' }} />
{ story() }
{story()}
</div>
)

View File

@ -0,0 +1 @@
<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><mask id="a" fill="#fff"><path d="m6.72043466.05975844h-6.62356495v11.84970376h6.62356495z" fill="#fff" fill-rule="evenodd"/></mask><g fill="#4a5579" fill-rule="evenodd"><path d="m4.14977665 6.07551536-1.71737342-1.70732942c-.154797.20785847-.24831026.46589514-.24831026.74441596 0 .67391239.54853704 1.22126772 1.22091168 1.22126772.27926965 0 .53821724-.09336958.744772-.25835426"/><path d="m1.87126776 2.19027617c1.03982725-1.02106347 2.40224018-1.57576779 3.8633547-1.57576779h.00917804c.01609919 0 .03219839.00091234.04814712.00121646v5.5467391zm3.85282252-2.13062417c-1.69583171 0-3.2740039.69414069-4.43103929 1.93158142l-.18657008.19904275 4.68546671 4.75589009v.85273625l-.01850655.01870302-1.20548342-1.2283173c-.55925885.37618928-1.27484536.48551834-1.95071051.24739691-1.13777654-.41618029-1.72637503-1.67445284-1.31411535-2.81366468.05852884-.17821093.14669825-.3371106.24449708-.48536628l-.51938702-.5253573-.09794929.16847927c-.5392477.89211904-.83339649 1.92230593-.83339649 2.98260013-.00947896 3.16111517 2.53900808 5.74578182 5.66631374 5.74578182l.95722485.0003041v-11.84889785z" mask="url(#a)" transform="translate(.218409)"/><path d="m11.7375061 6.11561396c0-2.64879063-2.15538824-4.8037754-4.80500459-4.80515818v.57492892c2.33248021.00122914 4.22991669 1.89824874 4.22991669 4.23022926 0 2.33136596-1.89743648 4.22869284-4.22991669 4.22992194v.574929c2.64961635-.0013828 4.80500459-2.15636759 4.80500459-4.80485094"/><path d="m8.02004901 6.01820975-.22912891 1.40770636h1.1220214l-.2288201-1.40770636c.25522242-.12241582.43247309-.37950419.43247309-.67820486 0-.41582039-.34214937-.75340965-.76443209-.75340965-.42197392 0-.76443209.33758926-.76443209.75340965-.00046319.2990033.17647867.55578904.4323187.67820486"/><path d="m7.75184322 2.83111882c.28114484.0716844.38948776-.34809944.1084868-.42035731-.28100096-.07197114-.38934388.34809944-.1084868.42035731"/><path d="m8.97850178 3.44035856c.21945107.18400118.4955759-.14470408.27612484-.3285634-.21945107-.18371744-.49543387.14484596-.27612484.3285634"/><path d="m9.79686881 4.68163059c.12643597.25912811.51314779.0686432.38671179-.19048491-.1261512-.25841307-.51314776-.06821418-.38671179.19048491"/><path d="m7.75184322 9.3998634c.28114484-.07200813.38948776.34827835.1084868.42028648s-.38934388-.34799147-.1084868-.42028648"/><path d="m8.97850178 8.5721264c.21945107-.18396063.4955759.14481403.27612484.32849098-.21945107.18396062-.49543387-.14481403-.27612484-.32849098"/><path d="m9.79686881 7.54913594c.12643597-.25888516.51314779-.06847377.38671179.19069729-.1261512.25831336-.51314776.06818787-.38671179-.19069729"/><path d="m10.208641 6.11535204c0 .29135677.4368186.29135677.4368186 0 0-.29106802-.4368186-.29106802-.4368186 0"/></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 557 B

After

Width:  |  Height:  |  Size: 557 B

View File

@ -1,8 +1,8 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Block from '~/components/layout/Block'
import Dot from '@material-ui/icons/FiberManualRecord'
import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img'
import { fancy, border, warning } from '~/theme/variables'
@ -61,7 +61,15 @@ const buildDotStyleFrom = (size: number, top: number, right: number, mode: Mode)
})
const KeyRing = ({
classes, circleSize, keySize, dotSize, dotTop, dotRight, mode, center = false, hideDot = false,
classes,
circleSize,
keySize,
dotSize,
dotTop,
dotRight,
mode,
center = false,
hideDot = false,
}: Props) => {
const keyStyle = buildKeyStyleFrom(circleSize, center, dotSize)
const dotStyle = buildDotStyleFrom(dotSize, dotTop, dotRight, mode)
@ -80,7 +88,7 @@ const KeyRing = ({
className={isWarning ? classes.warning : undefined}
/>
</Block>
{ !hideDot && <Dot className={classes.dot} style={dotStyle} /> }
{!hideDot && <Dot className={classes.dot} style={dotStyle} />}
</Block>
</React.Fragment>
)

View File

@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import { Link } from 'react-router-dom'
import { withStyles } from '@material-ui/core/styles'
import Grow from '@material-ui/core/Grow'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
@ -18,8 +19,8 @@ const logo = require('../assets/gnosis-safe-logo.svg')
type Props = Open & {
classes: Object,
providerDetails: React$Node,
providerInfo: React$Node,
providerDetails: React.Node,
providerInfo: React.Node,
}
const styles = () => ({
@ -49,7 +50,9 @@ const Layout = openHoc(({
<React.Fragment>
<Row className={classes.summary}>
<Col start="xs" middle="xs" className={classes.logo}>
<Img src={logo} height={32} alt="Gnosis Team Safe" />
<Link to="/">
<Img src={logo} height={32} alt="Gnosis Team Safe" />
</Link>
</Col>
<Divider />
<Spacer />
@ -58,9 +61,7 @@ const Layout = openHoc(({
{providerRef => (
<Popper open={open} anchorEl={providerRef.current} placement="bottom-end">
{({ TransitionProps }) => (
<Grow
{...TransitionProps}
>
<Grow {...TransitionProps}>
<ClickAwayListener onClickAway={clickAway} mouseEvent="onClick" touchEvent={false}>
<List className={classes.root} component="div">
{providerDetails}

View File

@ -8,11 +8,7 @@ import UserDetails from './ProviderDetails/UserDetails'
import ProviderDisconnected from './ProviderInfo/ProviderDisconnected'
import ConnectDetails from './ProviderDetails/ConnectDetails'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Components /Header', module)
.addDecorator(FrameDecorator)
@ -36,12 +32,7 @@ storiesOf('Components /Header', module)
const userAddress = '0x873faa4cddd5b157e8e5a57e7a5479afc5d30moe'
const network = 'RINKEBY'
const info = <ProviderAccesible provider={provider} network={network} userAddress={userAddress} connected={false} />
const details = (<UserDetails
provider={provider}
network={network}
userAddress={userAddress}
connected={false}
/>)
const details = <UserDetails provider={provider} network={network} userAddress={userAddress} connected={false} />
return <Layout providerInfo={info} providerDetails={details} />
})

View File

@ -10,8 +10,8 @@ import { sm, md } from '~/theme/variables'
type Props = Open & {
classes: Object,
popupDetails: React$Node,
info: React$Node,
popupDetails: React.Node,
info: React.Node,
children: Function,
}
@ -55,16 +55,13 @@ class Provider extends React.Component<Props> {
<React.Fragment>
<div ref={this.myRef} className={classes.root}>
<Col end="sm" middle="xs" className={classes.provider} onClick={toggle}>
{ info }
<IconButton
disableRipple
className={classes.expand}
>
{ open ? <ExpandLess /> : <ExpandMore />}
{info}
<IconButton disableRipple className={classes.expand}>
{open ? <ExpandLess /> : <ExpandMore />}
</IconButton>
</Col>
</div>
{ children(this.myRef) }
{children(this.myRef)}
</React.Fragment>
)
}

View File

@ -39,21 +39,19 @@ const ConnectDetails = ({ classes, onConnect }: Props) => (
<React.Fragment>
<div className={classes.container}>
<Row margin="lg" align="center">
<Paragraph className={classes.text} size="lg" noMargin weight="bolder">Connect a Wallet</Paragraph>
<Paragraph className={classes.text} size="lg" noMargin weight="bolder">
Connect a Wallet
</Paragraph>
</Row>
</div>
<Row className={classes.logo} margin="lg">
<CircleDot keySize={32} circleSize={75} dotSize={25} dotTop={50} dotRight={25} center mode="error" />
</Row>
<Row className={classes.connect}>
<Button
onClick={onConnect}
size="medium"
variant="raised"
color="primary"
fullWidth
>
<Paragraph className={classes.connectText} size="sm" weight="regular" color="white" noMargin>CONNECT</Paragraph>
<Button onClick={onConnect} size="medium" variant="contained" color="primary" fullWidth>
<Paragraph className={classes.connectText} size="sm" weight="regular" color="white" noMargin>
CONNECT
</Paragraph>
</Button>
</Row>
</React.Fragment>

View File

@ -3,22 +3,26 @@ import * as React from 'react'
import classNames from 'classnames'
import OpenInNew from '@material-ui/icons/OpenInNew'
import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord'
import Paragraph from '~/components/layout/Paragraph'
import Link from '~/components/layout/Link'
import Button from '~/components/layout/Button'
import Identicon from '~/components/Identicon'
import Dot from '@material-ui/icons/FiberManualRecord'
import Hairline from '~/components/layout/Hairline'
import Img from '~/components/layout/Img'
import Row from '~/components/layout/Row'
import Block from '~/components/layout/Block'
import Spacer from '~/components/Spacer'
import { xs, sm, md, lg, background, secondary, warning, connected as connectedBg } from '~/theme/variables'
import {
xs, sm, md, lg, background, secondary, warning, connected as connectedBg,
} from '~/theme/variables'
import { upperFirst } from '~/utils/css'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import CircleDot from '~/components/Header/component/CircleDot'
const metamask = require('../../assets/metamask.svg')
const metamaskIcon = require('../../assets/metamask-icon.svg')
const safeIcon = require('../../assets/gnosis-safe-icon.svg')
const dot = require('../../assets/dotRinkeby.svg')
type Props = {
@ -108,25 +112,28 @@ const UserDetails = ({
<React.Fragment>
<Block className={classes.container}>
<Row className={classes.identicon} margin="md" align="center">
{ connected
? <Identicon address={identiconAddress} diameter={60} />
: <CircleDot keySize={30} circleSize={75} dotSize={25} dotTop={50} dotRight={25} mode="warning" hideDot />
}
{connected ? (
<Identicon address={identiconAddress} diameter={60} />
) : (
<CircleDot keySize={30} circleSize={75} dotSize={25} dotTop={50} dotRight={25} mode="warning" hideDot />
)}
</Row>
<Block align="center" className={classes.user}>
<Paragraph className={classes.address} size="sm" noMargin>{address}</Paragraph>
{ userAddress &&
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(userAddress, network)}
/>
}
<Paragraph className={classes.address} size="sm" noMargin>
{address}
</Paragraph>
{userAddress && (
<Link className={classes.open} to={getEtherScanLink('address', userAddress, network)} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
)}
</Block>
</Block>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>Status </Paragraph>
<Paragraph noMargin align="right" className={classes.labels}>
Status
</Paragraph>
<Spacer />
<Dot className={classNames(classes.dot, connected ? classes.connected : classes.warning)} />
<Paragraph noMargin align="right" color={color} weight="bolder" className={classes.labels}>
@ -135,16 +142,23 @@ const UserDetails = ({
</Row>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>Client </Paragraph>
<Paragraph noMargin align="right" className={classes.labels}>
Client
</Paragraph>
<Spacer />
<Img className={classes.logo} src={metamask} height={14} alt="Metamask client" />
{provider === 'safe'
? <Img className={classes.logo} src={safeIcon} height={14} alt="Safe client" />
: <Img className={classes.logo} src={metamaskIcon} height={14} alt="Metamask client" />
}
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
{upperFirst(provider)}
</Paragraph>
</Row>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>Network </Paragraph>
<Paragraph noMargin align="right" className={classes.labels}>
Network
</Paragraph>
<Spacer />
<Img className={classes.logo} src={dot} height={14} alt="Network" />
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
@ -153,14 +167,10 @@ const UserDetails = ({
</Row>
<Hairline margin="xs" />
<Row className={classes.disconnect}>
<Button
onClick={onDisconnect}
size="medium"
variant="raised"
color="primary"
fullWidth
>
<Paragraph className={classes.disconnectText} size="sm" weight="bold" color="white" noMargin>DISCONNECT</Paragraph>
<Button onClick={onDisconnect} size="medium" variant="contained" color="primary" fullWidth>
<Paragraph className={classes.disconnectText} size="sm" weight="bold" color="white" noMargin>
DISCONNECT
</Paragraph>
</Button>
</Row>
</React.Fragment>

View File

@ -54,18 +54,20 @@ const ProviderInfo = ({
return (
<React.Fragment>
{ connected &&
{connected && (
<React.Fragment>
<Identicon address={identiconAddress} diameter={30} />
<Dot className={classes.logo} />
</React.Fragment>
}
{ !connected &&
<CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />
}
)}
{!connected && <CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />}
<Col start="sm" layout="column" className={classes.account}>
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bolder">{providerText}</Paragraph>
<Paragraph size="sm" className={classes.address} noMargin color={color}>{cutAddress}</Paragraph>
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bolder">
{providerText}
</Paragraph>
<Paragraph size="sm" className={classes.address} noMargin color={color}>
{cutAddress}
</Paragraph>
</Col>
</React.Fragment>
)

View File

@ -33,8 +33,12 @@ const ProviderDesconnected = ({ classes }: Props) => (
<React.Fragment>
<CircleDot keySize={17} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="error" />
<Col end="sm" middle="xs" layout="column" className={classes.account}>
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bold">Not Connected</Paragraph>
<Paragraph size="sm" color="fancy" className={classes.connect} noMargin>Connect Wallet</Paragraph>
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bold">
Not Connected
</Paragraph>
<Paragraph size="sm" color="fancy" className={classes.connect} noMargin>
Connect Wallet
</Paragraph>
</Col>
</React.Fragment>
)

View File

@ -2,8 +2,9 @@
import * as React from 'react'
import { connect } from 'react-redux'
import { logComponentStack, type Info } from '~/utils/logBoundaries'
import { SharedSnackbarConsumer, type Variant } from '~/components/SharedSnackBar/Context'
import { SharedSnackbarConsumer, type Variant } from '~/components/SharedSnackBar'
import { WALLET_ERROR_MSG } from '~/logic/wallets/store/actions'
import { getProviderInfo } from '~/logic/wallets/getWeb3'
import ProviderAccesible from './component/ProviderInfo/ProviderAccesible'
import UserDetails from './component/ProviderDetails/UserDetails'
import ProviderDisconnected from './component/ProviderInfo/ProviderDisconnected'
@ -12,9 +13,10 @@ import Layout from './component/Layout'
import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector'
type Props = Actions & SelectorProps & {
openSnackbar: (message: string, variant: Variant) => void,
}
type Props = Actions &
SelectorProps & {
openSnackbar: (message: string, variant: Variant) => void,
}
type State = {
hasError: boolean,
@ -26,22 +28,38 @@ class HeaderComponent extends React.PureComponent<Props, State> {
}
componentDidMount() {
this.props.fetchProvider(this.props.openSnackbar)
this.onConnect()
}
componentDidCatch(error: Error, info: Info) {
const { openSnackbar } = this.props
this.setState({ hasError: true })
this.props.openSnackbar(WALLET_ERROR_MSG, 'error')
openSnackbar(WALLET_ERROR_MSG, 'error')
logComponentStack(error, info)
}
onDisconnect = () => {
this.props.removeProvider(this.props.openSnackbar)
const { removeProvider, openSnackbar } = this.props
clearInterval(this.providerListener)
removeProvider(openSnackbar)
}
onConnect = () => {
this.props.fetchProvider(this.props.openSnackbar)
onConnect = async () => {
const { fetchProvider, openSnackbar } = this.props
clearInterval(this.providerListener)
let currentProvider: ProviderProps = await getProviderInfo()
fetchProvider(currentProvider, openSnackbar)
this.providerListener = setInterval(async () => {
const newProvider: ProviderProps = await getProviderInfo()
if (JSON.stringify(currentProvider) !== JSON.stringify(newProvider)) {
fetchProvider(newProvider, openSnackbar)
}
currentProvider = newProvider
}, 2000)
}
getProviderInfoBased = () => {
@ -67,13 +85,15 @@ class HeaderComponent extends React.PureComponent<Props, State> {
return <ConnectDetails onConnect={this.onConnect} />
}
return (<UserDetails
provider={provider}
network={network}
userAddress={userAddress}
connected={available}
onDisconnect={this.onDisconnect}
/>)
return (
<UserDetails
provider={provider}
network={network}
userAddress={userAddress}
connected={available}
onDisconnect={this.onDisconnect}
/>
)
}
render() {
@ -84,14 +104,13 @@ class HeaderComponent extends React.PureComponent<Props, State> {
}
}
const Header = connect(selector, actions)(HeaderComponent)
const Header = connect(
selector,
actions,
)(HeaderComponent)
const HeaderSnack = () => (
<SharedSnackbarConsumer>
{({ openSnackbar }) => (
<Header openSnackbar={openSnackbar} />
)}
</SharedSnackbarConsumer>
<SharedSnackbarConsumer>{({ openSnackbar }) => <Header openSnackbar={openSnackbar} />}</SharedSnackbarConsumer>
)
export default HeaderSnack

View File

@ -1,6 +1,12 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { providerNameSelector, userAccountSelector, networkSelector, availableSelector, loadedSelector } from '~/logic/wallets/store/selectors'
import {
providerNameSelector,
userAccountSelector,
networkSelector,
availableSelector,
loadedSelector,
} from '~/logic/wallets/store/selectors'
export type SelectorProps = {
provider: string,
@ -10,7 +16,7 @@ export type SelectorProps = {
available: boolean,
}
export default createStructuredSelector({
export default createStructuredSelector<Object, *>({
provider: providerNameSelector,
userAddress: userAccountSelector,
network: networkSelector,

View File

@ -1,10 +1,12 @@
/* eslint-disable */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.blockies = {})));
}(this, (function (exports) {
'use strict';
;(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? factory(exports)
: typeof define === 'function' && define.amd
? define(['exports'], factory)
: factory((global.blockies = {}))
})(this, function(exports) {
'use strict'
/**
* A handy class to calculate color values.
@ -17,207 +19,210 @@
*
*/
// helper functions for that ctx
function write(buffer, offs) {
for (var i = 2; i < arguments.length; i++) {
for (var j = 0; j < arguments[i].length; j++) {
buffer[offs++] = arguments[i].charAt(j);
buffer[offs++] = arguments[i].charAt(j)
}
}
}
function byte2(w) {
return String.fromCharCode((w >> 8) & 255, w & 255);
return String.fromCharCode((w >> 8) & 255, w & 255)
}
function byte4(w) {
return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255);
return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255)
}
function byte2lsb(w) {
return String.fromCharCode(w & 255, (w >> 8) & 255);
return String.fromCharCode(w & 255, (w >> 8) & 255)
}
var PNG = function (width, height, depth) {
this.width = width;
this.height = height;
this.depth = depth;
var PNG = function(width, height, depth) {
this.width = width
this.height = height
this.depth = depth
// pixel data and row filter identifier size
this.pix_size = height * (width + 1);
this.pix_size = height * (width + 1)
// deflate header, pix_size, block headers, adler32 checksum
this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4;
this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4
// offsets and sizes of Png chunks
this.ihdr_offs = 0; // IHDR offset and size
this.ihdr_size = 4 + 4 + 13 + 4;
this.plte_offs = this.ihdr_offs + this.ihdr_size; // PLTE offset and size
this.plte_size = 4 + 4 + 3 * depth + 4;
this.trns_offs = this.plte_offs + this.plte_size; // tRNS offset and size
this.trns_size = 4 + 4 + depth + 4;
this.idat_offs = this.trns_offs + this.trns_size; // IDAT offset and size
this.idat_size = 4 + 4 + this.data_size + 4;
this.iend_offs = this.idat_offs + this.idat_size; // IEND offset and size
this.iend_size = 4 + 4 + 4;
this.buffer_size = this.iend_offs + this.iend_size; // total PNG size
this.ihdr_offs = 0 // IHDR offset and size
this.ihdr_size = 4 + 4 + 13 + 4
this.plte_offs = this.ihdr_offs + this.ihdr_size // PLTE offset and size
this.plte_size = 4 + 4 + 3 * depth + 4
this.trns_offs = this.plte_offs + this.plte_size // tRNS offset and size
this.trns_size = 4 + 4 + depth + 4
this.idat_offs = this.trns_offs + this.trns_size // IDAT offset and size
this.idat_size = 4 + 4 + this.data_size + 4
this.iend_offs = this.idat_offs + this.idat_size // IEND offset and size
this.iend_size = 4 + 4 + 4
this.buffer_size = this.iend_offs + this.iend_size // total PNG size
this.buffer = new Array();
this.palette = new Object();
this.pindex = 0;
this.buffer = new Array()
this.palette = new Object()
this.pindex = 0
var _crc32 = new Array();
var _crc32 = new Array()
// initialize buffer with zero bytes
for (var i = 0; i < this.buffer_size; i++) {
this.buffer[i] = "\x00";
this.buffer[i] = '\x00'
}
// initialize non-zero elements
write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), "\x08\x03");
write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE');
write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS');
write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT');
write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND');
write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), '\x08\x03')
write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE')
write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS')
write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT')
write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND')
// initialize deflate header
var header = ((8 + (7 << 4)) << 8) | (3 << 6);
header += 31 - (header % 31);
var header = ((8 + (7 << 4)) << 8) | (3 << 6)
header += 31 - (header % 31)
write(this.buffer, this.idat_offs + 8, byte2(header));
write(this.buffer, this.idat_offs + 8, byte2(header))
// initialize deflate block headers
for (var i = 0; (i << 16) - 1 < this.pix_size; i++) {
var size, bits;
var size, bits
if (i + 0xffff < this.pix_size) {
size = 0xffff;
bits = "\x00";
size = 0xffff
bits = '\x00'
} else {
size = this.pix_size - (i << 16) - i;
bits = "\x01";
size = this.pix_size - (i << 16) - i
bits = '\x01'
}
write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size));
write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size))
}
/* Create crc32 lookup table */
for (var i = 0; i < 256; i++) {
var c = i;
var c = i
for (var j = 0; j < 8; j++) {
if (c & 1) {
c = -306674912 ^ ((c >> 1) & 0x7fffffff);
c = -306674912 ^ ((c >> 1) & 0x7fffffff)
} else {
c = (c >> 1) & 0x7fffffff;
c = (c >> 1) & 0x7fffffff
}
}
_crc32[i] = c;
_crc32[i] = c
}
// compute the index into a png for a given pixel
this.index = function (x, y) {
var i = y * (this.width + 1) + x + 1;
var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i;
return j;
};
this.index = function(x, y) {
var i = y * (this.width + 1) + x + 1
var j = this.idat_offs + 8 + 2 + 5 * Math.floor(i / 0xffff + 1) + i
return j
}
// convert a color and build up the palette
this.color = function (red, green, blue, alpha) {
this.color = function(red, green, blue, alpha) {
alpha = alpha >= 0 ? alpha : 255
var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue
alpha = alpha >= 0 ? alpha : 255;
var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue;
if (typeof this.palette[color] == 'undefined') {
if (this.pindex == this.depth) return '\x00'
if (typeof this.palette[color] == "undefined") {
if (this.pindex == this.depth) return "\x00";
var ndx = this.plte_offs + 8 + 3 * this.pindex
var ndx = this.plte_offs + 8 + 3 * this.pindex;
this.buffer[ndx + 0] = String.fromCharCode(red)
this.buffer[ndx + 1] = String.fromCharCode(green)
this.buffer[ndx + 2] = String.fromCharCode(blue)
this.buffer[this.trns_offs + 8 + this.pindex] = String.fromCharCode(alpha)
this.buffer[ndx + 0] = String.fromCharCode(red);
this.buffer[ndx + 1] = String.fromCharCode(green);
this.buffer[ndx + 2] = String.fromCharCode(blue);
this.buffer[this.trns_offs + 8 + this.pindex] = String.fromCharCode(alpha);
this.palette[color] = String.fromCharCode(this.pindex++);
this.palette[color] = String.fromCharCode(this.pindex++)
}
return this.palette[color];
};
return this.palette[color]
}
// output a PNG string, Base64 encoded
this.getBase64 = function () {
this.getBase64 = function() {
var s = this.getDump()
var s = this.getDump();
var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var c1, c2, c3, e1, e2, e3, e4;
var l = s.length;
var i = 0;
var r = "";
var ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
var c1, c2, c3, e1, e2, e3, e4
var l = s.length
var i = 0
var r = ''
do {
c1 = s.charCodeAt(i);
e1 = c1 >> 2;
c2 = s.charCodeAt(i + 1);
e2 = ((c1 & 3) << 4) | (c2 >> 4);
c3 = s.charCodeAt(i + 2);
if (l < i + 2) { e3 = 64; } else { e3 = ((c2 & 0xf) << 2) | (c3 >> 6); }
if (l < i + 3) { e4 = 64; } else { e4 = c3 & 0x3f; }
r += ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4);
} while ((i += 3) < l);
return r;
};
c1 = s.charCodeAt(i)
e1 = c1 >> 2
c2 = s.charCodeAt(i + 1)
e2 = ((c1 & 3) << 4) | (c2 >> 4)
c3 = s.charCodeAt(i + 2)
if (l < i + 2) {
e3 = 64
} else {
e3 = ((c2 & 0xf) << 2) | (c3 >> 6)
}
if (l < i + 3) {
e4 = 64
} else {
e4 = c3 & 0x3f
}
r += ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4)
} while ((i += 3) < l)
return r
}
// output a PNG string
this.getDump = function () {
this.getDump = function() {
// compute adler32 of output pixels + row filter bytes
var BASE = 65521; /* largest prime smaller than 65536 */
var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
var s1 = 1;
var s2 = 0;
var n = NMAX;
var BASE = 65521 /* largest prime smaller than 65536 */
var NMAX = 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
var s1 = 1
var s2 = 0
var n = NMAX
for (var y = 0; y < this.height; y++) {
for (var x = -1; x < this.width; x++) {
s1 += this.buffer[this.index(x, y)].charCodeAt(0);
s2 += s1;
s1 += this.buffer[this.index(x, y)].charCodeAt(0)
s2 += s1
if ((n -= 1) == 0) {
s1 %= BASE;
s2 %= BASE;
n = NMAX;
s1 %= BASE
s2 %= BASE
n = NMAX
}
}
}
s1 %= BASE;
s2 %= BASE;
write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1));
s1 %= BASE
s2 %= BASE
write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1))
// compute crc32 of the PNG chunks
function crc32(png, offs, size) {
var crc = -1;
var crc = -1
for (var i = 4; i < size - 4; i += 1) {
crc = _crc32[(crc ^ png[offs + i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff);
crc = _crc32[(crc ^ png[offs + i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff)
}
write(png, offs + size - 4, byte4(crc ^ -1));
write(png, offs + size - 4, byte4(crc ^ -1))
}
crc32(this.buffer, this.ihdr_offs, this.ihdr_size);
crc32(this.buffer, this.plte_offs, this.plte_size);
crc32(this.buffer, this.trns_offs, this.trns_size);
crc32(this.buffer, this.idat_offs, this.idat_size);
crc32(this.buffer, this.iend_offs, this.iend_size);
crc32(this.buffer, this.ihdr_offs, this.ihdr_size)
crc32(this.buffer, this.plte_offs, this.plte_size)
crc32(this.buffer, this.trns_offs, this.trns_size)
crc32(this.buffer, this.idat_offs, this.idat_size)
crc32(this.buffer, this.iend_offs, this.iend_size)
// convert PNG to string
return "\x89PNG\r\n\x1A\n" + this.buffer.join('');
};
return '\x89PNG\r\n\x1A\n' + this.buffer.join('')
}
this.fillRect = function (x, y, w, h, color) {
this.fillRect = function(x, y, w, h, color) {
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
this.buffer[this.index(x + i, y + j)] = color;
this.buffer[this.index(x + i, y + j)] = color
}
}
};
};
}
}
// https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
/**
@ -233,90 +238,90 @@
*/
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
if (t < 0) t += 1
if (t > 1) t -= 1
if (t < 1 / 6) return p + (q - p) * 6 * t
if (t < 1 / 2) return q
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6
return p
}
function hsl2rgb(h, s, l) {
var r, g, b;
var r, g, b
if (s == 0) {
r = g = b = l; // achromatic
r = g = b = l // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
var q = l < 0.5 ? l * (1 + s) : l + s - l * s
var p = 2 * l - q
r = hue2rgb(p, q, h + 1 / 3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1 / 3)
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255];
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255]
}
// The random number is a js implementation of the Xorshift PRNG
var randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values
var randseed = new Array(4) // Xorshift: [x, y, z, w] 32 bit values
function seedrand(seed) {
for (var i = 0; i < randseed.length; i++) {
randseed[i] = 0;
randseed[i] = 0
}
for (var i = 0; i < seed.length; i++) {
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i);
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i)
}
}
function rand() {
// based on Java's String.hashCode(), expanded to 4 32bit values
var t = randseed[0] ^ (randseed[0] << 11);
var t = randseed[0] ^ (randseed[0] << 11)
randseed[0] = randseed[1];
randseed[1] = randseed[2];
randseed[2] = randseed[3];
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);
randseed[0] = randseed[1]
randseed[1] = randseed[2]
randseed[2] = randseed[3]
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8)
return (randseed[3] >>> 0) / (1 << 31 >>> 0);
return (randseed[3] >>> 0) / ((1 << 31) >>> 0)
}
function createColor() {
//saturation is the whole color spectrum
var h = Math.floor(rand() * 360);
var h = Math.floor(rand() * 360)
//saturation goes from 40 to 100, it avoids greyish colors
var s = rand() * 60 + 40;
var s = rand() * 60 + 40
//lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
var l = (rand() + rand() + rand() + rand()) * 25;
var l = (rand() + rand() + rand() + rand()) * 25
return [h / 360, s / 100, l / 100];
return [h / 360, s / 100, l / 100]
}
function createImageData(size) {
var width = size; // Only support square icons for now
var height = size;
var width = size // Only support square icons for now
var height = size
var dataWidth = Math.ceil(width / 2);
var mirrorWidth = width - dataWidth;
var dataWidth = Math.ceil(width / 2)
var mirrorWidth = width - dataWidth
var data = [];
var data = []
for (var y = 0; y < height; y++) {
var row = [];
var row = []
for (var x = 0; x < dataWidth; x++) {
// this makes foreground and background color to have a 43% (1/2.3) probability
// spot color has 13% chance
row[x] = Math.floor(rand() * 2.3);
row[x] = Math.floor(rand() * 2.3)
}
var r = row.slice(0, mirrorWidth);
r.reverse();
row = row.concat(r);
var r = row.slice(0, mirrorWidth)
r.reverse()
row = row.concat(r)
for (var i = 0; i < row.length; i++) {
data.push(row[i]);
data.push(row[i])
}
}
return data;
return data
}
function buildOpts(opts) {
@ -324,43 +329,45 @@
throw 'No seed provided'
}
seedrand(opts.seed);
seedrand(opts.seed)
return Object.assign({
size: 8,
scale: 16,
color: createColor(),
bgcolor: createColor(),
spotcolor: createColor(),
}, opts)
return Object.assign(
{
size: 8,
scale: 16,
color: createColor(),
bgcolor: createColor(),
spotcolor: createColor(),
},
opts,
)
}
function toDataUrl(address) {
const opts = buildOpts({ seed: address.toLowerCase() });
const opts = buildOpts({ seed: address.toLowerCase() })
const imageData = createImageData(opts.size);
const width = Math.sqrt(imageData.length);
const imageData = createImageData(opts.size)
const width = Math.sqrt(imageData.length)
const p = new PNG(opts.size * opts.scale, opts.size * opts.scale, 3);
const bgcolor = p.color(...hsl2rgb(...opts.bgcolor));
const color = p.color(...hsl2rgb(...opts.color));
const spotcolor = p.color(...hsl2rgb(...opts.spotcolor));
const p = new PNG(opts.size * opts.scale, opts.size * opts.scale, 3)
const bgcolor = p.color(...hsl2rgb(...opts.bgcolor))
const color = p.color(...hsl2rgb(...opts.color))
const spotcolor = p.color(...hsl2rgb(...opts.spotcolor))
for (var i = 0; i < imageData.length; i++) {
var row = Math.floor(i / width);
var col = i % width;
var row = Math.floor(i / width)
var col = i % width
// if data is 0, leave the background
if (imageData[i]) {
// if data is 2, choose spot color, if 1 choose foreground
const pngColor = imageData[i] == 1 ? color : spotcolor;
p.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale, pngColor);
const pngColor = imageData[i] == 1 ? color : spotcolor
p.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale, pngColor)
}
}
return `data:image/png;base64,${p.getBase64()}`;
return `data:image/png;base64,${p.getBase64()}`
}
exports.toDataUrl = toDataUrl;
exports.toDataUrl = toDataUrl
Object.defineProperty(exports, '__esModule', { value: true });
})));
Object.defineProperty(exports, '__esModule', { value: true })
})

View File

@ -5,11 +5,18 @@ import { toDataUrl } from './blockies'
type Props = {
address: string,
diameter: number,
className?: string,
}
type IdenticonRef = { current: null | HTMLDivElement }
export default class Identicon extends React.PureComponent<Props> {
static defaultProps = {
className: '',
}
identicon: IdenticonRef
constructor(props: Props) {
super(props)
@ -55,13 +62,13 @@ export default class Identicon extends React.PureComponent<Props> {
return image
}
identicon: IdenticonRef
render() {
const style = this.getStyleFrom(this.props.diameter)
const { diameter, className } = this.props
const style = this.getStyleFrom(diameter)
return (
<div style={style} ref={this.identicon} />
<div className={className} style={style} ref={this.identicon} />
)
}
}

View File

@ -4,11 +4,7 @@ import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Components', module)
.addDecorator(FrameDecorator)

View File

@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import cn from 'classnames'
import Modal from '@material-ui/core/Modal'
import { withStyles } from '@material-ui/core/styles'
@ -8,8 +9,10 @@ type Props = {
description: string,
open: boolean,
handleClose: Function,
children: React$Node,
children: React.Node,
classes: Object,
modalClassName: ?string,
paperClassName: ?string,
}
const styles = () => ({
@ -35,18 +38,16 @@ const styles = () => ({
})
const GnoModal = ({
title, description, open, children, handleClose, classes,
title, description, open, children, handleClose, modalClassName, classes, paperClassName,
}: Props) => (
<Modal
aria-labelledby={title}
aria-describedby={description}
open={open}
onClose={handleClose}
className={classes.root}
className={cn(classes.root, modalClassName)}
>
<div className={classes.paper}>
{ children }
</div>
<div className={cn(classes.paper, paperClassName)}>{children}</div>
</Modal>
)

View File

@ -1,47 +0,0 @@
// @flow
import * as React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import RefreshIcon from '@material-ui/icons/Refresh'
import { sm, secondary } from '~/theme/variables'
type Props = {
callback: () => void,
}
type State = {
loading: boolean,
}
const loaderStyle = {
margin: `0px 0px 0px ${sm}`,
color: secondary,
}
class Loader extends React.Component<Props, State> {
constructor() {
super()
this.state = {
loading: false,
}
}
onReload = async () => {
this.setState({ loading: true }, await this.props.callback())
this.setState({ loading: false })
}
render() {
const { loading } = this.state
return (
<div style={loaderStyle}>
{loading
? <CircularProgress color="inherit" size={24} />
: <RefreshIcon color="inherit" onClick={this.onReload} /> }
</div>
)
}
}
export default Loader

View File

@ -0,0 +1,31 @@
// @flow
import 'babel-polyfill'
import { MuiThemeProvider } from '@material-ui/core/styles'
import React, { Suspense } from 'react'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router'
import { hot } from 'react-hot-loader/root'
import PageFrame from '../layout/PageFrame'
import Loader from '../Loader'
import { history, store } from '~/store'
import theme from '~/theme/mui'
import AppRoutes from '~/routes'
import './index.scss'
const Root = () => (
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<ConnectedRouter history={history}>
<PageFrame>
<Suspense fallback={<Loader />}>
<AppRoutes />
</Suspense>
</PageFrame>
</ConnectedRouter>
</MuiThemeProvider>
</Provider>
)
export default hot(Root)

View File

@ -1,67 +0,0 @@
// @flow
import * as React from 'react'
import SharedSnackBar from './index'
const SharedSnackbarContext = React.createContext({
openSnackbar: undefined,
closeSnackbar: undefined,
snackbarIsOpen: false,
message: '',
variant: 'info',
})
type Props = {
children: React$Node,
}
export type Variant = 'success' | 'error' | 'warning' | 'info'
type State = {
isOpen: boolean,
message: string,
variant: Variant,
}
export class SharedSnackbarProvider extends React.Component<Props, State> {
state = {
isOpen: false,
message: '',
variant: 'info',
}
openSnackbar = (message: string, variant: Variant) => {
this.setState({
message,
variant,
isOpen: true,
})
}
closeSnackbar = () => {
this.setState({
message: '',
isOpen: false,
})
}
render() {
const { children } = this.props
return (
<SharedSnackbarContext.Provider
value={{
openSnackbar: this.openSnackbar,
closeSnackbar: this.closeSnackbar,
snackbarIsOpen: this.state.isOpen,
message: this.state.message,
variant: this.state.variant,
}}
>
<SharedSnackBar />
{children}
</SharedSnackbarContext.Provider>
)
}
}
export const SharedSnackbarConsumer = SharedSnackbarContext.Consumer

View File

@ -2,9 +2,8 @@
import * as React from 'react'
import { Snackbar } from '@material-ui/core'
import SnackbarContent from '~/components/SnackbarContent'
import { SharedSnackbarConsumer } from './Context'
const SharedSnackbar = () => (
export const SharedSnackbar = () => (
<SharedSnackbarConsumer>
{(value) => {
const {
@ -32,4 +31,75 @@ const SharedSnackbar = () => (
</SharedSnackbarConsumer>
)
export default SharedSnackbar
type SnackbarContext = {
openSnackbar: Function,
closeSnackbar: Function,
snackbarIsOpen: boolean,
message: string,
variant: string,
}
const SharedSnackbarContext = React.createContext<SnackbarContext>({
openSnackbar: undefined,
closeSnackbar: undefined,
snackbarIsOpen: false,
message: '',
variant: 'info',
})
type Props = {
children: React.Node,
}
export type Variant = 'success' | 'error' | 'warning' | 'info'
type State = {
isOpen: boolean,
message: string,
variant: Variant,
}
export class SharedSnackbarProvider extends React.Component<Props, State> {
state = {
isOpen: false,
message: '',
variant: 'info',
}
openSnackbar = (message: string, variant: Variant) => {
this.setState({
message,
variant,
isOpen: true,
})
}
closeSnackbar = () => {
this.setState({
message: '',
isOpen: false,
})
}
render() {
const { children } = this.props
const { message, variant, isOpen } = this.state
return (
<SharedSnackbarContext.Provider
value={{
openSnackbar: this.openSnackbar,
closeSnackbar: this.closeSnackbar,
snackbarIsOpen: isOpen,
message,
variant,
}}
>
<SharedSnackbar />
{children}
</SharedSnackbarContext.Provider>
)
}
}
export const SharedSnackbarConsumer = SharedSnackbarContext.Consumer

View File

@ -64,7 +64,7 @@ const styles = theme => ({
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing.unit,
marginRight: theme.spacing(1),
},
message: {
display: 'flex',

View File

@ -48,7 +48,7 @@ const Controls = ({
<Button
style={secondButtonStyle}
size="small"
variant="raised"
variant="contained"
color="primary"
type="submit"
disabled={disabled}

View File

@ -21,8 +21,8 @@ const styles = () => ({
type Props = {
classes: Object,
children: React$Node,
controls: React$Node,
children: React.Node,
controls: React.Node,
container?: number,
padding?: boolean,
}
@ -41,7 +41,7 @@ const OpenPaper = ({
<Block style={containerStyle} className={`${classes.container} ${padding ? classes.padding : ''}`}>
{children}
</Block>
{ controls }
{controls}
</Paper>
)
}

View File

@ -2,7 +2,7 @@
import * as React from 'react'
type Props = {
children: React$Node,
children: React.Node,
}
const Step = ({ children }: Props) => (

View File

@ -16,11 +16,12 @@ export { default as Step } from './Step'
type Props = {
steps: string[],
onSubmit: (values: Object) => Promise<void>,
children: React$Node,
children: React.Node,
classes: Object,
onReset?: () => void,
initialValues?: Object,
disabledWhenValidating?: boolean,
testId?: string,
}
type State = {
@ -46,10 +47,11 @@ class GnoStepper extends React.PureComponent<Props, State> {
static FinishButton = ({
component, to, title, ...props
}) => (
<Button component={component} to={to} variant="raised" color="primary" {...props}>
<Button component={component} to={to} variant="contained" color="primary" {...props}>
{title}
</Button>
)
constructor(props: Props) {
super(props)
@ -60,38 +62,45 @@ class GnoStepper extends React.PureComponent<Props, State> {
}
onReset = () => {
const resetCallback = this.props.onReset
if (resetCallback) {
resetCallback()
const { onReset, initialValues } = this.props
if (onReset) {
onReset()
}
this.setState(() => ({
page: 0,
values: this.props.initialValues || {},
values: initialValues || {},
}))
}
getPageProps = (pages: React$Node): PageProps => React.Children.toArray(pages)[this.state.page].props
getPageProps = (pages: React.Node): PageProps => {
const { page } = this.state
getActivePageFrom = (pages: React$Node) => {
return React.Children.toArray(pages)[page].props
}
getActivePageFrom = (pages: React.Node) => {
const activePageProps = this.getPageProps(pages)
const { children, ...props } = activePageProps
return children({ ...props, updateInitialProps: this.updateInitialProps })
}
updateInitialProps = (initialValues) => {
this.setState({ values: initialValues })
updateInitialProps = (values) => {
this.setState({ values })
}
validate = (values: Object) => {
const activePage = React.Children.toArray(this.props.children)[
this.state.page
]
const { children } = this.props
const { page } = this.state
const activePage = React.Children.toArray(children)[page]
return activePage.props.validate ? activePage.props.validate(values) : {}
}
next = async (values: Object) => {
const activePageProps = this.getPageProps(this.props.children)
const { children } = this.props
const activePageProps = this.getPageProps(children)
const { prepareNextInitialProps } = activePageProps
let pageInitialProps
@ -101,14 +110,15 @@ class GnoStepper extends React.PureComponent<Props, State> {
const finalValues = { ...values, ...pageInitialProps }
this.setState(state => ({
page: Math.min(state.page + 1, React.Children.count(this.props.children) - 1),
page: Math.min(state.page + 1, React.Children.count(children) - 1),
values: finalValues,
}))
}
previous = () => {
const firstPage = this.state.page === 0
const { page } = this.state
const firstPage = page === 0
if (firstPage) {
return history.goBack()
}
@ -129,11 +139,14 @@ class GnoStepper extends React.PureComponent<Props, State> {
return this.next(values)
}
isLastPage = page => page === this.props.steps.length - 1
isLastPage = (page) => {
const { steps } = this.props
return page === steps.length - 1
}
render() {
const {
steps, children, classes, disabledWhenValidating = false,
steps, children, classes, disabledWhenValidating = false, testId,
} = this.props
const { page, values } = this.state
const activePage = this.getActivePageFrom(children)
@ -142,11 +155,7 @@ class GnoStepper extends React.PureComponent<Props, State> {
return (
<React.Fragment>
<GnoForm
onSubmit={this.handleSubmit}
initialValues={values}
validation={this.validate}
>
<GnoForm onSubmit={this.handleSubmit} initialValues={values} validation={this.validate} testId={testId}>
{(submitting: boolean, validating: boolean, ...rest: any) => {
const disabled = disabledWhenValidating ? submitting || validating : submitting
const controls = (
@ -167,9 +176,7 @@ class GnoStepper extends React.PureComponent<Props, State> {
{steps.map(label => (
<FormStep key={label}>
<StepLabel>{label}</StepLabel>
<StepContent TransitionProps={transitionProps}>
{activePage(controls, ...rest)}
</StepContent>
<StepContent TransitionProps={transitionProps}>{activePage(controls, ...rest)}</StepContent>
</FormStep>
))}
</Stepper>

View File

@ -9,12 +9,13 @@ import { type Order } from '~/components/Table/sorting'
export type Column = {
id: string,
numeric: boolean,
align?: string,
order: boolean, // If data for sorting will be provided in a different attr
disablePadding: boolean,
label: string,
custom: boolean, // If content will be rendered by user manually
width?: number,
static?: boolean, // If content can't be sorted by values in the column
}
export const cellWidth = (width: number | typeof undefined) => {
@ -36,7 +37,9 @@ type Props = {
class GnoTableHead extends React.PureComponent<Props> {
changeSort = (property: string, orderAttr: boolean) => () => {
this.props.onSort(property, orderAttr)
const { onSort } = this.props
onSort(property, orderAttr)
}
render() {
@ -48,17 +51,21 @@ class GnoTableHead extends React.PureComponent<Props> {
{columns.map((column: Column) => (
<TableCell
key={column.id}
numeric={column.numeric}
align={column.align}
padding={column.disablePadding ? 'none' : 'default'}
sortDirection={orderBy === column.id ? order : false}
>
<TableSortLabel
active={orderBy === column.id}
direction={order}
onClick={this.changeSort(column.id, column.order)}
>
{column.label}
</TableSortLabel>
{column.static ? (
column.label
) : (
<TableSortLabel
active={orderBy === column.id}
direction={order}
onClick={this.changeSort(column.id, column.order)}
>
{column.label}
</TableSortLabel>
)}
</TableCell>
))}
</TableRow>

View File

@ -2,14 +2,12 @@
import * as React from 'react'
import classNames from 'classnames'
import { List } from 'immutable'
import Row from '~/components/layout/Row'
import Table from '@material-ui/core/Table'
import TableBody from '@material-ui/core/TableBody'
import TableRow from '@material-ui/core/TableRow'
import TableCell from '@material-ui/core/TableCell'
import { withStyles } from '@material-ui/core/styles'
import CircularProgress from '@material-ui/core/CircularProgress'
import TablePagination from '@material-ui/core/TablePagination'
import Row from '~/components/layout/Row'
import { type Order, stableSort, getSorting } from '~/components/Table/sorting'
import TableHead, { type Column } from '~/components/Table/TableHead'
import { xl } from '~/theme/variables'
@ -23,15 +21,17 @@ type Props<K> = {
children: Function,
size: number,
defaultFixed?: boolean,
defaultOrder?: 'desc' | 'asc',
noBorder: boolean,
}
type State = {
page: number,
order: Order,
orderBy: string,
orderBy?: string,
orderProp: boolean,
rowsPerPage: number,
fixed: boolean,
fixed?: boolean,
}
const styles = {
@ -60,26 +60,56 @@ const styles = {
const FIXED_HEIGHT = 49
const backProps = {
'aria-label': 'Previous Page',
}
const nextProps = {
'aria-label': 'Next Page',
}
class GnoTable<K> extends React.Component<Props<K>, State> {
state = {
page: 0,
order: 'asc',
orderBy: this.props.defaultOrderBy,
fixed: !!this.props.defaultFixed,
order: undefined,
orderBy: undefined,
fixed: undefined,
orderProp: false,
rowsPerPage: 5,
}
onSort = (property: string, orderProp: boolean) => {
const orderBy = property
let order = 'desc'
componentDidMount() {
const { defaultOrderBy, columns } = this.props
if (this.state.orderBy === property && this.state.order === 'desc') {
order = 'asc'
if (defaultOrderBy && columns) {
const defaultOrderCol = columns.find(({ id }) => id === defaultOrderBy)
if (defaultOrderCol.order) {
this.setState({
orderProp: true,
})
}
}
}
onSort = (newOrderBy: string, orderProp: boolean) => {
const { order, orderBy } = this.state
const { defaultOrder } = this.props
let newOrder = 'desc'
// if table was previously sorted by the user
if (order && orderBy === newOrderBy && order === 'desc') {
newOrder = 'asc'
} else if (!order && defaultOrder === 'desc') {
// if it was not sorted and defaultOrder is used
newOrder = 'asc'
}
this.setState(() => ({
order, orderBy, orderProp, fixed: false,
order: newOrder,
orderBy: newOrderBy,
orderProp,
fixed: false,
}))
}
@ -91,69 +121,57 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
this.setState({ page })
}
handleChangeRowsPerPage = (event: SyntheticInputEvent<HTMLInputElement>) => {
const rowsPerPage = Number(event.target.value)
handleChangeRowsPerPage = (e: SyntheticInputEvent<HTMLInputElement>) => {
const rowsPerPage = Number(e.target.value)
this.setState({ rowsPerPage })
}
render() {
const {
data, label, columns, classes, children, size,
data, label, columns, classes, children, size, defaultOrderBy, defaultOrder, defaultFixed, noBorder,
} = this.props
const {
order, orderBy, page, orderProp, rowsPerPage, fixed,
} = this.state
const backProps = {
'aria-label': 'Previous Page',
}
const nextProps = {
'aria-label': 'Next Page',
}
const orderByParam = orderBy || defaultOrderBy
const orderParam = order || defaultOrder
const fixedParam = typeof fixed !== 'undefined' ? fixed : !!defaultFixed
const paginationClasses = {
selectRoot: classes.selectRoot,
root: classes.paginationRoot,
root: !noBorder && classes.paginationRoot,
input: classes.white,
}
const sortedData = stableSort(data, getSorting(order, orderBy, orderProp), fixed)
.slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage))
const sortedData = stableSort(data, getSorting(orderParam, orderByParam, orderProp), fixedParam).slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage,
)
const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - (page * rowsPerPage))
const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage)
const isEmpty = size === 0
return (
<React.Fragment>
{ !isEmpty &&
<Table aria-labelledby={label} className={classes.root}>
<TableHead
columns={columns}
order={order}
orderBy={orderBy}
onSort={this.onSort}
/>
<TableBody>
{ children(sortedData) }
{ emptyRows > 0 &&
<TableRow style={this.getEmptyStyle(emptyRows)}>
<TableCell colSpan={4} />
</TableRow>
}
</TableBody>
{!isEmpty && (
<Table aria-labelledby={label} className={noBorder ? '' : classes.root}>
<TableHead columns={columns} order={order} orderBy={orderByParam} onSort={this.onSort} />
<TableBody>{children(sortedData)}</TableBody>
</Table>
}
{ isEmpty &&
<Row className={classNames(classes.loader, classes.root)} style={this.getEmptyStyle(emptyRows + 1)}>
)}
{isEmpty && (
<Row
className={classNames(classes.loader, !noBorder && classes.root)}
style={this.getEmptyStyle(emptyRows + 1)}
>
<CircularProgress size={60} />
</Row>
}
)}
<TablePagination
component="div"
count={size}
rowsPerPage={rowsPerPage}
rowsPerPageOptions={[5, 10, 25, 50, 100]}
page={page}
backIconButtonProps={backProps}
nextIconButtonProps={nextProps}
@ -166,4 +184,8 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
}
}
GnoTable.defaultProps = {
defaultOrder: 'asc',
}
export default withStyles(styles)(GnoTable)

View File

@ -1,4 +1,5 @@
// @flow
import { List } from 'immutable'
export const FIXED = 'fixed'
type Fixed = {
@ -9,7 +10,6 @@ export type SortRow<T> = T & Fixed
export const buildOrderFieldFrom = (attr: string) => `${attr}Order`
const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => {
const order = orderProp ? buildOrderFieldFrom(orderBy) : orderBy
@ -24,13 +24,14 @@ const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => {
}
// eslint-disable-next-line
export const stableSort = <SortRow>(array: Array<SortRow>, cmp: any, fixed: boolean): Array<SortRow> => {
const fixedElems: Array<SortRow> = fixed ? array.filter((elem: any) => elem.fixed) : []
const data: Array<SortRow> = fixed ? array.filter((elem: any) => !elem[FIXED]) : array
const stabilizedThis = data.map((el, index) => [el, index])
export const stableSort = (dataArray: List<any>, cmp: any, fixed: boolean): List<any> => {
const fixedElems: List<any> = fixed ? dataArray.filter((elem: any) => elem.fixed) : List([])
const data: List<any> = fixed ? dataArray.filter((elem: any) => !elem[FIXED]) : dataArray
let stabilizedThis = data.map((el, index) => [el, index])
stabilizedThis.sort((a, b) => {
stabilizedThis = stabilizedThis.sort((a, b) => {
const order = cmp(a[0], b[0])
if (order !== 0) {
return order
}
@ -38,12 +39,13 @@ export const stableSort = <SortRow>(array: Array<SortRow>, cmp: any, fixed: bool
return a[1] - b[1]
})
const sortedElems: Array<SortRow> = stabilizedThis.map(el => el[0])
const sortedElems: List<any> = stabilizedThis.map(el => el[0])
return fixedElems.concat(sortedElems)
}
export type Order = 'asc' | 'desc'
export const getSorting = (order: Order, orderBy: string, orderProp: boolean) =>
(order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy, orderProp) : (a: any, b: any) => -desc(a, b, orderBy, orderProp))
export const getSorting = (order: Order, orderBy: string, orderProp: boolean) => (order === 'desc'
? (a: any, b: any) => desc(a, b, orderBy, orderProp)
: (a: any, b: any) => -desc(a, b, orderBy, orderProp))

View File

@ -15,6 +15,8 @@ type Props = {
padding?: number,
validation?: (values: Object) => Object | Promise<Object>,
initialValues?: Object,
formMutators?: Object,
testId?: string,
}
const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
@ -24,15 +26,16 @@ const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
})
const GnoForm = ({
onSubmit, validation, initialValues, children, padding = 0,
onSubmit, validation, initialValues, children, padding = 0, formMutators, testId = '',
}: Props) => (
<Form
validate={validation}
onSubmit={onSubmit}
initialValues={initialValues}
mutators={formMutators}
render={({ handleSubmit, ...rest }) => (
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
{children(rest.submitting, rest.validating, rest)}
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)} data-testid={testId}>
{children(rest.submitting, rest.validating, rest, rest.form.mutators)}
</form>
)}
/>

View File

@ -16,32 +16,31 @@ const SelectInput = ({
meta,
label,
formControlProps,
classes,
renderValue,
disableError,
...rest
}: SelectFieldProps) => {
const showError = ((meta.submitError && !meta.dirtySinceLastSubmit) || meta.error) && meta.touched
const inputProps = { ...restInput, name }
const showError = ((meta.submitError && !meta.dirtySinceLastSubmit) || meta.error) && meta.touched && !disableError
const inputProps = {
...restInput,
name,
}
return (
<FormControl
{...formControlProps}
error={showError}
style={style}
>
<FormControl {...formControlProps} error={showError} style={style}>
<InputLabel htmlFor={name}>{label}</InputLabel>
<Select
{...rest}
classes={classes}
onChange={onChange}
renderValue={renderValue}
inputProps={inputProps}
value={value}
{...rest}
/>
{ showError &&
<FormHelperText>
{meta.error || meta.submitError}
</FormHelperText>
}
{showError && <FormHelperText>{meta.error || meta.submitError}</FormHelperText>}
</FormControl>
)
}
export default SelectInput

View File

@ -29,6 +29,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
text,
inputAdornment,
classes,
testId,
...rest
} = this.props
const helperText = value ? text : undefined
@ -36,7 +37,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
const underline = meta.active || (meta.visited && !meta.valid)
const inputRoot = helperText ? classes.root : undefined
const inputProps = { ...restInput, autoComplete: 'off' }
const inputProps = { ...restInput, autoComplete: 'off', 'data-testid': testId }
const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot }
return (
@ -51,6 +52,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
inputProps={inputProps}
onChange={onChange}
value={value}
// data-testid={testId}
/>
)
}

View File

@ -2,15 +2,25 @@
import { type FieldValidator } from 'final-form'
import { getWeb3 } from '~/logic/wallets/getWeb3'
export const simpleMemoize = (fn: Function) => {
let lastArg
let lastResult
return (arg: any) => {
if (arg !== lastArg) {
lastArg = arg
lastResult = fn(arg)
}
return lastResult
}
}
type Field = boolean | string | null | typeof undefined
export const required = (value: Field) => (value ? undefined : 'Required')
export const required = simpleMemoize((value: Field) => (value ? undefined : 'Required'))
export const mustBeInteger = (value: string) =>
(!Number.isInteger(Number(value)) || value.includes('.') ? 'Must be an integer' : undefined)
export const mustBeInteger = (value: string) => (!Number.isInteger(Number(value)) || value.includes('.') ? 'Must be an integer' : undefined)
export const mustBeFloat = (value: number) =>
(Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
export const mustBeFloat = (value: number) => (Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
export const greaterThan = (min: number) => (value: string) => {
if (Number.isNaN(Number(value)) || Number.parseFloat(value) > Number(min)) {
@ -48,19 +58,19 @@ export const maxValue = (max: number) => (value: string) => {
export const ok = () => undefined
export const mustBeEthereumAddress = (address: Field) => {
const isAddress: boolean = getWeb3().isAddress(address)
export const mustBeEthereumAddress = simpleMemoize((address: Field) => {
const isAddress: boolean = getWeb3().utils.isAddress(address)
return isAddress ? undefined : 'Address should be a valid Ethereum address'
}
})
export const minMaxLength = (minLen: string | number, maxLen: string | number) => (value: string) => (value.length >= +minLen && value.length <= +maxLen ? undefined : `Should be ${minLen} to ${maxLen} symbols`)
export const ADDRESS_REPEATED_ERROR = 'Address already introduced'
export const uniqueAddress = (addresses: string[]) => (value: string) =>
(addresses.includes(value) ? ADDRESS_REPEATED_ERROR : undefined)
export const uniqueAddress = (addresses: string[]) => simpleMemoize((value: string) => (addresses.includes(value) ? ADDRESS_REPEATED_ERROR : undefined))
export const composeValidators = (...validators: Function[]): FieldValidator => (value: Field) =>
validators.reduce((error, validator) => error || validator(value), undefined)
export const composeValidators = (...validators: Function[]): FieldValidator => (value: Field) => validators.reduce((error, validator) => error || validator(value), undefined)
export const inLimit = (limit: number, base: number, baseText: string, symbol: string = 'ETH') => (value: string) => {
const amount = Number(value)
@ -72,4 +82,12 @@ export const inLimit = (limit: number, base: number, baseText: string, symbol: s
return `Should not exceed ${max} ${symbol} (amount to reach ${baseText})`
}
export const differentFrom = (diffValue: string) => (value: string) => {
if (value === diffValue.toString()) {
return `Value should be different than ${value}`
}
return undefined
}
export const noErrorsOn = (name: string, errors: Object) => errors[name] === undefined

View File

@ -10,8 +10,8 @@ const cx = classNames.bind(styles)
type Props = {
margin?: Size,
padding?: Size,
align?: 'center' | 'right',
children: React$Node,
align?: 'center' | 'right' | 'left',
children: React.Node,
className?: string,
}
@ -24,7 +24,7 @@ class Block extends PureComponent<Props> {
const paddingStyle = padding ? capitalize(padding, 'padding') : undefined
return (
<div className={cx(className, 'block', margin, paddingStyle, align)} {...props}>
{ children }
{children}
</div>
)
}

View File

@ -1,5 +1,4 @@
.block {
}
.xs {
@ -7,19 +6,19 @@
}
.sm {
margin-bottom: $sm;
margin-bottom: $sm;
}
.md {
margin-bottom: $md;
margin-bottom: $md;
}
.lg {
margin-bottom: $lg;
margin-bottom: $lg;
}
.xl {
margin-bottom: $xl;
margin-bottom: $xl;
}
.paddingXs {
@ -48,8 +47,13 @@
justify-content: center;
}
.left {
display: flex;
align-items: center;
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
}
}

View File

@ -2,18 +2,14 @@
import * as React from 'react'
type Props = {
children: React$Node,
children: React.Node,
}
class Bold extends React.PureComponent<Props> {
render() {
const { children, ...props } = this.props
return (
<b {...props}>
{ children }
</b>
)
return <b {...props}>{children}</b>
}
}

View File

@ -1,26 +1,27 @@
// @flow
import * as React from 'react'
import Button from '@material-ui/core/Button'
import { withStyles } from '@material-ui/core/styles'
const styles = {
root: {
borderRadius: 0,
},
}
type Props = {
minWidth?: number
minWidth?: number,
minHeight?: number,
rounded?: boolean,
testId?: string,
style?: Object,
}
const calculateStyleBased = minWidth => ({
minWidth: `${minWidth}px`,
const calculateStyleBased = (minWidth, minHeight, rounded) => ({
minWidth: minWidth && `${minWidth}px`,
minHeight: minHeight && `${minHeight}px`,
borderRadius: rounded ? '4px' : 0,
})
const GnoButton = ({ minWidth, ...props }: Props) => {
const style = minWidth ? calculateStyleBased(minWidth) : undefined
const GnoButton = ({
minWidth, minHeight = 27, testId = '', rounded, style = {}, ...props
}: Props) => {
const calculatedStyle = calculateStyleBased(minWidth, minHeight, rounded)
return <Button style={style} {...props} />
return <Button style={{ ...calculatedStyle, ...style }} data-testid={testId} {...props} />
}
export default withStyles(styles)(GnoButton)
export default GnoButton

View File

@ -0,0 +1,26 @@
// @flow
/* eslint-disable react/button-has-type */
import * as React from 'react'
import cn from 'classnames/bind'
import styles from './index.scss'
const cx = cn.bind(styles)
type Props = {
type?: 'button' | 'submit' | 'reset',
size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
weight?: 'light' | 'regular' | 'bolder' | 'bold',
color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'secondary' | 'warning' | 'disabled' | 'error',
testId?: string,
}
const GnoButtonLink = ({
type = 'button',
size = 'md',
weight = 'regular',
color = 'secondary',
testId = '',
...props
}: Props) => <button type={type} className={cx(styles.btnLink, size, color, weight)} data-testid={testId} {...props} />
export default GnoButtonLink

View File

@ -0,0 +1,83 @@
.btnLink {
background: transparent;
border: none;
text-decoration: underline;
font-family: 'Roboto Mono', monospace;
cursor: pointer;
}
.sm {
font-size: $smallFontSize;
}
.md {
font-size: $mediumFontSize;
}
.lg {
font-size: $largeFontSize;
}
.xl {
font-size: $extraLargeFontSize;
}
.xxl {
font-size: $xxlFontSize;
}
.light {
font-weight: $lightFont;
}
.regular {
font-weight: $regularFont;
}
.bolder {
font-weight: $bolderFont;
}
.bold {
font-weight: $boldFont;
}
.soft {
color: #888888;
}
.medium {
color: #686868;
}
.dark {
color: black;
}
.fancy {
color: $fancy;
}
.warning {
color: $warning;
}
.primary {
color: $fontColor;
}
.secondary {
color: $secondary;
}
.disabled {
color: $disabled;
}
.error {
color: $error;
}
.white {
color: white;
}

View File

@ -27,14 +27,30 @@ type Props = {
mdOffset?: number,
lgOffset?: number,
className?: string,
children: React$Node,
children: React.Node,
}
const Col = ({
children, margin, layout = 'inherit', overflow,
xs, sm, md, lg,
start, center, end, top, middle, bottom, around, between,
xsOffset, smOffset, mdOffset, lgOffset,
children,
margin,
layout = 'inherit',
overflow,
xs,
sm,
md,
lg,
start,
center,
end,
top,
middle,
bottom,
around,
between,
xsOffset,
smOffset,
mdOffset,
lgOffset,
className,
...props
}: Props) => {
@ -64,7 +80,7 @@ const Col = ({
return (
<div className={colClassNames} {...props}>
{ children }
{children}
</div>
)
}

View File

@ -184,19 +184,19 @@
text-align: end;
}
.top$(size) {
align-items: flex-start;
align-items: flex-start;
}
.middle$(size) {
align-items: center;
align-items: center;
}
.bottom$(size) {
align-items: flex-end;
align-items: flex-end;
}
.around$(size) {
justify-content: space-around;
justify-content: space-around;
}
.between$(size) {
justify-content: space-between;
justify-content: space-between;
}
}

View File

@ -7,8 +7,6 @@ const style = {
borderRight: `solid 1px ${border}`,
}
const Divider = () => (
<div style={style} />
)
const Divider = () => <div style={style} />
export default Divider

View File

@ -5,6 +5,7 @@ import { border } from '~/theme/variables'
const calculateStyleFrom = (color?: string, margin?: Size) => ({
width: '100%',
minHeight: '1px',
height: '1px',
backgroundColor: color || border,
margin: `${getSize(margin)} 0px`,
@ -13,12 +14,14 @@ const calculateStyleFrom = (color?: string, margin?: Size) => ({
type Props = {
margin?: Size,
color?: string,
style?: Object,
}
const Hairline = ({ margin, color }: Props) => {
const style = calculateStyleFrom(color, margin)
const Hairline = ({ margin, color, style }: Props) => {
const calculatedStyles = calculateStyleFrom(color, margin)
const mergedStyles = { ...calculatedStyles, ...(style || {}) }
return <div style={style} />
return <div style={mergedStyles} />
}
export default Hairline

Some files were not shown because too many files have changed in this diff Show More