Published
Edited
May 4, 2019
Importers
Insert cell
Insert cell
viewof web3 = new View(null)
Insert cell
viewof isProviderAuthorized = new View(false)
Insert cell
viewof web3CurrentProvider = {
const view = new View()
view.addEventListener('input', () => {
if (web3) {
web3.setProvider(view.value)
}
})
return view
}
Insert cell
Insert cell
/**
* Initiate the provider from the browser, aka givenProvider. This provider is
* attached to the app-wide web3 instance if it is initiated.
*
* @return {Web3Provider} Web3 given provider
*/
function getEthereumProvider() {
if (!Web3.givenProvider)
return null

viewof web3CurrentProvider.value = Web3.givenProvider
return Web3.givenProvider
}
Insert cell
/**
* Get an app-wide web3 instance. Initiate its provider if necessery.
*
* @return {Web3} The web3 instance
*/
function getWeb3Instance() {
if (!web3) {
viewof web3.value = new Web3()
}
return web3
}
Insert cell
/**
* Load the current address eagerly. If the address is hidden because of
* privacy mode or compliance of EIP-1102, ask for the user's permission
* first.
* Side effect: The first loaded address, if available, is updated to
* `web3.eth.defaultAccount`. Otherwise that property is untouched.
*
* @return {Promise<*>} Resolve to the account list; usually an array
*/
function loadCurrentAddressEagerly(web3) {
const ethProv = web3.currentProvider || getEthereumProvider()
return getCurrentAddress(web3)
.then(accList_ => {
if ((accList_ && accList_.length) || !ethProv.enable) {
// older/unsupported EthereumProvider (for EIP-1102)
return Promise.resolve(accList_)
}
// EP of MetaMask 5+ (EIP-1102-compliant) with privacy mode on
return ethProv.enable()
})
.then(accList => {
if (accList && accList.length) {
if (!isProviderAuthorized) {
viewof isProviderAuthorized.value = true
}
web3.eth.defaultAccount = accList[0]
}
return Promise.resolve(accList)
})
}
Insert cell
/**
* Fetch the current address if present. If no provider detected, null is returned.
* If somehow the address list is empty (maybe we are behind of privacy wall),
* return null.
*
* @return {Promise<*>} Resolve to the account list (probably empty) or null
*/
function getCurrentAddress(web3) {
return web3.eth.getAccounts()
.then(accList => {
if (accList) {
if (accList.length > 0) {
if (!isProviderAuthorized) {
viewof isProviderAuthorized.value = true
}
// for backward compatibility
web3.eth.defaultAccount = accList[0]
}
return Promise.resolve(accList)
}
return null
})
.catch(e => {
throw e
return null
})
}
Insert cell
/**
* Poll for the wallet address with a `setInterval` call; when the account
* changes, the callback is called.
* Note: sometimes we may expected the callback be called for multiple times,
* thus this function does not return a promise by design.
*
* @param {Web3} web3 A web3 instance to be listened
* @param {Function} callback The callback to be called
* @return {Timer} The return of setInterval()
*/
function watchAccountChange(web3, callback) {
return setInterval(() => {
web3.eth.getAccounts().then(acc => {
if (!acc || acc[0] != web3.eth.defaultAccount) {
callback(acc)
}
});
}, 500)
}
Insert cell
/**
* Get the network description
* @param {Web3} web3 A web3 instance
* @return {Object} An object describing the current network,
* unknown if not recognized.
*/
function getWeb3NetDesc(web3) {
return web3.eth.net.getId()
.then(netId => {
if (netDesc.hasOwnProperty(netId)) {
return Promise.resolve(netDesc[netId])
}
// a mocked object
return Promise.resolve({id: netId, name: `Unknown (${netId})` })
})
.catch(() => Promise.resolve({ id: -1, name: '[error]' }))
}
Insert cell
function assertWeb3NetId(web3, idExpected) {
return web3.eth.net.getId()
.then(id => {
if (id != idExpected) {
const err = new Error(`Assertion on network ID fails: expected ${id} but found ${idExpected}`)
err.netId = id
throw err
}
return Promise.resolve(id)
})
}
Insert cell
__default__ = ({
netDesc,
isProviderAuthorized,

getEthereumProvider,
getWeb3Instance,
loadCurrentAddressEagerly,
getCurrentAddress,
watchAccountChange,
getWeb3NetDesc,
assertWeb3NetId,
})
Insert cell
Insert cell
Web3 = require('https://gistcdn.githack.com/andy0130tw/72e5ceb85c76048105665ad002bdc10c/raw/bd73aa1e085c4d7b0cbe560e5c64a6d3192fb4c1/web3.js')
Insert cell
Web3_beta = require('https://bundle.run/web3@1.0.0-beta.40/dist/web3.cjs.js')
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more