How do I serialize SafeTransaction into a string and construct it from a string back to the instance with all data and signatures?

Using the safe-core-sdk, how does one serialize SafeTransaction (result of safeSdk.createTransaction) for storing in db or transport, so it can be passed to other signers? The docs for off-chain signing assumes that the distinct owners share memory and can pass along the safeTransaction instance object.

Owner A

const safeTransaction = await safeSdkA.createTransaction({ safeTransactionData })

// TODO: serialize safeTransaction to string to be stored in db or sent in HTTP request
const stringifiedData = safeTransaction.???

Owner B (does not share memory with A, is seperate Node.js process)

// TODO: create a valid SafeTransaction 
const safeTransaction = ???(stringifiedData)

const signedSafeTransaction = await safeSdkB.signTransaction(safeTransaction)

// TODO: serialize all data and signature
const stringifiedData = signedSafeTransaction.???

Owner C (does not share memory with A or B)

// TODO: create a valid SafeTransaction WITH SIGNATURES
const signedSafeTransaction = ???(stringifiedData)

const executeTxResponse = await safeSdkC.executeTransaction(safeTransaction)
await executeTxResponse.transactionResponse?.wait()

The constructor is only in internal utils module an d though there is a method to encode signatures to a string, there is no public API to decode them.

Edit This snippet seems to work correctly, however it is fragile to any updates (relies on the structure, uses classes from non-public utils).

import { SafeTransaction } from "@safe-global/safe-core-sdk-types";
import EthSignSignature from "@safe-global/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
import EthSafeTransaction from "@safe-global/safe-core-sdk/dist/src/utils/transactions/SafeTransaction";

const safeTransactionToString = (safeTransaction: SafeTransaction) => {
    return JSON.stringify({
        signatures: [...safeTransaction.signatures.values()].map(s => ({signer: s.signer, data: s.data})),
        data: safeTransaction.data,
const stringToSafeTransaction = (safeTransactionData: string): SafeTransaction => {
    const { signatures, data } = JSON.parse(safeTransactionData)
    const t = new EthSafeTransaction(data)
    for (const { signer, data } of signatures) {
        t.addSignature(new EthSignSignature(signer, data))
    return t


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.