@tria-sdk/authenticate-web

The Tria Authentication SDK provides a simple way to integrate authentication into your web applications. It includes features such as login, account management, and interacting with smart contracts

Tria Authentication SDK

Installation

You can install the SDK using npm or yarn:

npm install @tria-sdk/authenticate-web
yarn add @tria-sdk/authenticate-web

Usage

Importing the AuthManager

First, import the AuthManager class from the SDK:

import { AuthManager } from '@tria-sdk/authenticate-web';

Initializing the AuthManager

Create an instance of the AuthManager with the required options:

const authManager = new AuthManager({
  analyticsKey: {
   clientId : "string",
   projectId : "string"
  } 
  // Required: Provided by Tria
});

the analytics key object is to be provided by tria. please request for your client id and project id from us.

Configuring the AuthManager

Configuration Options

Configuration options are blockchain related configurations. Sepolia is set as the default chain and the minimum required option is the chain.

The TriaConfigOptions interface allows you to configure the following properties:

  • chain [string]: The blockchain network (e.g., 'MUMBAI', 'POLYGON').

  • environment [string]: The environment ('testnet' or 'mainnet').

  • dappDetails [object]: An object containing your Dapp's domain and logo.

  • aa [object]: Optional Anti-Addiction details.

  • rpcUrl [string]: Optional RPC URL for the blockchain network.

  • supportedChains [string array]: An array of strings containing the supported chains

   authManager.configure({
     chain: "SEPOLIA", // required
     environment: "mainnet",
     aa?: {
        supportAa: false;
        pimlicoApiKey?: abcabc;
        isSponsored?: false;
        sponsorshipPolicyId?: abcabc;
        sponsorshipPolicyIds?: mumbai;
     },
     rpcUrl: "https://my-rpc-url.com/",
     dappDetails:{
        dappDomain?: https://localhost:3000/;
        dappLogo?: https://something;
     }
   });

UI Configuration Options [Login component]

These are the configuration options to customize the Login components UI. Ability to hide and display parts of the UI as well as change the text on certain parts of the login flow and the buttons as well.

// object types
interface UIConfig {
  dappName?: string; 
  showLogo?: boolean;
  logoText?: string;
  logoUrl?: string;
  showPoweredByTria?: boolean;
  googleButtonText?: string;
  twitterButtonText?: string;
  appleButtonText?: string;
  phoneOtpButtonText?: string;
  allowExternalWallets?: boolean;
  showDivider?: boolean;
  showHeadingPill?: boolean;
  signupHeadingText?: string;
  signupSubHeadingText?: string;
  signupRetryInfoText?: string;
  signupRetryText?: string;
  usernameHeadingText?: string;
  usernameSubHeadingText?: string;
  otpBgColor?: string;
  otpTextColor?: string;
  otpBoxBgColor?: string;
  darkIcons?: boolean;
}

// usage
authManager.configureAuthUI({
  darkMode: false,
  allowExternalWallets: true,
  showDivider: true,
  showLogo: true,
  showPoweredByTria: true,
  otpBgColor: "#ffffff",
  otpTextColor: "#000000",
  otpBoxBgColor: "#e5e5e5",
  darkIcons: true,
});

Customizing the styles for the Login component

The css variables for the login component can be updated with the setAuthUIStyling method. An example is provided below along with the variables that can be changed and the default values that are currently set

--primary-color: #7d40ff;

--bg-color-primary: #101010;
--bg-color-tertiary: #ffffff;

--text-color-primary: #ffffff;
--text-color-secondary: #d1d5db;
--text-color-tertiary: #000000;
--text-extra-small: 12px;
--text-small: 14px;
--text-base: 16px;
--text-large: 20px;

--button-bg-email: #171717;
--button-bg-email-hover: #121212;
--button-bg-twitter: #262626;
--button-bg-twitter-hover: #1f1f1f;
--button-bg-google: #3b82f6;
--button-bg-google-hover: #2371ef;
--button-bg-apple: #171717;
--button-bg-apple-hover: #121212;
--button-bg-tertiary: #ffffff;

