WebSocket Quickstart

WebSocket 서비스 안내

WebSocket이란 무엇인가요?

WebSocket이란 실시간 양방향 통신을 지원하는 프로토콜 입니다. WebSocket은 이벤트가 발생할 때 해당 이벤트에 대한 정보를 HTTP 요청으로 전달하는 Webhook과 달리 지속적으로 네트워크와 연결을 유지하고 있어 실시간으로 변경하는 데이터를 주고 받을 때 유리합니다. 개발자가 모니터링 하고자 하는 온체인 이벤트를 정의한 뒤 이를 WebSocket으로 등록하면, 해당 조건에 맞는 이벤트를 실시간으로 전달받을 수 있습니다. 조건을 세분화 한 여러 WebSocket을 등록할 수 있으며, 이를 활용하여 DApp 구현시 실시간 반응형 UI 또는 사용자 알림 기능을 구현할 수 있습니다.


Usecases

다음은 루니버스 WebSocket을 활용한 몇가지 어플리케이션 구현 시나리오 예제입니다. WebSocket에서 구독 가능한 데이터를 확인하고 더 많은 활용 방법을 찾아보세요.

  • 사용자가 자신의 지갑 주소가 포함된 트랜잭션이 발생할 때 마다 실시간으로 확인할 수 있습니다.
  • 사용자 지갑의 잔고가 일정 수치 이하로 떨어지면 알림을 받아 사용자에게 토큰 구매를 요청할 수 있습니다.
  • 사용자의 지갑 주소 또는 특정 컨트랙트 주소에 이벤트(자산 전송, 트랜잭션 전송 등) 발생시 사용자에게 알람을 전송하거나 적절한 후처리 액션을 수행할 수 있습니다.
  • 블록이 생성될 때마다 알림을 받음으로서 특정 네트워크 환경이 안정적으로 동작하고 있는지 모니터링 할 수 있습니다.

WebSocket으로는 어떤 이벤트 및 데이터를 구독할 수 있나요?

루니버스 WebSocket으로 구독할 수 있는 이벤트 및 데이터에 대한 명세는 WebSocket Types페이지에서 확인하실 수 있습니다.


WebSocket 지원 체인

NetworkSupporting
Ethereum Mainnet:white-check-mark:
Ethereum Testnet (goerli):white-check-mark:
Ethereum Testnet (sepolia):white-check-mark:
Ethereum Testnet (holesky):white-check-mark:
Polygon Mainent:white-check-mark:
Polygon Testnet (mumbai):white-check-mark:
Arbitrum Mainnet:white-check-mark:
Arbitrum Testnet (goerli):white-check-mark:
Arbitrum Testnet (sepolia):white-check-mark:
Optimism Mainnet:white-check-mark:
Optimism Testnet (goerli):white-check-mark:
Optimism Testnet (sepolia):white-check-mark:

WebSocket 사용 방법

WebSocket 연결은 크게 아래 세 단계로 진행됩니다.

  1. WebSocket 연결 코드 구현하기
  2. Subscription Event 작성하기
  3. Event 수신 확인

1. WebSocket 연결 코드 구현하기

가장 먼저, WebSocket을 연결하기 위한 코드를 구현해야 합니다. 코드를 구현하기 위해서는 다음과 같은 작업이 선행되어야 합니다.

  1. Node.js 설치
    Node.js는 JavaScript 런타임으로 다양한 JS 애플리케이션을 실행할 수 있도록 지원합니다. 아래 링크를 클릭하여 Node.js를 설치할 수 있습니다.
  2. socket.io-client 설치
    socket.io-client는 클라이언트 측에서 사용되는 WebSocket 기반 실시간 통신을 위한 라이브러리입니다. 이를 이용하여 서버에 연결하여 실시간 데이터를 송수신하고 이벤트를 수신합니다. Node.js가 설치되어 있다면 터미널과 명령어를 이용하여 간편하게 설치할 수 있습니다. WebSocket을 구현할 Root Directory 경로의 터미널에 아래의 명령어를 입력합니다.
    npm install socket.io-client
    

  3. Luniverse Web3 Multichain Node 생성하기
    Luniverse는 유저가 다양한 블록체인 네트워크를 편리하게 이용할 수 있도록 Multichain Node를 지원하고 있습니다. Luniverse Console에 회원가입한 후, Multichain Node를 생성하면 이더리움, 폴리곤, 아비트럼 등 다양한 블록체인 네트워크를 이용할 수 있습니다. 아래 링크를 클릭하여 Luniverse Console 회원가입, Multichain Node 생성하는 방법을 쉽게 알아볼 수 있습니다.

