-
Notifications
You must be signed in to change notification settings - Fork 5
Conversation
- Create reducer for tokens that is an array - Create token with address in reducer and update details based on the address - Display token on balance page - RIF address is saved in config file to be expanded later
src/app/state/operations/tokens.ts
Outdated
@@ -0,0 +1,63 @@ | |||
import { Dispatch } from 'react' | |||
import Eth from 'ethjs' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t it enough to add just contract module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into it and I'm not sure, from their readme it says NOTE. Module not ready for use, still in heavy development. Which is why I opted for the full version
Tested with the contract module, and paired with the query module it works as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module imports that module. See https://github.com/ethjs/ethjs/blob/master/src/index.js#L35
src/app/state/operations/tokens.ts
Outdated
import { saveToLocalStorage, getValueFromLocalStorage } from '../../../features/localStorage' | ||
|
||
export const getTokenList = (provider: any) => (dispatch: Dispatch<any>) => | ||
getNetwork(provider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t this recoverable from state? We are performing twice same rpc for a same value that did not change
src/app/state/operations/tokens.ts
Outdated
const eth = new Eth(provider) | ||
const token = eth.contract(erc720).at(address) | ||
|
||
eth.getCode(address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would check this only when adding custom token. Anyway i wouldn’t get code. Just query needed calls and if one fails => invalid token
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the comment below about name and symbol being optional. balanceOf
is the only required method. I'll reorder the code to check this first and if it doesn't exist then consider it not valid.
src/app/state/operations/tokens.ts
Outdated
dispatch(addToken({ address })) | ||
|
||
token.symbol().then((symbol: string[]) => symbol[0]) | ||
.then((symbol: string) => dispatch(addTokenData({ data: { address, symbol } }))).catch() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is catch doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a ERC20 and 721 token contract, name
and symbol
are optional functions. So, if they don't exist in the contract, it will throw an error here. I don't want it to break, I want to continue to the next call, so I add the catch() here.
I do notice that it makes the UI look a bit off, so if a token doesn't have a name function, I'll add 'Custom Token 0x123456...1213` in the catch to show something back to the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we catch ONLY the error thrown by this case? Instead of catching everything. Maybe it throws another error...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that the errors returned by ethjs are strings not objects. This a similar issue to the previous PR where we tried to catch the error. Here is the error that is returned:
[ethjs-query] while formatting outputs from RPC '{"value":{"code":-32603,"message":"Non-200 status code: '500'","data":{"jsonrpc":"2.0","id":3846821291,"error":{"code":-32015,"message":"VM execution error: transaction reverted"}}}}'
src/app/state/operations/tokens.ts
Outdated
token.balanceOf(accounts[0]) | ||
.then((balance: any) => { | ||
dispatch(addTokenData( | ||
{ data: { address, balance: balance[0].toString() / Math.pow(10, decimals[0].toNumber()) } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use bn.js arithmetics. I understand this is the type of any uint value returned by ethjs. See https://github.com/indutny/bn.js
src/app/state/reducers/tokens.ts
Outdated
} | ||
|
||
export interface TokenState { | ||
tokens: any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing them as a address=>data map would be more clear and efficient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had trouble creating this with typescript and need assistance. For now, I have changed this to tokens: Token[]
.
src/features/localStorage.ts
Outdated
@@ -0,0 +1,21 @@ | |||
const LOCAL_STORAGE_KEY = 'id-manager-settings' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this to a /storage folder. Not /features
src/features/localStorage.ts
Outdated
@@ -0,0 +1,21 @@ | |||
const LOCAL_STORAGE_KEY = 'id-manager-settings' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we should test this module
src/app/state/operations/utils.ts
Outdated
@@ -0,0 +1,3 @@ | |||
export type Callback<T> = (err?: Error, res?: T) => void | |||
|
|||
export const callbackify = (promise: () => Promise<any>, cb: (arg0: undefined, arg1: undefined) => any) => cb ? promise().then((res: any) => cb(undefined, res)).catch((err: any) => cb(err, undefined)) : promise() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn’t find any import for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I tried using it and was unsuccessful, I'll remove it.
} | ||
|
||
export const addCustomToken = (provider: any, address: string) => (dispatch: Dispatch<any>) => | ||
new Promise((resolve, reject) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Promise seems to be unnecessary. It could be handled with the s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the 's'?
The promise is returned to the component to let it know to stop 'loading' and either return the error or close the modal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I want to say thens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dispatch() does not return a promise.
- Rename erc720 file - Move localStorage and add tests - Wrap identity in address/chainId to pass down to children
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Pass user address and chainId to operations - Use ethr contract and BN modules to handle opps - remove addToken() action and use addTokenData() instead. Creates new entry if missing. - Update missing props
@ilanolkies Added a new commit to refactor the tokens. Fixes the issue above with erc721 non-tokens and simplifies the code quite a bit. Thanks! |
Defaults to pulling in RIF on Mainnet and Testnet. No defaults for ethereum or local.
Allows the user to insert the contract address of an ERC20 or ERC721 token to track. Address is saved into local storage. For testing, here is the DoC contract addresses:
0xE700691Da7B9851F2F35f8b8182C69C53ccad9DB
0xcb46c0ddc60d18efeb0e586c17af6ea36452dae0