Skip to main content

Remote Attachment Content Type

Status Status

Remote attachments of any size can be sent using the RemoteAttachmentCodec and a storage provider.

Open for feedback

You are welcome to provide feedback on this implementation by commenting on the Remote Attachment Content Type XIP (XMTP Improvement Proposal).

Remote attachments with React

To learn how to use the remote attachment content type with the React SDK, see Handle content types with the React SDK.

Install the package

npm i @xmtp/content-type-remote-attachment

Import and register

// Import the codecs we're going to use
import {
AttachmentCodec,
RemoteAttachmentCodec,
} from "@xmtp/content-type-remote-attachment";
// Create the XMTP client
const xmtp = await Client.create(signer, { env: "dev" });
// Register the codecs. AttachmentCodec is for local attachments (<1MB)
xmtp.registerCodec(new AttachmentCodec());
//RemoteAttachmentCodec is for remote attachments (>1MB) using thirdweb storage
xmtp.registerCodec(new RemoteAttachmentCodec());

Create an attachment object

// Local file details
const attachment = {
filename: filename,
mimeType: extname,
data: new Uint8Array(data),
};

Encrypt the attachment

Use the RemoteAttachmentCodec.encodeEncrypted to encrypt the attachment:

const encryptedEncoded = await RemoteAttachmentCodec.encodeEncrypted(
attachment,
new AttachmentCodec(),
);

Upload the encrypted attachment

Upload the encrypted attachment anywhere where it will be accessible via an HTTPS GET request. For example, you can use web3.storage:

const { Web3Storage } = require("web3.storage");

class Upload {
constructor(name, data) {
this.name = name;
this.data = data;
}

stream() {
const self = this;
return new ReadableStream({
start(controller) {
controller.enqueue(Buffer.from(self.data));
controller.close();
},
});
}
}

const upload = new Upload("uploadIdOfYourChoice", encryptedEncoded.payload);

const web3Storage = new Web3Storage({
token: "YOURTOKENHERE",
});

const cid = await web3Storage.put([upload]);
const url = `https://${cid}.ipfs.w3s.link/uploadIdOfYourChoice`;

Create a remote attachment

Now that you have a url, you can create a RemoteAttachment.

const remoteAttachment = {
url: url,
contentDigest: encryptedEncoded.digest,
salt: encryptedEncoded.salt,
nonce: encryptedEncoded.nonce,
secret: encryptedEncoded.secret,
scheme: "https://",
filename: attachment.filename,
contentLength: attachment.data.byteLength,
};

Send a remote attachment

Now that you have a remote attachment, you can send it:

await conversation.send(remoteAttachment, {
contentType: ContentTypeRemoteAttachment,
});

Download, decrypt, and decode the attachment

Now that you can receive a remote attachment, you need a way to receive a remote attachment. For example:

if (message.contentType.sameAs(RemoteAttachmentContentType)) {
const attachment = await RemoteAttachmentCodec.load(message.content, client);
}
  • You now have the original attachment:
attachment.filename // => "screenshot.png"
attachment.mimeType // => "image/png",
attachment.data // => [the PNG data]

Create a preview attachment object

Once you have the attachment object created, you can also create a preview for what to show in a message input before sending:

URL.createObjectURL(
new Blob([Buffer.from(attachment.data)], {
type: attachment.mimeType,
}),
),

Was the information on this page helpful?
powered by XMTP