Skip to content

Commit

Permalink
Wallet: connect to daemon by default (#2669)
Browse files Browse the repository at this point in the history
* Wallet: connect to daemon by default

* Small review fixes
  • Loading branch information
Schmavery authored and mergify[bot] committed Jun 18, 2019
1 parent c2e3aee commit 6ef0827
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 319 deletions.
2 changes: 2 additions & 0 deletions frontend/wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"scripts": {
"fake": "graphql-faker --port 8080 -- schema.graphql",
"real": "./_build/coda-daemon-macos/coda.exe daemon -config-dir $(mktemp -d -t coda_config) -rest-port 8080 &> /dev/tty",
"fake-inspector": "graphql-faker --open -- schema.graphql",
"pull-macos-binary": "curl https://s3-us-west-2.amazonaws.com/wallet.o1test.net/coda-daemon-macos.zip > coda-daemon-macos.zip && rm -rf _build/coda-daemon-macos/ && unzip coda-daemon-macos.zip",
"build": "bsb -make-world",
Expand All @@ -35,6 +36,7 @@
"pack": "fpack --development ./lib/js/src/render/Index.js",
"query": "send-introspection-query http://localhost:8080/graphql",
"query-fake": "concurrently --kill-others 'yarn run fake' 'sleep 5 && yarn run query' || true",
"query-real": "concurrently --kill-others 'yarn run real' 'sleep 15 && yarn run query' || true",
"reformat": "bsrefmt --in-place $(find src -name '*.re' -or -name '*.rei' -print)",
"test": "yarn run build && jest lib/js/",
"dist": "yarn run build && yarn run pack && build",
Expand Down
28 changes: 11 additions & 17 deletions frontend/wallet/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
enum SyncStatus {
ERROR
OFFLINE
BOOTSTRAP # Resyncing
STALE # You haven't seen any activity recently
SYNCED
}

enum ChainReorganizationStatus {
CHANGED
}

type SyncUpdate {
status: SyncStatus!
estimatedPercentSynced: Float!
description: String @examples(values: ["Sync description"])
}

type SnarkWorker {
key: String! @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
fee: String! @fake(type: number)
Expand All @@ -24,17 +17,16 @@ type UserCommand {
id: String!
isDelegation: Boolean!
nonce: Int!
date: String! @fake(type: pastDate)
from: String! @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
to: String! @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
amount: String! @fake(type: number)
fee: String! @fake(type: number)
memo: String @fake(type:hackerPhrase)
memo: String! @fake(type:hackerPhrase)
}

type FeeTransfer {
recipient: String! @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
amount: String! @fake(type: number)
fee: String! @fake(type: number)
}

type BlockchainState {
Expand Down Expand Up @@ -162,7 +154,7 @@ type AddPaymentReceiptPayload {
}

type AddWalletPayload {
publicKey: String @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
publicKey: String! @examples(values: ["PUB_KEY_E9873DF4453213303DA61F2", "PUB_KEY_F1173DF4453213303DA61F2"])
}

type DeleteWalletPayload {
Expand Down Expand Up @@ -230,18 +222,20 @@ type Query {
currentSnarkWorker: SnarkWorker

# Current sync status of the node
syncState: SyncUpdate!
syncStatus: SyncStatus!

# version of the node (commit hash or version #)
version: String! @examples(values: ["aa8c3f93ec2bad4718c308914df9e47b586f8ecd"])
version: String @examples(values: ["aa8c3f93ec2bad4718c308914df9e47b586f8ecd"])

# Network that the node is connected to
network: String @examples(values: ["testnet"])
status: NodeStatus

initialPeers: [String!]! @examples(values: ["testnet"])
}

type Mutation {
createPayment(input: CreatePaymentInput!): CreatePaymentPayload
sendPayment(input: CreatePaymentInput!): CreatePaymentPayload

createDelegation(input: CreateDelegationInput!): CreateDelegationPayload

Expand All @@ -254,7 +248,7 @@ type Mutation {
addPaymentReceipt(input: AddPaymentReceiptInput!): AddPaymentReceiptPayload

# Tell server to track a private key and all associated transactions
addWallet(input: AddWalletInput!): AddWalletPayload
addWallet(input: AddWalletInput!): AddWalletPayload!

# Deletes private key associated with `key` and all related information
deleteWallet(input: DeleteWalletInput!): DeleteWalletPayload
Expand All @@ -264,7 +258,7 @@ type Mutation {

type Subscription {
# Subscribe to sync status of the node
newSyncUpdate: SyncUpdate!
newSyncUpdate: SyncStatus!

blockConfirmation: BlockConfirmation!

Expand Down
3 changes: 3 additions & 0 deletions frontend/wallet/src/common/Bindings.re
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ module ChildProcess = {
) =>
Process.t =
"spawn";

[@bs.val] [@bs.module "child_process"]
external execSync: (string, array(string)) => unit = "exec";
};

module Fs = {
Expand Down
5 changes: 1 addition & 4 deletions frontend/wallet/src/main/App.re
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
open BsElectron;
open Tc;

let killFaker = DaemonProcess.startFaker(8080);

let createTray = dispatch => {
let t = AppTray.get();
let trayItems =
Expand Down Expand Up @@ -41,8 +39,6 @@ let createTray = dispatch => {
// We need this handler here to prevent the application from exiting on all
// windows closed. Keep in mind, we have the tray.
App.on(`WindowAllClosed, () => ());
// TODO: Also kill coda.exe
App.on(`WillQuit, () => killFaker());

let initialTask = Task.uncallbackifyValue(App.on(`Ready));

Expand All @@ -65,6 +61,7 @@ let run = () =>
dispatch := Application.Store.apply((), store);
let dispatch = dispatch^;

App.on(`WillQuit, () => dispatch(Action.ControlCoda(None)));
createTray(dispatch);

AppWindow.deepLink({AppWindow.Input.path: Route.Home, dispatch});
Expand Down
76 changes: 41 additions & 35 deletions frontend/wallet/src/main/DaemonProcess.re
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ module Command = {
executable: string,
args: array(string),
env: Js.Dict.t(string),
logfileName: string,
};
};

let (^/) = Filename.concat;

let codaPath = "_build/coda-daemon-macos";
let codaCommand = (~port, ~extraArgs) => {
let codaPath = "_build/coda-daemon-macos";
{
Command.executable: ProjectRoot.resource ^/ codaPath ^/ "coda.exe",
args:
Expand All @@ -39,15 +38,30 @@ let codaCommand = (~port, ~extraArgs) => {
Js.Dict.entries(ChildProcess.Process.env),
),
),
logfileName: "daemon",
};
};

let fakerCommand = (~port) => {
Command.executable: "node",
args: [|
Filename.concat(
ProjectRoot.resource,
"node_modules/graphql-faker/dist/index.js",
),
"--port",
string_of_int(port),
"--",
"schema.graphql",
|],
env: ChildProcess.Process.env,
};

module Process = {
let start = (command: Command.t) => {
let {Command.executable, args, logfileName} = command;
let {Command.executable, args} = command;
let logfileName = "daemon.log";
print_endline(
{j|Starting $executable with $args. Logging to `$logfileName.log`|j},
{j|Starting $executable with $args. Logging to `$logfileName`|j},
);

/*
Expand All @@ -65,7 +79,7 @@ module Process = {
https://github.com/janestreet/async_unix/issues/15
*/

let log = Fs.openSync(command.logfileName ++ ".log", "w");
let log = Fs.openSync(logfileName, "w");
let process =
ChildProcess.spawn(
command.executable,
Expand All @@ -82,8 +96,8 @@ module Process = {
"Daemon process "
++ command.executable
++ " crashed. Logs are in `"
++ command.logfileName
++ ".log`. Error:"
++ logfileName
++ "`. Error:"
++ ChildProcess.Error.messageGet(e),
)
);
Expand All @@ -95,10 +109,10 @@ module Process = {
if (code != 0) {
Printf.fprintf(
stderr,
"Daemon process %s died with non-zero exit code: %d. Logs are in `%s.log`\n",
"Daemon process %s died with non-zero exit code: %d. Logs are in `%s`\n",
command.executable,
code,
command.logfileName,
logfileName,
);
} else {
print_endline(
Expand Down Expand Up @@ -127,32 +141,24 @@ module CodaProcess = {

let kill: t => unit = t => ChildProcess.Process.kill(t, "SIGINT");

let port = 0xc0da;

let start: list(string) => t =
args => {
Process.start(
codaCommand(~port=0xc0da, ~extraArgs=args |> Array.fromList),
);
switch (Js.Dict.get(ChildProcess.Process.env, "GRAPHQL_BACKEND")) {
| Some("faker") => Process.start(fakerCommand(~port))
| _ =>
/* Workaround for https://github.com/CodaProtocol/coda/issues/2667
Remove the config deletion when it is resolved. */
let transitionFrontierPath =
ProjectRoot.resource ^/ codaPath ^/ "config/transition_frontier";

Printf.fprintf(stderr, "Deleting %s\n%!", transitionFrontierPath);
Bindings.ChildProcess.execSync(
"rm",
[|"-rf", transitionFrontierPath|],
);
Process.start(codaCommand(~port, ~extraArgs=args |> Array.fromList));
};
};
};

let startFaker = port => {
let graphqlFaker = {
Command.executable: "node",
args: [|
Filename.concat(
ProjectRoot.resource,
"node_modules/graphql-faker/dist/index.js",
),
"--port",
string_of_int(port),
"--",
"schema.graphql",
|],
env: ChildProcess.Process.env,
logfileName: "faker",
};
let p = Process.start(graphqlFaker);
() => {
ChildProcess.Process.kill(p, "SIGINT");
};
};
54 changes: 17 additions & 37 deletions frontend/wallet/src/render/Apollo.re
Original file line number Diff line number Diff line change
@@ -1,57 +1,37 @@
open Tc;

type retryOptions;
let retryOptions: retryOptions = [%bs.raw
{|
{delay: {
initial: 300,
max: 500,
jitter: false
},
attempts: {
max: 60,
}
}
|}
];

[@bs.module "apollo-link-retry"] [@bs.new]
external createRetryLink: retryOptions => ReasonApolloTypes.apolloLink =
"RetryLink";

let createClient = (~faker, ~coda) => {
let client = {
let inMemoryCache = ApolloInMemoryCache.createInMemoryCache();
let fakerLink =
ApolloLinks.createHttpLink(~uri=faker, ~fetch=Bindings.Fetch.fetch, ());

let uri = "http://localhost:49370/graphql";
let codaLink =
ApolloLinks.createHttpLink(~uri=coda, ~fetch=Bindings.Fetch.fetch, ());

let _link =
ApolloLinks.split(
operation => {
let operation: {. "operationName": option(string)} =
Obj.magic(operation);
operation##operationName == Some("addWalletss")
||
operation##operationName == Some("getWallets");
ApolloLinks.createHttpLink(~uri, ~fetch=Bindings.Fetch.fetch, ());

let retryOptions: retryOptions = [%bs.raw
{|
{delay: {
initial: 300,
max: 500,
jitter: false
},
codaLink,
fakerLink,
);

attempts: {
max: 60,
}}
|}
];
let retry = createRetryLink(retryOptions);

let retryLink = ApolloLinks.from([|retry, fakerLink|]);
let retryLink = ApolloLinks.from([|retry, codaLink|]);

ReasonApollo.createApolloClient(~link=retryLink, ~cache=inMemoryCache, ());
};

let client =
createClient(
~faker="http://localhost:8080/graphql",
~coda="http://localhost:49370/graphql",
);

module Decoders = {
let int64 = Int64.of_string;
let optInt64 = Option.map(~f=Int64.of_string);
Expand Down
Loading

0 comments on commit 6ef0827

Please sign in to comment.