WebSocket을 서버와 연결하기 위한 코드를 작성합니다. const options에 작성된 token과 nodeId는 Luniverse Web3 Multichain Node를 생성한 후, 확인할 수 있습니다.

import io from "socket.io-client";

 const url = "https://web3.luniverse.io/v1/websocket";
 const options = {
    rejectUnauthorized: false,
    transports: ["websocket", "polling"],
    path: "/v1/websocket/",
    auth: {
        token:
            "{Your Auth Token}",
    },
    query: {
        nodeId: "{Your Node ID}",
    },
};

 function connectToServer() {
    return new Promise((resolve, reject) => {
        const socket = io(url, options);

        socket.on("connect", () => {
            socket.on("subscription_registered", (message) => {
                console.log(message);
            });

            socket.on("subscription_connected", (message) => {
                console.log(message);

                socket.emit("subscription", messageId, eventType, JSON.stringify(params));
            });

            socket.on("subscription_error", (message) => {
                console.error(`nova_subscription_error: ${message}`);
            });

            socket.on("subscription_event", (message) => {
                console.log(message);
            });

            socket.on("disconnect", (message) => {
                console.warn(message);
            });

            resolve(socket);
        });

        socket.on("connect_error", (error) => {
            console.error(`Socket connection error to`, error);
            reject(error);
        });
    });
}

connectToServer();

2. Subscription Event 작성하기

앞서 작성한 코드에 구독할 이벤트에 대한 내용을 작성합니다. Luniverse Multichain WebSocket에서 지원하는 Event Type은 다음과 같습니다.

eventTypedescription
ADDRESS_ACTIVITY특정 주소가 from 또는 to에 포함된 트랜잭션에 대한 trace 변경사항 및 트랜잭션 발생을 알림으로 받을 수 있습니다.
MINED_TRANSACTION특정 주소가 from에 포함된 트랜잭션이 최종 채굴 완료되었을 때 트랜잭션 receipt 정보를 알림으로 받을 수 있습니다.
SUCCESSFUL_TRANSACTION특정 주소가 from에 포함된 트랜잭션의 상태가 성공적으로 처리되었을 때(receipt상 상태 코드가 0x1인 경우)알림을 받을 수 있습니다.
FAILED_TRANSACTION특정 주소가 from에 포함된 트랜잭션이 정상적으로 처리되지 못한 경우(receipt상 상태 코드가 0x0인 경우)알림을 받을 수 있습니다.
TOKEN_TRANSFER특정 ERC20 또는 ERC721 토큰의 Transfer 이벤트가 발생한 경우 알림을 받을 수 있습니다. 컨트랙트 주소를 지정할 수 있으며, ERC721 특정 토큰 ID로 조건을 설정할 수 있습니다.
BELOW_THRESHOLD_BALANCE지정한 계정의 잔고가 설정한 수치 이하로 떨어지면 알림을 받을 수 있습니다.
BLOCK_PERIOD네트워크 블록 생성 주기에 따라 알림을 받을 수 있습니다. 주기 값에 따라 매 블록 또는 N개의 블록 생성시마다 알림을 받도록 설정할 수 있습니다.
NEW_HEADS새로운 블록이 Head로 지정될 때마다 알림을 받습니다.
BLOCK_LIST_CALLER대상 주소와 여러 Blocklist 계정 주소를 등록한 뒤, 해당 Blocklist주소들로부터 대상 주소로 Native Token 또는 ERC20 토큰이 전송되었을 때 알림을 받을 수 있습니다.
ALLOW_LIST_CALLER대상 주소와 여러 Allowlist 계정 주소를 등록한 뒤, 해당 Allowlist주소들로부터 대상 주소로 Native Token 또는 ERC20 토큰이 전송되었을 때 알림을 받을 수 있습니다.
LOG지정한 스마트 컨트랙트에서 특정 Topic에 해당하는 이벤트 LOG가 발생하는 경우 알림을 받을 수 있습니다.

필요한 Event Type을 선택한 뒤 아래 코드와 같이 입력합니다. 예제에 사용된 Event Type은 BLOCK_PERIOD입니다.

 const messageId = {Your can set your messageId};
 const eventType = "BLOCK_PERIOD";
 const url = "https://web3.luniverse.io/v1/websocket";

 const params = {
    protocol: "ETHEREUM",
    network: "MAINNET",
    description: "ethereum mainnet block period 1",
    condition: {
      period: 1
    }
  };

