Generate blockchain types

yann300-patch-36
ioedeveloper 3 years ago committed by yann300
parent ed45748826
commit ba1bba8ac0
  1. 5
      apps/remix-ide/src/app/udapp/run-tab.js
  2. 29
      libs/remix-ui/run-tab/src/lib/actions/custom.ts
  3. 204
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  4. 7
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  5. 15
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  6. 52
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  7. 78
      libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts
  8. 38
      libs/remix-ui/run-tab/src/lib/types/execution-context.d.ts
  9. 10
      libs/remix-ui/run-tab/src/lib/types/index.ts
  10. 12
      libs/remix-ui/run-tab/src/lib/types/injected.d.ts
  11. 13
      libs/remix-ui/run-tab/src/lib/types/node.d.ts
  12. 16
      libs/remix-ui/run-tab/src/lib/types/vm.d.ts

@ -46,6 +46,7 @@ export class RunTab extends ViewPlugin {
this.compilersArtefacts = compilersArtefacts
this.networkModule = networkModule
this.fileProvider = fileProvider
this.REACT_API = {}
this.setupEvents()
this.el = document.createElement('div')
}
@ -230,4 +231,8 @@ export class RunTab extends ViewPlugin {
<RunTabUI plugin={this} />
, this.el)
}
onReady (api) {
this.REACT_API = api
}
}

@ -3,10 +3,11 @@ import React from 'react'
import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3'
import { shortenAddress } from '@remix-ui/helper'
import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload'
import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload'
import { runTabInitialState, runTabReducer } from '../reducers/runTab'
export function useRunTabPlugin (plugin) {
// eslint-disable-next-line no-undef
export function useRunTabPlugin (plugin, executionContextModal: (executionContext: { context: string, fork: string }) => void) {
const [runTab, dispatch] = React.useReducer(runTabReducer, runTabInitialState)
const setupEvents = () => {
@ -32,7 +33,7 @@ export function useRunTabPlugin (plugin) {
}
}
})
plugin.blockchain.events.on('newTransaction', (tx, receipt) => {
plugin.emit('newTransaction', tx, receipt)
})
@ -180,18 +181,24 @@ export function useRunTabPlugin (plugin) {
dispatch(removeProvider(name))
}
const setProviderFromEndpoint = (executionContext: { context: string, fork: string }) => {
plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => {
// if (alertMsg) addTooltip(alertMsg)
setFinalContext()
})
}
const setExecutionContext = (executionContext: { context: string, fork: string }) => {
plugin.blockchain.changeExecutionContext(executionContext, () => {
// modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://127.0.0.1:8545', (target) => {
// this.blockchain.setProviderFromEndpoint(target, context, (alertMsg) => {
// if (alertMsg) addTooltip(alertMsg)
// setFinalContext()
// })
// }, this.setFinalContext.bind(this))
// }, (alertMsg) => {
executionContextModal(executionContext)
}, (alertMsg) => {
// addTooltip(alertMsg)
}, setFinalContext())
}
return { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee, setExecEnv, setFinalContext, setExecutionContext }
const setWeb3Endpoint = (endpoint: string) => {
dispatch(setExternalEndpoint(endpoint))
}
return { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee, setExecEnv, setFinalContext, setExecutionContext, setProviderFromEndpoint, setWeb3Endpoint }
}

