liquid-tap
    TypeScript icon, indicating that this package has built-in type declarations

    0.3.6 • Public • Published

    LiquidTap Javascript Client

    To manage API tokens, refer to: https://app.liquid.com/settings/api-tokens

    To learn more about Liquid Api token management, see the help links below: https://help.liquid.com/connect-to-liquid-via-api

    Links

    Events Authentication [Troubleshooting] (#troubleshooting) [Contributing] (#contributing)

    Quick Start

    Install via npm or yarn:

    npm install liquid-tap
    yarn add liquid-tap
    

    OR Include the library:

    <script src="../dist/liquid-tap.js"></script>
    import { TapClient } from "liquid-tap";
    
    const tap = new TapClient();
    const public_channel = tap.subscribe("product_cash_btcsgd_7");
    public_channel.bind("updated", function(data) {
      console.log("product_cash_btcsgd_7 has been updated", data);
    });

    Events

    Event Payload Description
    connected { reconnect: boolean } Fires on successful connection. Contains a boolean indicating whether this was an automatic reconnection.
    disconnected n/a Fires on disconnect.
    unavailable n/a Fires when a connection is unavailable for any reason.
    tick_received { event: string, data: any, channel?: string } Fires on every websocket event. Contains the entire websocket payload.
    authenticated n/a Fires when the websocket has successfully authenticated
    authentication_failed { message: string, attempts: number } Fires when authentication has failed. Contains a message from the server and the number of authentication attempts.
    authentication_aborted { attempts: number } Fires when the maximum number of automatic authentication retries is reached. Contains the number of attempts.

    Binding to events

    Callbacks

    import { TapClient }, { CLIENT_EVENTS } from 'liquid-js'
    
    var tap = new TapClient();
    tap.bind(CLIENT_EVENTS.CONNECTED, function () {
      console.log('Connected!');
    });
    tap.bind(CLIENT_EVENTS.AUTH_SUCCESS, function () {
      console.log('Authenticated!');
    });
    tap.bind(CLIENT_EVENTS.AUTH_FAILURE, function () {
      console.log('Authentication Failed!');
    });

    Promises

    var tap = new TapClient();
    tap.bind(CLIENT_EVENTS.CONNECTED).then(() => {
      console.log("Connected!");
    });
    tap.bind(CLIENT_EVENTS.AUTH_SUCCESS).then(() => {
      console.log("Authenticated!");
    });
    tap.bind(CLIENT_EVENTS.AUTH_FAILURE).then(() => {
      console.log("Authentication Failed!");
    });

    Options

    Key Type Default Description
    wsHost string 'tap.liquid.com' Tap WS host to connect to.
    wsPort number 433 Port to connect to.
    wssPort number 433 SSL Port to connect to.
    useTls boolean true Should connect using SSL.
    auth AuthType (see below) null Authentication information. See below.
    appId string 'LiquidTapClient' Arbitrary name to use in the WS url.
    authenticationTimeout number (ms) 5000 Timeout to assume authentication has failed. (Note a auth_failed event is expected)
    authRetryDelay number (ms) 200 Time to wait before retrying authentication.
    authRetryMaxAttempts number 3 Maximum number of authentication retries.

    Authentication

    To subscribe to protected channels, the client must provide a token_id and token_secret which has permission to view those channels. The library will attempt to authenticate three times by default.

    Authenticate Sequence

    Before Initialization

    var tap = new TapClient({
      auth: { tokenId: token_id, toeknSecret: token_secret }
    });
    // Refer to profile page for user_id: https://app.liquid.com/settings/profile
    var protected_channel = tap.subscribe("user_<user_id>");
    protected_channel.bind("updated", function(data) {
      console.log("sensitive user data has been updated", data);
    });

    After Initialization

    The library allows the LiquidTap client to be created and subscribe to public channels, then when a protected channel is required the client can authenticate.

    var tap = new TapClient();
    
    var public_channel = tap.subscribe("product_cash_btcsgd_7");
    public_channel.bind("updated", function(data) {
      console.log("product_cash_btcsgd_7 has been updated", data);
    });
    
    tap.authenticate({ tokenId: token_id, tokenSecret: token_secret });
    var protected_channel = tap.subscribe("user_<user_id>");
    protected_channel.bind("updated", function(data) {
      console.log("sensitive user data has been updated", data);
    });

    Authentication Input

    The authentication can be done either by providing an API token ID and secret, JWT token, or callback.

    Token ID and Secret

    var tap = new TapClient({
      auth: { tokenId: token_id, tokenSecret: token_secret }
    });
    var tap = new TapClient();
    tap.authenticate({ tokenId: token_id, tokenSecret: token_secret });

    Signed JWT

    var tap = new TapClient({ auth: signed_jwt });
    var tap = new TapClient();
    tap.authenticate(signed_jwt);

    Callback (return string)

    var tap = new TapClient({
      auth: ({ path }) => jwt.encode({token_id: my_token_id, path: path}, my_secret)
    });

    Callback (return Promise)

    The authentication process inside TapClient will wait for the promise to resolve before authenticating.

    const createJwtWhenReady = ({ path }) => {
      return new Promise<string>(
        (resolve) => {
            setTimeout(
              () => resolve(jwt.encode({token_id: my_token_id, path: path}, my_secret)), 
              some_wait_period
            )
        })
    }
    var tap = new TapClient({
      auth: createJwtWhenReady
    });

    TapClient will also wrap the promise to allow process order management

    var tap = new TapClient();
    const createJwtWhenReady = ({ path }) => {
      return new Promise<string>(
        (resolve) => {
            setTimeout(
              () => resolve(jwt.encode({token_id: my_token_id, path: path}, my_secret)), 
              some_wait_period
            )
        })
    }
    tap.authenticate({
      auth: createJwtWhenReady
    })
    .then(() => {
      // do something
    })
    .catch(() => {
      // some error in either generating the jwt, or the websocket request event
    })

    Callback (which takes another callback)

    var tap = new TapClient();
    
    // Create a service to manage nonce and JWT creation
    const createJwtWhenReady = ({ path }, callback) => {
        setTimeout(
          () => {
            nonce_counter += 1;
            // this callback will return a Promise that resolves when the auth request comes back, either success or failure
            await callback(jwt.encode({token_id: my_token_id, path: path, nonce: nonce_counter }, my_secret));
          }, some_wait_period
        )
    }
    
    tap.authenticate({
      auth: createJwtWhenReady
    })
    .then(() => {
      // will be called after the resolver for the above JWT creator
    })
    .catch(() => {
      // log error
    })

    Troubleshooting

    Open the chrome dev tools and inspect the network traffic as shown in the image below: inspecting websocket frames

    Contributing

    Setup

    npm install
    

    Development

    npm run build:dev
    npm run sample
    

    Testing

    npm test
    

    Ensure changes are also thoroughly tested with the real world server responses.

    Building

    npm run build
    

    Ensure to commit compiled assets in dist.

    Install

    npm i liquid-tap

    DownloadsWeekly Downloads

    140

    Version

    0.3.6

    License

    MIT

    Unpacked Size

    172 kB

    Total Files

    53

    Last publish

    Collaborators

    • jeredmasters
    • dfcowell
    • quoine-front-end