---
title: Send Encrypted Message
slug: signum/send-encrypted-message
createdAt: 2022-09-07T20:23:03.000Z
---

Sending an encrypted message to another is account is almost identical to [Send Message](docId\:SaUGSy22lp_R9pooOth8J), but with two very important differences:

1. You need to use the `agreementPrivateKey`&#x20;
2. You need the recipients public key. (See also [Accounts](docId\:RYgZpMxXYFxEwL83Fkg2b))

Encrypted messaging uses a [Diffie-Hellman-Key-Exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) to guarantee that no secret must be sent over the network. That's why encrypted messages are only readable by the sender and the receiver.&#x20;

:::hint{type="info"}
Smart Contracts do not have public keys, so they are not able to process encrypted messages.
:::

```javascript
const {Address, AddressPrefix} = require("@signumjs/core");
const {generateMasterKeys} = require("@signumjs/crypto");

const LedgerHostUrls = {
    TestNet: 'http://localhost:6876',
    MainNet: 'https://europe.signum.network',
}

async function sendMessage(args) {
    try {
        const {ledgerType, recipient, message, feeType, passphrase} = args

        // we create our client depending on the parameter
        const ledger = LedgerClientFactory.create({
            nodeHost: LedgerHostUrls[ledgerType])
        }
        // we check if incoming account is either a Signum Address, or Numeric Id
        // eventually, we convert to Numeric Id, if the value is invalid an error will be thrown
        const recipientId = Address.create(recipient).getNumericId()

        // now we check if the account exists. If it does not exist the method throws an
        // exception and the further flow is interrupted.
        // Using exception to assert certain conditions is IMHO more robust than checking returned
        // values with if-statements. The code is much cleaner
        console.info("Verifying recipient...")
        await ledger.account.getAccount({accountId: recipientId})

        // before we can send we need to get the private signing key from the user
        // the agreementPrivateKey is necessary for encrypting the message
        const {publicKey, signPrivateKey, agreementPrivateKey} = generateMasterKeys(passphrase)

        // as a next step, we use the systems fee suggestion mechanism to give us the current costs for the chosen
        // fee type. In this example we let it flexible, but you can fix the fee costs to a minimum, i.e. 0,00735 SIGNA
        const suggestedFees = await ledger.network.getSuggestedFees()

        // we assume that the feeType is either ['Minimum', 'Cheap', 'Standard', 'Priority']
        const selectedFeePlanck = suggestedFees[feeType.toLowerCase()]

        // 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
        // for P2P encrypted messages the agreementPrivateKey and the recipients public key is needed
        const {transaction} = await ledger.message.sendEncryptedMessage({
                recipientId,
                message,
                messageIsText: true,
                feePlanck: selectedFeePlanck,
                senderPrivateKey: signPrivateKey,
                senderAgreementKey: agreementPrivateKey,
                senderPublicKey: publicKey,
                recipientPublicKey
            })

        // now, some final nice message
        const addressPrefix = ledgerType === 'MainNet' ? AddressPrefix.MainNet : AddressPrefix.TestNet
        console.info(`Successfully sent the message to ${Address.create(recipientId, addressPrefix).getReedSolomonAddress()} - Transaction Id: ${transaction}`)
    } catch (e) {
        // If the API returns an exception,
        // the return error object is of type HttpError
        handleError(e);
    }
}

// // Our entry point has to be async, as our subsequent calls are.
// // This pattern keeps your app running until all async calls are executed
(async () => {
    await sendSigna({
        ledgerType: 'TestNet',
        recipient: 'TS-QAJA-QW5Y-SWVP-4RVP4',
        message: 'This is a simple message',
        feeType: 'cheap',
        passphrase: 'YourVerySecretPassphraseWhichCannotBeRevealedHere'
    });
})();
```
