Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@expandorg/app-web3

Package Overview
Dependencies
Maintainers
3
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expandorg/app-web3 - npm Package Compare versions

Comparing version 0.0.32 to 0.0.33

6

package.json
{
"name": "@expandorg/app-web3",
"version": "0.0.32",
"version": "0.0.33",
"description": "web3 app",

@@ -21,7 +21,7 @@ "main": "index.js",

"dependencies": {
"@expandorg/app-utils": "^0.0.36",
"@expandorg/app-utils": "^0.0.37",
"@expandorg/utils": "^0.0.8",
"@gemsorg/gems-token": "^1.0.0"
},
"gitHead": "610bca6faa505b76fa8c7916ed4344380573b61f"
"gitHead": "32124066122cb67ee261472b69f4993331538e31"
}
// @flow
import {
web3StateSelector,
metamaskStateSelector,
initGemsStateSelector,
} from './src/selectors';
import { web3StateSelector, metamaskStateSelector } from './src/selectors';
export { web3StateSelector, metamaskStateSelector, initGemsStateSelector };
export { web3StateSelector, metamaskStateSelector };

@@ -5,10 +5,6 @@ // @flow

const web3ActionTypes = createActionTypes('web3', {
INIT_WEB3_COMPLETE: null,
INIT_WEB3_FAILED: null,
INIT_GEMS: null,
INIT_GEMS_COMPLETE: null,
INIT_GEMS_FAILED: null,
INIT_METAMASK: null,
CHANGE_STATE: null,
});
export default web3ActionTypes;

@@ -9,12 +9,14 @@ import React from 'react';

const Actions = ({ onHide, children, className }) => (
<div className={cn(styles.actions, className)}>
{children}
{onHide && (
<Button theme="grey" className={styles.back} onClick={onHide}>
no, go back
</Button>
)}
</div>
);
export default function Actions({ onHide, children, className }) {
return (
<div className={cn(styles.actions, className)}>
{children}
{onHide && (
<Button theme="grey" className={styles.back} onClick={onHide}>
no, go back
</Button>
)}
</div>
);
}

@@ -30,3 +32,1 @@ Actions.propTypes = {

};
export default Actions;

@@ -1,5 +0,5 @@

import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { Button, ErrorMessage } from '@expandorg/components';
import { Button, ErrorMessage } from '@expandorg/components';
import Actions from './Actions';

@@ -9,31 +9,34 @@

export default class Form extends Component {
static propTypes = {
action: PropTypes.string.isRequired,
headline: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
error: PropTypes.string,
onAction: PropTypes.func.isRequired,
};
export default function Form({
onAction,
action,
headline,
description,
error,
}) {
return (
<div className={styles.container}>
<div className={styles.headline}>{headline}</div>
<div className={styles.description}>{description}- </div>
<div className={styles.screenshot} />
<ErrorMessage errors={error} className={styles.error} />
<Actions className={styles.actions}>
<Button className={styles.action} onClick={onAction}>
{action}
</Button>
</Actions>
</div>
);
}
static defaultProps = {
error: null,
};
Form.propTypes = {
action: PropTypes.string.isRequired,
headline: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
error: PropTypes.oneOfType(PropTypes.object, PropTypes.string),
onAction: PropTypes.func.isRequired,
};
render() {
const { onAction, action, headline, description, error } = this.props;
return (
<div className={styles.container}>
<div className={styles.headline}>{headline}</div>
<div className={styles.description}>{description}- </div>
<div className={styles.screenshot} />
<ErrorMessage errors={error} className={styles.error} />
<Actions className={styles.actions}>
<Button className={styles.action} onClick={onAction}>
{action}
</Button>
</Actions>
</div>
);
}
}
Form.defaultProps = {
error: null,
};

@@ -1,7 +0,11 @@

import React, { Component } from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useSelector, useDispatch } from 'react-redux';
import { Dialog } from '@expandorg/components';
import MetamaskState from '../../MetamaskState';
import { metamaskStateSelector } from '../../selectors';
import { initMetamask } from '../../sagas';

@@ -14,52 +18,58 @@ import Install from './Install';

