Skip to content
This repository has been archived by the owner on Oct 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1026 from statechannels/tc-ag-xstate-messaging
Browse files Browse the repository at this point in the history
Xstate Messaging Service (rebased)
  • Loading branch information
tomclose committed Feb 15, 2020
2 parents c23a958 + f7e5db3 commit e650171
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 365 deletions.
13 changes: 11 additions & 2 deletions packages/xstate-wallet/.vscode/launch.json
Expand Up @@ -8,11 +8,20 @@
"name": "Jest Current",
"type": "node",
"request": "launch",
"args": ["node_modules/.bin/jest", "--runInBand", "--env=jsdom", "${relativeFile}"],
"args": [
"node_modules/.bin/jest",
"--config=${workspaceRoot}/config/jest/jest.config.js",
"--runInBand",
"--env=jsdom",

"${relativeFile}"
],
"skipFiles": ["<node_internals>/**/*.js"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
"internalConsoleOptions": "neverOpen",
"smartStep": true
}
]
}
65 changes: 65 additions & 0 deletions packages/xstate-wallet/src/channel-wallet.ts
@@ -0,0 +1,65 @@
import {Store} from './store/memory-store';
import {MessagingServiceInterface} from './messaging';

import {applicationWorkflow} from './workflows/application';
import ReactDOM from 'react-dom';
import React from 'react';
import WalletUi from './ui/wallet';
import {interpret, Interpreter} from 'xstate';
import {Guid} from 'guid-typescript';
import {convertToOpenEvent} from './utils/workflow-utils';
export interface Workflow {
id: string;
machine: Interpreter<any, any, any>;
domain: string; // TODO: Is this useful?
}
export class ChannelWallet {
private workflows: Workflow[];

constructor(private store: Store, private messagingService: MessagingServiceInterface) {
this.workflows = [];
this.messagingService.requestFeed.subscribe(r => {
if (r.method === 'CreateChannel' || r.method === 'JoinChannel') {
const workflow = this.startApplicationWorkflow();
this.workflows.push(workflow);
workflow.machine.send(convertToOpenEvent(r));
}
});
}

private startApplicationWorkflow(): Workflow {
const workflowId = Guid.create().toString();
const machine = interpret<any, any, any>(
applicationWorkflow(this.store, this.messagingService),
{
devTools: true
}
)
.onDone(() => (this.workflows = this.workflows.filter(w => w.id !== workflowId)))
.start();
// TODO: Figure out how to resolve rendering priorities
this.renderUI(machine);

return {id: workflowId, machine, domain: 'TODO'};
}

private renderUI(machine) {
if (document.getElementById('root')) {
ReactDOM.render(
React.createElement(WalletUi, {workflow: machine}),
document.getElementById('root')
);
}
}

public async pushMessage(message) {
// Update the store first
await this.store.pushMessage(message);
// Update any workflows waiting on an observable
await this.messagingService.receiveMessage(message);
}

public onSendMessage(callback: (message) => void) {
this.messagingService.outboxFeed.subscribe(m => callback(m));
}
}
19 changes: 10 additions & 9 deletions packages/xstate-wallet/src/index.ts
@@ -1,17 +1,18 @@
import {handleMessage} from './messaging';

import {ethers} from 'ethers';

// TODO import {ChainWatcher} from './chain';
import {WorkflowManager} from './workflow-manager';
import {MemoryStore, Store} from './store/memory-store';

const ourWallet = ethers.Wallet.createRandom();
import {MemoryStore} from './store/memory-store';

const store: Store = new MemoryStore([ourWallet.privateKey]);
import {ChannelWallet} from './channel-wallet';
import {MessagingService} from './messaging';

const workflowManager = new WorkflowManager(store);
const {privateKey} = ethers.Wallet.createRandom();
const store = new MemoryStore([privateKey]);
const messagingService = new MessagingService(store);
const channelWallet = new ChannelWallet(store, messagingService);

// Communicate via postMessage
window.addEventListener('message', async event => {
await handleMessage(event, workflowManager, store, ourWallet);
channelWallet.pushMessage(event.data);
});
channelWallet.onSendMessage(m => window.parent.postMessage(m, '*'));

0 comments on commit e650171

Please sign in to comment.