3. Event 수신 확인

WebSocket 연결 코드와 Subscription Event에서 작성한 코드를 합친 코드는 다음과 같습니다.

import io from "socket.io-client";

 const messageId = "Test WebSocket";
 const eventType = "BLOCK_PERIOD";
 const url = "https://web3.luniverse.io/v1/websocket";

 const params = {
    protocol: "ETHEREUM",
    network: "MAINNET",
    description: "ethereum mainnet block period 1",
    condition: {
      period: 1
    }
  };

 const options = {
    rejectUnauthorized: false,
    transports: ["websocket", "polling"],
    path: "/v1/websocket/",
    auth: {
        token:
            "{Your Auth Token}",
    },
    query: {
        nodeId: "{Your Node ID}",
    },
};

 function connectToServer() {
    return new Promise((resolve, reject) => {
        const socket = io(url, options);

        socket.on("connect", () => {
            socket.on("subscription_registered", (message) => {
                console.log("registered" ,message);
            });

            socket.on("subscription_connected", (message) => {
                console.log("subscription_connected", message);

                socket.emit("subscription", messageId, eventType, JSON.stringify(params));
            });

            socket.on("subscription_error", (message) => {
                console.error(`nova_subscription_error: ${message}`);
            });

            socket.on("subscription_event", (message) => {
                console.log("subscription Event : ",message);
            });

            socket.on("disconnect", (message) => {
                console.warn(`disconnect`, message);
            });

            resolve(socket);
        });

        socket.on("connect_error", (error) => {
            console.error(`Socket connection error to : `, error);
            reject(error);
        });
    });
}

connectToServer();

위의 코드와 같이 작성되었다면 터미널과 Node.js를 이용하여 해당 파일을 실행합니다. node your_file_name.js를 입력하여 실행할 수 있습니다. 실행 후, 예제의 WebSocket이 이더리움 네트워크와 정상적으로 연결되었다면 블록이 생성될 때 마다 다음과 같이 이벤트를 수신받게 됩니다.

subscriptionId: 97139
subscription Event :  subscriptionId: 97139,
          eventType: "BLOCK_PERIOD",
          event: {
          	"period":1,
            "message":{
            	"number":17767702,
              "hash":"0x836c2ada70123019592fc52763757c87061935bbab2609d2dac1d0e9a93a6186",
              "parent_hash":"0xc8936f4c504b1640df7e1c920dbd1879a0906c7d44cf369d7f26b2939bfa2864",
              "nonce":"0x0000000000000000",
              "sha3_uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
              "logs_bloom":"0x1d374002c00c144a39093818900082b050884050220a14960209123380de5e80c4581182411812b173505850b0b5818112ad99b88dcf39abc651fc95d5ed2b04649070b87fa209ccbe23c02fc829b16c9c804020016e0c8b20805f42cc611800da80041507d304350971a2476d921a8db9934bcc290e0549d68d13f014082f062e3a92d03692002012d0704842a08800f9050d835910246c56aa4153a81134308ef82dc47101fec2601329e7f05414a2860c003f226d86ee8221276610108c5d89548da24018c10e261ca6422096378c0d7903076328129800d520868a11e846c1ffb1a904c68590034524c47c818c2480e137be5b1e44e268198af3b6023d89",
              "transactions_root":"0xed72506de019800931029aa7f4efdb255b9a6c2ebab2751afd98e3d2875e4159",
              "state_root":"0x35ee38917ecf6a96f9512690b4717002f233dd0dfe08f404097c0eff91f4aa20",
              "receipts_root":"0x59f4b1fc17aa8e408eec5377f4b37314333476229b350fe4b4549868ba8c7fdc",
              "miner":"0x1f9090aae28b8a3dceadf281b0f12828e676c326",
              "difficulty":0,
              "total_difficulty":5.875000371659836e+22,
              "size":58801,
              "extra_data":"0x7273796e632d6275696c6465722e78797a",
              "gas_limit":30000000,
              "gas_used":11663189,
              "timestamp":1690258955,
              "transaction_count":107,
              "base_fee_per_gas":17895212572
              }
           }

WebSocket을 이용하여 실시간으로 이벤트를 수신받을 수 있으며, 수신받은 이벤트를 다양하게 활용하여 필요한 기능을 구현할 수 있습니다. 예제로 확인한 BLOCK_PERIOD 외에도, Luniverse에서 제공하는 다양한 WebSocket용 이벤트도 확해 보세요!