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
}