Skip to content

Commit

Permalink
WebSocketClient
Browse files Browse the repository at this point in the history
  • Loading branch information
pragmaxim committed Nov 11, 2024
1 parent d1b2cee commit 6f310f5
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 43 deletions.
1 change: 1 addition & 0 deletions packages/web3/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export * from './signer'
export * from './utils'
export * from './transaction'
export * from './token'
export * from './ws'

export * from './constants'
export * as web3 from './global'
Expand Down
19 changes: 19 additions & 0 deletions packages/web3/src/ws/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

export { WebSocketClient } from './websocket-client'
76 changes: 76 additions & 0 deletions packages/web3/src/ws/websocket-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import WebSocket from 'ws';

type WsMessageType = string;
type WsSubscription = [WsMessageType, (params: any) => void];

export class WebSocketClient {
private ws: WebSocket;
private subscriptions: WsSubscription[] = [];

constructor(endpoint: string, eventSubscriptions: WsSubscription[] = []) {
this.ws = new WebSocket(endpoint);
eventSubscriptions.forEach(([messageType, callback]) => {
this.subscriptions.push([messageType, callback]);
});

this.ws.on('open', () => {
console.log('WebSocket connection opened');
this.subscribeToEvents();
});

this.ws.on('message', (data) => {
try {
const parsedData = JSON.parse(data.toString());
this.subscriptions.forEach(([method, callback]) => {
if (parsedData.method === method) {
callback(parsedData.params);
}
});
} catch (error) {
console.error('Error parsing message:', error);
}
});

this.ws.on('error', (error) => {
console.error('WebSocket error:', error);
});

this.ws.on('close', () => {
console.log('WebSocket connection closed');
});
}

private subscribeToEvents() {
this.subscriptions.forEach(([method]) => {
console.log(`Subscribing to ${method}`);
this.ws.send(`subscribe:${method}`);
});
}

onOpen(callback: () => void) {
this.ws.on('open', callback);
}

close() {
this.ws.close();
}
}

71 changes: 28 additions & 43 deletions test/websocket.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,60 +16,45 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import WebSocket from 'ws';
import { DEFAULT_GAS_ALPH_AMOUNT, ONE_ALPH, NodeProvider, sleep, web3 } from '@alephium/web3';
import { ONE_ALPH, SignerProviderSimple, web3, WebSocketClient } from '@alephium/web3';
import { getSigner } from '@alephium/web3-test';

const WS_ENDPOINT = 'ws://127.0.0.1:22973/ws';

describe('WebSocket and Transaction Test', () => {
let signer;
describe('WebSocket', () => {
let signer: SignerProviderSimple;
let wsClient: WebSocketClient;

beforeAll(async () => {
web3.setCurrentNodeProvider('http://127.0.0.1:22973', undefined, fetch);
signer = await getSigner();
});

it('should connect, subscribe, and receive block event after a transaction is submitted', async () => {
const ws = new WebSocket(WS_ENDPOINT);

await new Promise<void>((resolve, reject) => {
ws.on('open', async () => {
try {
ws.send('subscribe:block');

const address = (await signer.getSelectedAccount()).address;
const fee = 0.01;
const attoAlphAmount = ONE_ALPH;

await signer.signAndSubmitTransferTx({
signerAddress: address,
destinations: [{ address, attoAlphAmount }],
fee,
});
} catch (error) {
console.error('Error during transaction submission:', error);
reject(error);
}
});

ws.on('message', (data) => {
try {
console.log('Received:', data.toString());
const parsedData = JSON.parse(data.toString());
expect(parsedData).toBeDefined();
expect(parsedData.method).toBe('block');
resolve();
} catch (error) {
reject(error);
} finally {
ws.close();
}
});

ws.on('error', (error) => {
console.error('WebSocket error:', error);
reject(error);
await new Promise<boolean>((resolve, reject) => {
wsClient = new WebSocketClient(WS_ENDPOINT, [
['block', async (params: any) => {
console.log('Received block event:', params);
expect(params).toBeDefined();
}],
]);
wsClient.onOpen(() => {
(async () => {
try {
const address = (await signer.getSelectedAccount()).address;
const attoAlphAmount = ONE_ALPH;

await signer.signAndSubmitTransferTx({
signerAddress: address,
destinations: [{ address, attoAlphAmount }],
});
resolve(true);
wsClient.close();
} catch (error) {
console.error('Error during transaction submission:', error);
reject(error);
}
})();
});
});
});
Expand Down

0 comments on commit 6f310f5

Please sign in to comment.