-
Notifications
You must be signed in to change notification settings - Fork 247
Notes on Bindings
Exported method:
func CreateAccount(password *C.char) *C.char
Internally relies on:
// createAccount creates an internal geth account
// BIP44-compatible keys are generated: CKD#1 is stored as account key, CKD#2 stored as sub-account root
// Public key of CKD#1 is returned, with CKD#2 securely encoded into account key file (to be used for
// sub-account derivations)
func createAccount(password string) (address, pubKey, mnemonic string, err error)
Sample response:
{
"Address": "0xdeadbeef..",
"PubKey": "0xdeadbeef..",
"Mnemonic": "stupid lazy fox jump crazy..",
"Error": ""
}
Exported method:
func CreateChildAccount(parentAddress, password *C.char) *C.char
Internally relies on:
// createChildAccount creates sub-account for an account identified by parent address.
// CKD#2 is used as root for master accounts (when parentAddress is "").
// Otherwise (when parentAddress != ""), child is derived directly from parent.
func createChildAccount(parentAddress, password string) (address, pubKey string, err error)
Sample Response:
{
"Address": "0xdeadbeef..",
"PubKey": "0xdeadbeef..",
"Error": ""
}
Exported Method:
func RecoverAccount(password, mnemonic *C.char) *C.char
Internally relies on:
// recoverAccount re-creates master key using given details.
// Once master key is re-generated, it is inserted into keystore (if not already there).
func recoverAccount(password, mnemonic string) (address, pubKey string, err error)
Sample Response: (same as on main account creation)
{
"Address": "0xdeadbeef..",
"PubKey": "0xdeadbeef..",
"Mnemonic": "stupid lazy fox jump crazy..",
"Error": ""
}
Exported Method:
func Login(address, password *C.char) *C.char
Internally:
// selectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
// all previous identities are removed).
func selectAccount(address, password string) error
Sample Response:
{
"Error": "some issue occurred, login failed.."
}
When called system makes sure that Whisper identity (injected on Login()
) is wiped out.
Exported method:
func Logout() *C.char
Sample Response:
{
"Error": ""
}
Every time somebody unlocks Ethereum account Cthulhu kills kittens (🐱 😸 ), dozens of them. So, don't use this method.
This method is deprecated, and will return error, asking you to rely on Login()
instead (if kittens weren't enough for you!)
Output:
{
"Error": "no need to unlock accounts, login instead"
}
Every time transaction is sent to geth node (via SendTransaction
, which passes through jail
package's Send
method) it is intercepted and queued. Call is NOT returned immediately and hangs on until either of below happens:
-
CompleteTransaction()
received (see below) -
DiscardTransaction()
received (see below) - request times out (normally, after 300 seconds)
When request is queued, native application will receive a signal (with transaction id
to be used to complete pending/queued transaction).
In order to complete transaction, use the following exported method:
func CompleteTransaction(id, password *C.char) *C.char
where id
is transaction id, and password
is user's password we will attempt to sign transaction with (if this succeeds, then transaction will be sent to blockchain).
If user wants to cancel transaction (instead of providing password and completing), then the following method should be used:
func DiscardTransaction(id *C.char) *C.char
Note that in order to discard a transaction, only id
is required (no need to supply password). Whenever transaction is discarded, SendTransaction()
unblocks (and triggers transaction.failed
signal to application, with error code 4).
When DiscardTransaction()
returns, its response is JSON having the following data:
{
id: "transaction id passed to DiscardTransaction()",
error: "error message, if any"
}
🌟 Below are possible error codes that binding can signal back to react-native app:
SendTransactionNoErrorCode = "0" // no error, tx executed ok
SendTransactionDefaultErrorCode = "1" // some error
SendTransactionPasswordErrorCode = "2" // wrong password
SendTransactionTimeoutErrorCode = "3" // request times out
SendTransactionDiscardedErrorCode = "4" // tx discarded manually
In addition to discarding and completing transactions one by one, you can act on multiple items:
-
DiscardTransactions('["tx-id1", "tx-id2", .., "tx-idN"]')
allows you to discard multiple items, and response looks sth like this (note that redundant usage of id both as key inresults
and attribute is intentional, as it allows to quickly navigate the results + the very same struct is used to return on a single discard, where knowing theid
might be necessary):
{
"results":{
"invalid-tx-id":{
"id":"invalid-tx-id",
"error":"transaction hash not found"
}
}
}
-
CompleteTransactions('["tx-id1", "tx-id2", .., "tx-idN"]', 'password')
, and response contains result for each transaction (since it is important to know the status of each request):
{
"results":{
"300d79e3-71c2-4000-a954-21c9f1762e26":{
"id":"300d79e3-71c2-4000-a954-21c9f1762e26",
"hash":"0x17e4e80f7b19f168fe123f475884161c22e37180b342efe9044c1ef27850a78f",
"error":""
},
"679fa40b-34ab-495e-bb4d-177ebcf2ea22":{
"id":"679fa40b-34ab-495e-bb4d-177ebcf2ea22",
"hash":"0xe7bd3619e7e6fbcc7ee4fb4f4e2be9ecde662641911bbc4326afba78f9155a0c",
"error":""
},
"6b079a73-2515-4ead-a5e9-2eeb536b55b3":{
"id":"6b079a73-2515-4ead-a5e9-2eeb536b55b3",
"hash":"0x2763cae97579319b87529e981ad6821bd83a8fa8abd27d0c89cdcde02ef4abcf",
"error":""
},
"invalid-tx-id":{
"id":"invalid-tx-id",
"hash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"error":"transaction hash not found"
}
}
}
⭐️ It is important to note that response of multi-entity actions will be returned when all of the items are processed (success, failure or timeout for each item). Of course, bindings will send async signals as transactions are being processed (so that app can react on each tx individually, w/o waiting for all of them to be done with).
To generate default configuration object (in JSON format):
func GenerateConfig(datadir *C.char, networkId C.int) *C.char
Note: GenerateConfig()
requires data directory and network id to be present, because for special networks (like testnet) default network parameters (genesis, for instance) are loaded.
To start a node with a given configuration:
func StartNode(configJSON *C.char) *C.char
To stop/resume the running node:
func StopNode() *C.char
func ResumeNode() *C.char
One can stop/resume just node's HTTP RPC server:
func StopNodeRPCServer() *C.char
func StartNodeRPCServer() *C.char
From time to time it might be necessary to wipe out the chain data, and re-sync, for that:
func ResetChainData() *C.char
To add peer node:
func AddPeer(url *C.char) *C.char // adds peer, which main node will listen to
Requests from native application do NOT go directly to running node. Instead, they are forwarded via Otto VMs i.e. you use Call()
binding which internally executes JavaScript code within jailed JS environment.
That jailed environment is initialized with JS code from jail/web3.go
, and is augmented with the code coming via Parse()
method (thus allowing native apps specify their custom methods/commands).
Everything MUST start with InitJail()
:
func InitJail(js *C.char)
which accepts custom JS, to setup custom JS environment. If you haven't initialized jailed environment with InitJail()
calls to other exported methods will fail.
Now, once jailed environment is prepared, it is time to start/setup VM:
func Parse(chatId *C.char, js *C.char) *C.char
You need to specify chatId
and custom JS. That chatId
will uniquely identify crated VM. Then, to execute some JS code on that uniquely identified VM:
func Call(chatId *C.char, path *C.char, params *C.char) *C.char
The path
identifies command to run e.g. ["commands", "send"]
and params
is just command arguments (passed as object i.e. {}
).
This section will be updated once we migrate to Whisper ver.5 + Enable Push Notifications and Inboxing
A few bindings that can be used to collect some CPU and memory reports.
Collected data is not returned directly, but instead it is saved into a file in the directory passed in the first argument.
Exported Methods:
To collect CPU profiling data:
func StartCPUProfile(dataDir *C.char) *C.char
and to stop it:
func StopCPUProfiling() *C.char
Internally relies on:
// StartCPUProfile enables CPU profiling for the current process. While profiling,
// the profile will be buffered and written to the file in folder dataDir.
func StartCPUProfile(dataDir string) error
and
// StopCPUProfile stops the current CPU profile, if any, and closes the file.
func StopCPUProfile() error
To collect memory profiling data:
func WriteHeapProfile(dataDir *C.char) *C.char
Internally relies on:
// WriteHeapFile writes heap memory to the file.
func WriteHeapFile(dataDir string) error
Project Information
Getting started
Developers
Support
Internal