Bako Safe SDK
Transactions
Overview

Transactions Overview

Understanding the transaction lifecycle in Bako Safe multi-signature vaults.

Transaction Lifecycle

Transaction Status

StatusValueDescription
AWAIT_REQUIREMENTSawait_requirementsWaiting for required signatures
PENDING_SENDERpending_senderReady to send, all signatures collected
PROCESS_ON_CHAINprocess_on_chainSubmitted, awaiting confirmation
SUCCESSsuccessCompleted successfully
DECLINEDdeclinedRejected by signers
FAILEDfailedExecution failed
CANCELEDcanceledCanceled before completion

Transaction Flow

1. Creation

const { tx, hashTxId } = await vault.transaction({
  name: 'Payment',
  assets: [{
    assetId: '0x...',
    amount: '1000000',
    to: 'fuel1...'
  }]
});
// Status: AWAIT_REQUIREMENTS

2. Signature Collection

Signers approve the transaction via:

  • Bako Safe web app (safe.bako.global)
  • SDK signing methods
  • Wallet connections

3. Execution

// When all signatures collected
const result = await vault.send(tx);
// Status: SUCCESS or FAILED

Transaction Types

enum TransactionType {
  BLOB = 'blob',
  SCRIPT = 'script',
  CREATE = 'create',
  UPGRADE = 'upgrade',
  UPLOAD = 'upload',
  DEPOSIT = 'deposit'
}

Transaction Data Structure

VaultTransaction

interface VaultTransaction {
  name?: string;           // Transaction name/description
  assets: ITransferAsset[];  // Assets to transfer
}
 
interface ITransferAsset {
  assetId: string;   // Asset ID (token address)
  amount: string;    // Amount in base units
  to: string;        // Recipient address
}

ITransactionResume

interface ITransactionResume {
  hash: string;              // Transaction hash
  BakoSafeID: string;        // Bako ecosystem ID
  totalSigners: number;      // Total vault signers
  requiredSigners: number;   // Required signatures
  predicate: {
    id: string;
    address: string;
  };
  outputs: ITransferAsset[]; // Transfer details
  status: TransactionStatus;
  witnesses?: string[];      // Collected signatures
  gasUsed?: string;          // Gas consumption
  sendTime?: Date;           // Execution time
}

Quick Example

import { BakoProvider, Vault, TransactionStatus } from 'bakosafe';
 
async function createAndMonitorTransaction() {
  const provider = await BakoProvider.create(networkUrl, { apiToken });
  const vault = await Vault.fromAddress(vaultAddress, provider);
 
  // Create transaction
  const { tx, hashTxId } = await vault.transaction({
    name: 'Monthly Payment',
    assets: [{
      assetId: ETH_ASSET_ID,
      amount: '1000000000', // 1 ETH
      to: recipientAddress
    }]
  });
 
  console.log('Transaction created:', hashTxId);
 
  // Monitor status
  const checkStatus = async () => {
    const txData = await vault.transactionFromHash(hashTxId);
 
    switch (txData.status) {
      case TransactionStatus.AWAIT_REQUIREMENTS:
        console.log(`Waiting for signatures: ${txData.witnesses.length}/${txData.requiredSigners}`);
        break;
      case TransactionStatus.PENDING_SENDER:
        console.log('Ready to send!');
        const result = await vault.send(tx);
        console.log('Sent:', result.id);
        break;
      case TransactionStatus.SUCCESS:
        console.log('Completed!');
        break;
      case TransactionStatus.FAILED:
        console.log('Failed:', txData.error);
        break;
    }
 
    return txData.status;
  };
 
  // Poll until complete
  let status = await checkStatus();
  while (status === TransactionStatus.AWAIT_REQUIREMENTS) {
    await new Promise(r => setTimeout(r, 5000));
    status = await checkStatus();
  }
}

Next Steps