update pos app to work with the new tx type
This commit is contained in:
parent
244624c207
commit
996002ba0b
|
@ -2,6 +2,8 @@ import EmbarkJS from 'Embark/EmbarkJS';
|
|||
import KeycardWalletFactory from 'Embark/contracts/KeycardWalletFactory';
|
||||
import KeycardWallet from 'Embark/contracts/KeycardWallet';
|
||||
import { emptyAddress } from '../utils';
|
||||
import { recoverTypedSignature } from 'eth-sig-util';
|
||||
import ethUtil from 'ethereumjs-util';
|
||||
|
||||
export const NEW_WALLET = 'NEW_WALLET';
|
||||
export const newWallet = () => ({
|
||||
|
@ -64,9 +66,8 @@ export const loadingWallet = () => ({
|
|||
});
|
||||
|
||||
export const WALLET_LOADED = 'WALLET_LOADED';
|
||||
export const walletLoaded = (nonce, balance, maxTxValue) => ({
|
||||
export const walletLoaded = (balance, maxTxValue) => ({
|
||||
type: WALLET_LOADED,
|
||||
nonce,
|
||||
balance,
|
||||
maxTxValue,
|
||||
});
|
||||
|
@ -87,7 +88,9 @@ export const loadNetworkID = () => {
|
|||
}
|
||||
}
|
||||
|
||||
function signPaymentRequest(message, cb) {
|
||||
function signPaymentRequest(getState, message, cb) {
|
||||
const state = getState();
|
||||
|
||||
let domain = [
|
||||
{ name: "name", type: "string" },
|
||||
{ name: "version", type: "string" },
|
||||
|
@ -105,11 +108,11 @@ function signPaymentRequest(message, cb) {
|
|||
let domainData = {
|
||||
name: "KeycardWallet",
|
||||
version: "1",
|
||||
chainId: 1,
|
||||
chainId: state.networkID,
|
||||
verifyingContract: KeycardWalletFactory.address
|
||||
};
|
||||
|
||||
let data = {
|
||||
const data = {
|
||||
types: {
|
||||
EIP712Domain: domain,
|
||||
Payment: payment
|
||||
|
@ -119,13 +122,20 @@ function signPaymentRequest(message, cb) {
|
|||
message: message
|
||||
};
|
||||
|
||||
signer = web3.eth.defaultAccount;
|
||||
const dataString = JSON.stringify(data);
|
||||
|
||||
if (web3.keycard.signTypedData) {
|
||||
web3.keycard.signTypedData(data, cb);
|
||||
const signer = state.owner;
|
||||
if (window.ethereum && window.ethereum.isStatus) {
|
||||
//FIXME: why is signer needed?
|
||||
window.ethereum.send("keycard_signTypedData", [signer, dataString])
|
||||
.then(resp => cb(undefined, resp, data))
|
||||
.catch(err => cb(err, undefined, data));
|
||||
} else {
|
||||
let signer = web3.eth.defaultAccount
|
||||
web3.currentProvider.sendAsync({method: "eth_signTypedData", params: [signer, data], from: signer}, cb);
|
||||
web3.currentProvider.sendAsync({
|
||||
method: "eth_signTypedData_v3",
|
||||
params: [signer, dataString],
|
||||
from: signer
|
||||
}, (err, resp) => cb(err, resp, data));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +211,6 @@ export const paymentRequested = () => ({
|
|||
|
||||
export const sendPaymentRequest = (walletContract, message, sig) => {
|
||||
return async (dispatch) => {
|
||||
|
||||
try {
|
||||
dispatch(requestingPayment())
|
||||
const requestPayment = await walletContract.methods.requestPayment(message, sig);
|
||||
|
@ -211,7 +220,7 @@ export const sendPaymentRequest = (walletContract, message, sig) => {
|
|||
});
|
||||
dispatch(paymentRequested())
|
||||
} catch(err) {
|
||||
alert(err)
|
||||
console.error("ERROR: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,15 +236,10 @@ export const loadWallet = (walletAddress, message, sig) => {
|
|||
});
|
||||
walletContract.address = walletAddress;
|
||||
|
||||
const balance = await web3.eth.getBalance(walletAddress);
|
||||
const maxTxValue = await walletContract.methods.settings().call();
|
||||
const balance = await walletContract.methods.availableBalance().call();
|
||||
const settings = await walletContract.methods.settings().call();
|
||||
|
||||
let icon = "";
|
||||
try {
|
||||
icon = String.fromCodePoint(name);
|
||||
} catch(e){}
|
||||
|
||||
dispatch(walletLoaded(nonce, balance, maxTxValue))
|
||||
dispatch(walletLoaded(balance, settings.maxTxValue))
|
||||
dispatch(sendPaymentRequest(walletContract, message, sig))
|
||||
};
|
||||
}
|
||||
|
@ -268,6 +272,7 @@ export const findWallet = (keycardAddress, message, sig) => {
|
|||
dispatch(findingWallet());
|
||||
KeycardWalletFactory.methods.keycardsWallets(keycardAddress).call()
|
||||
.then((address) => {
|
||||
//FIXME: if 0x00, the wallet was not found
|
||||
dispatch(walletFound(address))
|
||||
dispatch(loadWallet(address, message, sig))
|
||||
})
|
||||
|
@ -277,14 +282,26 @@ export const findWallet = (keycardAddress, message, sig) => {
|
|||
|
||||
export const requestPayment = () => {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
let block = await web3.eth.getBlock("latest");
|
||||
const message = {blockNumber: block.number, blockHash: block.hash, to: getState().owner, amount: getState().txAmount}
|
||||
const message = {
|
||||
blockNumber: block.number,
|
||||
blockHash: block.hash,
|
||||
to: state.owner,
|
||||
amount: state.txAmount,
|
||||
}
|
||||
|
||||
try {
|
||||
signPaymentRequest(message, function(err, sig) {
|
||||
signPaymentRequest(getState, message, function(err, response, data) {
|
||||
if (err) {
|
||||
dispatch(web3Error(err))
|
||||
} else {
|
||||
const address = web3.eth.accounts.recover(sig)
|
||||
const sig = response.result;
|
||||
const address = recoverTypedSignature({
|
||||
data: data,
|
||||
sig: sig,
|
||||
})
|
||||
|
||||
dispatch(keycardDiscovered(address));
|
||||
dispatch(findWallet(address, message, sig));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export const compressedAddress = (a, padding) => {
|
|||
|
||||
const formattedBalance = (balance) => {
|
||||
if (balance) {
|
||||
return web3.utils.fromWei(balance);
|
||||
return web3.utils.fromWei(new web3.utils.BN(balance));
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -63,7 +63,6 @@ const Pos = ({requestingPayment, paymentRequested, onTapRequest, customerKeycard
|
|||
|
||||
{customerWallet && <p>
|
||||
<strong>Wallet</strong><br />
|
||||
Nonce: {customerWallet.nonce} <br />
|
||||
Balance: {formattedBalance(customerWallet.balance)} <br />
|
||||
Max Tx Value: {formattedBalance(customerWallet.maxTxValue)} <br />
|
||||
</p>}
|
||||
|
|
|
@ -50,14 +50,13 @@ export default function(state, action) {
|
|||
|
||||
switch (action.type) {
|
||||
case ETHEREUM_LOAD_ERROR:
|
||||
alert(action.error)
|
||||
console.error(action.error)
|
||||
return Object.assign({}, state, {
|
||||
loadingWeb3: false,
|
||||
loadingWeb3Error: action.err
|
||||
});
|
||||
case WEB3_ERROR:
|
||||
console.error(action.error)
|
||||
alert(action.error)
|
||||
break;
|
||||
case ETHEREUM_LOADED:
|
||||
return Object.assign({}, state, {
|
||||
|
@ -105,7 +104,6 @@ export default function(state, action) {
|
|||
});
|
||||
case WALLET_LOADED:
|
||||
const wallet = {
|
||||
nonce: action.nonce,
|
||||
balance: action.balance,
|
||||
maxTxValue: action.maxTxValue,
|
||||
}
|
||||
|
@ -129,7 +127,7 @@ export default function(state, action) {
|
|||
case PAYMENT_AMOUNT_VALUE_CHANGE:
|
||||
return Object.assign({}, state, {
|
||||
txAmount: action.value
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -1 +1 @@
|
|||
../../network-contracts/contracts
|
||||
../../network-contracts/contracts
|
|
@ -9,7 +9,10 @@ contract KeycardWallet {
|
|||
event NewWithdrawal(address to, uint256 value);
|
||||
|
||||
//TODO: replace with chainid opcode
|
||||
uint256 constant chainId = 1;
|
||||
// uint256 constant chainId = 1;
|
||||
uint256 constant chainId = 3;
|
||||
// uint256 constant chainId = 5;
|
||||
// uint256 constant chainId = 1337;
|
||||
|
||||
// must be less than 256, because the hash of older blocks cannot be retrieved
|
||||
uint256 constant maxTxDelayInBlocks = 10;
|
||||
|
@ -177,6 +180,10 @@ contract KeycardWallet {
|
|||
emit NewPaymentRequest(_payment.blockNumber, _payment.to, _payment.amount);
|
||||
}
|
||||
|
||||
function availableBalance() public returns (int256) {
|
||||
return int256(address(this).balance - totalPendingWithdrawals);
|
||||
}
|
||||
|
||||
function withdraw() public {
|
||||
uint256 amount = pendingWithdrawals[msg.sender];
|
||||
require(amount > 0, "no pending withdrawal");
|
||||
|
|
|
@ -63,8 +63,8 @@ contract KeycardWalletFactory is KeycardRegistry {
|
|||
delete keycardsWallets[_keycard];
|
||||
}
|
||||
|
||||
function countWalletsForOwner() public view returns (uint) {
|
||||
return ownersWallets[msg.sender].length;
|
||||
function countWalletsForOwner(address owner) public view returns (uint) {
|
||||
return ownersWallets[owner].length;
|
||||
}
|
||||
|
||||
function unregister(address _owner, address _keycard) public {
|
||||
|
|
|
@ -34,6 +34,7 @@ contract('KeycardWalletFactory', () => {
|
|||
|
||||
it ('create (keycard is owner)', async () => {
|
||||
const keycard = "0x0000000000000000000000000000000000000002";
|
||||
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(keycard).call(), 0);
|
||||
|
||||
const create = KeycardWalletFactory.methods.create(keycard, {maxTxValue: 999, minBlockDistance: 1}, true);
|
||||
const receipt = await create.send({
|
||||
|
@ -44,6 +45,7 @@ contract('KeycardWalletFactory', () => {
|
|||
const walletAddress = event.returnValues.wallet;
|
||||
assert.notEqual(walletAddress, keycard);
|
||||
|
||||
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(keycard).call(), 1);
|
||||
assert.equal(await KeycardWalletFactory.methods.ownersWallets(keycard, 0).call(), walletAddress);
|
||||
assert.equal(await KeycardWalletFactory.methods.keycardsWallets(keycard).call(), walletAddress);
|
||||
});
|
||||
|
@ -56,21 +58,23 @@ contract('KeycardWalletFactory', () => {
|
|||
const receipt = await create.send({
|
||||
from: owner2
|
||||
});
|
||||
|
||||
|
||||
assert.fail("should have failed")
|
||||
} catch (err) {
|
||||
assert.equal(getErrorReason(err), "the keycard is already associated to a wallet");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it ('unregisterFromOwner', async () => {
|
||||
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(owner).call(), 1);
|
||||
|
||||
const walletAddress = await KeycardWalletFactory.methods.ownersWallets(owner, 0).call();
|
||||
const unregisterFromOwner = KeycardWalletFactory.methods.unregisterFromOwner(walletAddress, "0x0000000000000000000000000000000000000001");
|
||||
const receipt = await unregisterFromOwner.send({
|
||||
from: owner
|
||||
});
|
||||
|
||||
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner().call(), 0);
|
||||
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(owner).call(), 0);
|
||||
assert.equal(await KeycardWalletFactory.methods.keycardsWallets("0x0000000000000000000000000000000000000001").call(), "0x0000000000000000000000000000000000000000");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue