2. Fetch and display security tokens - PolymathNetwork/whitelist-standalone GitHub Wiki
In this guide, we're going add a select list that lets app user to select the token they need to manage. There are many aspects of Security Tokens that could be managed. We'll focus on managing token holders whitelist in this guide.
You can manage said white list of you are either 1) the token owner, which means that you have created a token in the past, or had the ownership of a token transferred to you or 2) you are delegated by the token owner to manage the whitelist.
We will discuss how to delegate 3rd party address to manage the whitelist, in a following guide.
// App.js
function App() {
const [state, dispatch] = useReducer(reducer,initialState)
const { walletAddress, tokenSelectOpts } = state;
return (
<div className="App">
...
...
{/* Append the following component to App component. It displays the list of tokens owned by current app user */}
{ walletAddress &&
<TokenSelector
tokenSelectOpts={tokenSelectOpts}/>
}
</div>
)
}
...
// TokenSelector.js
/**
* This is a simple Ant Design select list. It provides search via autocompletion, too.
*/
function TokenSelector({ tokenSelectOpts }) {
const dispatch = useContext(DispatchContext)
return (
<Select
showSearch
placeholder="Select a token"
optionFilterProp="children"
// On token selection, dispatch an action with selected Id.
onChange={(index) => dispatch({
type: actions.TOKEN_SELECTED,
selectedToken: index
})}
// This function will filter select list items as user types.
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{tokenSelectOpts}
</Select>
)
}
Just a plain-old select list with searchable items.
Here's our meat and potatoes. We need to fetch user tokens, as soon once we've established an SDK connection (see previous guide), and we have user's address from Metamask.
// App.js
function App() {
...
// b. Fetch tokens
useEffect(() => {
// An async action to retrieve relevant tokens.
async function fetchTokens(dispatch, polyClient, walletAddress) {
// An auxiliary action to start a spinner.
dispatch({type: a.FETCHING_TOKENS})
// Use the SDK to fetch tokens.
const tokens = await polyClient.getSecurityTokens({ walletAddress })
const tokenSelectOpts = tokens.map((token, i) =>
<Option value={i} key={i}>{token.symbol}</Option>)
// Send fetched tokens to be saved in app state. Also stop the spinner.
dispatch({type: a.FETCHED_TOKENS, tokens, tokenSelectOpts})
}
if (polyClient && walletAddress && !tokens) {
fetchTokens(dispatch, polyClient, walletAddress)
}
}, [walletAddress, polyClient, tokens])
...
return (
...
}
This is the most important line. Behind the scenes, the SDK will query SecurityTokenRegistry
for tokens owned by walletAddress
.
const tokens = await polyClient.getSecurityTokens({ walletAddress })
We're going to use the same reducer function we created in the previous guide. We'll just append the following three cases towards the bottom of switch
statement. Those cases will handle actions around token fetching and selection.
// App.js
function reducer() {
...
case a.FETCHING_TOKENS:
return {
...state,
fetching: true,
tip: 'Fetching tokens'
}
case a.FETCHED_TOKENS:
const { tokens, tokenSelectOpts } = action
return {
...state,
tokenSelectOpts,
tokens,
fetching: false,
tip: ''
}
case a.TOKEN_SELECTED:
const { selectedToken } = action
return {
...state,
selectedToken,
tip: 'Loading shareholders...', // Don't worry about this now.
fetching: true
}
}
}
Note if you haven't deployed any tokens to the current ethereum network, then the select list will be empty. You can try and create a token using Polymath Token Studio, then come back to this app to make sure they show up on the list.