update pos app to work with the new tx type

This commit is contained in:
Andrea Franz 2020-02-12 13:24:13 +01:00
parent 244624c207
commit 996002ba0b
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
7 changed files with 62 additions and 37 deletions

View File

@ -2,6 +2,8 @@ import EmbarkJS from 'Embark/EmbarkJS';
import KeycardWalletFactory from 'Embark/contracts/KeycardWalletFactory'; import KeycardWalletFactory from 'Embark/contracts/KeycardWalletFactory';
import KeycardWallet from 'Embark/contracts/KeycardWallet'; import KeycardWallet from 'Embark/contracts/KeycardWallet';
import { emptyAddress } from '../utils'; import { emptyAddress } from '../utils';
import { recoverTypedSignature } from 'eth-sig-util';
import ethUtil from 'ethereumjs-util';
export const NEW_WALLET = 'NEW_WALLET'; export const NEW_WALLET = 'NEW_WALLET';
export const newWallet = () => ({ export const newWallet = () => ({
@ -64,9 +66,8 @@ export const loadingWallet = () => ({
}); });
export const WALLET_LOADED = 'WALLET_LOADED'; export const WALLET_LOADED = 'WALLET_LOADED';
export const walletLoaded = (nonce, balance, maxTxValue) => ({ export const walletLoaded = (balance, maxTxValue) => ({
type: WALLET_LOADED, type: WALLET_LOADED,
nonce,
balance, balance,
maxTxValue, maxTxValue,
}); });
@ -87,7 +88,9 @@ export const loadNetworkID = () => {
} }
} }
function signPaymentRequest(message, cb) { function signPaymentRequest(getState, message, cb) {
const state = getState();
let domain = [ let domain = [
{ name: "name", type: "string" }, { name: "name", type: "string" },
{ name: "version", type: "string" }, { name: "version", type: "string" },
@ -105,11 +108,11 @@ function signPaymentRequest(message, cb) {
let domainData = { let domainData = {
name: "KeycardWallet", name: "KeycardWallet",
version: "1", version: "1",
chainId: 1, chainId: state.networkID,
verifyingContract: KeycardWalletFactory.address verifyingContract: KeycardWalletFactory.address
}; };
let data = { const data = {
types: { types: {
EIP712Domain: domain, EIP712Domain: domain,
Payment: payment Payment: payment
@ -119,13 +122,20 @@ function signPaymentRequest(message, cb) {
message: message message: message
}; };
signer = web3.eth.defaultAccount; const dataString = JSON.stringify(data);
if (web3.keycard.signTypedData) { const signer = state.owner;
web3.keycard.signTypedData(data, cb); 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 { } else {
let signer = web3.eth.defaultAccount web3.currentProvider.sendAsync({
web3.currentProvider.sendAsync({method: "eth_signTypedData", params: [signer, data], from: signer}, cb); 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) => { export const sendPaymentRequest = (walletContract, message, sig) => {
return async (dispatch) => { return async (dispatch) => {
try { try {
dispatch(requestingPayment()) dispatch(requestingPayment())
const requestPayment = await walletContract.methods.requestPayment(message, sig); const requestPayment = await walletContract.methods.requestPayment(message, sig);
@ -211,7 +220,7 @@ export const sendPaymentRequest = (walletContract, message, sig) => {
}); });
dispatch(paymentRequested()) dispatch(paymentRequested())
} catch(err) { } catch(err) {
alert(err) console.error("ERROR: ", err)
} }
} }
} }
@ -227,15 +236,10 @@ export const loadWallet = (walletAddress, message, sig) => {
}); });
walletContract.address = walletAddress; walletContract.address = walletAddress;
const balance = await web3.eth.getBalance(walletAddress); const balance = await walletContract.methods.availableBalance().call();
const maxTxValue = await walletContract.methods.settings().call(); const settings = await walletContract.methods.settings().call();
let icon = ""; dispatch(walletLoaded(balance, settings.maxTxValue))
try {
icon = String.fromCodePoint(name);
} catch(e){}
dispatch(walletLoaded(nonce, balance, maxTxValue))
dispatch(sendPaymentRequest(walletContract, message, sig)) dispatch(sendPaymentRequest(walletContract, message, sig))
}; };
} }
@ -268,6 +272,7 @@ export const findWallet = (keycardAddress, message, sig) => {
dispatch(findingWallet()); dispatch(findingWallet());
KeycardWalletFactory.methods.keycardsWallets(keycardAddress).call() KeycardWalletFactory.methods.keycardsWallets(keycardAddress).call()
.then((address) => { .then((address) => {
//FIXME: if 0x00, the wallet was not found
dispatch(walletFound(address)) dispatch(walletFound(address))
dispatch(loadWallet(address, message, sig)) dispatch(loadWallet(address, message, sig))
}) })
@ -277,14 +282,26 @@ export const findWallet = (keycardAddress, message, sig) => {
export const requestPayment = () => { export const requestPayment = () => {
return async (dispatch, getState) => { return async (dispatch, getState) => {
const state = getState();
let block = await web3.eth.getBlock("latest"); 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 { try {
signPaymentRequest(message, function(err, sig) { signPaymentRequest(getState, message, function(err, response, data) {
if (err) { if (err) {
dispatch(web3Error(err)) dispatch(web3Error(err))
} else { } else {
const address = web3.eth.accounts.recover(sig) const sig = response.result;
const address = recoverTypedSignature({
data: data,
sig: sig,
})
dispatch(keycardDiscovered(address)); dispatch(keycardDiscovered(address));
dispatch(findWallet(address, message, sig)); dispatch(findWallet(address, message, sig));
} }

View File

@ -18,7 +18,7 @@ export const compressedAddress = (a, padding) => {
const formattedBalance = (balance) => { const formattedBalance = (balance) => {
if (balance) { if (balance) {
return web3.utils.fromWei(balance); return web3.utils.fromWei(new web3.utils.BN(balance));
} }
return ""; return "";
@ -63,7 +63,6 @@ const Pos = ({requestingPayment, paymentRequested, onTapRequest, customerKeycard
{customerWallet && <p> {customerWallet && <p>
<strong>Wallet</strong><br /> <strong>Wallet</strong><br />
Nonce: {customerWallet.nonce} <br />
Balance: {formattedBalance(customerWallet.balance)} <br /> Balance: {formattedBalance(customerWallet.balance)} <br />
Max Tx Value: {formattedBalance(customerWallet.maxTxValue)} <br /> Max Tx Value: {formattedBalance(customerWallet.maxTxValue)} <br />
</p>} </p>}

View File

@ -50,14 +50,13 @@ export default function(state, action) {
switch (action.type) { switch (action.type) {
case ETHEREUM_LOAD_ERROR: case ETHEREUM_LOAD_ERROR:
alert(action.error) console.error(action.error)
return Object.assign({}, state, { return Object.assign({}, state, {
loadingWeb3: false, loadingWeb3: false,
loadingWeb3Error: action.err loadingWeb3Error: action.err
}); });
case WEB3_ERROR: case WEB3_ERROR:
console.error(action.error) console.error(action.error)
alert(action.error)
break; break;
case ETHEREUM_LOADED: case ETHEREUM_LOADED:
return Object.assign({}, state, { return Object.assign({}, state, {
@ -105,7 +104,6 @@ export default function(state, action) {
}); });
case WALLET_LOADED: case WALLET_LOADED:
const wallet = { const wallet = {
nonce: action.nonce,
balance: action.balance, balance: action.balance,
maxTxValue: action.maxTxValue, maxTxValue: action.maxTxValue,
} }
@ -129,7 +127,7 @@ export default function(state, action) {
case PAYMENT_AMOUNT_VALUE_CHANGE: case PAYMENT_AMOUNT_VALUE_CHANGE:
return Object.assign({}, state, { return Object.assign({}, state, {
txAmount: action.value txAmount: action.value
}); });
} }
return state; return state;

View File

@ -1 +1 @@
../../network-contracts/contracts ../../network-contracts/contracts

View File

@ -9,7 +9,10 @@ contract KeycardWallet {
event NewWithdrawal(address to, uint256 value); event NewWithdrawal(address to, uint256 value);
//TODO: replace with chainid opcode //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 // must be less than 256, because the hash of older blocks cannot be retrieved
uint256 constant maxTxDelayInBlocks = 10; uint256 constant maxTxDelayInBlocks = 10;
@ -177,6 +180,10 @@ contract KeycardWallet {
emit NewPaymentRequest(_payment.blockNumber, _payment.to, _payment.amount); emit NewPaymentRequest(_payment.blockNumber, _payment.to, _payment.amount);
} }
function availableBalance() public returns (int256) {
return int256(address(this).balance - totalPendingWithdrawals);
}
function withdraw() public { function withdraw() public {
uint256 amount = pendingWithdrawals[msg.sender]; uint256 amount = pendingWithdrawals[msg.sender];
require(amount > 0, "no pending withdrawal"); require(amount > 0, "no pending withdrawal");

View File

@ -63,8 +63,8 @@ contract KeycardWalletFactory is KeycardRegistry {
delete keycardsWallets[_keycard]; delete keycardsWallets[_keycard];
} }
function countWalletsForOwner() public view returns (uint) { function countWalletsForOwner(address owner) public view returns (uint) {
return ownersWallets[msg.sender].length; return ownersWallets[owner].length;
} }
function unregister(address _owner, address _keycard) public { function unregister(address _owner, address _keycard) public {

View File

@ -34,6 +34,7 @@ contract('KeycardWalletFactory', () => {
it ('create (keycard is owner)', async () => { it ('create (keycard is owner)', async () => {
const keycard = "0x0000000000000000000000000000000000000002"; const keycard = "0x0000000000000000000000000000000000000002";
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(keycard).call(), 0);
const create = KeycardWalletFactory.methods.create(keycard, {maxTxValue: 999, minBlockDistance: 1}, true); const create = KeycardWalletFactory.methods.create(keycard, {maxTxValue: 999, minBlockDistance: 1}, true);
const receipt = await create.send({ const receipt = await create.send({
@ -44,6 +45,7 @@ contract('KeycardWalletFactory', () => {
const walletAddress = event.returnValues.wallet; const walletAddress = event.returnValues.wallet;
assert.notEqual(walletAddress, keycard); 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.ownersWallets(keycard, 0).call(), walletAddress);
assert.equal(await KeycardWalletFactory.methods.keycardsWallets(keycard).call(), walletAddress); assert.equal(await KeycardWalletFactory.methods.keycardsWallets(keycard).call(), walletAddress);
}); });
@ -56,21 +58,23 @@ contract('KeycardWalletFactory', () => {
const receipt = await create.send({ const receipt = await create.send({
from: owner2 from: owner2
}); });
assert.fail("should have failed") assert.fail("should have failed")
} catch (err) { } catch (err) {
assert.equal(getErrorReason(err), "the keycard is already associated to a wallet"); assert.equal(getErrorReason(err), "the keycard is already associated to a wallet");
} }
}); });
it ('unregisterFromOwner', async () => { it ('unregisterFromOwner', async () => {
assert.equal(await KeycardWalletFactory.methods.countWalletsForOwner(owner).call(), 1);
const walletAddress = await KeycardWalletFactory.methods.ownersWallets(owner, 0).call(); const walletAddress = await KeycardWalletFactory.methods.ownersWallets(owner, 0).call();
const unregisterFromOwner = KeycardWalletFactory.methods.unregisterFromOwner(walletAddress, "0x0000000000000000000000000000000000000001"); const unregisterFromOwner = KeycardWalletFactory.methods.unregisterFromOwner(walletAddress, "0x0000000000000000000000000000000000000001");
const receipt = await unregisterFromOwner.send({ const receipt = await unregisterFromOwner.send({
from: owner 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"); assert.equal(await KeycardWalletFactory.methods.keycardsWallets("0x0000000000000000000000000000000000000001").call(), "0x0000000000000000000000000000000000000000");
}); });
}); });