Bako Connector
Quickstart
Installation

Installation & Setup

Complete guide to integrating the Bako Safe Connector in your dApp.

Installation

npm install bakosafe fuels @fuels/connectors @fuels/react

Basic Setup

1. Configure FuelProvider

Wrap your application with the Fuel provider and include the BSafeConnector:

// main.tsx or _app.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { FuelProvider } from '@fuels/react';
import { BSafeConnector } from 'bakosafe';
import App from './App';
 
// Create connector instance
const bsafeConnector = new BSafeConnector();
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <FuelProvider
      theme="dark"
      fuelConfig={{
        connectors: [bsafeConnector],
      }}
    >
      <App />
    </FuelProvider>
  </React.StrictMode>
);

2. Connect to Vault

Use Fuel hooks to connect users:

import { useConnectUI, useAccount, useIsConnected, useDisconnect } from '@fuels/react';
 
function ConnectButton() {
  const { connect } = useConnectUI();
  const { account } = useAccount();
  const { isConnected } = useIsConnected();
  const { disconnect } = useDisconnect();
 
  if (isConnected) {
    return (
      <div>
        <p>Connected: {account}</p>
        <button onClick={() => disconnect()}>Disconnect</button>
      </div>
    );
  }
 
  return <button onClick={() => connect()}>Connect Vault</button>;
}

3. Create Transactions

Once connected, create transactions from the vault:

import { useFuel, useAccount } from '@fuels/react';
import { bn, Provider, Address } from 'fuels';
 
function TransferForm() {
  const { fuel } = useFuel();
  const { account } = useAccount();
 
  async function handleTransfer(recipient: string, amount: string) {
    if (!account) return;
 
    // Get provider and wallet
    const provider = await Provider.create('https://mainnet.fuel.network/v1/graphql');
    const wallet = await fuel.getWallet(account, provider);
    const baseAssetId = provider.getBaseAssetId();
 
    // Create transfer
    const result = await wallet.transfer(
      Address.fromString(recipient),
      bn.parseUnits(amount),
      baseAssetId
    );
 
    // Wait for result
    const { id, status } = await result.waitForResult();
    console.log('Transaction:', { id, status });
  }
 
  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      const form = e.target as HTMLFormElement;
      handleTransfer(form.recipient.value, form.amount.value);
    }}>
      <input name="recipient" placeholder="Recipient address" />
      <input name="amount" placeholder="Amount" type="number" step="0.001" />
      <button type="submit">Transfer</button>
    </form>
  );
}

Contract Calls

Call smart contracts through the vault:

import { useFuel, useAccount } from '@fuels/react';
import { Provider, Contract, bn } from 'fuels';
import { MyContractAbi } from './contracts';
 
function ContractCall() {
  const { fuel } = useFuel();
  const { account } = useAccount();
 
  async function callContract() {
    if (!account) return;
 
    const provider = await Provider.create('https://mainnet.fuel.network/v1/graphql');
    const wallet = await fuel.getWallet(account, provider);
 
    // Connect to contract
    const contract = new Contract(
      '0xYourContractId...',
      MyContractAbi,
      wallet
    );
 
    // Call contract method
    const { value, transactionId } = await contract.functions
      .your_method(param1, param2)
      .call();
 
    console.log('Result:', value);
    console.log('Transaction:', transactionId);
  }
 
  return <button onClick={callContract}>Call Contract</button>;
}

Transaction Flow

When a transaction is created through the connector:

  1. Transaction Created: dApp creates transfer/contract call
  2. Sent to Bako Safe: Transaction queued for approval
  3. Signers Notified: Vault signers receive notifications
  4. Signatures Collected: Signers approve in Bako Safe app
  5. Broadcast: After threshold met, transaction is broadcast
  6. Result Returned: dApp receives transaction result
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│    dApp     │────▶│  Bako Safe  │────▶│  Fuel       │
│             │     │  (Approval) │     │  Network    │
└─────────────┘     └─────────────┘     └─────────────┘


                    ┌─────────────┐
                    │  Signers    │
                    │  (Approve)  │
                    └─────────────┘

Available Hooks

From @fuels/react:

HookPurpose
useFuel()Access Fuel instance
useAccount()Get connected account
useIsConnected()Check connection status
useConnectUI()Trigger connect dialog
useDisconnect()Disconnect wallet
useBalance()Get account balance
useWallet()Get wallet instance

Error Handling

async function safeTransfer(recipient: string, amount: string) {
  try {
    const provider = await Provider.create(networkUrl);
    const wallet = await fuel.getWallet(account!, provider);
 
    const result = await wallet.transfer(
      Address.fromString(recipient),
      bn.parseUnits(amount),
      provider.getBaseAssetId()
    );
 
    return await result.waitForResult();
 
  } catch (error) {
    if (error.message?.includes('rejected')) {
      console.error('Transaction rejected by user');
    } else if (error.message?.includes('insufficient')) {
      console.error('Insufficient balance');
    } else {
      console.error('Transaction failed:', error);
    }
    throw error;
  }
}

Next.js Setup

For Next.js applications:

// app/providers.tsx
'use client';
 
import { FuelProvider } from '@fuels/react';
import { BSafeConnector } from 'bakosafe';
 
const bsafeConnector = new BSafeConnector();
 
export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <FuelProvider
      theme="dark"
      fuelConfig={{
        connectors: [bsafeConnector],
      }}
    >
      {children}
    </FuelProvider>
  );
}
// app/layout.tsx
import { Providers } from './providers';
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Support

If you have questions:

Next Steps