# RemoveMessage

Removes one or more messages from the mailbox. The caller must prove ownership of the receiver key by providing a Schnorr signature over SHA256(receiver_id || big-endian uint64 message_id_1 || ...). Only messages that belong to the authenticated receiver are deleted.

Source: [authmailboxrpc/mailbox.proto](https://github.com/lightninglabs/taproot-assets/blob/0bf1b0f1d89f0cf5b7560389a089728ded156952/taprpc/authmailboxrpc/mailbox.proto#L50)

### gRPC

```text
rpc RemoveMessage (RemoveMessageRequest) returns (RemoveMessageResponse);
```

### REST

| HTTP Method | Path |
| --- | --- |
| POST | `/v1/taproot-assets/mailbox/remove` |

## Code Samples

- gRPC
- REST

- Javascript
- Python
- grpcurl

```javascript
const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const GRPC_HOST = 'localhost:10029'
const MACAROON_PATH = 'TAPD_DIR/data/regtest/admin.macaroon'
const TLS_PATH = 'TAPD_DIR/tls.cert'

const loaderOptions = {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
};
const packageDefinition = protoLoader.loadSync('authmailboxrpc/mailbox.proto', loaderOptions);
const authmailboxrpc = grpc.loadPackageDefinition(packageDefinition).authmailboxrpc;
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
const tlsCert = fs.readFileSync(TLS_PATH);
const sslCreds = grpc.credentials.createSsl(tlsCert);
const macaroon = fs.readFileSync(MACAROON_PATH).toString('hex');
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
  let metadata = new grpc.Metadata();
  metadata.add('macaroon', macaroon);
  callback(null, metadata);
});
let creds = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
let client = new authmailboxrpc.Mailbox(GRPC_HOST, creds);
let request = {
  receiver_id: <bytes>,
  message_ids: <uint64>,
  signature: <bytes>,
};
client.removeMessage(request, function(err, response) {
  console.log(response);
});
// Console output:
//  {
//    "num_removed": <uint64>,
//  }
```

```python
import codecs, grpc, os
# Generate the following 2 modules by compiling the authmailboxrpc/mailbox.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import mailbox_pb2 as authmailboxrpc, mailbox_pb2_grpc as mailboxstub

GRPC_HOST = 'localhost:10029'
MACAROON_PATH = 'TAPD_DIR/data/regtest/admin.macaroon'
TLS_PATH = 'TAPD_DIR/tls.cert'

# create macaroon credentials
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
def metadata_callback(context, callback):
  callback([('macaroon', macaroon)], None)
auth_creds = grpc.metadata_call_credentials(metadata_callback)
# create SSL credentials
os.environ['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA'
cert = open(TLS_PATH, 'rb').read()
ssl_creds = grpc.ssl_channel_credentials(cert)
# combine macaroon and SSL credentials
combined_creds = grpc.composite_channel_credentials(ssl_creds, auth_creds)
# make the request
channel = grpc.secure_channel(GRPC_HOST, combined_creds)
stub = mailboxstub.MailboxStub(channel)
request = authmailboxrpc.RemoveMessageRequest(
  receiver_id=<bytes>,
  message_ids=<uint64>,
  signature=<bytes>,
)
response = stub.RemoveMessage(request)
print(response)
# {
#    "num_removed": <uint64>,
# }
```

```bash
# grpcurl docs: https://github.com/fullstorydev/grpcurl
# Proto source: https://github.com/lightninglabs/taproot-assets
GRPC_HOST=localhost:10029
TAPD_DIR=~/.tapd
TAPD_SOURCE=path/to/taproot-assets
NETWORK=mainnet
MACAROON_PATH="$TAPD_DIR/data/$NETWORK/admin.macaroon"
TLS_PATH="$TAPD_DIR/tls.cert"

grpcurl \
    -import-path $TAPD_SOURCE/taprpc/ \
    -proto authmailboxrpc/mailbox.proto \
    -cacert $TLS_PATH \
    -H "macaroon: $(xxd -ps -u -c 1000 $MACAROON_PATH)" \
    -d '{ "receiver_id": BASE64_ENCODED_VALUE, "message_ids": <uint64>, "signature": BASE64_ENCODED_VALUE }' \
    $GRPC_HOST \
    authmailboxrpc.Mailbox/RemoveMessage
```

- Javascript
- Python
- curl

```javascript
const fs = require('fs');
const request = require('request');

const REST_HOST = 'localhost:8089'
const MACAROON_PATH = 'TAPD_DIR/data/regtest/admin.macaroon'

let requestBody = {
  receiver_id: <string>, // <bytes> (base64 encoded)
  message_ids: <array>, // <uint64>
  signature: <string>, // <bytes> (base64 encoded)
};
let options = {
  url: `https://${REST_HOST}/v1/taproot-assets/mailbox/remove`,
  // Work-around for self-signed certificates.
  rejectUnauthorized: false,
  json: true,
  headers: {
    'Grpc-Metadata-macaroon': fs.readFileSync(MACAROON_PATH).toString('hex'),
  },
  form: JSON.stringify(requestBody),
}
request.post(options, function(error, response, body) {
  console.log(body);
});
// Console output:
//  {
//    "num_removed": <string>, // <uint64>
//  }
```

```python
import base64, codecs, json, requests