--info-pill-bg: rgba(190, 24, 93, 0.1);
--info-pill-text-color: rgba(244, 63, 94, 0.9);
--info-pill-padding-left: 6px;
--info-pill-padding-right: 6px;
--info-pill-padding-top: 2px;
--info-pill-padding-bottom: 2px;

--pill-bg: #262626;
--pill-border-radius: 9999px;
--pill-padding-left: 16px;
--pill-padding-right: 16px;
--pill-padding-top: 4px;
--pill-padding-bottom: 4px;

--toggle-bg: #262626;

--input-bg-primary: #262626;
--input-border-radius: 9999px;
--input-padding-left: 16px;
--input-padding-right: 16px;
--input-padding-top: 6px;
--input-padding-bottom: 6px;

--header-font-size: 16px;
--sub-header-font-size: 16px;

--modal-width: 448px;
--modal-height: 840px;
--modal-scale-sm: 0.6;
--modal-scale: 0.7;
--modal-scale-md: 0.8;
--modal-scale-lg: 0.9;
--modal-scale-xl: 1;
--modal-scale-2xl: 1.1;

--border-size-primary: 1px;
--border-radius-primary: 16px;
--border-color-primary: rgba(167, 139, 250, 0.3);

--padding-primary: 16px;

--button-border-radius: 12px;
--button-height: 100%;
--button-width: 100%;
--button-padding: 12px;

--button-submit-bg: #ffffff;
--button-submit-border-radius: 9999px;
--button-submit-height: auto;
--button-submit-width: 6rem;
--button-submit-padding: 0px;

--phone-input-bg: #171717;
--phone-input-border-radius: 9999px;
--phone-input-padding-left: 88px;
--phone-input-padding-right: 16px;
--phone-input-padding-top: 6px;
--phone-input-padding-bottom: 6px;

--phone-input-code-bg: #262626;
--phone-input-code-border-radius-left: 9999px;
--phone-input-code-border-radius-right: 0px;

--country-dropdown-bg: #262626;
--country-dropdown-border-radius: 16px;
--country-dropdown-padding: 16px;
--country-dropdown-bg-hover: #171717;

--country-dropdown-search-bg: #171717;
--country-dropdown-search-border-radius: 8px;

--scrollbar-thumb-color: #888;
--scrollbar-track-color: #171717;
--scrollbar-thumb-color-hover: #555;

--divider-color: rgba(255, 255, 255, 0.1);


// white mode
authManager.setAuthUIStyling({
  "modal-height": "auto",
  "primary-color": "#7d40ff",

  "bg-color-primary": "#ffffff",
  "bg-color-tertiary": "#f5f5f5",

  "text-color-primary": "#000000",
  "text-color-secondary": "#000000",
  "text-color-tertiary": "#ffffff",

  "button-bg-email": "#f5f5f5",
});

Transactions UI Configuration Options [Approval popups]

These are the configuration options to customise the UI of the transaction popups, approval for signing message, sending transactions, minting NFTs approval and other relevant popups.

// object types

interface TransactionsUIConfig {
  darkMode?: boolean;
  primaryColor?: string;
  secondaryColor?: string;
  primaryFontColor?: string;
  secondaryFontColor?: string;
  backgroundGridColor?: string;
  buttonPrimaryColor?: string;
  buttonSecondaryColor?: string;
  buttonFontPrimaryColor?: string;
  buttonFontSecondaryColor?: string;
  borderColor?: string;
  balanceLabel?: string;
  feeLabel?: string;
  totalCostLabel?: string;
  sendLabel?: string;
  signLabel?: string;
  showUserCard?: boolean;
  approveButtonLabel?: string;
  rejectButtonLabel?: string;
}

// usage
authManager.configureTransactionsUI({ darkMode: false });

Wallet UI Configuration Options [Embedded Wallet]

These are the customisable properties for the embedded wallet. The wallet currently only has limited customization options. as of now switching between light mode and dark mode is possible and the primary color can be changed. This changes the glow color of the logo of the embedded wallet as well as the home page card background color when the wallet is open.

// object types
interface WalletUIConfig {
  darkMode: boolean;
  primaryColor: string;
}


// usage
authManager.configureWalletUI({
  darkMode: false,
  primaryColor: "#7D40FF",
});

Using AuthManager Methods

Login

To prompt the user to log in, call the login method:

const response = await authManager.login();

// console.log(response)
The response structure is shown below

interface LoginResponse {
  method: string; // login or signup
  success: boolean; // success or false
  platform: string; // google twitter etc
  name: string;
  loginId: string;
  sessionToken?: string; // session token will be provided only on signups
  account?: Account | null;
}

interface Account = {
  triaName: string | null;
  evm: {
    address: string;
  };
  nonEvm: [
    {
      chainName: string;
      address: string;
    }
  ];
  aa: {
    address: string;
  };
};

Validating the Session token

The session token is a unique token provided so that clients can verify the logged in user. this is unique to each user and generated on the backend. Upon login or signup a session token is returned from the login method so that the authenticated user can be validated. This token is short lived.

try {
  const data = {
   triaName : "myTriaName",
   code : "mySessionToken"
  }
  const response = await fetch("https://dev.tria.so/api/v1/auth/code/verify", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(data),
  });

  const result = await response.json();
  console.log("Success:", result);
} catch (error) {
  console.error("Error:", error);
}

// result data type on success
const result = {
    "isAuthenticate": true,
    "uuid": "4bdd1c63-f6a9-4363-88bf-b10d7e7ca14a",
    "triaName": "paroxi3187@tria"
}

// result data type on failure
const result = {
    "isAuthenticate": false,
}

Logout

To log the user out, call the disconnect method:

await authManager.disconnect();

Get Account

To get the user's account information, call the getAccount method:

const account = authManager.getAccount();

This method returns an Account object with the following properties:

  • triaName: The user's Tria username.

  • evm: An object containing the user's EVM-compatible address.

  • nonEvm: An object containing the user's non-EVM-compatible address.

Check Authentication Status

To check if the user is authenticated, call the isAuthenticated method:

const isAuthenticated = authManager.isAuthenticated();

This method returns a boolean indicating whether the user is logged in.

Send Transaction

To send a transaction, call the send method with the amount, recipient address, and optional token address:

await authManager.send(amount, recipientAddress, tokenAddress);

Sign Message

To sign a message, call the signMessage method with the message:

const signature = await authManager.signMessage(message);

Write Contract

To write to a smart contract, call the writeContract method with the contract details and optional payment token:

await authManager.writeContract(contractDetails, payToken);

Read Contract

To read from a smart contract, call the readContract method with the contract details:

const result = await authManager.readContract(contractDetails);

Send NFT

To send an NFT, call the sendNft method with the recipient's Tria name and NFT details:

await authManager.sendNft(recipientTriaName, nftDetails);

Approve

To approve a spender to spend an amount of user's erc20 token:

await approve(calldata: ApproveParams);

Check Token Allowance

To check allowance of a erc20 token for spender:

await checkTokenAllowance(calldata: CheckTokenAllowanceParams);

Broadcast Transaction

To broadcast a txnObject to a chain:

await broadcastTransaction(calldata: BroadcastTxnParams);

Get Bridge Quote (Refer connect sdk section for types)

To get a quote for a bridge txn and use the allowanceTarget and allowanceValue to check for allowance and approve the token:

await getBridgeQuote(calldata: BridgeParams);

Create a Bridge Transaction

To create a txn object for the bridge transaction:

await createBridgeTxn(calldata: BridgeParams);

Cancel Bridge Txn

To cancel a transaction using the orderId returned in the quote and create txn responses:

await cancelBridgeTxn(calldata: CancelBridgeTxnParams);

📝 Refer the connect sdk actions here for types and responses.

Event Listeners

You can listen to login and logout events by adding event listeners:

authManager.addEventListener('TRIA_LOGIN', (event) => {
  // Handle login event
});

authManager.addEventListener('TRIA_LOGOUT', (event) => {
  // Handle logout event
});

Removing Event Listeners

To remove an event listener, use the removeEventListener method:

authManager.removeEventListener('TRIA_LOGIN', loginHandler);
authManager.removeEventListener('TRIA_LOGOUT', logoutHandler);

Example

Here's an example of how you might use the Tria Authentication SDK in a web application:

import { AuthManager } from '@tria-sdk/authenticate-web';

const authManager = new AuthManager({
  metaToken: 'your-meta-token',
});

// Prompt user to log in
const response = await authManager.login();

// Check if user is logged in
if (authManager.isAuthenticated()) {
  console.log('User is logged in');
} 

CDN Usage

If you dont use npm as a package manager and want to simply use our cdn link to the package to use it on a static html page then follow the instructions below.

The cdn link for the package is as follows. It would be appropriate to use specific versions instead of @latest so as to keep breaking changes to a minimal if any. The package must be used inside a script tag declared as a module type. Please follow the provided example below. Examples for basic methods are provided. Further configurations are mentioned in the usage section of this document along with types, methods and parameters for the methods.

https://unpkg.com/@tria-sdk/authenticate-web@1.0.3/dist/index.es.js
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
    
    <script type="module">
      // step 1 - declare the script as a module
      // step 2 - import the auth manager class from the cdn package
      import { AuthManager } from "https://unpkg.com/@tria-sdk/authenticate-web@1.0.5/dist/index.es.js";
     
      // step 3 - initialise the auth manager class with your credentials
      const authManager = new AuthManager({
        analyticsKeys: {
          clientId: "abc123",
          projectId: "abc123",
        },
      });
      
      // step 4 - configure chain related settings
      authManager.configure({
        chain: "SEPOLIA",
        environment: "testnet",
        triaStaging: false,
        // optional AA parameters
        aa: { 
          pimlicoApiKey: "af86d1ab-0dc4-4be7-96eb-ce9fc9fd48c0",
          isSponsored: true,
          sponsorshipPolicyIds: {
            FUSE: "sp_cheerful_thing",
            POLYGON: "sp_slim_namor",
          },
          accountType: "Etherspot",
        },
      });
      
      // step 4 - configure UI if needed
      authManager.configureAuthUI({
        darkMode: true,
        allowExternalWallets: true,
      });
      
      // optional: configure UI on transaction pages
      authManager.configureTransactionsUI({ darkMode: false });

      // optional: configure UI for wallet
      authManager.configureWalletUI({
        darkMode: true,
        primaryColor: "#7D40FF", // glow color
      });


      // Login function
      function login() {
        authManager.login().then((result) => {
          console.log("Login:", result);
        });
      }

      // Disconnect function
      function disconnect() {
        authManager.disconnect();
      }

      // Sign message function
      function signMessage() {
        const message = document.getElementById("sign-input").value;
        authManager.signMessage(message).then((result) => {
          console.log("Signed message:", result);
        });
      }

      // Get account function
      function getAccount() {
        const account = authManager.getAccount();
        console.log("Account:", account);
      }

      // Send transaction function
      function sendTransaction() {
        const amount = 0.000001;
        const recipientAddress = "0x59f7843B267E79ea51B687a04Ef497bA240E7B26";
        authManager.send(amount, recipientAddress).then((result) => {
          console.log("Transaction sent:", result);
        });
      }

      // Write contract function
      function writeContract() {
        const contractDetails = {
          contractAddress: "0xFfC6F3186985e963821D3E30Cdb2ec4c0bE110e5",
          abi: [
            {
              inputs: [
                { internalType: "uint256", name: "_tokenId", type: "uint256" },
                { internalType: "uint256", name: "_amount", type: "uint256" },
                { internalType: "address", name: "_claimer", type: "address" },
              ],
              name: "airdropCoupon",
              outputs: [],
              stateMutability: "nonpayable",
              type: "function",
            },
          ],
          functionName: "airdropCoupon",
          args: [
            1,
            1,
            JSON.parse(localStorage.getItem("tria.wallet.store"))?.aa?.address,
          ],
        };
        authManager.writeContract(contractDetails).then((result) => {
          console.log("Contract written:", result);
        });
      }

      // read contract function
      function readContract() {
        const contractDetails = {
          contractAddress: "0xFfC6F3186985e963821D3E30Cdb2ec4c0bE110e5",
          abi: [
            {
              inputs: [
                { internalType: "uint256", name: "tokenId", type: "uint256" },
              ],
              name: "uri",
              outputs: [{ internalType: "string", name: "", type: "string" }],
              stateMutability: "view",
              type: "function",
            },
          ],
          functionName: "uri",
          args: ["1"],
        };
        authManager.readContract(contractDetails).then((result) => {
          console.log("Contract read:", result);
        });
      }

      // Add event listeners
      document.addEventListener("DOMContentLoaded", () => {
        document
          .getElementById("login-button")
          .addEventListener("click", login);
        document
          .getElementById("disconnect-button")
          .addEventListener("click", disconnect);
        document
          .getElementById("sign-button")
          .addEventListener("click", signMessage);
        document
          .getElementById("acc-button")
          .addEventListener("click", getAccount);
        document
          .getElementById("send-button")
          .addEventListener("click", sendTransaction);
        document
          .getElementById("write-button")
          .addEventListener("click", writeContract);
        document
          .getElementById("read-button")
          .addEventListener("click", readContract);
 
        // events are available for both log out and log in functions
        authManager.addEventListener("TRIA_LOGOUT", (event) => {
          console.log("TRIA_LOGOUT event received:", event.detail);
        });
      });
    </script>
    <style>
      body {
        background: #f5f5f5;
        font-family: "Arial", sans-serif;
        height: 100vh;
        display: flex;
      }
      .container {
        margin-top: auto;
        margin-bottom: auto;
        max-width: 500px;
        margin: auto;
        background: white;
        padding: 20px;
        border-radius: 10px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      }
      .title {
        color: #333;
        text-align: center;
        margin-bottom: 20px;
      }
      .input-group {
        margin-bottom: 20px;
      }
      input[type="text"] {
        width: calc(100% - 24px);
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
        font-size: 16px;
        margin: 10px;
      }
      button {
        width: 100%;
        padding: 10px;
        border: none;
        background: #2196f3;
        color: white;
        font-size: 16px;
        border-radius: 5px;
        cursor: pointer;
        transition: background 0.3s;
        margin: 10px;
      }
      button:hover {
        background: #1976d2;
      }
      .footer {
        text-align: center;
        margin-top: 20px;
        color: #777;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <button id="login-button">Login</button>
      <button id="custom-google-login">Google</button>
      <button id="disconnect-button">Disconnect</button>
      <input id="sign-input" type="text" placeholder="Message to sign" />
      <button id="sign-button">Sign message</button>
      <button id="acc-button">Get account</button>
      <button id="send-button">Send transaction</button>
      <button id="write-button">Write contract</button>
      <button id="read-button">Read contract</button>
    </div>
  </body>
</html>

NuxtJS setup

If your NuxtJS is old (older than nuxt 3) and does not handle optional chaining parameters or nullish coalescing oeprators

npm install @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-optional-chaining

create a file in your plugins folder named auth-manager.js

import { AuthManager } from "@tria-sdk/authenticate-web";

export default ({ app }, inject) => {
  // Initialize the AuthManager
  const authManager = new AuthManager({
    analyticsKey : {
      clientId: "string",
      projectId: "string"
    }
  });

// configure web 3 settings
authManager.configure({
 chain: "MUMBAI",
 environment: "mainnet",
});

  // Inject the authManager into the app
  inject("authManager", authManager);
};

update your nuxt config

plugins: [{ src: "~/plugins/auth-manager.js", mode: "client" }],

  build: {
    babel: {
      plugins: [
        "@babel/plugin-proposal-nullish-coalescing-operator",
        "@babel/plugin-proposal-optional-chaining",
      ],
    },
    transpile: ["@tria-sdk/authenticate-web"],
  },

Example NuxtJS component as below. the auth manager should now be usable across your app

<template>
  <div class="login-container">
    <button v-if="!isLoggedIn" @click="login" class="login-btn">Login</button>
    <div v-else class="actions-container">
      <div class="action">
        <input
          v-model="message"
          type="text"
          placeholder="Enter a message to sign"
          class="input"
        />
        <button @click="signMessage" class="action-btn">Sign Message</button>
      </div>
      <div class="action">
        <input
          v-model.number="amount"
          type="number"
          placeholder="Enter amount to send"
          class="input"
        />
        <input
          v-model="recipientAddress"
          type="text"
          placeholder="Enter recipient address"
          class="input"
        />
        <button @click="sendTransaction" class="action-btn">
          Send Transaction
        </button>
      </div>
      <div class="action">
        <button @click="writeContract" class="action-btn">
          Write Contract
        </button>
        <button @click="readContract" class="action-btn">Read Contract</button>
      </div>
      <div class="action">
        <button @click="disconnect" class="action-btn">Disconnect</button>
      </div>
      <div class="action">
        <button @click="getAccountInfo" class="action-btn">Get Account</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isLoggedIn: false,
      message: "",
      amount: 0,
      recipientAddress: "",
      account: null,
    };
  },
  mounted() {
    this.checkLoginStatus();
    this.getAccountInfo();
    this.logoutListen();
    this.loginListen();
  },
  methods: {
    checkLoginStatus() {
      console.log("login status", this.$authManager.getAccount());
      if (this.$authManager.getAccount()) {
        console.log("login state", this.$authManager.isLoggedIn);

        this.isLoggedIn = true;
      } else {
        this.isLoggedIn = false;
      }
    },
    login() {
      this.$authManager.login();
    },
    loginListen() {
      this.$authManager.addEventListener("TRIA_LOGIN", () => {
        console.log("setting login state");
        this.isLoggedIn = true;
      });
    },
    logoutListen() {
      this.$authManager.addEventListener("TRIA_LOGOUT", () => {
        this.isLoggedIn = false;
      });
    },
    async disconnect() {
      await this.$authManager.disconnect();
      this.isLoggedIn = false;
    },
    async signMessage() {
      if (this.message) {
        const result = await this.$authManager.signMessage(this.message);
        console.log("Signed message:", result);
      }
    },
    async sendTransaction() {
      if (this.amount && this.recipientAddress) {
        const result = await this.$authManager.send(
          this.amount,
          this.recipientAddress
        );
        console.log("Transaction sent:", result);
      }
    },
    async writeContract() {
      const contractDetails = {
        contractAddress: "0x9f5033463b31D213462Ce03A81610364aa80Ba14",
        abi: [
          {
            inputs: [
              { internalType: "uint256", name: "_tokenId", type: "uint256" },
              { internalType: "uint256", name: "_amount", type: "uint256" },
              { internalType: "address", name: "_claimer", type: "address" },
            ],
            name: "airdropCoupon",
            outputs: [],
            stateMutability: "nonpayable",
            type: "function",
          },
        ],
        functionName: "airdropCoupon",
        args: [2, 1, "0xCA679c7e0a1E88C950F71A57dd457A39872DE640"],
      };
      const result = await this.$authManager.writeContract(contractDetails);
      console.log("Contract written:", result);
    },
    async readContract() {
      const contractDetails = {
        contractAddress: "0x9f5033463b31D213462Ce03A81610364aa80Ba14",
        abi: [
          {
            inputs: [
              { internalType: "uint256", name: "tokenId", type: "uint256" },
            ],
            name: "uri",
            outputs: [{ internalType: "string", name: "", type: "string" }],
            stateMutability: "view",
            type: "function",
          },
        ],
        functionName: "uri",
        args: [
          "0xd3b267e459b2dd2d06cad080b75e12cf0ecf35807bb0719ce28f5dd9ae1516cc",
        ],
      };
      const result = await this.$authManager.readContract(contractDetails);
      console.log("Contract read:", result);
    },
    getAccountInfo() {
      this.account = this.$authManager.getAccount();
      console.log("Account:", this.account);
    },
  },
};
</script>

<style scoped>
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f5f5f5;
}

.login-btn {
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
}

.actions-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.action {
  margin-bottom: 20px;
}

.input {
  margin-right: 10px;
  padding: 10px;
  font-size: 14px;
}

.action-btn {
  padding: 10px 20px;
  font-size: 14px;
  cursor: pointer;
}
</style>

Last updated