swarmcity / SwarmCityConcept

This is the high level description of what needs to be built
9 stars 1 forks source link

As a user, I can see all my transactions so I can feel secure about my history being correct. #2

Closed kikipluche closed 6 years ago

kikipluche commented 6 years ago

Abstract:

At any given time, we want the user to be able to see their transaction history. It is found in the /my-wallet view. In this iteration, transaction history is a list of items. Each item is a transaction on Ethereum’s Rinkeby network.

This should result in the user having a feeling of security and control, as the log always represents the history of past transactions.

How it works:

The API has a txHistory topic.

The client registers with the txHistory topic by sending its publicKey and the lastblock, which indicates the state of the client's local redux. Lastblock defaults to the block when we deployed SWT token contract.

The API returns to the client the current txHistory for that pubkey from lastblock up to the current block.

The API emits to the client an update message on each new transaction ( filtered on the pubkey that was given during the registration) Either this is a new transaction - or it is an update of the state existing transaction. The primary key is the transactionhash.

Jobs:

transactionLogIndexer

API:

API documentation

txHistory topic

subscribe:

/**
 * @request
 * Represents the client request
 * @param {string} publicKey - The publickey of the user
 * @param {number} lastBlock - The last block time the client has in redux
 */

{
    publicKey: <String>,
    lastBlock: <Number>,
}

subscription returns:

/**
 * Represents the txHistoryChanged response
 * @response
 * @param {number} response - The HTTP response code
 * @param {string} subscriptionId - The SubscriptionID 
 * @param {array} txHistory - Array of items 
 */

{ 
    response: <Number>,   
    subscriptionId: <String>,
    txHistory: <Array of historyItems>
}
Events

txHistoryChanged

/**
 * Represents a txHistory change
 * @response
 */
{
    subscriptionId: <String>,
    txHistoryChanges: <Array of historyItems>
}

txHistoryChanges can be updates or new inserts ( primary key is txhash ). An update could be an existing pending txhash changing state from pending to success.

historyItem model:

Each historyItem has following properties:

'transactionHash': '0x....' ( primary key )
'dateTime': <timestamp>
'direction': <'in'/'out'>
'amount': <in token units> ( 1e18 = 1 SWT )
'from': '0x....' 
'to': '0x....'
'block': <blocknumber where tx was mined>
'status': <0 => success , 1 => failure, 2 => pending>

What it looks like in front end:

route: /my-wallet image

In the wallet-view, we see the transaction history at the bottom. It's a list, ordered by newest first. It consists of historyItems. A historyItem has 3 states: 1.pending, 2.confirmed, 3.rejected.

1. Pending The transaction has been sent to the node, but not mined yet.

It contains:

link "show on etherscan" that links to this transaction on external (Rinkeby) explorer image

2. Confirmed The transaction has been mined and included in a block.

It contains:

image

image

3. Rejected The transaction has been mined but rejected by the network.

image

Documentation / references

Example:

var subscription = web3.eth.subscribe('pendingTransactions', function(error, result){
    if (!error)
        console.log(result);
})
.on("data", function(transaction){
    console.log(transaction);
});

// unsubscribes the subscription
subscription.unsubscribe(function(error, success){
    if(success)
        console.log('Successfully unsubscribed!');
});

pending transactions: http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-pendingtransactions

new blocks: http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-newblockheaders

xardass commented 6 years ago

Since a txHistory Item only has two possible states, either success or failure, I assume pending transactions have to be processed on the front-end. I propose on front-end, at transaction creation, we fill the client-side txHistoryArray with a historyItem with the same data as one would expect to receive from the API.

Whenever the API triggers txHistoryChanged with a historyItem with the same tx hash, we can replace the pending item with the success/failure one.

Question: Since a user refresh will drop the pending item from txHistory, do we want to copy this update to localStorage? Please advise.

UPDATE: It has been decided:

bkawk commented 6 years ago

In the design, it clearly shows a name for who the transaction is with, yet in the history item model, there is no name being returned.

The number 44 SWT as shown in the design looks nice, I would like to see how this will look with 18 decimal places to ensure it still looks good on a mobile device.

kikipluche commented 6 years ago

Changed in the epic:

GriffGreen commented 6 years ago

This is EPIC documentation. It will be great for a wiki and for the community later!

bkawk commented 6 years ago

Please can we maintain correct case and full names
pubkey => publicKey lastblock => lastBlock

kikipluche commented 6 years ago

19/3: issue is clear for dev, ready for execution

xardass commented 6 years ago

Please confirm/correct my assumption:

Currently the spec says the list should be ordered by 'newest first'.

Should I make an exception for pending transactions, i.e. putting them always first, regardless if newer transactions have been confirmed after older pending ones?

If so, should this be handled front-end or at API level? (I would prefer at API level).

xardass commented 6 years ago

@faffydee Can I get the color/font schemes your prefer for the different states?

kikipluche commented 6 years ago

@xardass let's make it as described in the spec, newest first.

xardass commented 6 years ago

further clarification: There is no need on the front-end to count confirmations to flag a transaction as successful.

eduadiez commented 6 years ago

I think there is no quick and easy way to get the failed transactions, since failed transactions don't generate events. For example, this code returns only 113 events, which doesn't match what can be seen on etherscan.