REST_HOST = 'localhost:8089'
MACAROON_PATH = 'TAPD_DIR/data/regtest/admin.macaroon'
TLS_PATH = 'TAPD_DIR/tls.cert'

url = f'https://{REST_HOST}/v1/taproot-assets/mailbox/remove'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
data = {
  'receiver_id': base64.b64encode(<bytes>),
  'message_ids': <uint64>,
  'signature': base64.b64encode(<bytes>),
}
r = requests.post(url, headers=headers, data=json.dumps(data), verify=TLS_PATH)
print(r.json())
# {
#    "num_removed": <uint64>,
# }
```

```bash
REST_HOST=localhost:8089
TAPD_DIR=~/.tapd
NETWORK=mainnet
MACAROON_PATH="$TAPD_DIR/data/$NETWORK/admin.macaroon"
TLS_PATH="$TAPD_DIR/tls.cert"

curl -X POST \
    --cacert $TLS_PATH \
    -H "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000 $MACAROON_PATH)" \
    -d '{ "receiver_id": BASE64_ENCODED_VALUE, "message_ids": <uint64>, "signature": BASE64_ENCODED_VALUE }' \
    https://$REST_HOST/v1/taproot-assets/mailbox/remove
```

## Messages

### authmailboxrpc.RemoveMessageRequest

Source: [authmailboxrpc/mailbox.proto](https://github.com/lightninglabs/taproot-assets/blob/0bf1b0f1d89f0cf5b7560389a089728ded156952/taprpc/authmailboxrpc/mailbox.proto#L260)

| Field | gRPC Type | REST Type | REST Placement |
| --- | --- | --- | --- |
| `receiver_id`<br>The public key identifier of the receiver whose messages should be removed, encoded as the raw bytes of the compressed public key. This is the same key used when subscribing for messages via ReceiveMessages. | `bytes` | `string` | `body` |
| `message_ids`<br>The IDs of the messages to remove. Only messages that belong to the specified receiver will be deleted. IDs that don't exist or belong to a different receiver are silently skipped. | `uint64[]` | `array` | `body` |
| `signature`<br>A Schnorr signature proving ownership of the receiver key. The signature must be over SHA256(receiver_id || msg_id_1 || msg_id_2 || ...) where each message ID is encoded as a big-endian uint64. | `bytes` | `string` | `body` |

### authmailboxrpc.RemoveMessageResponse

Source: [authmailboxrpc/mailbox.proto](https://github.com/lightninglabs/taproot-assets/blob/0bf1b0f1d89f0cf5b7560389a089728ded156952/taprpc/authmailboxrpc/mailbox.proto#L278)

| Field | gRPC Type | REST Type |
| --- | --- | --- |
| `num_removed`<br>The number of messages that were actually removed. | `uint64` | `string` |
