---
title: Dispatch Transactions
slug: signum/dispatch-transactions
createdAt: 2022-08-30T21:11:52.000Z
---

Broadcasting transactions requires slightly more effort, due to the signing process. In SignumJS all transactions are signed locally, that is no secret is ever sent over the wire.&#x20;

![](https://api.archbee.com/api/optimize/l2AIpSUU6srSQmG1-K2bb/js6CbKyX8kpE-jgsoDD_5_image.png)

To sign the transaction you need the private signing key, which can be obtained by the `generateMasterKeys` function. All functions that requires signing in SignumJS can work in two modes:

- Automatic Signing
- Manual Signing

## Automatic Signing

For the most common cases, the developer has somehow access to a private key, may it by asking the user for his passphrase, and/or having the necessary keys securely stored somewhere, for example as environment variable on the server, or in an encrypted form on the clients browser.&#x20;

Everytime the `signPrivateKey` is provided, SignumJS automatically uses the key, signs and broadcasts the transaction.

```javascript
// before we can send we need to get the private signing key from the user
const {publicKey, signPrivateKey} = generateMasterKeys(passphrase)

// Now, we execute the transaction
// within the method the local signing flow is being executed, i.e.
// the private key is used only locally for signing, but never sent over the network
const {transaction} = await ledger.transaction.sendAmountToSingleRecipient({
    recipientId,
    amountPlanck: Amount.fromSigna(amount).getPlanck(),
    feePlanck: selectedFeePlanck,
    senderPrivateKey: signPrivateKey, // <<< causes AUTOMATIC SIGNING
    senderPublicKey: publicKey
});
```

## Manual Signing

In contrast to Automatic Signing, it is also possible to sign and broadcast a transaction manually. Actually, this is most commonly used in conjunction with the XT Wallet. The XT Wallet securely manages the keys of an user and thus the wallet can be used as "Signer". This way, the developer does not take care of securing an users keys (which can be an annoying and also risky task), and simply sends the <u>unsigned transaction bytes</u>  to the wallet.

:::hint{type="info"}
It is not possible to request unsigned bytes on one node and use another node for broadcasting.&#x20;
:::

```javascript
async function sendMessage() {
    const recipientId = getRecipientAccountId()
    const message = getMessage()
    try {
        // Here,we do not provide a private key, and this way the node returns 
        // not an transaction object, but the unsigned byte sequence
        const {unsignedTransactionBytes} = await window.signumLedger.message.sendMessage({
            feePlanck: calcFee(),
            recipientId,
            message,
            messageIsText: true,
            senderPublicKey: window.wallet.connection.publicKey
            // NO PRIVATE KEY PROVIDED
        })
        // Now, we send the unsigned transaction to the wallet, which manages
        // the users keys. This way, the developer does not take care about 
        // managing accounts. This is the recommended way for DApps
        const {transaction} = await window.wallet.confirm(unsignedTransactionBytes)
        showSuccess(`Message sent successfully - Id: ${transaction}`)
    } catch (e) {
        showError(e.message)
    }
}
```