export default class MetamaskPromt extends Component {
static propTypes = {
metamaskState: PropTypes.string.isRequired,
action: PropTypes.string,
headline: PropTypes.string,
description: PropTypes.string,
error: PropTypes.object, // eslint-disable-line react/forbid-prop-types
onLogin: PropTypes.func.isRequired,
onHide: PropTypes.func.isRequired,
};
export default function MetamaskPromt({
onAction,
onHide,
action,
error,
headline,
description,
}) {
const dispatch = useDispatch();
const mmask = useSelector(metamaskStateSelector);
static defaultProps = {
action: 'Sign in',
error: null,
headline: 'You’ll need to sign in using MetaMask',
description: '(similar to the above). Click below to log in.',
};
useEffect(() => {
dispatch(initMetamask());
}, [dispatch]);
render() {
const {
metamaskState,
onLogin,
onHide,
action,
error,
headline,
description,
} = this.props;
return (
<Dialog onHide={onHide} hideButton visible contentLabel="matamask">
<div className={styles.container}>
{metamaskState === MetamaskState.NotInstalled && (
<Install onHide={onHide} />
)}
{metamaskState === MetamaskState.NotAuthorized && (
<Unlock onHide={onHide} />
)}
{metamaskState === MetamaskState.Authorized && (
<Form
onAction={onLogin}
description={description}
headline={headline}
action={action}
error={error}
/>
)}
</div>
</Dialog>
);
}
const install =
mmask.state === MetamaskState.NotInstalled ||
mmask.state === MetamaskState.Installing;
const auth =
mmask.state === MetamaskState.NotAuthorized ||
mmask.state === MetamaskState.Authorizing;
return (
<Dialog onHide={onHide} hideButton visible contentLabel="matamask">
<div className={styles.container}>
{install && <Install onHide={onHide} />}
{auth && <Unlock onHide={onHide} />}
{mmask.state === MetamaskState.Authorized && (
<Form
onAction={onAction}
description={description}
headline={headline}
action={action}
error={error}
/>
)}
</div>
</Dialog>
);
}
MetamaskPromt.propTypes = {
action: PropTypes.string,
headline: PropTypes.string,
description: PropTypes.string,
error: PropTypes.object, // eslint-disable-line react/forbid-prop-types
onAction: PropTypes.func.isRequired,
onHide: PropTypes.func.isRequired,
};
MetamaskPromt.defaultProps = {
action: 'Sign in',
error: null,
headline: 'You’ll need to sign in using MetaMask',
description: '(similar to the above). Click below to log in.',
};

@@ -11,2 +11,9 @@ // @flow

function calculateGasPrice(average: number) {
return Math.min(
Math.max(average * GAS_PRICE_FACTOR, GAS_PRICE_MIN),
GAS_PRICE_MAX
);
}
export default class GemsService {

@@ -46,6 +53,2 @@ vault: string;

initGemTokens = async () => {
this.gemsTokens = await this.getGemTokensInstance();
};
getGemTokensInstance = async () => {
const instance = new GemsToken(

@@ -56,11 +59,5 @@ this.web3.currentProvider,

await instance.init();
return instance;
this.gemsTokens = instance;
};
calculateGasPrice = (average: number) =>
Math.min(
Math.max(average * GAS_PRICE_FACTOR, GAS_PRICE_MIN),
GAS_PRICE_MAX
);
approve = async (value: number, average: number) => {

@@ -70,12 +67,13 @@ if (!this.gemsTokens) {

}
const gasPrice = this.calculateGasPrice(average);
await this.gemsTokens.approve(this.vault, value * 1e18, {
gasPrice,
});
const props = { gasPrice: calculateGasPrice(average) };
await this.gemsTokens.approve(this.vault, value * 1e18, props);
};
getDefaultAccount = () => this.web3.eth.accounts[0];
getDefaultAccount = () => {
return this.web3.eth.accounts[0];
};
verifyAccount = async (accountId: string) => {
const accounts = await this.getAccounts();
const getAccounts = promisify(this.web3.eth.getAccounts, this.web3.eth);
const accounts = await getAccounts();
if (`0x${accountId}` !== accounts[0]) {

@@ -96,7 +94,2 @@ throw new Error('Invalid account');

getAccounts = async () => {
const call = promisify(this.web3.eth.getAccounts, this.web3.eth);
return call();
};
sendAsync = async (data: any) => {

@@ -103,0 +96,0 @@ const call = promisify(

import MetamaskState from './MetamaskState';
import web3ActionTypes from './actionTypes';
const initialState = MetamaskState.NotInstalled;
const initialState = { state: MetamaskState.NotInstalled };
export default function metamaskReducer(state = initialState, action) {
switch (action.type) {
case web3ActionTypes.INIT_WEB3_FAILED:
return initialState;
case web3ActionTypes.INIT_WEB3_COMPLETE:
return MetamaskState.NotAuthorized;
case web3ActionTypes.INIT_GEMS:
return MetamaskState.NotAuthorized;
case web3ActionTypes.INIT_GEMS_COMPLETE:
return MetamaskState.Authorized;
case web3ActionTypes.CHANGE_STATE:
return action.payload;
default:

@@ -17,0 +11,0 @@ break;

// @flow
const MetamaskState = {
NotInstalled: 'NotInstalled',
NotAuthorized: 'NotAuthorized',
Authorized: 'Authorized',
NotInstalled: 0,
Installing: 1,
NotAuthorized: 2,
Authorizing: 3,
Authorized: 4,
};
export default MetamaskState;

@@ -1,27 +0,32 @@

import { takeEvery, put, call, getContext } from 'redux-saga/effects';
import { takeEvery, put, call, getContext, select } from 'redux-saga/effects';
import { delay } from '@expandorg/utils';
import { appActionTypes } from '@expandorg/app-utils/app';
import web3ActionTypes from './actionTypes';
import { metamaskStateSelector } from './selectors';
function* handleInitWeb3() {
import MetamaskState from './MetamaskState';
export const initMetamask = () => ({
type: web3ActionTypes.INIT_METAMASK,
payload: null,
});
const changeMetamaskState = (state, error) => ({
type: web3ActionTypes.CHANGE_STATE,
payload: { state, error },
});
function* ensureInstalled(gemsService) {
try {
const services = yield getContext('services');
const gemsService = services.resolve('gems');
yield put(changeMetamaskState(MetamaskState.Installing));
yield call(gemsService.initWeb3);
yield put({ type: web3ActionTypes.INIT_WEB3_COMPLETE, payload: null });
} catch (error) {
yield put({ type: web3ActionTypes.INIT_WEB3_FAILED, payload: error });
yield put(changeMetamaskState(MetamaskState.NotAuthorized));
} catch (e) {
yield put(changeMetamaskState(MetamaskState.NotInstalled, e));
}
}
function* initGemsInstance() {
function* ensureAuthorized(gemsService) {
try {
yield put({ type: web3ActionTypes.INIT_GEMS, payload: null });
const services = yield getContext('services');
const gemsService = services.resolve('gems');
yield put(changeMetamaskState(MetamaskState.Authorizing));
yield call(gemsService.ensureEnable);

@@ -37,12 +42,32 @@

yield call(gemsService.initGemTokens);
yield put({ type: web3ActionTypes.INIT_GEMS_COMPLETE, payload: null });
yield put(changeMetamaskState(MetamaskState.Authorized));
} catch (e) {
yield put({ type: web3ActionTypes.INIT_GEMS_FAILED, payload: e });
yield put(changeMetamaskState(MetamaskState.NotAuthorized, e));
}
}
/* eslint-disable import/prefer-default-export */
function* runInitMetamask() {
const services = yield getContext('services');
const gemsService = services.resolve('gems');
let mmask = yield select(metamaskStateSelector);
if (mmask.state === MetamaskState.Installing) {
return;
}
if (mmask.state === MetamaskState.NotInstalled) {
yield ensureInstalled(gemsService);
}
mmask = yield select(metamaskStateSelector);
if (mmask.state === MetamaskState.Installing) {
return;
}
if (mmask.state === MetamaskState.NotAuthorized) {
yield ensureAuthorized(gemsService);
}
}
export function* web3Sagas() {
yield takeEvery(appActionTypes.INIT, handleInitWeb3);
yield takeEvery(web3ActionTypes.INIT_WEB3_COMPLETE, initGemsInstance);
yield takeEvery(web3ActionTypes.INIT_METAMASK, runInitMetamask);
}
// @flow
import { createSelector } from 'reselect';
import { uiStateSelector } from '@expandorg/app-utils/app';

@@ -11,6 +10,1 @@ export const web3StateSelector = (state: Object) => state.web3;

);
export const initGemsStateSelector = createSelector(
uiStateSelector,
state => state.initGems
);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc