Brahma Docs
Access Console
  • Brahma Overview
  • Brahma Accounts
    • Key benefits
    • Which Account Version Is Right for You?
    • Understanding the dashboard
    • Brahma
      • Onboarding to Brahma
      • In-App Features
        • Swapping
        • Bridging
        • Lending
      • Multichain
      • Transacting in Brahma
        • Transaction Builder
        • Smart Execution
      • Connecting to Onchain Applications
        • Brahma Connect
        • Wallet Connect
      • Portfolio Management
        • Unified History
        • Positions
    • Brahma Pro
      • Converting your account to Pro
      • Onboarding to Brahma Pro
      • In-App Features
        • Swapping
        • Bridging
        • Lending
      • Multichain
      • Transacting in Brahma pro
        • Transaction Builder
        • Smart Execution
      • Connecting to Onchain Applications
        • Brahma Connect
        • Wallet Connect
      • Portfolio Management
        • Unified History
        • Positions
      • Team Management & Access Control
        • Inviting Operator & Role Management
        • Sub-Accounts
        • Policies
          • Types of Policies
      • Custom Transaction Builder
    • Brahma | Strategies
      • Automations
        • TWAP | DCA Automation
        • Morpho Yield Optimizer
        • Infrared iBGT Automation
        • BGT Automation
        • Berabaddies AutoBGT
      • Templates
        • Morpho Earn
  • Brahma ConsoleKit
    • API Reference
  • Rewards
    • | Brahma Rewards
      • Karma & Levels | SNAPSHOTED
  • Brahma Agents | Built with Console kit
    • Surge & Purge Agent
    • 🦋Morpho Agent
  • FAQs
    • Brahma & Brahma Pro FAQs
    • Brahma Connect FAQs
  • Others
    • Security Audits
    • Pricing & Fees
    • Risks
      • Counterparty Risk
      • Other Risks
    • Error Codes
  • Change log
  • Github
  • Discord
  • Press Kit
  • Developer
    • Deployed Contracts: Console
    • Brahma Console Integration [for dApp developers]
Powered by GitBook
On this page
  • Signature support for smart contract wallets [Must have]
  • Packages
  • Additional Support for Brahma Connect [Ideal]
  • 1. Adding Browser/Injected Wallet Support in your dApp Connect Kit [Must Have]
  • 2. For dApps with signatures in their flow (e.g., auth signatures)
  1. Developer

Brahma Console Integration [for dApp developers]

An integration guide to ensure both general smart contract wallet support, as well as Brahma Connect support, an advanced dApp connection and execution workflow.

PreviousDeployed Contracts: Console

Last updated 1 month ago

Brahma Console dApp connection methods natively works with any dApp, unless there are signature schemes (such as auth signatures) in the user journey, which require extra attention.

The flagship connection method in Console is , which allows user to batch and chain multiple actions across dApps in a single transaction, loading them in a secure iFrame directly in Console thanks to simulating the state on a forked RPC. This method doesn't support the collection of signatures, and therefore it requires the dApp whitelisting Brahma Connect as a method to bypass it, see Additional Support for Brahma Connect [Ideal].

Wallet Connect is a backup connection method, which requires #id-1.-signature-support-for-smart-contract-wallets, as well as Wallet Connect as an available connection method in the dApp

Signature support for smart contract wallets [Must have]

As Consoles are Safe smart contract wallets, they do not support EIP-191 signatures, and even EIP-712 signatures are required to be transformed into a SafeMessage type to be compatible, which are then verified using EIP-1271 which is the smart contract signature verification standard. The digest generation & signing is handled by Console, but the integrating DApps must support EIP-1271 to verify these signatures

Below are some code snippets that can be used for the implementation. Alternatively, multiple npm packages make it easy for dApps to add support for EIP 1271.

Packages

​​​

​​​

Code Snippets for manual validation

Using viem
const viem = require("viem");
const chains = require("viem/chains");

const EIP_1271_MAGIC_VALUE = "0x1626ba7e";
const EIP_1271_ABI = [
  {
    constant: true,
    inputs: [
      {
        name: "_hash",
        type: "bytes32"
      },
      {
        name: "_sig",
        type: "bytes"
      }
    ],
    name: "isValidSignature",
    outputs: [
      {
        name: "magicValue",
        type: "bytes4"
      }
    ],
    payable: false,
    stateMutability: "view",
    type: "function"
  }
];

function parse(hex) {
  return decodeURIComponent("%" + hex.match(/.{1,2}/g).join("%"));
}

const validate1271Signature = async (signer, digest, signature) => {
  const publicClient = viem.createPublicClient({
    chain: chains["desired_chain"],
    transport: viem.http()
  });

  const parsedDigest = parse(digest);

  const magicValue = await publicClient.readContract({
    address: signer,
    abi: EIP_1271_ABI,
    functionName: "isValidSignature",
    args: [
      viem.keccak256(
        viem.encodePacked(
          ["string"],
          [
            "\\x19Ethereum Signed Message:\\n" +
              parsedDigest.length +
              parsedDigest
          ]
        )
      ),
      signature
    ]
  });

  return magicValue === EIP_1271_MAGIC_VALUE;
};

Using ether
const ethers = require("ethers");

const EIP_1271_MAGIC_VALUE = "0x1626ba7e";
const EIP_1271_ABI = [
  {
    constant: true,
    inputs: [
      {
        name: "_hash",
        type: "bytes32"
      },
      {
        name: "_sig",
        type: "bytes"
      }
    ],
    name: "isValidSignature",
    outputs: [
      {
        name: "magicValue",
        type: "bytes4"
      }
    ],
    payable: false,
    stateMutability: "view",
    type: "function"
  }
];

function parse(hex) {
  return decodeURIComponent("%" + hex.match(/.{1,2}/g).join("%"));
}

const validate1271Signature = async (signer, digest, signature) => {
  const provider = new ethers.providers.JsonRpcProvider("<rpc_url>");
  const verifyingContract = new ethers.Contract(signer, EIP_1271_ABI, provider);

  const parsedDigest = parse(digest);

  const magicValue = await verifyingContract.isValidSignature(
    ethers.utils.keccak256(
      ethers.utils.solidityPack(
        ["string"],
        ["\\x19Ethereum Signed Message:\\n" + parsedDigest.length + parsedDigest]
      )
    ),
    signature
  );

  return magicValue === EIP_1271_MAGIC_VALUE;
};

Additional Support for Brahma Connect [Ideal]

Brahma Connect is a new dApp connection mechanism which allows users to perform multiple sequential interactions on a single or multiple dApps in a single interaction and transaction.

For example: approving > swapping and then LPing in a separate protocol, all in 1 txn

Brahma Connect is powered by a suite of forked nodes that propagate the simulated state to dApps. dApps that support connect allow Brahma users to perform operations and strategy with the best possible UX and increase the dApp usage. More on the Brahma Connect UX here.

1. Adding Browser/Injected Wallet Support in your dApp Connect Kit [Must Have]

If you use Rainbox kit
If you are using web3-onboard by BlockNative
If you are using Web3Modal by WalletConne

Web3Modal supports injected wallets by default, but if your project is in custom configuration mode, injected wallet support can be added with a single line of code:

new InjectedConnector({ chains, options: { shimDisconnect: true } }),

2. For dApps with signatures in their flow (e.g., auth signatures)

Connect doesn’t support signatures, and therefore if a dApp has an authentication signature or similar signature steps, it needs to bypass the signature step for users connecting through Brahma Connect:

Detect if Brahma Connect is the connected wallet

const brahmaConnectUUID = 'f3c205d4-5785-4f34-b019-2472b4e03a7a';
const providers: EIP6963ProviderDetail[];

let isBrahmaConnectDetected;

function onPageLoad() {
  window.addEventListener(
    "eip6963:announceProvider",
    (event: EIP6963AnnounceProviderEvent) => {
      providers.push(event.detail);
      
      if(
	      !isBrahmaConnectDetected && 
	      event.detail?.info?.uuid === brahmaConnectUUID
	     ) {
		     isBrahmaConnectDetected = true
	     }
    }
  );

  window.dispatchEvent(new Event("eip6963:requestProvider"));
}

Add support for browser/injected wallet with a single line of code change

web3-onboard has 6963 support out of the box, but if disable6963Support is set to true on your project for any reason, refer to the following guide to add support for injected wallet:

Custom Wallet List — RainbowKit
https://onboard.blocknative.com/docs/wallets/injected
https://docs.walletconnect.com/web3modal/vue/wagmi1/about/implementation
(https://eips.ethereum.org/EIPS/eip-1271).
https://github.com/etherspot/eip1271-verification-util/
https://github.com/AmbireTech/signature-validator/
https://docs.sequence.xyz/wallet/guides/sign-message/#verifying-message-signatures
Brahma Connect