Babylon Transaction Signing
1. Prepare the Unsigned Transaction
Obtain the unsigned transaction in the required format (Babylon transaction object). Typically, this is provided by the API endpoint or a transaction builder.
Example (object form):
{
"messages": [/*...Babylon messages...*/],
"fee": {
"amount": [{"denom": "ubbn", "amount": "1000"}],
"gas": "200000"
},
"memo": ""
}
2. Sign the Transaction Using the Script Below
import { DirectSecp256k1HdWallet, Registry, GeneratedType } from '@cosmjs/proto-signing';
import { SigningCosmWasmClient, defaultRegistryTypes } from '@cosmjs/cosmwasm-stargate';
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
import axios from 'axios';
// Replace with actual Babylon message types if needed
import {
MsgWrappedDelegate,
MsgWrappedUndelegate,
} from '@babylonlabs-io/babylon-proto-ts/dist/generated/babylon/epoching/v1/tx';
const BABYLON_RPC = '<BABYLON_NODE_RPC>'; // e.g. https://rpc.testnet.babylonchain.io:443
const BABYLON_API_URL = '<P2P_API_URL>'; // e.g. https://api.testnet.p2p.org
const BABYLON_API_KEY = '<P2P_API_KEY>';
const BABYLON_NETWORK = '<NETWORK_NAME>'; // e.g. testnet, mainnet
const BABYLON_MNEMONIC = '<MNEMONIC>';
const BABYLON_ADDRESS = '<BBN_ADDRESS>'; // e.g. bbn1xyz...
const UNSIGNED_TX = {
// Paste your unsigned transaction object here
messages: [],
fee: {
amount: [{ denom: 'ubbn', amount: '1000' }],
gas: '200000',
},
memo: '',
};
function getBabylonRegistry(): Registry {
const registry = new Registry([...defaultRegistryTypes]);
registry.register(
'/babylon.epoching.v1.MsgWrappedDelegate',
MsgWrappedDelegate as unknown as GeneratedType
);
registry.register(
'/babylon.epoching.v1.MsgWrappedUndelegate',
MsgWrappedUndelegate as unknown as GeneratedType
);
return registry;
}
async function signTransaction(
mnemonic: string,
address: string,
unsignedTx: any
): Promise<string> {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: 'bbn' });
const registry = getBabylonRegistry();
const client = await SigningCosmWasmClient.connectWithSigner(BABYLON_RPC, wallet, { registry });
const { bodyBytes, authInfoBytes, signatures } = await client.sign(
address,
unsignedTx.messages,
unsignedTx.fee,
unsignedTx.memo
);
const txRaw = TxRaw.fromPartial({
bodyBytes,
authInfoBytes,
signatures,
});
// Return the signed transaction as hex string
return Buffer.from(TxRaw.encode(txRaw).finish()).toString('hex');
}
async function broadcastTransaction(signedTxHex: string): Promise<string> {
const endpoint = `${BABYLON_API_URL}/api/v1/babylon/${BABYLON_NETWORK}/transaction/send`;
const response = await axios.post(
endpoint,
{ signedTransaction: signedTxHex },
{
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: `Bearer ${BABYLON_API_KEY}`,
},
}
);
if (!response.data.result?.transactionHash) {
throw new Error(`Broadcast failed: ${JSON.stringify(response.data)}`);
}
return response.data.result.transactionHash;
}
async function main() {
if (!BABYLON_MNEMONIC || !BABYLON_ADDRESS) {
throw new Error('❌ Babylon mnemonic or address is missing.');
}
if (!UNSIGNED_TX.messages || !Array.isArray(UNSIGNED_TX.messages)) {
throw new Error('❌ Invalid unsigned transaction.');
}
const signedTxHex = await signTransaction(BABYLON_MNEMONIC, BABYLON_ADDRESS, UNSIGNED_TX);
console.log('✅ Signed Babylon Tx (hex):');
console.log(signedTxHex);
// Broadcast (optional, can be run separately)
const txHash = await broadcastTransaction(signedTxHex);
console.log('✅ Broadcasted Tx Hash:', txHash);
}
main().catch(console.error);
3. On Successful Execution
The script prints the signed transaction in hex format, then broadcasts it. Example output:
✅ Signed Babylon Tx (hex):
aabbcc...deadbeef
✅ Broadcasted Tx Hash:
BABYLON_TX_HASH_HERE
What's Next?
Updated 3 months ago