Beispiel #1
0
// newREPLConsole creates a new JavaScript interpreter console that can be used
// by the API to serve fronted console requests.
func newREPLConsole(eapis *etherapis.EtherAPIs) *jsre.JSRE {
	// Create a JavaScript interpreter with web3 injected
	console := jsre.New("")

	client, _ := eapis.Geth().Stack().Attach()

	jeth := utils.NewJeth(console, client)
	console.Set("jeth", struct{}{})
	t, _ := console.Get("jeth")
	jethObj := t.Object()

	jethObj.Set("send", jeth.Send)
	jethObj.Set("sendAsync", jeth.Send)

	console.Compile("bignumber.js", jsre.BigNumber_JS)
	console.Compile("web3.js", jsre.Web3_JS)
	console.Run("var Web3 = require('web3');")
	console.Run("var web3 = new Web3(jeth);")

	// Inject all of the APIs exposed by the inproc RPC client
	shortcut := "var eth = web3.eth; var personal = web3.personal; "
	apis, _ := client.SupportedModules()
	for api, _ := range apis {
		if api == "web3" || api == "rpc" {
			continue
		}
		if jsFile, ok := web3ext.Modules[api]; ok {
			console.Compile(fmt.Sprintf("%s.js", api), jsFile)
			shortcut += fmt.Sprintf("var %s = web3.%s; ", api, api)
		}
	}
	console.Run(shortcut)

	// Finally return the ready console
	return console
}
Beispiel #2
0
func (js *jsre) apiBindings() error {
	apis, err := js.supportedApis()
	if err != nil {
		return err
	}

	apiNames := make([]string, 0, len(apis))
	for a, _ := range apis {
		apiNames = append(apiNames, a)
	}

	jeth := utils.NewJeth(js.re, js.client)
	js.re.Set("jeth", struct{}{})
	t, _ := js.re.Get("jeth")
	jethObj := t.Object()

	jethObj.Set("send", jeth.Send)
	jethObj.Set("sendAsync", jeth.Send)

	err = js.re.Compile("bignumber.js", re.BigNumber_JS)
	if err != nil {
		utils.Fatalf("Error loading bignumber.js: %v", err)
	}

	err = js.re.Compile("web3.js", re.Web3_JS)
	if err != nil {
		utils.Fatalf("Error loading web3.js: %v", err)
	}

	_, err = js.re.Run("var Web3 = require('web3');")
	if err != nil {
		utils.Fatalf("Error requiring web3: %v", err)
	}

	_, err = js.re.Run("var web3 = new Web3(jeth);")
	if err != nil {
		utils.Fatalf("Error setting web3 provider: %v", err)
	}

	// load only supported API's in javascript runtime
	shortcuts := "var eth = web3.eth; var personal = web3.personal; "
	for _, apiName := range apiNames {
		if apiName == "web3" || apiName == "rpc" {
			continue // manually mapped or ignore
		}

		if jsFile, ok := web3ext.Modules[apiName]; ok {
			if err = js.re.Compile(fmt.Sprintf("%s.js", apiName), jsFile); err == nil {
				shortcuts += fmt.Sprintf("var %s = web3.%s; ", apiName, apiName)
			} else {
				utils.Fatalf("Error loading %s.js: %v", apiName, err)
			}
		}
	}

	_, err = js.re.Run(shortcuts)
	if err != nil {
		utils.Fatalf("Error setting namespaces: %v", err)
	}

	js.re.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `);   registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)

	// overrule some of the methods that require password as input and ask for it interactively
	p, err := js.re.Get("personal")
	if err != nil {
		fmt.Println("Unable to overrule sensitive methods in personal module")
		return nil
	}

	// Override the unlockAccount and newAccount methods on the personal object since these require user interaction.
	// Assign the jeth.unlockAccount and jeth.newAccount in the jsre the original web3 callbacks. These will be called
	// by the jeth.* methods after they got the password from the user and send the original web3 request to the backend.
	if persObj := p.Object(); persObj != nil { // make sure the personal api is enabled over the interface
		js.re.Run(`jeth.unlockAccount = personal.unlockAccount;`)
		persObj.Set("unlockAccount", jeth.UnlockAccount)
		js.re.Run(`jeth.newAccount = personal.newAccount;`)
		persObj.Set("newAccount", jeth.NewAccount)
	}

	// The admin.sleep and admin.sleepBlocks are offered by the console and not by the RPC layer.
	// Bind these if the admin module is available.
	if a, err := js.re.Get("admin"); err == nil {
		if adminObj := a.Object(); adminObj != nil {
			adminObj.Set("sleepBlocks", jeth.SleepBlocks)
			adminObj.Set("sleep", jeth.Sleep)
		}
	}

	return nil
}