Also it seems that there is some more inconsistency that I would like to analalize about what is shown in etherscan.

eduadiez commented 6 years ago

Some of the missing transactions between what returns getPastEvents and what appears in etherscan is due to the used version of minime. In this version the transfer event is not generated when the amount transferred is 0, as if it happens in new versions of minime. Example: 0x6ea1a80d557b2756389ea16e448111155cb3184f6f1e8c7de62771cf1a68f606

kingflurkel commented 6 years ago

@eduadiez Rinkeby SWT does not have to match the tokencontract version on mainnet. It's more important for the bridging later that we have a rinkeby SWT token contract that does generate the events.

As far as I know these are the events we can get in:

@eduadiez Is this correct?

kingflurkel commented 6 years ago

My suggestion is in this iteration we leave out "failed transactions". Other people are looking into creating an open source block explorer we later will be able to use.

BvL13 commented 6 years ago

@kingflurkel I agree to leave it out. Please change the description and delete all parts that cover failed/rejected transactions. This would be in: historyItem model 'status': <0 => success , 1 => failure, 2 => pending>

What it looks like in front end:

  1. Rejected

Thank you.

kingflurkel commented 6 years ago

@BvL13 Below the updated epic. Changes:

As a user, I can see all my transactions so I can feel secure about my history being correct.

Abstract:

At any given time, we want the user to be able to see their transaction history. It is found in the /my-wallet view. In this iteration, transaction history is a list of items. Each item is a pending or successful transaction.

This should result in the user having a feeling of security and control, as the log always represents the history of past transactions.

How it works:

The API has a txHistory topic.

The client registers with the txHistory topic by sending its address and the lastblock, which indicates the state of the client's local redux. Lastblock defaults to the block when we deployed SWT token contract.

The API returns to the client the current txHistory for that address from lastblock up to the current block.

The API emits to the client an update message on each new transaction ( filtered on the address that was given during the registration) Either this is a new transaction - or it is an update of the state existing transaction. The primary key is the transactionhash.

Jobs:

transactionLogIndexer

API:

API documentation

txHistory topic

subscribe:

/**
 * @request
 * Represents the client request
 * @param {string} address - The address of the user
 * @param {number} lastBlock - The last block time the client has in redux
 */

{
    address: <String>,
    lastBlock: <Number>,
}

subscription returns:

/**
 * Represents the txHistoryChanged response
 * @response
 * @param {number} response - The HTTP response code
 * @param {string} subscriptionId - The SubscriptionID 
 * @param {array} txHistory - Array of items 
 */

{ 
    response: <Number>,   
    subscriptionId: <String>,
    txHistory: <Array of historyItems>
}
Events

txHistoryChanged

/**
 * Represents a txHistory change
 * @response
 */
{
    subscriptionId: <String>,
    txHistoryChanges: <Array of historyItems>
}

txHistoryChanges can be updates or new inserts ( primary key is txhash ). An update could be an existing pending txhash changing state from pending to success.

historyItem model:

Each historyItem has following properties:

'transactionHash': '0x....' ( primary key )
'dateTime': <timestamp>
'direction': <'in'/'out'>
'amount': <in token units> ( 1e18 = 1 SWT )
'from': '0x....' 
'to': '0x....'
'block': <blocknumber where tx was mined>
'status': <0 => pending, 1 => success>

What it looks like in front end:

route: /my-wallet image

In the wallet-view, we see the transaction history at the bottom. It's a list, ordered by newest first. It consists of historyItems. A historyItem has 3 states: 1.pending, 2.confirmed, 3.rejected.

1. Pending The transaction has been sent to the node, but not mined yet.

It contains:

link "show on etherscan" that links to this transaction on external (Rinkeby) explorer image

2. Confirmed The transaction has been mined and included in a block.

It contains:

image

image

Documentation / references

Example:

var subscription = web3.eth.subscribe('pendingTransactions', function(error, result){
    if (!error)
        console.log(result);
})
.on("data", function(transaction){
    console.log(transaction);
});

// unsubscribes the subscription
subscription.unsubscribe(function(error, success){
    if(success)
        console.log('Successfully unsubscribed!');
});

pending transactions: http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-pendingtransactions

new blocks: http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-newblockheaders

xardass commented 6 years ago

Update: The API only sends back a list of successful transactions. Failed and pending tx's are not being processed by the API at this moment, although tx items do get a code '0' flagging them as succesful (so we can add the other codes later).

On front-end, at transaction creation, we fill the client-side txHistoryArray with a historyItem with the same data as one would expect to receive from the API, except with code '2': pending.

The API will return an object with all the user's transaction data on every update of this array. Whenever the client gets an update of this Array, it will replace the pending tx's with txHash as key.

xardass commented 6 years ago

@eduadiez do you think it is possible to order the list of HistoryItems according to their txHash? So I can use this txHash as key for checking if the same one already exists (as a pending tranasction on the front-end). We might need to rewrite the Epic accordingly to reflect this need.

xardass commented 6 years ago

The front-end now defaults to state 'success', so we don't need to add a status success from the API anymore. Only for future implementation, if we add failed/pending tx's we then can add an extra property to identify those.