@ -1,48 +1,29 @@
// eslint-disable-next-line no-unused-vars
import React from 'react'
import { shortenAddress } from '@remix-ui/helper'
import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3'
import { fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess } from './payload'
let plugin, dispatch: React.Dispatch<any>
import { shortenAddress } from '@remix-ui/helper'
import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload'
import { Udapp } from '../types'
export const initSettingsTab = (udapp) => async (reducerDispatch: React.Dispatch<any>) => {
if (udapp) {
plugin = udapp
dispatch = reducerDispatch
setupEvents()
let plugin: Udapp, dispatch: React.Dispatch<any>
setInterval(() => {
fillAccountsList()
}, 1000)
}
export const initRunTab = (udapp: Udapp) => async (reducerDispatch: React.Dispatch<any>) => {
plugin = udapp
dispatch = reducerDispatch
setupEvents()
}
const setupEvents = () => {
plugin.blockchain.events.on('newTransaction', (tx, receipt) => {
plugin.emit('newTransaction', tx, receipt)
})
plugin.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
// if (!lookupOnly) this.el.querySelector('#value').value = 0
if (error) return
updateAccountBalances()
})
plugin.blockchain.resetAndInit(plugin.config, {
getAddress: (cb) => {
cb(null, $('#txorigin').val())
cb(null, plugin.REACT_API.accounts.selectedAccount)
},
getValue: (cb) => {
try {
const number = document.querySelector('#value').value
const select = document.getElementById('unit')
const index = select.selectedIndex
const selectedUnit = select.querySelectorAll('option')[index].dataset.unit
let unit = 'ether' // default
if (['ether', 'finney', 'gwei', 'wei'].indexOf(selectedUnit) >= 0) {
unit = selectedUnit
}
const number = plugin.REACT_API.sendValue
const unit = plugin.REACT_API.sendUnit
cb(null, Web3.utils.toWei(number, unit))
} catch (e) {
cb(e)
@ -50,27 +31,66 @@ const setupEvents = () => {
},
getGasLimit: (cb) => {
try {
cb(null, '0x' + new ethJSUtil.BN($('#gasLimit').val(), 10).toString(16))
cb(null, '0x' + new ethJSUtil.BN(plugin.REACT_API.gasLimit, 10).toString(16))
} catch (e) {
cb(e.message)
}
}
})
plugin.blockchain.events.on('newTransaction', (tx, receipt) => {
plugin.emit('newTransaction', tx, receipt)
})
plugin.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
if (!lookupOnly) dispatch(setSendValue(0))
if (error) return
updateAccountBalances()
})
plugin.blockchain.event.register('contextChanged', (context, silent) => {
setFinalContext()
})
plugin.blockchain.event.register('networkStatus', ({ error, network }) => {
if (error) {
const netUI = 'can\'t detect network '
setNetworkNameFromProvider(netUI)
return
}
const networkProvider = plugin.networkModule.getNetworkProvider.bind(plugin.networkModule)
const netUI = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : ''
setNetworkNameFromProvider(netUI)
})
plugin.blockchain.event.register('addProvider', provider => addExternalProvider(provider))
plugin.blockchain.event.register('removeProvider', name => removeExternalProvider(name))
plugin.on('manager', 'pluginActivated', addPluginProvider.bind(plugin))
plugin.on('manager', 'pluginDeactivated', removePluginProvider.bind(plugin))
// setInterval(() => {
// fillAccountsList()
// }, 1000)
// fillAccountsList()
setTimeout(() => {
fillAccountsList()
}, 0)
}
const updateAccountBalances = () => {
// const accounts = $(this.el.querySelector('#txorigin')).children('option')
const accounts = runTab.accounts.loadedAccounts
// accounts.each((index, account) => {
// plugin.blockchain.getBalanceInEther(account.value, (err, balance) => {
// if (err) return
// const updated = shortenAddress(account.value, balance)
Object.keys(accounts).map((value) => {
plugin.blockchain.getBalanceInEther(value, (err, balance) => {
if (err) return
const updated = shortenAddress(value, balance)
// if (updated !== account.innerText) { // check if the balance has been updated and update UI accordingly.
// account.innerText = updated
// }
// })
// })
accounts[value] = updated
})
})
dispatch(fetchAccountsListSuccess(accounts))
}
const fillAccountsList = async () => {
@ -79,7 +99,18 @@ const fillAccountsList = async () => {
const promise = plugin.blockchain.getAccounts()
promise.then((accounts: string[]) => {
dispatch(fetchAccountsListSuccess(accounts))
const loadedAccounts = {}
if (!accounts) accounts = []
accounts.forEach((account) => {
plugin.blockchain.getBalanceInEther(account, (err, balance) => {
if (err) return
const updated = shortenAddress(account, balance)
loadedAccounts[account] = updated
})
})
dispatch(fetchAccountsListSuccess(loadedAccounts))
}).catch((e) => {
dispatch(fetchAccountsListFailed(e.message))
})
@ -87,3 +118,88 @@ const fillAccountsList = async () => {
// addTooltip(`Cannot get account list: ${e}`)
}
}
const setAccount = (account: string) => {
dispatch(setSelectedAccount(account))
}
const setUnit = (unit: 'ether' | 'finney' | 'gwei' | 'wei') => {
dispatch(setSendUnit(unit))
}
const setGasFee = (value: number) => {
dispatch(setGasLimit(value))
}
const addPluginProvider = (profile) => {
if (profile.kind === 'provider') {
((profile, app) => {
const web3Provider = {
async sendAsync (payload, callback) {
try {
const result = await app.call(profile.name, 'sendAsync', payload)
callback(null, result)
} catch (e) {
callback(e)
}
}
}
app.blockchain.addProvider({ name: profile.displayName, provider: web3Provider })
})(profile, plugin)
}
}
const removePluginProvider = (profile) => {
if (profile.kind === 'provider') plugin.blockchain.removeProvider(profile.displayName)
}
const setFinalContext = () => {
// set the final context. Cause it is possible that this is not the one we've originaly selected
const value = _getProviderDropdownValue()
setExecEnv(value)
// this.event.trigger('clearInstance', [])
}
const _getProviderDropdownValue = (): string => {
const provider = plugin.blockchain.getProvider()
const fork = plugin.blockchain.getCurrentFork()
return provider === 'vm' ? provider + '-' + fork : provider
}
const setExecEnv = (env: string) => {
dispatch(setExecutionEnvironment(env))
}
const setNetworkNameFromProvider = (networkName: string) => {
dispatch(setNetworkName(networkName))
}
const addExternalProvider = (network) => {
dispatch(addProvider(network))
// addTooltip(yo`<span><b>${network.name}</b> provider added</span>`)
}
const removeExternalProvider = (name) => {
dispatch(removeProvider(name))
}
const setProviderFromEndpoint = (executionContext: { context: string, fork: string }) => {
plugin.blockchain.setProviderFromEndpoint(runTab.externalEndpoint, executionContext, (alertMsg) => {
// if (alertMsg) addTooltip(alertMsg)
setFinalContext()
})
}
const setExecutionContext = (executionContext: { context: string, fork: string }) => {
plugin.blockchain.changeExecutionContext(executionContext, () => {
executionContextModal(executionContext)
}, (alertMsg) => {
// addTooltip(alertMsg)
}, setFinalContext())
}
const setWeb3Endpoint = (endpoint: string) => {
dispatch(setExternalEndpoint(endpoint))
}

@ -94,3 +94,10 @@ export const hideNotification = () => {
type: 'HIDE_NOTIFICATION'
}
}
export const setExternalEndpoint = (endpoint: string) => {
return {
type: 'SET_EXTERNAL_WEB3_ENDPOINT',
payload: endpoint
}
}

