-
-
Notifications
You must be signed in to change notification settings - Fork 10
AIP-18: Decentralized file transfer #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
b9ecc00
Implemented AIP 18
StanislavDevIOS 8064378
small fixes
StanislavDevIOS e76a769
Add 'file_resolution' param
StanislavDevIOS a94b841
fix: AIP discussion link
adamant-al 8d67c94
chore: rewriting several parts
adamant-al 269d9e3
chore: separate examples for regular message and reply-to
adamant-al 984a12a
chore: update the Rationale section
adamant-al f25b541
feat: add Transfer scenario
adamant-al 6ef0c89
feat: new structure
StanislavDevIOS 8da03d8
fix: Transfer scenario
StanislavDevIOS 2233391
feat: new fields (mimeType, extension, duration)
StanislavDevIOS 167d5ad
Update AIPS/aip-18.md
StanislavDevIOS a8aa0d3
Update AIPS/aip-18.md
StanislavDevIOS 69f9f5e
Update AIPS/aip-18.md
adamant-al 06b4c38
fix: typo 4 to 3 of `
adamant-al 90a1825
Update AIPS/aip-18.md
adamant-al 66d2eb7
chore: update a sender's client app sequencing
adamant-al 3ebc406
fix: grammar
adamant-al c77c3c2
chore: make up
adamant-al d7c8703
feat: accept AIP-18
adamant-al File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,214 @@ | ||
| --- | ||
| aip: 18 | ||
| title: Decentralized File Transfer | ||
| author: Aleksei Lebedev (@adamant-al), Stanislav Jelezoglo (@StanislavDevIOS) | ||
| discussions-to: https://github.com/Adamant-im/AIPs/issues/55 | ||
| requires: 5 | ||
| extends: https://aips.adamant.im/AIPS/aip-5 | ||
| status: Accepted | ||
| type: Standards | ||
| category: ARC | ||
| created: 2024-03-21 | ||
| --- | ||
|
|
||
| ## Simple Summary | ||
|
|
||
| This proposal introduces a decentralized file-transfer feature in ADAMANT Messenger apps. | ||
|
|
||
| ## Abstract | ||
|
|
||
| The ability to send files within a messaging platform enhances communication by providing users with a versatile and efficient means of sharing information. Sending files lets users exchange various types of content—documents, images, videos, and more—directly within the chat interface. This functionality promotes collaboration, facilitates the sharing of important documents, and enriches conversations by adding context and additional information. | ||
|
|
||
| The key distinction of file transfer in ADAMANT is its privacy-first approach, which relies on decentralized storage solutions such as the [InterPlanetary File System (IPFS)](https://en.wikipedia.org/wiki/InterPlanetary_File_System) and storage blockchains. This aligns with ADAMANT’s principles of privacy and censorship resistance. | ||
|
|
||
| ## Motivation | ||
|
|
||
| A comprehensive specification is necessary to establish a consistent and standardized approach to implementing decentralized file transfer in ADAMANT Messenger apps. | ||
|
|
||
| ## Specification | ||
|
|
||
| At a high level, decentralized file transfer consists of the following steps: | ||
|
|
||
| - Encrypting the file using the end-to-end encryption defined in [AIP-4](https://aips.adamant.im/AIPS/aip-4) | ||
| - Generating a file ID (locally on device) | ||
| - Uploading the encrypted file to a decentralized-storage node | ||
| - Sending that ID to the recipient in an ADM rich-text message | ||
| - Later, the recipient decrypts the ADM message, downloads the file (from any decentralized-storage node), and decrypts it. | ||
|
|
||
| While the encryption and decryption steps are covered in other AIPs, the process of embedding file IDs in messages requires its own specification. | ||
|
|
||
| Once a client has the file ID, it sends an ADM rich-text message, as described in [AIP-5](https://aips.adamant.im/AIPS/aip-5), containing both storage and file information. The `id` field represents the unique identifier of the file; other fields convey the file type, size, preview ID, file name, and nonces used for encryption. | ||
|
|
||
| ## Syntax | ||
|
|
||
| According to [AIP-5](https://aips.adamant.im/AIPS/aip-5), the field `transaction.asset.chat.message` must contain **encrypted, stringified** JSON that includes the attached-file information. | ||
|
|
||
| The structure of the file-transfer object is as follows: | ||
|
|
||
| ```json | ||
| { | ||
| "files": [ | ||
| { | ||
| "id": "String", | ||
| "mimeType": "String", | ||
| "extension": "String", | ||
| "size": Int64, | ||
| "preview": { | ||
| "id": "String", | ||
| "nonce": "String", | ||
| "extension": "String" | ||
| }, | ||
| "name": "String", | ||
| "nonce": "String", | ||
| "resolution": [Float, Float], | ||
| "duration": Float | ||
| } | ||
| ], | ||
| "storage": { "id": "String" }, | ||
| "comment": "String" | ||
bludnic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| ``` | ||
|
|
||
| Object fields: | ||
|
|
||
| - `files`: Array containing metadata for each attached encrypted file | ||
| - `id`: Unique file identifier within `storage` | ||
| - `mimeType`: MIME type of the file (optional) | ||
| - `extension`: File-extension string (optional) | ||
| - `size`: Size of the *encrypted* file in bytes | ||
| - `preview`: Preview-image data (optional) | ||
| - `name`: Original file name (optional) | ||
| - `nonce`: Nonce used for encryption | ||
| - `resolution`: [width, height] in pixels; useful for images and videos (optional) | ||
| - `duration`: Duration of a video or audio file in seconds (optional) | ||
| - `storage`: Describes the decentralized storage in which the file resides | ||
| - `comment`: Caption or comment associated with the file (optional) | ||
|
|
||
| ### Examples | ||
|
|
||
| Object `transaction.asset.chat.message` *before encryption*, which includes a single file: | ||
|
|
||
| ``` json | ||
| { | ||
| "storage": { | ||
| "id": "ipfs" | ||
| }, | ||
| "files": [ | ||
| { | ||
| "id": "bafkreifxs2buan4anxwhfnt...v25rewteppsh6u4s4x5hi4o4du", | ||
| "name": "IMG_308", | ||
| "resolution": [ | ||
| 1179, | ||
| 2556 | ||
| ], | ||
| "preview": { | ||
| "id": "bafkreidqpnqmqocqp...if4xb3bi76gl6g4kmtg62cmpw5ufu", | ||
| "nonce": "297d443aa29aa...485309f9f5ae159df9784d", | ||
| "extension": "jpeg" | ||
| }, | ||
| "nonce": "030aa714943dc1dd...1c7091920d9d", | ||
| "mimeType": "image/jpeg", | ||
| "extension": "jpeg", | ||
| "size": 150998 | ||
| } | ||
| ], | ||
| "comment": "Hello!" | ||
| } | ||
| ``` | ||
|
|
||
| The entire transaction after encryption from U15677078342684640219 to U7972131227889954319 looks like this: | ||
|
|
||
| ``` json | ||
| { | ||
| "transaction": { | ||
| "type": 8, | ||
| "amount": 0, // Amount should be 0 | ||
| "senderId": "U15677078342684640219", | ||
| "senderPublicKey": "e16e624fd0a5123294b448c21f30a07a0435533c693b146b14e66830e4e20404", | ||
| "asset": { | ||
| "chat": { | ||
| "message": "70cbd07ff2ceaf0fc38a01ef9...", // encrypted files object | ||
| "own_message": "e98794eaedf47e...", | ||
| "type": 2 // Type should be 2 (Rich Content Message) | ||
| } | ||
| }, | ||
| "recipientId": "U7972131227889954319", | ||
| "timestamp": 46116887, | ||
| "signature": "8fc2a54604109a6fcdccec2..." | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| You can combine file sending with [AIP-16](https://aips.adamant.im/AIPS/aip-16) to reply to a message that has an attachment. Supply the following structure in the `reply_message` field: | ||
|
|
||
| ``` json | ||
| { | ||
| "replyto_id": "7452709338464950789", | ||
| "reply_message": { | ||
| "storage": { | ||
| "id": "ipfs" | ||
| }, | ||
| "files": [ | ||
| { | ||
| "id": "bafkreifxs2buan4anxwhfnt...v25rewteppsh6u4s4x5hi4o4du", | ||
| "name": "IMG_308", | ||
| "resolution": [ | ||
| 1179, | ||
| 2556 | ||
| ], | ||
| "preview": { | ||
| "id": "bafkreidqpnqmqocqp...if4xb3bi76gl6g4kmtg62cmpw5ufu", | ||
| "nonce": "297d443aa29aa...485309f9f5ae159df9784d", | ||
| "extension": "jpeg" | ||
| }, | ||
| "nonce": "030aa714943dc1dd...1c7091920d9d", | ||
| "mimeType": "video/quicktime", | ||
| "extension": "mov", | ||
| "size": 150998, | ||
| "duration": 129.3 | ||
| } | ||
| ], | ||
| "comment": "Hello!" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Transfer Scenario | ||
|
|
||
| ### Sender’s client | ||
|
|
||
| 1. Create a placeholder in the chat for the file transfer | ||
| 2. Display the file(s) inside the placeholder with a spinner or progress indicator; the user can cancel the transfer at any time. | ||
| 3. Encrypt the file(s) | ||
| 4. Calculate the file ID(s) locally on device | ||
| 5. Upload the encrypted file(s) to a storage node | ||
| 6. Wait until the upload completes, retrieve the file ID(s), and verify that they match the locally calculated value(s). If a network issue occurs, let the user retry or cancel. | ||
| 7. Send the ADM rich-text message. If a network issue occurs, let the user retry or cancel. | ||
|
|
||
| ### Recipient’s client | ||
|
|
||
| 1. Fetch and decrypt the ADM message | ||
| 2. Create a placeholder for the file(s) in the chat with a spinner | ||
| 3. *(Optional)* Fetch the preview image if *auto-preview* is enabled | ||
| 4. *(Optional)* Fetch the full file if *auto-download* is enabled | ||
| 5. Decrypt the file(s) | ||
| 6. Replace the placeholder with the final content | ||
|
|
||
| As with in-chat crypto transfers, retry logic and timeouts depend on the message age; very recent transfers may need extra time before the file becomes available on the node to which the recipient is connected. | ||
|
|
||
| ## Assumptions and Limitations | ||
|
|
||
| Although ADAMANT’s privacy-first design is a core strength, it also introduces several limitations: | ||
|
|
||
| - Mandatory end-to-end encryption may introduce a slight UX delay and demands additional client-side resources | ||
| - Forwarding attachments requires downloading the content and re-encrypting it with the new recipient’s public key | ||
| - Decentralized storage networks can exhibit propagation delays between nodes | ||
| - Most decentralized-storage solutions cannot guarantee file deletion; any node may retain a file indefinitely | ||
|
|
||
| ## Rationale | ||
|
|
||
| This AIP adds a file-sharing feature that follows the decentralized ethos of ADAMANT, providing strong privacy and censorship resistance. A standardized approach guarantees consistent behavior across all ADAMANT Messenger clients. | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.