polkadot-js/api

View on GitHub
packages/typegen/src/util/wsMeta.ts

Summary

Maintainability
A
1 hr
Test Coverage
// Copyright 2017-2024 @polkadot/typegen authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { HexString } from '@polkadot/util/types';

import { promiseTracker } from '@polkadot/api/promise/decorateMethod';
import { stringify } from '@polkadot/util';
import { WebSocket } from '@polkadot/x-ws';

async function getWsData <T> (endpoint: string, method: 'rpc_methods' | 'state_getMetadata' | 'state_getRuntimeVersion'): Promise<T> {
  return new Promise((resolve, reject): void => {
    const tracker = promiseTracker<T>(resolve, reject);

    try {
      const websocket = new WebSocket(endpoint);

      websocket.onclose = (event: { code: number; reason: string }): void => {
        if (event.code !== 1000) {
          tracker.reject(new Error(`disconnected, code: '${event.code}' reason: '${event.reason}'`));
        }
      };

      websocket.onerror = (event: unknown): void => {
        tracker.reject(new Error(`WebSocket error:: ${stringify(event)}`));
      };

      websocket.onopen = (): void => {
        console.log('connected');
        websocket.send(`{"id":"1","jsonrpc":"2.0","method":"${method}","params":[]}`);
      };

      websocket.onmessage = (message: { data: string }): void => {
        try {
          tracker.resolve((JSON.parse(message.data) as { result: T }).result);
        } catch (error) {
          tracker.reject(error as Error);
        }

        websocket.close();
      };
    } catch (error) {
      tracker.reject(error as Error);
    }
  });
}

export async function getMetadataViaWs (endpoint: string): Promise<HexString> {
  return getWsData<HexString>(endpoint, 'state_getMetadata');
}

export async function getRpcMethodsViaWs (endpoint: string): Promise<string[]> {
  const result = await getWsData<{ methods: string[] }>(endpoint, 'rpc_methods');

  return result.methods;
}

export async function getRuntimeVersionViaWs (endpoint: string): Promise<[apiHash: string, apiVersion: number][]> {
  const result = await getWsData<{ apis: [string, number][] }>(endpoint, 'state_getRuntimeVersion');

  return result.apis;
}