SDK
API Kit

API Kit

The API Kit (opens in a new tab) facilitates the interaction with the Safe Transaction Service API (opens in a new tab), allowing to propose and share transactions with the other signers of a Safe, sending the signatures to the service to collect them, getting information about a Safe (like reading the transaction history, pending transactions, enabled Modules and Guards, etc.), among other features.

Quickstart

In this guide we will see how to propose transactions to the service and collect the signatures from the owners so they become executable.

For more detailed information, see the guide Integrating the Protocol Kit and API Kit (opens in a new tab) and the API Kit Reference.

Prerequisites

  1. Node.js and npm (opens in a new tab)
  2. A Safe with several signers

Install dependencies

To add the API Kit to your project, run:


_10
yarn add @safe-global/api-kit

Instantiate an EthAdapter

First of all, we need to create an EthAdapter, which contains all the required utilities for the SDKs to interact with the blockchain. It acts as a wrapper for web3.js (opens in a new tab) or ethers.js (opens in a new tab) Ethereum libraries.

Depending on the library used by the dapp, there are two options:

Once the instance of EthersAdapter or Web3Adapter is created, it can be used in the initialization of the API Kit.


_10
import { EthersAdapter } from '@safe-global/protocol-kit'
_10
_10
const provider = new ethers.JsonRpcProvider(config.RPC_URL)
_10
const signer = new ethers.Wallet(config.SIGNER_ADDRESS_PRIVATE_KEY, provider)
_10
_10
const ethAdapter = new EthersAdapter({
_10
ethers,
_10
signerOrProvider: signer
_10
})

Initialize the API Kit

We need to create an instance of the API Kit. In chains where Safe provides a Transaction Service, it's enough to specify the chainId. You can set your own service using the optional txServiceUrl parameter.


_12
import SafeApiKit from '@safe-global/api-kit'
_12
_12
const apiKit = new SafeApiKit({
_12
chainId: 1n
_12
})
_12
_12
_12
// or using a custom service
_12
const apiKit = new SafeApiKit({
_12
chainId: 1n, // set the correct chainId
_12
txServiceUrl: 'https://url-to-your-custom-service'
_12
})

Propose a transaction to the service

Before a transaction can be executed, any of the Safe signers needs to initiate the process by creating a proposal of a transaction. We send this transaction to the service to make it accessible by the other owners so they can give their approval and sign the transaction as well.


_30
import Safe from '@safe-global/protocol-kit'
_30
_30
// Create Safe instance
_30
const protocolKit = await Safe.create({
_30
ethAdapter,
_30
safeAddress: config.SAFE_ADDRESS
_30
})
_30
_30
// Create transaction
_30
const safeTransactionData: MetaTransactionData = {
_30
to: '0x',
_30
value: '1', // 1 wei
_30
data: '0x',
_30
operation: OperationType.Call
_30
}
_30
_30
const safeTransaction = await protocolKit.createTransaction({ transactions: [safeTransactionData] })
_30
_30
const senderAddress = await signer.getAddress()
_30
const safeTxHash = await protocolKit.getTransactionHash(safeTransaction)
_30
const signature = await protocolKit.signHash(safeTxHash)
_30
_30
// Propose transaction to the service
_30
await apiKit.proposeTransaction({
_30
safeAddress: await protocolKit.getAddress(),
_30
safeTransactionData: safeTransaction.data,
_30
safeTxHash,
_30
senderAddress,
_30
senderSignature: signature.data
_30
})

Retrieve the pending transactions

Different methods in the API Kit are available to retrieve pending transactions depending on the situation. To retrieve a transaction given the Safe transaction hash use the method that's not commented.


_10
const transaction = await service.getTransaction("<SAFE_TX_HASH>")
_10
// const transactions = await service.getPendingTransactions()
_10
// const transactions = await service.getIncomingTransactions()
_10
// const transactions = await service.getMultisigTransactions()
_10
// const transactions = await service.getModuleTransactions()
_10
// const transactions = await service.getAllTransactions()

Confirm the transaction

In this step we need to sign the transaction with the Protocol Kit and submit the signature to the Safe Transaction Service using the confirmTransaction method.


_10
const safeTxHash = transaction.transactionHash
_10
const signature = await protocolKit.signHash(safeTxHash)
_10
_10
// Confirm the Safe transaction
_10
const signatureResponse = await apiKit.confirmTransaction(safeTxHash, signature.data)

The Safe transaction is now ready to be executed. This can be done using the Safe{Wallet} web interface, the Protocol Kit or any other tool that's available.

Was this page helpful?