# Encryption

Canonical: https://docs.projectbabbage.com/docs/guides/wallet/encryption

Encrypting and decrypting data using the WalletClient

This page shows how the **WalletClient** lets you **encrypt** and **decrypt** data using your identityKeys and how you can send encrypted messages to another party.

---

## Why Encryption?

-   Keeps app data (messages, invoices, configuration files, etc.) private whether it lives on-chain or off-chain.
    
-   Achieve secure data flows by having the wallet encrypt/decrypt locally; private keys never leave the device.
    
-   Work with identity keys on both sides, so every operation lines up with the key concepts you learned in the previous guide.
   
---

## Encrypting to Yourself

```ts
const secret = new TextEncoder().encode('hello, future me');

const { ciphertext } =  await wallet.encrypt({
  plaintext:  Array.from(secret),
  protocolID: [0, 'notes'], // specify the protocol to use
  keyID:  'encrypt-1',      // specify the key that you want to use
  counterparty:  'self'     // using your wallet's identity key
})

console.log('Cipher:', ciphertext);
```

The wallet derives a shared secret from your **identity key** and returns an encrypted byte array you can store anywhere.

---

## Decrypting Later

> Decryption **must** use the _exact_ same `protocolID`, `keyID`, and corresponding `counterparty` that were used to encrypt.

```ts
const { plaintext } = await wallet.decrypt({
  ciphertext,
  protocolID: [0, 'notes'],
  keyID: 'encrypt-1',
  counterparty: 'self'
});

console.log(new TextDecoder().decode(Uint8Array.from(plaintext))); // → hello, future me
```

---

## Encrypting for a Friend

If Alice wants to send their friend Bob an encrypted message including a file, they must first know each other's identity keys. Here I'm starting with Bob's side:

```ts
// Bob runs this once and sends Alice the result
const { publicKey: bobsIDKey } = await wallet.getPublicKey({ identityKey: true });
console.log('Bob’s Identity Key:', bobsIDKey);
```

### Alice → Bob: encrypt and send

```ts
// Alice’s side
const fileBytes = Array.from(await fileForBob.arrayBuffer());

const { ciphertext } = await wallet.encrypt({
  plaintext: fileBytes,
  protocolID: [1, 'files'],   // must match on decrypt
  keyID: 'encrypt-1',        // must match on decrypt
  counterparty: bobsIDKey,   // Bob’s identity key
});

const { publicKey: alicesIDKey } = await wallet.getPublicKey({ identityKey: true })
console.log('Alice’s Identity Key:', alicesIDKey);
// Send ciphertext and alicesIDKey to Bob 
```

### Bob ← Alice: decrypt

```ts
// Bob receives the ciphertext and Alice’s identity key:
const { plaintext } = await wallet.decrypt({
  ciphertext,
  protocolID: [1, 'files'],
  keyID: 'encrypt-1',
  counterparty: alicesIDKey,   // Alice’s identity key
});

// `plaintext` now holds the original file bytes

```

> Both sides **must** supply the same `protocolID` and `keyID`, and each uses the _other_ party’s identity key in the `counterparty` field. If any of those values differ, decryption fails.

---

## Summary

-   **`wallet.encrypt()`** secures any byte array to an identity key with a defined protocol ID, key ID, and counterparty.
    
-   **`wallet.decrypt()`** works only when you supply the matching `protocolID`, `keyID`, `counterparty`, and `securityLevel`.
    
-   Keys always come from identity-level `getPublicKey()` calls, keeping the flow consistent across your app.
 
Next up: **Signing**—learn how WalletClient attaches provable signatures to data and transactions.

---
