MT4 manager JavaScript TypeScript grpc client from browser (Webpack)

MT4 manager JavaScript TypeScript grpc client from browser (Webpack)

API methods browser

MT4 manager proto file

You need npm be installed

You need npx be installed

npm install -g npx

You need tsc be installed

npm install typescript --save-dev

You need protoc tool be installed

Install protoc plugins

npm install -g protoc-gen-js
npm install -g protoc-gen-grpc-web

You can find ready to run example here

Run example steps:
Step 1. Generate client files. JS and TS files generation by mt4mng.proto. Create grpc folder before runnig the script.

protoc proto/*.proto --js_out=import_style=commonjs,binary:./grpc --grpc-web_out=import_style=typescript,mode=grpcwebtext:./grpc

where ./grpc is a output folder
This script generates client's files to the "grpc" folder.

Step 2. Insert your ceredentials in the example

Step 3. Install all dependencies

npm install

Step 4. Compile typescript to js files.

tsc -p .

This script generates client.js file from client.ts file.

Step 5. Bild browser bundle.

npx webpack ./client.js

This script creates main.js file in the dist folder. This file could be consumed by a browser.

Step 6. Create a developer http server. Which would provide bundle files to a browser, by GET request.
For the purpose of prototype demonstration, I would like to recommend using lightweigt developer http server.

npm install --global http-server

Step 7. Finally, you can run a developer server

http-server

Step 8. Check how it works.

Full example:

import {MainControllerClient} from "./grpc/proto/Mt4mngServiceClientPb";
import {AccountDetailsRequest, AccountsRequest, ConnectRequest} from "./grpc/proto/mt4mng_pb";

const host : string = ``;
const port : number = 443;
const userId : number = 1;
const password: string = `password`;

const sessionId = generateUUID();

const serverAddress = 'https://mng4grpcweb.mtapi.io:443';
console.log(`Server:${serverAddress}`)
console.log(`Session id: ${sessionId}`)

const mainControllerClient = new MainControllerClient(serverAddress);

DoTheDemo().then(() => {
    console.log(`Demo is completed!`)
});

async function GetAccountData(clientConnectionId: string, accountId: number) {
    let accountDetailsRequest = new AccountDetailsRequest();
    accountDetailsRequest.setId(clientConnectionId);
    accountDetailsRequest.setLogin(accountId);
    await mainControllerClient.accountDetails(accountDetailsRequest, {"mt4-sticky-session-header": sessionId})
        .then(accountDetailsReply => {
            if (accountDetailsReply?.getError())
                console.error(`AccountDetails. Internal server error: ${accountDetailsReply?.getError()?.getMessage()}`);
            else {
                console.log(`AccountDetails. Successful response`);
                console.log(`Account ID: ${accountId}`);
                console.log(`Account Name: ${accountDetailsReply?.getResult()?.getName()}`);
                console.log(`Account Credit: ${accountDetailsReply?.getResult()?.getCredit()}`);
                console.log(`Account Balance: ${accountDetailsReply?.getResult()?.getBalance()}`);
                console.log(`Account Status: ${accountDetailsReply?.getResult()?.getStatus()}`);
            }
        })
        .catch(error => {
            console.error(`RPC mainControllerClient.accountDetails() error message: ${error.message}`);
        })
}

async function GetAccountsList(clientConnectionId: string) : Promise<number[] | undefined> {
    let result : number[] | undefined;
    let accountsRequest = new AccountsRequest();
    accountsRequest.setId(clientConnectionId);
    await mainControllerClient.accountsList(accountsRequest, {"mt4-sticky-session-header" : sessionId})
        .then(accountsReply => {
            if (accountsReply.getError())
            {
                console.error(`mainControllerClient.accountsList(). Internal server error: ${accountsReply?.getError()?.getMessage()}`);
            }
            else
            {
                console.log(`Successful getting accounts`);
                let accountsIds = accountsReply.getResultList();
                if (accountsIds)
                    result = accountsIds;
            }
        })
    return result;
}

function generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        let r = Math.random() * 16 | 0,
            v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

async function Connect(): Promise<string | undefined> {
    let result: string | undefined;
    let connectRequest = new ConnectRequest();
    connectRequest.setUser(userId);
    connectRequest.setServer(`${host}:${port}`);
    connectRequest.setPassword(password);
    await mainControllerClient.connect(connectRequest, {"mt4-sticky-session-header" : sessionId})
        .then(connectReply => {
            if (connectReply.getError())
            {
                console.error(`mainControllerClient.connect(). Internal server error: ${connectReply?.getError()?.getMessage()}`);
            }
            else
            {
                let clientConnectionId = connectReply.getResult();
                if (clientConnectionId)
                {
                    console.log(`Successful connected`);
                    console.log(`Connection client id: ${clientConnectionId}`);
                    result = connectReply.getResult();
                }

            }
        })
        .catch(error => {
            console.error(`RPC mainControllerClient.connect() error message: ${error.message}`);
        })
    return result;
}
async function DoTheDemo() {
    const clientConnectionId = await Connect();

    console.log(`Connection method is completed`);
    if (clientConnectionId != undefined)
    {
        console.log(`Getting accounts list is next`);
        const accountsIds = await GetAccountsList(clientConnectionId);
        console.log(`Account ids: ${accountsIds}`);
        if (accountsIds != undefined)
        {
            console.log(`Getting accounts data for the first 10 accounts`)
            const accountDataPromises =
                accountsIds.slice(0,10).map(accountId => GetAccountData(clientConnectionId, accountId));
            await Promise.all(accountDataPromises);
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *