Files
Daniel DimitrovandGitHub 55278b441c chore: migrate tx-builder from safe-apps repo to this monorepo (#6953)
* chore: migrate tx-builder from safe-apps repo to this monorepo

create-react-app is deprecated and I’ve migrated the code to vite.
web3 is deprecated and I’ve moved the code to ethersjs
the cypress tests were broken and I dropped them
original code used mui4 -> here we’ve migrated to mui6

* fix(tx-builder): remove build from tx-builder

* fix(tx-builder): vite config

* fix(tx-builder): linting

* fix(tx-builder): fix typo

* fix(tx-builder): don’t mutate array

* fix(tx-builder): fix exponential backtracking

* fix(tx-builder): git workflows

* fix(tx-builder): fix lint setup

* fix(tx-builder): align package dependencies

* fix(tx-builder): invalid react-dom version

* fix(tx-builder): git workflow

* fix(tx-builder): drag and drop was not working

react-beautiful-dnd was no longer supported and it was not compatible with react 19. Moved to @hello-pangea/dnd

* fix(tx-builder): fix pallet issues
2026-01-22 12:43:50 +01:00

1.9 KiB

Safe Apps SDK Interface

tx-builder communicates with the Safe{Wallet} host application via the Safe Apps SDK.

SDK Integration

Initialization

import { SafeProvider } from '@safe-global/safe-apps-react-sdk'

// Wrap app with SafeProvider
<SafeProvider>
  <App />
</SafeProvider>

Using SDK Hooks

import { useSafeAppsSDK } from '@safe-global/safe-apps-react-sdk'

const { sdk, safe, connected } = useSafeAppsSDK()

// safe object contains:
interface SafeInfo {
  safeAddress: string // Current Safe address
  chainId: number // Current chain ID
  threshold: number // Required signatures
  owners: string[] // Owner addresses
  isReadOnly: boolean // Whether user can sign
}

Transaction Submission

Single Transaction

const txResponse = await sdk.txs.send({
  txs: [
    {
      to: contractAddress,
      value: '0',
      data: encodedCallData,
    },
  ],
})

// Response
interface SendTransactionsResponse {
  safeTxHash: string // Safe transaction hash
}

Multi-Send Batch

// tx-builder batches multiple transactions into one
const txResponse = await sdk.txs.send({
  txs: transactions.map((tx) => ({
    to: tx.to,
    value: tx.value,
    data: tx.data,
  })),
})

Safe Gateway API

Contract ABI Fetching

GET /v1/chains/{chainId}/contracts/{address}

Response:

interface ContractInfo {
  address: string
  name: string
  displayName: string
  logoUri: string
  contractAbi: {
    abi: ABIItem[]
    description: string
  }
  trustedForDelegateCall: boolean
}

Implementation Detection (Proxies)

tx-builder uses evm-proxy-detection library to detect proxy contracts and fetch implementation ABIs.

import detectProxyTarget from 'evm-proxy-detection'

const implementation = await detectProxyTarget(contractAddress, provider.request.bind(provider))