@ -37,7 +37,8 @@ export interface RunTabState {
actionCancel: (() => void) | null,
labelOk: string,
labelCancel: string
}
},
externalEndpoint: string
}
export const runTabInitialState: RunTabState = {
@ -94,7 +95,8 @@ export const runTabInitialState: RunTabState = {
actionCancel: () => {},
labelOk: '',
labelCancel: ''
}
},
externalEndpoint: 'http://127.0.0.1:8545'
}
export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => {
@ -294,6 +296,15 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
}
case 'SET_EXTERNAL_WEB3_ENDPOINT': {
const payload: string = action.payload
return {
...state,
externalEndpoint: payload
}
}
default:
return state
}

@ -8,11 +8,12 @@ import { ContractDropdownUI } from './components/contractDropdownUI'
import { InstanceContainerUI } from './components/instanceContainerUI'
import { RecorderUI } from './components/recorderCardUI'
import { SettingsUI } from './components/settingsUI'
import './css/run-tab.css'
import { Modal, RunTabProps } from './types'
import { runTabInitialState, runTabReducer } from './reducers/runTab'
import './css/run-tab.css'
export function RunTabUI (props: RunTabProps) {
const { runTab, setupEvents, setAccount, setUnit, setGasFee, setExecEnv, setExecutionContext } = useRunTabPlugin(props.plugin)
const { runTab, setupEvents, setAccount, setUnit, setGasFee, setExecEnv, setExecutionContext, setProviderFromEndpoint, setFinalContext, setWeb3Endpoint } = useRunTabPlugin(props.plugin, executionContextModal)
const [focusModal, setFocusModal] = useState<Modal>({
hide: true,
title: '',
@ -23,6 +24,7 @@ export function RunTabUI (props: RunTabProps) {
cancelFn: () => {}
})
const [modals, setModals] = useState<Modal[]>([])
const REACT_API = { runTab }
useEffect(() => {
setupEvents()
@ -55,6 +57,10 @@ export function RunTabUI (props: RunTabProps) {
}
}, [runTab.notification])
useEffect(() => {
props.plugin.onReady(runTab)
}, [REACT_API])
// eslint-disable-next-line no-undef
const modal = (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
setModals(modals => {
@ -69,6 +75,48 @@ export function RunTabUI (props: RunTabProps) {
})
}
const handleInputEndpoint = (e: any) => {
setWeb3Endpoint(e.target.value)
}
function executionContextModal (executionContext: { context: string, fork: string }) {
modal('External node request', web3ProviderDialogBody(), 'OK', () => { setProviderFromEndpoint(executionContext) }, 'Cancel', () => { setFinalContext() })
}
const web3ProviderDialogBody = () => {
const thePath = '<path/to/local/folder/for/test/chain>'
return (
<>
<div className="">
Note: To use Geth & https://remix.ethereum.org, configure it to allow requests from Remix:(see <a href="https://geth.ethereum.org/docs/rpc/server" target="_blank">Geth Docs on rpc server</a>)
<div className="border p-1">geth --http --http.corsdomain https://remix.ethereum.org</div>
<br />
To run Remix & a local Geth test node, use this command: (see <a href="https://geth.ethereum.org/getting-started/dev-mode" target="_blank">Geth Docs on Dev mode</a>)
<div className="border p-1">geth --http --http.corsdomain="${window.origin}" --http.api web3,eth,debug,personal,net --vmdebug --datadir ${thePath} --dev console</div>
<br />
<br />
<b>WARNING:</b> It is not safe to use the --http.corsdomain flag with a wildcard: <b>--http.corsdomain *</b>
<br />
<br />For more info: <a href="https://remix-ide.readthedocs.io/en/latest/run.html#more-about-web3-provider" target="_blank">Remix Docs on Web3 Provider</a>
<br />
<br />
Web3 Provider Endpoint
</div>
<input
onInput={handleInputEndpoint}
type='text'
name='prompt_text'
id='prompt_text'
style={{ width: '100%' }}
className="form-control"
defaultValue={runTab.externalEndpoint}
data-id="modalDialogCustomPromptText"
/>
</>
)
}
return (
<Fragment>
<div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView">

@ -0,0 +1,78 @@
export class Blockchain extends Plugin<any, any> {
constructor(config: any);
event: any;
executionContext: ExecutionContext;
events: EventEmitter;
config: any;
txRunner: any;
networkcallid: number;
networkStatus: {
name: string;
id: string;
};
setupEvents(): void;
getCurrentNetworkStatus(): {
name: string;
id: string;
};
setupProviders(): void;
providers: {};
getCurrentProvider(): any;
/** Return the list of accounts */
getAccounts(cb: any): any;
deployContractAndLibraries(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void;
deployContractWithLibrary(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void;
createContract(selectedContract: any, data: any, continueCb: any, promptCb: any, confirmationCb: any, finalCb: any): void;
determineGasPrice(cb: any): void;
getInputs(funABI: any): any;
fromWei(value: any, doTypeConversion: any, unit: any): string;
toWei(value: any, unit: any): import("bn.js");
calculateFee(gas: any, gasPrice: any, unit: any): import("bn.js");
determineGasFees(tx: any): (gasPrice: any, cb: any) => void;
changeExecutionContext(context: any, confirmCb: any, infoCb: any, cb: any): Promise<any>;
setProviderFromEndpoint(target: any, context: any, cb: any): void;
detectNetwork(cb: any): void;
getProvider(): any;
/**
* return the fork name applied to the current envionment
* @return {String} - fork name
*/
getCurrentFork(): string;
isWeb3Provider(): boolean;
isInjectedWeb3(): boolean;
signMessage(message: any, account: any, passphrase: any, cb: any): void;
web3(): any;
getTxListener(opts: any): any;
runOrCallContractMethod(contractName: any, contractAbi: any, funABI: any, contract: any, value: any, address: any, callType: any, lookupOnly: any, logMsg: any, logCallback: any, outputCb: any, confirmationCb: any, continueCb: any, promptCb: any): void;
context(): "memory" | "blockchain";
resetAndInit(config: any, transactionContextAPI: any): void;
transactionContextAPI: any;
addProvider(provider: any): void;
removeProvider(name: any): void;
/** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */
startListening(txlistener: any): void;
resetEnvironment(): void;
/**
* Create a VM Account
* @param {{privateKey: string, balance: string}} newAccount The new account to create
*/
createVMAccount(newAccount: {
privateKey: string;
balance: string;
}): any;
newAccount(_password: any, passwordPromptCb: any, cb: any): any;
/** Get the balance of an address, and convert wei to ether */
getBalanceInEther(address: any, cb: any): void;
pendingTransactionsCount(): number;
/**
* This function send a tx only to javascript VM or testnet, will return an error for the mainnet
* SHOULD BE TAKEN CAREFULLY!
*
* @param {Object} tx - transaction.
*/
sendTransaction(tx: any): any;
runTx(args: any, confirmationCb: any, continueCb: any, promptCb: any, cb: any): void;
}
import { Plugin } from "@remixproject/engine/lib/abstract";
import { ExecutionContext } from "./execution-context";
import { EventEmitter } from "events";

@ -0,0 +1,38 @@
import Web3 from 'web3'
export class ExecutionContext {
event: any;
executionContext: any;
lastBlock: any;
blockGasLimitDefault: number;
blockGasLimit: number;
currentFork: string;
mainNetGenesisHash: string;
customNetWorks: {};
blocks: {};
latestBlockNumber: number;
txs: {};
customWeb3: {};
init(config: any): void;
askPermission(): void;
getProvider(): any;
getCurrentFork(): string;
isVM(): boolean;
setWeb3(context: any, web3: any): void;
web3(): any;
detectNetwork(callback: any): void;
removeProvider(name: any): void;
addProvider(network: any): void;
internalWeb3(): any;
blankWeb3(): Web3;
setContext(context: any, endPointUrl: any, confirmCb: any, infoCb: any): void;
executionContextChange(value: any, endPointUrl: any, confirmCb: any, infoCb: any, cb: any): Promise<any>;
currentblockGasLimit(): number;
stopListenOnLastBlock(): void;
// eslint-disable-next-line no-undef
listenOnLastBlockId: NodeJS.Timer;
_updateChainContext(): Promise<void>;
listenOnLastBlock(): void;
setProviderFromEndpoint(endpoint: any, value: any, cb: any): void;
txDetailsLink(network: any, hash: any): any;
}

@ -1,5 +1,13 @@
import { RunTabState } from '../reducers/runTab'
import { Blockchain } from './blockchain'
export interface Udapp {
onReady: (api: RunTabState) => void,
REACT_API: RunTabState,
blockchain: Blockchain
}
export interface RunTabProps {
plugin: any
plugin: Udapp
}
export interface SettingsProps {

@ -0,0 +1,12 @@
export = InjectedProvider;
declare class InjectedProvider {
constructor(executionContext: any);
executionContext: any;
getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): void;
resetEnvironment(): void;
getBalanceInEther(address: any, cb: any): void;
getGasPrice(cb: any): void;
signMessage(message: any, account: any, _passphrase: any, cb: any): void;
getProvider(): string;
}

@ -0,0 +1,13 @@
export = NodeProvider;
declare class NodeProvider {
constructor(executionContext: any, config: any);
executionContext: any;
config: any;
getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): any;
resetEnvironment(): void;
getBalanceInEther(address: any, cb: any): void;
getGasPrice(cb: any): void;
signMessage(message: any, account: any, passphrase: any, cb: any): void;
getProvider(): any;
}

@ -0,0 +1,16 @@
export = VMProvider;
declare class VMProvider {
constructor(executionContext: any);
executionContext: any;
getAccounts(cb: any): void;
resetEnvironment(): void;
accounts: {};
RemixSimulatorProvider: any;
web3: any;
createVMAccount(newAccount: any): string;
newAccount(_passwordPromptCb: any, cb: any): void;
getBalanceInEther(address: any, cb: any): void;
getGasPrice(cb: any): void;
signMessage(message: any, account: any, _passphrase: any, cb: any): void;
getProvider(): string;
}
Loading…
Cancel
Save