add web3 and wallet contract actions:
This commit is contained in:
parent
dc337a2ae5
commit
09158b15f4
|
@ -0,0 +1,81 @@
|
|||
import { Dispatch } from 'redux';
|
||||
import { RootState } from '../reducers';
|
||||
import Web3 from 'web3';
|
||||
import { abi as keycardWalletFactoryABI } from '../contracts/KeycardWalletFactory';
|
||||
import { abi as keycardWalletABI } from '../contracts/KeycardWallet';
|
||||
import { isEmptyAddress } from '../utils';
|
||||
|
||||
const walletFactoryAddress = "0xF42dC64c5F580FFC120d6bc281C1293E63d8132a";
|
||||
const testKeycardAddress = "0xfD51b65f6Dee2aDd1C867c05d5B8d189b9da7060";
|
||||
|
||||
export const WALLET_FACTORY_LOADING = "WALLET_FACTORY_LOADING";
|
||||
export interface WalletFactoryAction {
|
||||
type: typeof WALLET_FACTORY_LOADING
|
||||
keycardAddress: string
|
||||
}
|
||||
|
||||
export const WALLET_KEYCARD_NOT_FOUND = "WALLET_KEYCARD_NOT_FOUND";
|
||||
export interface WalletKeycardNotFoundAction {
|
||||
type: typeof WALLET_KEYCARD_NOT_FOUND
|
||||
keycardAddress: string
|
||||
}
|
||||
|
||||
export const WALLET_LOADING = "WALLET_LOADING";
|
||||
export interface WalletLoadingAction {
|
||||
type: typeof WALLET_LOADING
|
||||
address: string
|
||||
}
|
||||
|
||||
export const WALLET_BALANCE_LOADED = "WALLET_BALANCE_LOADED";
|
||||
export interface WalletBalanceLoadedAction {
|
||||
type: typeof WALLET_BALANCE_LOADED
|
||||
balance: string
|
||||
}
|
||||
|
||||
export type WalletActions =
|
||||
WalletFactoryAction |
|
||||
WalletKeycardNotFoundAction |
|
||||
WalletLoadingAction;
|
||||
|
||||
export const loadingWalletFactory = (keycardAddress: string): WalletFactoryAction => ({
|
||||
type: WALLET_FACTORY_LOADING,
|
||||
keycardAddress,
|
||||
});
|
||||
|
||||
export const keycardNotFound = (keycardAddress: string): WalletKeycardNotFoundAction => ({
|
||||
type: WALLET_KEYCARD_NOT_FOUND,
|
||||
keycardAddress,
|
||||
});
|
||||
|
||||
export const loadingWallet = (address: string): WalletLoadingAction => ({
|
||||
type: WALLET_LOADING,
|
||||
address,
|
||||
});
|
||||
|
||||
export const balanceLoaded = (balance: string): WalletBalanceLoadedAction => ({
|
||||
type: WALLET_BALANCE_LOADED,
|
||||
balance,
|
||||
});
|
||||
|
||||
export const loadWallet = (dispatch: Dispatch) => {
|
||||
const keycardAddress = testKeycardAddress;
|
||||
|
||||
dispatch(loadingWalletFactory(keycardAddress));
|
||||
const web3: Web3 = (window as any).web3;
|
||||
const factory = new web3.eth.Contract(keycardWalletFactoryABI, walletFactoryAddress);
|
||||
factory.methods.keycardsWallets(keycardAddress).call().then((walletAddress: string) => {
|
||||
if (isEmptyAddress(walletAddress)) {
|
||||
dispatch(keycardNotFound(keycardAddress));
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(loadingWallet(walletAddress));
|
||||
const wallet = new web3.eth.Contract(keycardWalletABI, walletAddress);
|
||||
return web3.eth.getBalance(walletAddress);
|
||||
}).then((balance: string) => {
|
||||
dispatch(balanceLoaded(balance));
|
||||
}).catch((error: string) => {
|
||||
//FIXME: manage error
|
||||
console.log("error", error)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
import Web3 from 'web3';
|
||||
import {
|
||||
Dispatch,
|
||||
AnyAction,
|
||||
} from 'redux';
|
||||
import { RootState } from '../reducers';
|
||||
import { loadWallet } from './wallet';
|
||||
import { ThunkAction } from 'redux-thunk';
|
||||
|
||||
|
||||
export const WEB3_INITIALIZED = "WEB3_INITIALIZED";
|
||||
export interface Web3InitializedAction {
|
||||
type: typeof WEB3_INITIALIZED
|
||||
}
|
||||
|
||||
export const WEB3_ERROR = "WEB3_ERROR";
|
||||
export interface Web3ErrorAction {
|
||||
type: typeof WEB3_ERROR
|
||||
error: string
|
||||
}
|
||||
|
||||
export const WEB3_NETWORK_ID_LOADED = "WEB3_NETWORK_ID_LOADED";
|
||||
export interface Web3NetworkIDLoadedAction {
|
||||
type: typeof WEB3_NETWORK_ID_LOADED
|
||||
networkID: number
|
||||
}
|
||||
|
||||
export type Web3Actions =
|
||||
Web3InitializedAction |
|
||||
Web3ErrorAction |
|
||||
Web3NetworkIDLoadedAction;
|
||||
|
||||
export const web3Initialized = (): Web3Actions => {
|
||||
return {
|
||||
type: WEB3_INITIALIZED,
|
||||
};
|
||||
}
|
||||
|
||||
export const web3NetworkIDLoaded = (id: number): Web3Actions => {
|
||||
return {
|
||||
type: WEB3_NETWORK_ID_LOADED,
|
||||
networkID: id,
|
||||
};
|
||||
}
|
||||
|
||||
export const web3Error = (error: string): Web3Actions => {
|
||||
return {
|
||||
type: WEB3_ERROR,
|
||||
error: error,
|
||||
};
|
||||
}
|
||||
|
||||
export const initializeWeb3 = () => {
|
||||
//FIXME: move to config
|
||||
const web3 = new Web3('https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a');
|
||||
(window as any).web3 = web3;
|
||||
|
||||
|
||||
return (dispatch: Dispatch, getState: () => RootState) => {
|
||||
dispatch(web3Initialized());
|
||||
web3.eth.net.getId().then((id) => {
|
||||
dispatch(web3NetworkIDLoaded(id))
|
||||
loadWallet(dispatch);
|
||||
}).catch((err) => {
|
||||
dispatch(web3Error(err))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
import { AbiItem } from 'web3-utils';
|
||||
|
||||
export const abi: AbiItem[] = [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes3"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "hash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "sig",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "recover",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_keycard",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setKeycard",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "keycard",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_maxTxValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setSettings",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "nonce",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_hashToSign",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "_signature",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "_nonce",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "requestPayment",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "settings",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "maxTxValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "pendingWithdrawals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "bytes3"
|
||||
},
|
||||
{
|
||||
"name": "_keycard",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_maxTxValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "nonce",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "NewPaymentRequest",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "NewWithdrawal",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,104 @@
|
|||
import { AbiItem } from 'web3-utils';
|
||||
|
||||
export const abi: AbiItem[] = [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "bytes3"
|
||||
},
|
||||
{
|
||||
"name": "keycard",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "maxTxValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "create",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function",
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ownerWalletsCount",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "keycardsWallets",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ownersWallets",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "wallet",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "name",
|
||||
"type": "bytes3"
|
||||
}
|
||||
],
|
||||
"name": "NewWallet",
|
||||
"type": "event",
|
||||
}
|
||||
]
|
|
@ -8,6 +8,7 @@ import {
|
|||
Middleware,
|
||||
MiddlewareAPI,
|
||||
Dispatch,
|
||||
AnyAction,
|
||||
} from 'redux'
|
||||
import { initializeWeb3 } from './actions/web3';
|
||||
import { createRootReducer } from './reducers'
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import {
|
||||
Web3Actions,
|
||||
WEB3_INITIALIZED,
|
||||
WEB3_ERROR,
|
||||
WEB3_NETWORK_ID_LOADED,
|
||||
} from '../actions/web3';
|
||||
|
||||
export interface Web3State {
|
||||
initialized: boolean
|
||||
networkID: number | undefined
|
||||
error: string | undefined
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
initialized: false,
|
||||
networkID: undefined,
|
||||
error: undefined,
|
||||
};
|
||||
|
||||
export function web3Reducer(state: Web3State = initialState, action: Web3Actions): Web3State {
|
||||
switch (action.type) {
|
||||
case WEB3_INITIALIZED: {
|
||||
return {
|
||||
...state,
|
||||
initialized: true,
|
||||
}
|
||||
}
|
||||
|
||||
case WEB3_ERROR: {
|
||||
return {
|
||||
...state,
|
||||
error: action.error,
|
||||
}
|
||||
}
|
||||
|
||||
case WEB3_NETWORK_ID_LOADED: {
|
||||
return {
|
||||
...state,
|
||||
networkID: action.networkID,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue