AbdulElahGwaith commited on
Commit
0220cd3
·
verified ·
1 Parent(s): ae486ac

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .cargo/config.toml +11 -0
  2. .gitattributes +30 -35
  3. .github/ISSUE_TEMPLATE/bug_report.md +35 -0
  4. .github/dependabot.yml +20 -0
  5. .github/workflows/ci.yml +380 -0
  6. .github/workflows/deltachat-rpc-server.yml +531 -0
  7. .github/workflows/dependabot.yml +24 -0
  8. .github/workflows/jsonrpc-client-npm-package.yml +47 -0
  9. .github/workflows/jsonrpc.yml +42 -0
  10. .github/workflows/nix.yml +109 -0
  11. .github/workflows/publish-deltachat-rpc-client-pypi.yml +50 -0
  12. .github/workflows/repl.yml +28 -0
  13. .github/workflows/upload-docs.yml +95 -0
  14. .github/workflows/upload-ffi-docs.yml +31 -0
  15. .github/workflows/zizmor-scan.yml +31 -0
  16. .gitignore +57 -0
  17. .npmignore +56 -0
  18. .npmrc +1 -0
  19. CHANGELOG.md +0 -0
  20. CMakeLists.txt +46 -0
  21. CONTRIBUTING.md +122 -0
  22. Cargo.lock +0 -0
  23. Cargo.toml +218 -0
  24. LICENSE +377 -0
  25. README.md +215 -0
  26. RELEASE.md +21 -0
  27. STYLE.md +157 -0
  28. assets/icon-archive.png +0 -0
  29. assets/icon-archive.svg +60 -0
  30. assets/icon-broadcast.png +0 -0
  31. assets/icon-broadcast.svg +149 -0
  32. assets/icon-device.png +0 -0
  33. assets/icon-device.svg +83 -0
  34. assets/icon-saved-messages.png +0 -0
  35. assets/icon-saved-messages.svg +71 -0
  36. assets/icon-unencrypted.png +0 -0
  37. assets/icon-unencrypted.svg +47 -0
  38. assets/icon-webxdc.png +0 -0
  39. assets/icon-webxdc.svg +181 -0
  40. assets/qr_overlay_delta.svg-part +12 -0
  41. assets/qrcode_logo_footer.svg +10 -0
  42. assets/statistics-bot.vcf +7 -0
  43. assets/welcome-image.jpg +3 -0
  44. benches/contacts.rs +47 -0
  45. benches/create_account.rs +30 -0
  46. benches/decrypting.rs +201 -0
  47. benches/get_chat_msgs.rs +48 -0
  48. benches/get_chatlist.rs +35 -0
  49. benches/marknoticed_chat.rs +95 -0
  50. benches/receive_emails.rs +160 -0
.cargo/config.toml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [env]
2
+ # In unoptimised builds tokio tends to use a lot of stack space when
3
+ # creating some complicated futures, tokio has an open issue for this:
4
+ # https://github.com/tokio-rs/tokio/issues/2055. Some of our tests
5
+ # manage to not fit in the default 2MiB stack anymore due to this, so
6
+ # while the issue is not resolved we want to work around this.
7
+ # Because compiling optimised builds takes a very long time we prefer
8
+ # to avoid that. Setting this environment variable ensures that when
9
+ # invoking `cargo test` threads are allowed to have a large enough
10
+ # stack size without needing to use an optimised build.
11
+ RUST_MIN_STACK = "8388608"
.gitattributes CHANGED
@@ -1,35 +1,30 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ # normal text files should contain a simple LF lineend, the following settings
2
+ # ensures this even if the user has not set core.autocrlf.
3
+ * text=auto
4
+
5
+ # Checkout JavaScript files with LF line endings
6
+ # to prevent `prettier` from reporting errors on Windows.
7
+ *.js eol=lf
8
+ *.jsx eol=lf
9
+ *.ts eol=lf
10
+ *.tsx eol=lf
11
+ *.json eol=lf
12
+
13
+ # This directory contains email messages verbatim, and changing CRLF to
14
+ # LF will corrupt them.
15
+ test-data/** text=false
16
+
17
+ # binary files should be detected by git, however, to be sure, you can add them here explicitly
18
+ *.png binary
19
+ *.jpg binary
20
+ *.gif binary
21
+ *.ico binary
22
+
23
+ *.py diff=python
24
+ *.rs diff=rust
25
+ *.md diff=markdown
26
+ assets/welcome-image.jpg filter=lfs diff=lfs merge=lfs -text
27
+ test-data/image/screenshot-rgba.png filter=lfs diff=lfs merge=lfs -text
28
+ test-data/image/screenshot.gif filter=lfs diff=lfs merge=lfs -text
29
+ test-data/image/screenshot.jpg filter=lfs diff=lfs merge=lfs -text
30
+ test-data/image/screenshot.png filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
.github/ISSUE_TEMPLATE/bug_report.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Bug report
3
+ about: Report something that isn't working.
4
+ title: ''
5
+ assignees: ''
6
+ labels: bug
7
+ ---
8
+
9
+ <!--
10
+ This is the chatmail core's bug report tracker.
11
+ For Delta Chat feature requests and support, please go to the forum: https://support.delta.chat
12
+ Please fill out as much of this form as you can (leaving out stuff that is not applicable is ok).
13
+ -->
14
+
15
+ - Operating System (Linux/Mac/Windows/iOS/Android):
16
+ - Core Version:
17
+ - Client Version:
18
+
19
+ ## Expected behavior
20
+
21
+ *What did you try to achieve?*
22
+
23
+ ## Actual behavior
24
+
25
+ *What happened instead?*
26
+
27
+ ### Steps to reproduce the problem
28
+
29
+ 1.
30
+ 2.
31
+
32
+ ### Screenshots
33
+
34
+ ### Logs
35
+
.github/dependabot.yml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "cargo"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "monthly"
7
+ commit-message:
8
+ prefix: "chore(cargo)"
9
+ open-pull-requests-limit: 50
10
+ cooldown:
11
+ default-days: 7
12
+
13
+ # Keep GitHub Actions up to date.
14
+ # <https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot>
15
+ - package-ecosystem: "github-actions"
16
+ directory: "/"
17
+ schedule:
18
+ interval: "weekly"
19
+ cooldown:
20
+ default-days: 7
.github/workflows/ci.yml ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GitHub Actions workflow to
2
+ # lint Rust and Python code
3
+ # and run Rust tests, Python tests and async Python tests.
4
+
5
+ name: Rust CI
6
+
7
+ # Cancel previously started workflow runs
8
+ # when the branch is updated.
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ on:
14
+ pull_request:
15
+ push:
16
+ branches:
17
+ - main
18
+
19
+ permissions: {}
20
+
21
+ env:
22
+ RUSTFLAGS: -Dwarnings
23
+ RUST_VERSION: 1.92.0
24
+
25
+ # Minimum Supported Rust Version
26
+ MSRV: 1.88.0
27
+
28
+ jobs:
29
+ lint_rust:
30
+ name: Lint Rust
31
+ runs-on: ubuntu-latest
32
+ timeout-minutes: 60
33
+ steps:
34
+ - uses: actions/checkout@v6
35
+ with:
36
+ show-progress: false
37
+ persist-credentials: false
38
+ - name: Install rustfmt and clippy
39
+ run: rustup toolchain install $RUST_VERSION --profile minimal --component rustfmt --component clippy
40
+ - run: rustup override set $RUST_VERSION
41
+ shell: bash
42
+ - name: Cache rust cargo artifacts
43
+ uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
44
+ - name: Run rustfmt
45
+ run: cargo fmt --all -- --check
46
+ - name: Run clippy
47
+ run: scripts/clippy.sh
48
+ - name: Check with all features
49
+ run: cargo check --workspace --all-targets --all-features
50
+ - name: Check with only default features
51
+ run: cargo check --all-targets
52
+
53
+ cargo_deny:
54
+ name: cargo deny
55
+ runs-on: ubuntu-latest
56
+ timeout-minutes: 60
57
+ steps:
58
+ - uses: actions/checkout@v6
59
+ with:
60
+ show-progress: false
61
+ persist-credentials: false
62
+ - uses: EmbarkStudios/cargo-deny-action@76cd80eb775d7bbbd2d80292136d74d39e1b4918
63
+ with:
64
+ arguments: --all-features --workspace
65
+ command: check
66
+ command-arguments: "-Dwarnings"
67
+
68
+ provider_database:
69
+ name: Check provider database
70
+ runs-on: ubuntu-latest
71
+ timeout-minutes: 60
72
+ steps:
73
+ - uses: actions/checkout@v6
74
+ with:
75
+ show-progress: false
76
+ persist-credentials: false
77
+ - name: Install rustfmt
78
+ run: rustup component add --toolchain stable-x86_64-unknown-linux-gnu rustfmt
79
+ - name: Check provider database
80
+ run: scripts/update-provider-database.sh
81
+
82
+ docs:
83
+ name: Rust doc comments
84
+ runs-on: ubuntu-latest
85
+ timeout-minutes: 60
86
+ env:
87
+ RUSTDOCFLAGS: -Dwarnings
88
+ steps:
89
+ - uses: actions/checkout@v6
90
+ with:
91
+ show-progress: false
92
+ persist-credentials: false
93
+ - name: Cache rust cargo artifacts
94
+ uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
95
+ - name: Rustdoc
96
+ run: cargo doc --document-private-items --no-deps
97
+
98
+ rust_tests:
99
+ name: Rust tests
100
+ strategy:
101
+ matrix:
102
+ include:
103
+ - os: ubuntu-latest
104
+ rust: latest
105
+ - os: windows-latest
106
+ rust: latest
107
+ - os: macos-latest
108
+ rust: latest
109
+
110
+ # Minimum Supported Rust Version
111
+ - os: ubuntu-latest
112
+ rust: minimum
113
+ runs-on: ${{ matrix.os }}
114
+ timeout-minutes: 60
115
+ steps:
116
+ - run:
117
+ echo "RUSTUP_TOOLCHAIN=$MSRV" >> $GITHUB_ENV
118
+ shell: bash
119
+ if: matrix.rust == 'minimum'
120
+ - run:
121
+ echo "RUSTUP_TOOLCHAIN=$RUST_VERSION" >> $GITHUB_ENV
122
+ shell: bash
123
+ if: matrix.rust == 'latest'
124
+
125
+ - uses: actions/checkout@v6
126
+ with:
127
+ show-progress: false
128
+ persist-credentials: false
129
+
130
+ - name: Install Rust ${{ matrix.rust }}
131
+ run: rustup toolchain install --profile minimal $RUSTUP_TOOLCHAIN
132
+ shell: bash
133
+ - run: rustup override set $RUSTUP_TOOLCHAIN
134
+ shell: bash
135
+
136
+ - name: Cache rust cargo artifacts
137
+ uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
138
+
139
+ - name: Install nextest
140
+ uses: taiki-e/install-action@69e777b377e4ec209ddad9426ae3e0c1008b0ef3
141
+ with:
142
+ tool: nextest
143
+
144
+ - name: Tests
145
+ env:
146
+ RUST_BACKTRACE: 1
147
+ run: cargo nextest run --workspace --locked
148
+
149
+ - name: Doc-Tests
150
+ env:
151
+ RUST_BACKTRACE: 1
152
+ run: cargo test --workspace --locked --doc
153
+
154
+ - name: Test cargo vendor
155
+ run: cargo vendor
156
+
157
+ c_library:
158
+ name: Build C library
159
+ strategy:
160
+ matrix:
161
+ os: [ubuntu-latest, macos-latest]
162
+ runs-on: ${{ matrix.os }}
163
+ timeout-minutes: 60
164
+ steps:
165
+ - uses: actions/checkout@v6
166
+ with:
167
+ show-progress: false
168
+ persist-credentials: false
169
+
170
+ - name: Cache rust cargo artifacts
171
+ uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
172
+
173
+ - name: Build C library
174
+ run: cargo build -p deltachat_ffi
175
+
176
+ - name: Upload C library
177
+ uses: actions/upload-artifact@v6
178
+ with:
179
+ name: ${{ matrix.os }}-libdeltachat.a
180
+ path: target/debug/libdeltachat.a
181
+ retention-days: 1
182
+
183
+ rpc_server:
184
+ name: Build deltachat-rpc-server
185
+ strategy:
186
+ matrix:
187
+ os: [ubuntu-latest, macos-latest, windows-latest]
188
+ runs-on: ${{ matrix.os }}
189
+ timeout-minutes: 60
190
+ steps:
191
+ - uses: actions/checkout@v6
192
+ with:
193
+ show-progress: false
194
+ persist-credentials: false
195
+
196
+ - name: Cache rust cargo artifacts
197
+ uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
198
+
199
+ - name: Build deltachat-rpc-server
200
+ run: cargo build -p deltachat-rpc-server
201
+
202
+ - name: Upload deltachat-rpc-server
203
+ uses: actions/upload-artifact@v6
204
+ with:
205
+ name: ${{ matrix.os }}-deltachat-rpc-server
206
+ path: ${{ matrix.os == 'windows-latest' && 'target/debug/deltachat-rpc-server.exe' || 'target/debug/deltachat-rpc-server' }}
207
+ retention-days: 1
208
+
209
+ python_lint:
210
+ name: Python lint
211
+ runs-on: ubuntu-latest
212
+ timeout-minutes: 60
213
+ steps:
214
+ - uses: actions/checkout@v6
215
+ with:
216
+ show-progress: false
217
+ persist-credentials: false
218
+
219
+ - name: Install tox
220
+ run: pip install tox
221
+
222
+ - name: Lint Python bindings
223
+ working-directory: python
224
+ run: tox -e lint
225
+
226
+ - name: Lint deltachat-rpc-client
227
+ working-directory: deltachat-rpc-client
228
+ run: tox -e lint
229
+
230
+ # mypy does not work with PyPy since mypy 1.19
231
+ # as it introduced native `librt` dependency
232
+ # that uses CPython internals.
233
+ # We only run mypy with CPython because of this.
234
+ cffi_python_mypy:
235
+ name: CFFI Python mypy
236
+ needs: ["c_library", "python_lint"]
237
+ runs-on: ubuntu-latest
238
+ timeout-minutes: 60
239
+ steps:
240
+ - uses: actions/checkout@v6
241
+ with:
242
+ show-progress: false
243
+ persist-credentials: false
244
+
245
+ - name: Download libdeltachat.a
246
+ uses: actions/download-artifact@v7
247
+ with:
248
+ name: ubuntu-latest-libdeltachat.a
249
+ path: target/debug
250
+
251
+ - name: Install tox
252
+ run: pip install tox
253
+
254
+ - name: Run mypy
255
+ env:
256
+ DCC_RS_TARGET: debug
257
+ DCC_RS_DEV: ${{ github.workspace }}
258
+ working-directory: python
259
+ run: tox -e mypy
260
+
261
+
262
+ cffi_python_tests:
263
+ name: CFFI Python tests
264
+ needs: ["c_library", "python_lint"]
265
+ strategy:
266
+ fail-fast: false
267
+ matrix:
268
+ include:
269
+ # Currently used Rust version.
270
+ - os: ubuntu-latest
271
+ python: 3.14
272
+ - os: macos-latest
273
+ python: 3.14
274
+
275
+ # PyPy tests
276
+ - os: ubuntu-latest
277
+ python: pypy3.10
278
+ - os: macos-latest
279
+ python: pypy3.10
280
+
281
+ # Minimum Supported Python Version = 3.10
282
+ # This is the minimum version for which manylinux Python wheels are
283
+ # built. Test it with minimum supported Rust version.
284
+ - os: ubuntu-latest
285
+ python: "3.10"
286
+
287
+ runs-on: ${{ matrix.os }}
288
+ timeout-minutes: 60
289
+ steps:
290
+ - uses: actions/checkout@v6
291
+ with:
292
+ show-progress: false
293
+ persist-credentials: false
294
+
295
+ - name: Download libdeltachat.a
296
+ uses: actions/download-artifact@v7
297
+ with:
298
+ name: ${{ matrix.os }}-libdeltachat.a
299
+ path: target/debug
300
+
301
+ - name: Install python
302
+ uses: actions/setup-python@v6
303
+ with:
304
+ python-version: ${{ matrix.python }}
305
+
306
+ - name: Install tox
307
+ run: pip install tox
308
+
309
+ - name: Run python tests
310
+ env:
311
+ CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }}
312
+ DCC_RS_TARGET: debug
313
+ DCC_RS_DEV: ${{ github.workspace }}
314
+ working-directory: python
315
+ run: tox -e doc,py
316
+
317
+ rpc_python_tests:
318
+ name: JSON-RPC Python tests
319
+ needs: ["python_lint", "rpc_server"]
320
+ strategy:
321
+ fail-fast: false
322
+ matrix:
323
+ include:
324
+ - os: ubuntu-latest
325
+ python: 3.14
326
+ - os: macos-latest
327
+ python: 3.14
328
+ - os: windows-latest
329
+ python: 3.14
330
+
331
+ # PyPy tests
332
+ - os: ubuntu-latest
333
+ python: pypy3.10
334
+ - os: macos-latest
335
+ python: pypy3.10
336
+
337
+ # Minimum Supported Python Version = 3.10
338
+ - os: ubuntu-latest
339
+ python: "3.10"
340
+
341
+ runs-on: ${{ matrix.os }}
342
+ timeout-minutes: 60
343
+ steps:
344
+ - uses: actions/checkout@v6
345
+ with:
346
+ show-progress: false
347
+ persist-credentials: false
348
+
349
+ - name: Install python
350
+ uses: actions/setup-python@v6
351
+ with:
352
+ python-version: ${{ matrix.python }}
353
+
354
+ - name: Install tox
355
+ run: pip install tox
356
+
357
+ - name: Download deltachat-rpc-server
358
+ uses: actions/download-artifact@v7
359
+ with:
360
+ name: ${{ matrix.os }}-deltachat-rpc-server
361
+ path: target/debug
362
+
363
+ - name: Make deltachat-rpc-server executable
364
+ if: ${{ matrix.os != 'windows-latest' }}
365
+ run: chmod +x target/debug/deltachat-rpc-server
366
+
367
+ - name: Add deltachat-rpc-server to path
368
+ if: ${{ matrix.os != 'windows-latest' }}
369
+ run: echo ${{ github.workspace }}/target/debug >> $GITHUB_PATH
370
+
371
+ - name: Add deltachat-rpc-server to path
372
+ if: ${{ matrix.os == 'windows-latest' }}
373
+ run: |
374
+ "${{ github.workspace }}/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
375
+
376
+ - name: Run deltachat-rpc-client tests
377
+ env:
378
+ CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }}
379
+ working-directory: deltachat-rpc-client
380
+ run: tox -e py
.github/workflows/deltachat-rpc-server.yml ADDED
@@ -0,0 +1,531 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GitHub Actions workflow
2
+ # to build `deltachat-rpc-server` binaries
3
+ # and upload them to the release.
4
+ #
5
+ # The workflow is automatically triggered on releases.
6
+ # It can also be triggered manually
7
+ # to produce binary artifacts for testing.
8
+
9
+ name: Build deltachat-rpc-server binaries
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ on:
16
+ workflow_dispatch:
17
+ release:
18
+ types: [published]
19
+
20
+ permissions: {}
21
+
22
+ jobs:
23
+ # Build a version statically linked against musl libc
24
+ # to avoid problems with glibc version incompatibility.
25
+ build_linux:
26
+ name: Linux
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ arch: [aarch64, armv7l, armv6l, i686, x86_64]
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v6
34
+ with:
35
+ show-progress: false
36
+ persist-credentials: false
37
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
38
+
39
+ - name: Build deltachat-rpc-server binaries
40
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-linux
41
+
42
+ - name: Upload binary
43
+ uses: actions/upload-artifact@v6
44
+ with:
45
+ name: deltachat-rpc-server-${{ matrix.arch }}-linux
46
+ path: result/bin/deltachat-rpc-server
47
+ if-no-files-found: error
48
+
49
+ build_linux_wheel:
50
+ name: Linux wheel
51
+ strategy:
52
+ fail-fast: false
53
+ matrix:
54
+ arch: [aarch64, armv7l, armv6l, i686, x86_64]
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - uses: actions/checkout@v6
58
+ with:
59
+ show-progress: false
60
+ persist-credentials: false
61
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
62
+
63
+ - name: Build deltachat-rpc-server wheels
64
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-linux-wheel
65
+
66
+ - name: Upload wheel
67
+ uses: actions/upload-artifact@v6
68
+ with:
69
+ name: deltachat-rpc-server-${{ matrix.arch }}-linux-wheel
70
+ path: result/*.whl
71
+ if-no-files-found: error
72
+
73
+ build_windows:
74
+ name: Windows
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ arch: [win32, win64]
79
+ runs-on: ubuntu-latest
80
+ steps:
81
+ - uses: actions/checkout@v6
82
+ with:
83
+ show-progress: false
84
+ persist-credentials: false
85
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
86
+
87
+ - name: Build deltachat-rpc-server binaries
88
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}
89
+
90
+ - name: Upload binary
91
+ uses: actions/upload-artifact@v6
92
+ with:
93
+ name: deltachat-rpc-server-${{ matrix.arch }}
94
+ path: result/bin/deltachat-rpc-server.exe
95
+ if-no-files-found: error
96
+
97
+ build_windows_wheel:
98
+ name: Windows wheel
99
+ strategy:
100
+ fail-fast: false
101
+ matrix:
102
+ arch: [win32, win64]
103
+ runs-on: ubuntu-latest
104
+ steps:
105
+ - uses: actions/checkout@v6
106
+ with:
107
+ show-progress: false
108
+ persist-credentials: false
109
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
110
+
111
+ - name: Build deltachat-rpc-server wheels
112
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-wheel
113
+
114
+ - name: Upload wheel
115
+ uses: actions/upload-artifact@v6
116
+ with:
117
+ name: deltachat-rpc-server-${{ matrix.arch }}-wheel
118
+ path: result/*.whl
119
+ if-no-files-found: error
120
+
121
+ build_macos:
122
+ name: macOS
123
+ strategy:
124
+ fail-fast: false
125
+ matrix:
126
+ arch: [x86_64, aarch64]
127
+
128
+ runs-on: macos-latest
129
+ steps:
130
+ - uses: actions/checkout@v6
131
+ with:
132
+ show-progress: false
133
+ persist-credentials: false
134
+
135
+ - name: Setup rust target
136
+ run: rustup target add ${{ matrix.arch }}-apple-darwin
137
+
138
+ - name: Build
139
+ run: cargo build --release --package deltachat-rpc-server --target ${{ matrix.arch }}-apple-darwin --features vendored
140
+
141
+ - name: Upload binary
142
+ uses: actions/upload-artifact@v6
143
+ with:
144
+ name: deltachat-rpc-server-${{ matrix.arch }}-macos
145
+ path: target/${{ matrix.arch }}-apple-darwin/release/deltachat-rpc-server
146
+ if-no-files-found: error
147
+
148
+ build_android:
149
+ name: Android
150
+ strategy:
151
+ fail-fast: false
152
+ matrix:
153
+ arch: [arm64-v8a, armeabi-v7a]
154
+ runs-on: ubuntu-latest
155
+ steps:
156
+ - uses: actions/checkout@v6
157
+ with:
158
+ show-progress: false
159
+ persist-credentials: false
160
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
161
+
162
+ - name: Build deltachat-rpc-server binaries
163
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-android
164
+
165
+ - name: Upload binary
166
+ uses: actions/upload-artifact@v6
167
+ with:
168
+ name: deltachat-rpc-server-${{ matrix.arch }}-android
169
+ path: result/bin/deltachat-rpc-server
170
+ if-no-files-found: error
171
+
172
+ build_android_wheel:
173
+ name: Android wheel
174
+ strategy:
175
+ fail-fast: false
176
+ matrix:
177
+ arch: [arm64-v8a, armeabi-v7a]
178
+ runs-on: ubuntu-latest
179
+ steps:
180
+ - uses: actions/checkout@v6
181
+ with:
182
+ show-progress: false
183
+ persist-credentials: false
184
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
185
+
186
+ - name: Build deltachat-rpc-server wheels
187
+ run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-android-wheel
188
+
189
+ - name: Upload wheel
190
+ uses: actions/upload-artifact@v6
191
+ with:
192
+ name: deltachat-rpc-server-${{ matrix.arch }}-android-wheel
193
+ path: result/*.whl
194
+ if-no-files-found: error
195
+
196
+ publish:
197
+ name: Build wheels and upload binaries to the release
198
+ needs: ["build_linux", "build_linux_wheel", "build_windows", "build_windows_wheel", "build_macos", "build_android", "build_android_wheel"]
199
+ environment:
200
+ name: pypi
201
+ url: https://pypi.org/p/deltachat-rpc-server
202
+ permissions:
203
+ id-token: write
204
+ contents: write
205
+ runs-on: "ubuntu-latest"
206
+ steps:
207
+ - uses: actions/checkout@v6
208
+ with:
209
+ show-progress: false
210
+ persist-credentials: false
211
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
212
+
213
+ - name: Download Linux aarch64 binary
214
+ uses: actions/download-artifact@v7
215
+ with:
216
+ name: deltachat-rpc-server-aarch64-linux
217
+ path: deltachat-rpc-server-aarch64-linux.d
218
+
219
+ - name: Download Linux aarch64 wheel
220
+ uses: actions/download-artifact@v7
221
+ with:
222
+ name: deltachat-rpc-server-aarch64-linux-wheel
223
+ path: deltachat-rpc-server-aarch64-linux-wheel.d
224
+
225
+ - name: Download Linux armv7l binary
226
+ uses: actions/download-artifact@v7
227
+ with:
228
+ name: deltachat-rpc-server-armv7l-linux
229
+ path: deltachat-rpc-server-armv7l-linux.d
230
+
231
+ - name: Download Linux armv7l wheel
232
+ uses: actions/download-artifact@v7
233
+ with:
234
+ name: deltachat-rpc-server-armv7l-linux-wheel
235
+ path: deltachat-rpc-server-armv7l-linux-wheel.d
236
+
237
+ - name: Download Linux armv6l binary
238
+ uses: actions/download-artifact@v7
239
+ with:
240
+ name: deltachat-rpc-server-armv6l-linux
241
+ path: deltachat-rpc-server-armv6l-linux.d
242
+
243
+ - name: Download Linux armv6l wheel
244
+ uses: actions/download-artifact@v7
245
+ with:
246
+ name: deltachat-rpc-server-armv6l-linux-wheel
247
+ path: deltachat-rpc-server-armv6l-linux-wheel.d
248
+
249
+ - name: Download Linux i686 binary
250
+ uses: actions/download-artifact@v7
251
+ with:
252
+ name: deltachat-rpc-server-i686-linux
253
+ path: deltachat-rpc-server-i686-linux.d
254
+
255
+ - name: Download Linux i686 wheel
256
+ uses: actions/download-artifact@v7
257
+ with:
258
+ name: deltachat-rpc-server-i686-linux-wheel
259
+ path: deltachat-rpc-server-i686-linux-wheel.d
260
+
261
+ - name: Download Linux x86_64 binary
262
+ uses: actions/download-artifact@v7
263
+ with:
264
+ name: deltachat-rpc-server-x86_64-linux
265
+ path: deltachat-rpc-server-x86_64-linux.d
266
+
267
+ - name: Download Linux x86_64 wheel
268
+ uses: actions/download-artifact@v7
269
+ with:
270
+ name: deltachat-rpc-server-x86_64-linux-wheel
271
+ path: deltachat-rpc-server-x86_64-linux-wheel.d
272
+
273
+ - name: Download Win32 binary
274
+ uses: actions/download-artifact@v7
275
+ with:
276
+ name: deltachat-rpc-server-win32
277
+ path: deltachat-rpc-server-win32.d
278
+
279
+ - name: Download Win32 wheel
280
+ uses: actions/download-artifact@v7
281
+ with:
282
+ name: deltachat-rpc-server-win32-wheel
283
+ path: deltachat-rpc-server-win32-wheel.d
284
+
285
+ - name: Download Win64 binary
286
+ uses: actions/download-artifact@v7
287
+ with:
288
+ name: deltachat-rpc-server-win64
289
+ path: deltachat-rpc-server-win64.d
290
+
291
+ - name: Download Win64 wheel
292
+ uses: actions/download-artifact@v7
293
+ with:
294
+ name: deltachat-rpc-server-win64-wheel
295
+ path: deltachat-rpc-server-win64-wheel.d
296
+
297
+ - name: Download macOS binary for x86_64
298
+ uses: actions/download-artifact@v7
299
+ with:
300
+ name: deltachat-rpc-server-x86_64-macos
301
+ path: deltachat-rpc-server-x86_64-macos.d
302
+
303
+ - name: Download macOS binary for aarch64
304
+ uses: actions/download-artifact@v7
305
+ with:
306
+ name: deltachat-rpc-server-aarch64-macos
307
+ path: deltachat-rpc-server-aarch64-macos.d
308
+
309
+ - name: Download Android binary for arm64-v8a
310
+ uses: actions/download-artifact@v7
311
+ with:
312
+ name: deltachat-rpc-server-arm64-v8a-android
313
+ path: deltachat-rpc-server-arm64-v8a-android.d
314
+
315
+ - name: Download Android wheel for arm64-v8a
316
+ uses: actions/download-artifact@v7
317
+ with:
318
+ name: deltachat-rpc-server-arm64-v8a-android-wheel
319
+ path: deltachat-rpc-server-arm64-v8a-android-wheel.d
320
+
321
+ - name: Download Android binary for armeabi-v7a
322
+ uses: actions/download-artifact@v7
323
+ with:
324
+ name: deltachat-rpc-server-armeabi-v7a-android
325
+ path: deltachat-rpc-server-armeabi-v7a-android.d
326
+
327
+ - name: Download Android wheel for armeabi-v7a
328
+ uses: actions/download-artifact@v7
329
+ with:
330
+ name: deltachat-rpc-server-armeabi-v7a-android-wheel
331
+ path: deltachat-rpc-server-armeabi-v7a-android-wheel.d
332
+
333
+ - name: Create bin/ directory
334
+ run: |
335
+ mkdir -p bin
336
+ mv deltachat-rpc-server-aarch64-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-aarch64-linux
337
+ mv deltachat-rpc-server-armv7l-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-armv7l-linux
338
+ mv deltachat-rpc-server-armv6l-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-armv6l-linux
339
+ mv deltachat-rpc-server-i686-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-i686-linux
340
+ mv deltachat-rpc-server-x86_64-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-x86_64-linux
341
+ mv deltachat-rpc-server-win32.d/deltachat-rpc-server.exe bin/deltachat-rpc-server-win32.exe
342
+ mv deltachat-rpc-server-win64.d/deltachat-rpc-server.exe bin/deltachat-rpc-server-win64.exe
343
+ mv deltachat-rpc-server-x86_64-macos.d/deltachat-rpc-server bin/deltachat-rpc-server-x86_64-macos
344
+ mv deltachat-rpc-server-aarch64-macos.d/deltachat-rpc-server bin/deltachat-rpc-server-aarch64-macos
345
+ mv deltachat-rpc-server-arm64-v8a-android.d/deltachat-rpc-server bin/deltachat-rpc-server-arm64-v8a-android
346
+ mv deltachat-rpc-server-armeabi-v7a-android.d/deltachat-rpc-server bin/deltachat-rpc-server-armeabi-v7a-android
347
+
348
+ - name: List binaries
349
+ run: ls -l bin/
350
+
351
+ - name: Install wheel
352
+ run: pip install wheel
353
+
354
+ - name: Build deltachat-rpc-server Python wheels
355
+ run: |
356
+ mkdir -p dist
357
+ mv deltachat-rpc-server-aarch64-linux-wheel.d/*.whl dist/
358
+ mv deltachat-rpc-server-armv7l-linux-wheel.d/*.whl dist/
359
+ mv deltachat-rpc-server-armv6l-linux-wheel.d/*.whl dist/
360
+ mv deltachat-rpc-server-i686-linux-wheel.d/*.whl dist/
361
+ mv deltachat-rpc-server-x86_64-linux-wheel.d/*.whl dist/
362
+ mv deltachat-rpc-server-win64-wheel.d/*.whl dist/
363
+ mv deltachat-rpc-server-win32-wheel.d/*.whl dist/
364
+ mv deltachat-rpc-server-arm64-v8a-android-wheel.d/*.whl dist/
365
+ mv deltachat-rpc-server-armeabi-v7a-android-wheel.d/*.whl dist/
366
+ python3 scripts/wheel-rpc-server.py x86_64-darwin bin/deltachat-rpc-server-x86_64-macos
367
+ python3 scripts/wheel-rpc-server.py aarch64-darwin bin/deltachat-rpc-server-aarch64-macos
368
+ mv *.whl dist/
369
+
370
+ - name: List artifacts
371
+ run: ls -l dist/
372
+
373
+ - name: Upload binaries to the GitHub release
374
+ if: github.event_name == 'release'
375
+ env:
376
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
377
+ REF_NAME: ${{ github.ref_name }}
378
+ run: |
379
+ gh release upload "$REF_NAME" \
380
+ --repo ${{ github.repository }} \
381
+ bin/* dist/*
382
+
383
+ - name: Publish deltachat-rpc-server to PyPI
384
+ if: github.event_name == 'release'
385
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e
386
+
387
+ publish_npm_package:
388
+ name: Build & Publish npm prebuilds and deltachat-rpc-server
389
+ needs: ["build_linux", "build_windows", "build_macos"]
390
+ runs-on: "ubuntu-latest"
391
+ environment:
392
+ name: npm-stdio-rpc-server
393
+ url: https://www.npmjs.com/package/@deltachat/stdio-rpc-server
394
+ permissions:
395
+ id-token: write
396
+
397
+ # Needed to publish the binaries to the release.
398
+ contents: write
399
+ steps:
400
+ - uses: actions/checkout@v6
401
+ with:
402
+ show-progress: false
403
+ persist-credentials: false
404
+ - uses: actions/setup-python@v6
405
+ with:
406
+ python-version: "3.11"
407
+
408
+ - name: Download Linux aarch64 binary
409
+ uses: actions/download-artifact@v7
410
+ with:
411
+ name: deltachat-rpc-server-aarch64-linux
412
+ path: deltachat-rpc-server-aarch64-linux.d
413
+
414
+ - name: Download Linux armv7l binary
415
+ uses: actions/download-artifact@v7
416
+ with:
417
+ name: deltachat-rpc-server-armv7l-linux
418
+ path: deltachat-rpc-server-armv7l-linux.d
419
+
420
+ - name: Download Linux armv6l binary
421
+ uses: actions/download-artifact@v7
422
+ with:
423
+ name: deltachat-rpc-server-armv6l-linux
424
+ path: deltachat-rpc-server-armv6l-linux.d
425
+
426
+ - name: Download Linux i686 binary
427
+ uses: actions/download-artifact@v7
428
+ with:
429
+ name: deltachat-rpc-server-i686-linux
430
+ path: deltachat-rpc-server-i686-linux.d
431
+
432
+ - name: Download Linux x86_64 binary
433
+ uses: actions/download-artifact@v7
434
+ with:
435
+ name: deltachat-rpc-server-x86_64-linux
436
+ path: deltachat-rpc-server-x86_64-linux.d
437
+
438
+ - name: Download Win32 binary
439
+ uses: actions/download-artifact@v7
440
+ with:
441
+ name: deltachat-rpc-server-win32
442
+ path: deltachat-rpc-server-win32.d
443
+
444
+ - name: Download Win64 binary
445
+ uses: actions/download-artifact@v7
446
+ with:
447
+ name: deltachat-rpc-server-win64
448
+ path: deltachat-rpc-server-win64.d
449
+
450
+ - name: Download macOS binary for x86_64
451
+ uses: actions/download-artifact@v7
452
+ with:
453
+ name: deltachat-rpc-server-x86_64-macos
454
+ path: deltachat-rpc-server-x86_64-macos.d
455
+
456
+ - name: Download macOS binary for aarch64
457
+ uses: actions/download-artifact@v7
458
+ with:
459
+ name: deltachat-rpc-server-aarch64-macos
460
+ path: deltachat-rpc-server-aarch64-macos.d
461
+
462
+ - name: Download Android binary for arm64-v8a
463
+ uses: actions/download-artifact@v7
464
+ with:
465
+ name: deltachat-rpc-server-arm64-v8a-android
466
+ path: deltachat-rpc-server-arm64-v8a-android.d
467
+
468
+ - name: Download Android binary for armeabi-v7a
469
+ uses: actions/download-artifact@v7
470
+ with:
471
+ name: deltachat-rpc-server-armeabi-v7a-android
472
+ path: deltachat-rpc-server-armeabi-v7a-android.d
473
+
474
+ - name: make npm packets for prebuilds and `@deltachat/stdio-rpc-server`
475
+ run: |
476
+ cd deltachat-rpc-server/npm-package
477
+
478
+ python --version
479
+
480
+ python scripts/pack_binary_for_platform.py aarch64-unknown-linux-musl ../../deltachat-rpc-server-aarch64-linux.d/deltachat-rpc-server
481
+ python scripts/pack_binary_for_platform.py armv7-unknown-linux-musleabihf ../../deltachat-rpc-server-armv7l-linux.d/deltachat-rpc-server
482
+ python scripts/pack_binary_for_platform.py arm-unknown-linux-musleabihf ../../deltachat-rpc-server-armv6l-linux.d/deltachat-rpc-server
483
+ python scripts/pack_binary_for_platform.py i686-unknown-linux-musl ../../deltachat-rpc-server-i686-linux.d/deltachat-rpc-server
484
+ python scripts/pack_binary_for_platform.py x86_64-unknown-linux-musl ../../deltachat-rpc-server-x86_64-linux.d/deltachat-rpc-server
485
+ python scripts/pack_binary_for_platform.py i686-pc-windows-gnu ../../deltachat-rpc-server-win32.d/deltachat-rpc-server.exe
486
+ python scripts/pack_binary_for_platform.py x86_64-pc-windows-gnu ../../deltachat-rpc-server-win64.d/deltachat-rpc-server.exe
487
+ python scripts/pack_binary_for_platform.py x86_64-apple-darwin ../../deltachat-rpc-server-x86_64-macos.d/deltachat-rpc-server
488
+ python scripts/pack_binary_for_platform.py aarch64-apple-darwin ../../deltachat-rpc-server-aarch64-macos.d/deltachat-rpc-server
489
+ python scripts/pack_binary_for_platform.py aarch64-linux-android ../../deltachat-rpc-server-arm64-v8a-android.d/deltachat-rpc-server
490
+ python scripts/pack_binary_for_platform.py armv7-linux-androideabi ../../deltachat-rpc-server-armeabi-v7a-android.d/deltachat-rpc-server
491
+
492
+ ls -lah platform_package
493
+
494
+ for platform in ./platform_package/*; do npm pack "$platform"; done
495
+ npm pack
496
+ ls -lah
497
+
498
+ - name: Upload to artifacts
499
+ uses: actions/upload-artifact@v6
500
+ with:
501
+ name: deltachat-rpc-server-npm-package
502
+ path: deltachat-rpc-server/npm-package/*.tgz
503
+ if-no-files-found: error
504
+
505
+ - name: Upload npm packets to the GitHub release
506
+ if: github.event_name == 'release'
507
+ env:
508
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
509
+ REF_NAME: ${{ github.ref_name }}
510
+ run: |
511
+ gh release upload "$REF_NAME" \
512
+ --repo ${{ github.repository }} \
513
+ deltachat-rpc-server/npm-package/*.tgz
514
+
515
+ # Configure Node.js for publishing.
516
+ - uses: actions/setup-node@v6
517
+ with:
518
+ node-version: 20
519
+ registry-url: "https://registry.npmjs.org"
520
+
521
+ # Ensure npm 11.5.1 or later is installed.
522
+ # It is needed for <https://docs.npmjs.com/trusted-publishers>
523
+ - name: Update npm
524
+ run: npm install -g npm@latest
525
+
526
+ - name: Publish npm packets for prebuilds and `@deltachat/stdio-rpc-server`
527
+ if: github.event_name == 'release'
528
+ working-directory: deltachat-rpc-server/npm-package
529
+ run: |
530
+ ls -lah platform_package
531
+ for platform in *.tgz; do npm publish --provenance "$platform" --access public; done
.github/workflows/dependabot.yml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GitHub Actions workflow
2
+ # to automatically approve PRs made by Dependabot.
3
+
4
+ name: Dependabot auto-approve
5
+ on: pull_request
6
+
7
+ permissions:
8
+ pull-requests: write
9
+
10
+ jobs:
11
+ dependabot:
12
+ runs-on: ubuntu-latest
13
+ if: ${{ github.actor == 'dependabot[bot]' }}
14
+ steps:
15
+ - name: Dependabot metadata
16
+ id: metadata
17
+ uses: dependabot/fetch-metadata@v2.4.0
18
+ with:
19
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
20
+ - name: Approve a PR
21
+ run: gh pr review --approve "$PR_URL"
22
+ env:
23
+ PR_URL: ${{github.event.pull_request.html_url}}
24
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
.github/workflows/jsonrpc-client-npm-package.yml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "Publish @deltachat/jsonrpc-client"
2
+ on:
3
+ workflow_dispatch:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions: {}
8
+
9
+ jobs:
10
+ pack-module:
11
+ name: "Publish @deltachat/jsonrpc-client"
12
+ runs-on: ubuntu-latest
13
+ environment:
14
+ name: npm-jsonrpc-client
15
+ url: https://www.npmjs.com/package/@deltachat/jsonrpc-client
16
+ permissions:
17
+ id-token: write
18
+ contents: read
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+ with:
22
+ show-progress: false
23
+ persist-credentials: false
24
+
25
+ - uses: actions/setup-node@v6
26
+ with:
27
+ node-version: 20
28
+ registry-url: "https://registry.npmjs.org"
29
+
30
+ # Ensure npm 11.5.1 or later is installed.
31
+ # It is needed for <https://docs.npmjs.com/trusted-publishers>
32
+ - name: Update npm
33
+ run: npm install -g npm@latest
34
+
35
+ - name: Install dependencies without running scripts
36
+ working-directory: deltachat-jsonrpc/typescript
37
+ run: npm install --ignore-scripts
38
+
39
+ - name: Package
40
+ working-directory: deltachat-jsonrpc/typescript
41
+ run: |
42
+ npm run build
43
+ npm pack .
44
+
45
+ - name: Publish
46
+ working-directory: deltachat-jsonrpc/typescript
47
+ run: npm publish --provenance deltachat-jsonrpc-client-* --access public
.github/workflows/jsonrpc.yml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: JSON-RPC API Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions: {}
10
+
11
+ env:
12
+ CARGO_TERM_COLOR: always
13
+ RUST_MIN_STACK: "8388608"
14
+
15
+ jobs:
16
+ build_and_test:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v6
20
+ with:
21
+ show-progress: false
22
+ persist-credentials: false
23
+ - name: Use Node.js 18.x
24
+ uses: actions/setup-node@v6
25
+ with:
26
+ node-version: 18.x
27
+ - name: Add Rust cache
28
+ uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5
29
+ - name: npm install
30
+ working-directory: deltachat-jsonrpc/typescript
31
+ run: npm install
32
+ - name: Build TypeScript, run Rust tests, generate bindings
33
+ working-directory: deltachat-jsonrpc/typescript
34
+ run: npm run build
35
+ - name: Run integration tests
36
+ working-directory: deltachat-jsonrpc/typescript
37
+ run: npm run test
38
+ env:
39
+ CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }}
40
+ - name: Run linter
41
+ working-directory: deltachat-jsonrpc/typescript
42
+ run: npm run prettier:check
.github/workflows/nix.yml ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Test Nix flake
2
+
3
+ on:
4
+ pull_request:
5
+ paths:
6
+ - flake.nix
7
+ - flake.lock
8
+ - .github/workflows/nix.yml
9
+ push:
10
+ paths:
11
+ - flake.nix
12
+ - flake.lock
13
+ - .github/workflows/nix.yml
14
+ branches:
15
+ - main
16
+
17
+ permissions: {}
18
+
19
+ jobs:
20
+ format:
21
+ name: check flake formatting
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v6
25
+ with:
26
+ show-progress: false
27
+ persist-credentials: false
28
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
29
+ - run: nix fmt flake.nix -- --check
30
+
31
+ build:
32
+ name: nix build
33
+ runs-on: ubuntu-latest
34
+ strategy:
35
+ fail-fast: false
36
+ matrix:
37
+ installable:
38
+ # Ensure `nix develop` will work.
39
+ - devShells.x86_64-linux.default
40
+
41
+ - deltachat-python
42
+ - deltachat-repl
43
+ - deltachat-repl-aarch64-linux
44
+ - deltachat-repl-arm64-v8a-android
45
+ - deltachat-repl-armeabi-v7a-android
46
+ - deltachat-repl-armv6l-linux
47
+ - deltachat-repl-armv7l-linux
48
+ - deltachat-repl-i686-linux
49
+ - deltachat-repl-win32
50
+ - deltachat-repl-win64
51
+ - deltachat-repl-x86_64-linux
52
+ - deltachat-rpc-client
53
+ - deltachat-rpc-server
54
+ - deltachat-rpc-server-aarch64-linux
55
+ - deltachat-rpc-server-aarch64-linux-wheel
56
+ - deltachat-rpc-server-arm64-v8a-android
57
+ - deltachat-rpc-server-arm64-v8a-android-wheel
58
+ - deltachat-rpc-server-armeabi-v7a-android
59
+ - deltachat-rpc-server-armeabi-v7a-android-wheel
60
+ - deltachat-rpc-server-armv6l-linux
61
+ - deltachat-rpc-server-armv6l-linux-wheel
62
+ - deltachat-rpc-server-armv7l-linux
63
+ - deltachat-rpc-server-armv7l-linux-wheel
64
+ - deltachat-rpc-server-i686-linux
65
+ - deltachat-rpc-server-i686-linux-wheel
66
+ - deltachat-rpc-server-source
67
+ - deltachat-rpc-server-win32
68
+ - deltachat-rpc-server-win32-wheel
69
+ - deltachat-rpc-server-win64
70
+ - deltachat-rpc-server-win64-wheel
71
+ - deltachat-rpc-server-x86_64-linux
72
+ - deltachat-rpc-server-x86_64-linux-wheel
73
+ - docs
74
+ - libdeltachat
75
+ - python-docs
76
+
77
+ # Fails to build
78
+ #- deltachat-repl-x86_64-android
79
+ #- deltachat-repl-x86-android
80
+ #- deltachat-rpc-server-x86_64-android
81
+ #- deltachat-rpc-server-x86-android
82
+ steps:
83
+ - uses: actions/checkout@v6
84
+ with:
85
+ show-progress: false
86
+ persist-credentials: false
87
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
88
+ - run: nix build .#${{ matrix.installable }}
89
+
90
+ build-macos:
91
+ name: nix build on macOS
92
+ runs-on: macos-latest
93
+ strategy:
94
+ fail-fast: false
95
+ matrix:
96
+ installable:
97
+ - deltachat-rpc-server
98
+ - deltachat-rpc-server-x86_64-darwin
99
+
100
+ # Fails to build
101
+ # because of <https://github.com/NixOS/nixpkgs/issues/413910>.
102
+ # - deltachat-rpc-server-aarch64-darwin
103
+ steps:
104
+ - uses: actions/checkout@v6
105
+ with:
106
+ show-progress: false
107
+ persist-credentials: false
108
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
109
+ - run: nix build .#${{ matrix.installable }}
.github/workflows/publish-deltachat-rpc-client-pypi.yml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Publish deltachat-rpc-client to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [published]
7
+
8
+ permissions: {}
9
+
10
+ jobs:
11
+ build:
12
+ name: Build distribution
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ show-progress: false
19
+ persist-credentials: false
20
+ - name: Install pypa/build
21
+ run: python3 -m pip install build
22
+ - name: Build a binary wheel and a source tarball
23
+ working-directory: deltachat-rpc-client
24
+ run: python3 -m build
25
+ - name: Store the distribution packages
26
+ uses: actions/upload-artifact@v6
27
+ with:
28
+ name: python-package-distributions
29
+ path: deltachat-rpc-client/dist/
30
+
31
+ publish-to-pypi:
32
+ name: Publish Python distribution to PyPI
33
+ if: github.event_name == 'release'
34
+ needs:
35
+ - build
36
+ runs-on: ubuntu-latest
37
+ environment:
38
+ name: pypi
39
+ url: https://pypi.org/p/deltachat-rpc-client
40
+ permissions:
41
+ id-token: write
42
+
43
+ steps:
44
+ - name: Download all the dists
45
+ uses: actions/download-artifact@v7
46
+ with:
47
+ name: python-package-distributions
48
+ path: dist/
49
+ - name: Publish deltachat-rpc-client to PyPI
50
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e
.github/workflows/repl.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Manually triggered GitHub Actions workflow
2
+ # to build a Windows repl.exe which users can
3
+ # download to debug complex bugs.
4
+
5
+ name: Build Windows REPL .exe
6
+
7
+ on:
8
+ workflow_dispatch:
9
+
10
+ permissions: {}
11
+
12
+ jobs:
13
+ build_repl:
14
+ name: Build REPL example
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ with:
19
+ show-progress: false
20
+ persist-credentials: false
21
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
22
+ - name: Build
23
+ run: nix build .#deltachat-repl-win64
24
+ - name: Upload binary
25
+ uses: actions/upload-artifact@v6
26
+ with:
27
+ name: repl.exe
28
+ path: "result/bin/deltachat-repl.exe"
.github/workflows/upload-docs.yml ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build & deploy documentation on rs.delta.chat, c.delta.chat, and py.delta.chat
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - build_jsonrpc_docs_ci
8
+
9
+ permissions: {}
10
+
11
+ jobs:
12
+ build-rs:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ show-progress: false
19
+ persist-credentials: false
20
+ - name: Build the documentation with cargo
21
+ run: |
22
+ cargo doc --package deltachat --no-deps --document-private-items
23
+ - name: Upload to rs.delta.chat
24
+ run: |
25
+ mkdir -p "$HOME/.ssh"
26
+ echo "${{ secrets.KEY }}" > "$HOME/.ssh/key"
27
+ chmod 600 "$HOME/.ssh/key"
28
+ rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/target/doc "${{ secrets.USERNAME }}@rs.delta.chat:/var/www/html/rs/"
29
+
30
+ build-python:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - uses: actions/checkout@v6
35
+ with:
36
+ show-progress: false
37
+ persist-credentials: false
38
+ fetch-depth: 0 # Fetch history to calculate VCS version number.
39
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
40
+ - name: Build Python documentation
41
+ run: nix build .#python-docs
42
+ - name: Upload to py.delta.chat
43
+ run: |
44
+ mkdir -p "$HOME/.ssh"
45
+ echo "${{ secrets.CODESPEAK_KEY }}" > "$HOME/.ssh/key"
46
+ chmod 600 "$HOME/.ssh/key"
47
+ rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/result/html/ "delta@py.delta.chat:/home/delta/build/master"
48
+
49
+ build-c:
50
+ runs-on: ubuntu-latest
51
+
52
+ steps:
53
+ - uses: actions/checkout@v6
54
+ with:
55
+ show-progress: false
56
+ persist-credentials: false
57
+ fetch-depth: 0 # Fetch history to calculate VCS version number.
58
+ - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
59
+ - name: Build C documentation
60
+ run: nix build .#docs
61
+ - name: Upload to c.delta.chat
62
+ run: |
63
+ mkdir -p "$HOME/.ssh"
64
+ echo "${{ secrets.CODESPEAK_KEY }}" > "$HOME/.ssh/key"
65
+ chmod 600 "$HOME/.ssh/key"
66
+ rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/result/html/ "delta@c.delta.chat:/home/delta/build-c/master"
67
+
68
+ build-ts:
69
+ runs-on: ubuntu-latest
70
+ defaults:
71
+ run:
72
+ working-directory: ./deltachat-jsonrpc/typescript
73
+
74
+ steps:
75
+ - uses: actions/checkout@v6
76
+ with:
77
+ show-progress: false
78
+ persist-credentials: false
79
+ fetch-depth: 0 # Fetch history to calculate VCS version number.
80
+ - name: Use Node.js
81
+ uses: actions/setup-node@v6
82
+ with:
83
+ node-version: '18'
84
+ - name: npm install
85
+ run: npm install
86
+ - name: npm run build
87
+ run: npm run build
88
+ - name: Run docs script
89
+ run: npm run docs
90
+ - name: Upload to js.jsonrpc.delta.chat
91
+ run: |
92
+ mkdir -p "$HOME/.ssh"
93
+ echo "${{ secrets.KEY }}" > "$HOME/.ssh/key"
94
+ chmod 600 "$HOME/.ssh/key"
95
+ rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/deltachat-jsonrpc/typescript/docs/ "${{ secrets.USERNAME }}@js.jsonrpc.delta.chat:/var/www/html/js-jsonrpc/"
.github/workflows/upload-ffi-docs.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GitHub Actions workflow
2
+ # to build `deltachat_ffi` crate documentation
3
+ # and upload it to <https://cffi.delta.chat/>
4
+
5
+ name: Build & Deploy Documentation on cffi.delta.chat
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - main
11
+
12
+ permissions: {}
13
+
14
+ jobs:
15
+ build:
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - uses: actions/checkout@v6
20
+ with:
21
+ show-progress: false
22
+ persist-credentials: false
23
+ - name: Build the documentation with cargo
24
+ run: |
25
+ cargo doc --package deltachat_ffi --no-deps
26
+ - name: Upload to cffi.delta.chat
27
+ run: |
28
+ mkdir -p "$HOME/.ssh"
29
+ echo "${{ secrets.KEY }}" > "$HOME/.ssh/key"
30
+ chmod 600 "$HOME/.ssh/key"
31
+ rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/target/doc/ "${{ secrets.USERNAME }}@delta.chat:/var/www/html/cffi/"
.github/workflows/zizmor-scan.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: GitHub Actions Security Analysis with zizmor
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["**"]
8
+
9
+ jobs:
10
+ zizmor:
11
+ name: zizmor latest via PyPI
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ security-events: write
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v6
18
+ with:
19
+ persist-credentials: false
20
+
21
+ - name: Install the latest version of uv
22
+ uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867
23
+
24
+ - name: Run zizmor
25
+ run: uvx zizmor --format sarif . > results.sarif
26
+
27
+ - name: Upload SARIF file
28
+ uses: github/codeql-action/upload-sarif@v4
29
+ with:
30
+ sarif_file: results.sarif
31
+ category: zizmor
.gitignore ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ target/
2
+ **/*.rs.bk
3
+ /build
4
+ /dist
5
+ /fuzz/fuzz_targets/corpus/
6
+ /fuzz/fuzz_targets/crashes/
7
+
8
+ # ignore vi temporaries
9
+ *~
10
+ *.swp
11
+ *.swo
12
+
13
+ include
14
+ .dc-history.txt
15
+ *.db
16
+ *.db-blobs
17
+
18
+ .tox
19
+ python/.eggs
20
+ *.egg-info
21
+ __pycache__
22
+ python/src/deltachat/capi*.so
23
+ python/.venv/
24
+ python/venv/
25
+ venv/
26
+ env/
27
+
28
+ python/liveconfig*
29
+
30
+ # ignore doxgen generated files
31
+ deltachat-ffi/html
32
+ deltachat-ffi/xml
33
+
34
+ .rsynclist
35
+
36
+ coverage/
37
+ .DS_Store
38
+ .vscode
39
+ .zed
40
+ python/accounts.txt
41
+ python/all-testaccounts.txt
42
+ tmp/
43
+
44
+ # from deltachat-node
45
+ node_modules/
46
+ node/build/
47
+ node/dist/
48
+ node/prebuilds/
49
+ node/.nyc_output/
50
+
51
+ # Nix symlink.
52
+ result
53
+
54
+ # direnv
55
+ .envrc
56
+ .direnv
57
+ .aider*
.npmignore ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .circleci/
2
+ .gitmodules
3
+ node/.nyc_output/
4
+ .travis.yml
5
+ appveyor.yml
6
+ node/build/
7
+ node/README.md
8
+ rustfmt.toml
9
+ spec.md
10
+ test-data/
11
+ build2/
12
+ node_modules
13
+ .git
14
+ .idea/
15
+ .pytest_cache
16
+ CMakeLists.txt
17
+ README.md
18
+ contrib/
19
+ node/ci_scripts/
20
+ coverage/
21
+ node/.circleci
22
+ node/appveyor.yml
23
+ ci/
24
+ ci_scripts/
25
+ python/
26
+ target
27
+ proptest-regressions
28
+ deltachat-ffi/Doxyfile
29
+ scripts
30
+ webxdc.md
31
+ standards.md
32
+ draft/
33
+ node/examples/
34
+ # deltachat-core-rust/assets # don't exclude assets, otherwise it won't build
35
+ node/images/
36
+ node/test/
37
+ node/windows.md
38
+ node/*.tar.gz
39
+ node/old_docs.md
40
+ .vscode/
41
+ .github/
42
+ node/.prettierrc.yml
43
+
44
+ deltachat-jsonrpc/TODO.md
45
+ deltachat-jsonrpc/README.MD
46
+ deltachat-jsonrpc/.gitignore
47
+ deltachat-jsonrpc/typescript/.gitignore
48
+ deltachat-jsonrpc/typescript/.prettierignore
49
+ deltachat-jsonrpc/typescript/accounts/
50
+ deltachat-jsonrpc/typescript/index.html
51
+ deltachat-jsonrpc/typescript/node-demo.js
52
+ deltachat-jsonrpc/typescript/report_api_coverage.mjs
53
+ deltachat-jsonrpc/typescript/test
54
+ deltachat-jsonrpc/typescript/example.ts
55
+
56
+ .DS_Store
.npmrc ADDED
@@ -0,0 +1 @@
 
 
1
+ package-lock=false
CHANGELOG.md ADDED
The diff for this file is too large to render. See raw diff
 
CMakeLists.txt ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.16)
2
+ project(deltachat LANGUAGES C)
3
+ include(GNUInstallDirs)
4
+
5
+ find_program(CARGO cargo)
6
+
7
+ if(APPLE)
8
+ set(DYNAMIC_EXT "dylib")
9
+ elseif(UNIX)
10
+ set(DYNAMIC_EXT "so")
11
+ else()
12
+ set(DYNAMIC_EXT "dll")
13
+ endif()
14
+
15
+ if(DEFINED ENV{CARGO_BUILD_TARGET})
16
+ set(ARCH_DIR "$ENV{CARGO_BUILD_TARGET}")
17
+ else()
18
+ set(ARCH_DIR "./")
19
+ endif()
20
+
21
+ add_custom_command(
22
+ OUTPUT
23
+ "${CMAKE_BINARY_DIR}/target/release/libdeltachat.a"
24
+ "${CMAKE_BINARY_DIR}/target/release/libdeltachat.${DYNAMIC_EXT}"
25
+ "${CMAKE_BINARY_DIR}/target/release/pkgconfig/deltachat.pc"
26
+ COMMAND
27
+ PREFIX=${CMAKE_INSTALL_PREFIX}
28
+ LIBDIR=${CMAKE_INSTALL_FULL_LIBDIR}
29
+ INCLUDEDIR=${CMAKE_INSTALL_FULL_INCLUDEDIR}
30
+ ${CARGO} build --target-dir=${CMAKE_BINARY_DIR}/target --release
31
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deltachat-ffi
32
+ )
33
+
34
+ add_custom_target(
35
+ lib_deltachat
36
+ ALL
37
+ DEPENDS
38
+ "${CMAKE_BINARY_DIR}/target/release/libdeltachat.a"
39
+ "${CMAKE_BINARY_DIR}/target/release/libdeltachat.${DYNAMIC_EXT}"
40
+ "${CMAKE_BINARY_DIR}/target/release/pkgconfig/deltachat.pc"
41
+ )
42
+
43
+ install(FILES "deltachat-ffi/deltachat.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
44
+ install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/libdeltachat.a" DESTINATION ${CMAKE_INSTALL_LIBDIR})
45
+ install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/libdeltachat.${DYNAMIC_EXT}" DESTINATION ${CMAKE_INSTALL_LIBDIR})
46
+ install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/pkgconfig/deltachat.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
CONTRIBUTING.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributing to chatmail core
2
+
3
+ ## Bug reports
4
+
5
+ If you found a bug, [report it on GitHub](https://github.com/chatmail/core/issues).
6
+ If the bug you found is specific to
7
+ [Android](https://github.com/deltachat/deltachat-android/issues),
8
+ [iOS](https://github.com/deltachat/deltachat-ios/issues) or
9
+ [Desktop](https://github.com/deltachat/deltachat-desktop/issues),
10
+ report it to the corresponding repository.
11
+
12
+ ## Feature proposals
13
+
14
+ If you have a feature request, create a new topic on the [forum](https://support.delta.chat/).
15
+
16
+ ## Code contributions
17
+
18
+ If you want to contribute a code, follow this guide.
19
+
20
+ 1. **Select an issue to work on.**
21
+
22
+ If you have an write access to the repository, assign the issue to yourself.
23
+ Otherwise state in the comment that you are going to work on the issue
24
+ to avoid duplicate work.
25
+
26
+ If the issue does not exist yet, create it first.
27
+
28
+ 2. **Write the code.**
29
+
30
+ Follow the [coding conventions](STYLE.md) when writing the code.
31
+
32
+ 3. **Commit the code.**
33
+
34
+ If you have write access to the repository,
35
+ push a branch named `<username>/<feature>`
36
+ so it is clear who is responsible for the branch,
37
+ and open a PR proposing to merge the change.
38
+ Otherwise fork the repository and create a branch in your fork.
39
+
40
+ Commit messages follow the [Conventional Commits] notation.
41
+ We use [git-cliff] to generate the changelog from commit messages before the release.
42
+
43
+ With **`git cliff --unreleased`**, you can check how the changelog entry for your commit will look.
44
+
45
+ The following prefix types are used:
46
+ - `feat`: Features, e.g. "feat: Pause IO for BackupProvider". If you are unsure what's the category of your commit, you can often just use `feat`.
47
+ - `fix`: Bug fixes, e.g. "fix: delete `smtp` rows when message sending is canceled"
48
+ - `api`: API changes, e.g. "api(rust): add `get_msg_read_receipts(context, msg_id)`"
49
+ - `refactor`: Refactorings, e.g. "refactor: iterate over `msg_ids` without `.iter()`"
50
+ - `perf`: Performance improvements, e.g. "perf: improve SQLite performance with `PRAGMA synchronous=normal`"
51
+ - `test`: Test changes and improvements to the testing framework.
52
+ - `build`: Build system and tool configuration changes, e.g. "build(git-cliff): put "ci" commits into "CI" section of changelog"
53
+ - `ci`: CI configuration changes, e.g. "ci: limit artifact retention time for `libdeltachat.a` to 1 day"
54
+ - `docs`: Documentation changes, e.g. "docs: add contributing guidelines"
55
+ - `chore`: miscellaneous tasks, e.g. "chore: add `.DS_Store` to `.gitignore`"
56
+
57
+ Release preparation commits are marked as "chore(release): prepare for X.Y.Z"
58
+ as described in [releasing guide](RELEASE.md).
59
+
60
+ Use a `!` to mark breaking changes, e.g. "api!: Remove `dc_chat_can_send`".
61
+
62
+ Alternatively, breaking changes can go into the commit description, e.g.:
63
+
64
+ ```
65
+ fix: Fix race condition and db corruption when a message was received during backup
66
+
67
+ BREAKING CHANGE: You have to call `dc_stop_io()`/`dc_start_io()` before/after `dc_imex(DC_IMEX_EXPORT_BACKUP)`
68
+ ```
69
+
70
+ 4. [**Open a Pull Request**](https://github.com/chatmail/core/pulls).
71
+
72
+ Refer to the corresponding issue.
73
+
74
+ If you intend to squash merge the PR from the web interface,
75
+ make sure the PR title follows the conventional commits notation
76
+ as it will end up being a commit title.
77
+ Otherwise make sure each commit title follows the conventional commit notation.
78
+
79
+ 5. **Make sure all CI checks succeed.**
80
+
81
+ CI runs the tests and checks code formatting.
82
+
83
+ While it is running, self-review your PR to make sure all the changes you expect are there
84
+ and there are no accidentally committed unrelated changes and files.
85
+
86
+ Push the necessary fixup commits or force-push to your branch if needed.
87
+
88
+ 6. **Ask for review.**
89
+
90
+ Use built-in GitHub feature to request a review from suggested reviewers.
91
+
92
+ If you do not have write access to the repository, ask for review in the comments.
93
+
94
+ 7. **Merge the PR.**
95
+
96
+ Once a PR has an approval and passes CI, it can be merged.
97
+
98
+ PRs from a branch created in the main repository,
99
+ i.e. authored by those who have write access, are merged by their authors.
100
+
101
+ This is to ensure that PRs are merged as intended by the author,
102
+ e.g. as a squash merge, by rebasing from the web interface or manually from the command line.
103
+
104
+ If you have multiple changes in one PR, do a rebase merge.
105
+ Otherwise, you should usually do a squash merge.
106
+
107
+ If PR author does not have write access to the repository,
108
+ maintainers who reviewed the PR can merge it.
109
+
110
+ If you do not have access to the repository and created a PR from a fork,
111
+ ask the maintainers to merge the PR and say how it should be merged.
112
+
113
+ ## Other ways to contribute
114
+
115
+ For other ways to contribute, refer to the [website](https://delta.chat/en/contribute).
116
+
117
+ You can find the list of good first issues
118
+ and a link to this guide
119
+ on the contributing page: <https://github.com/chatmail/core/contribute>
120
+
121
+ [Conventional Commits]: https://www.conventionalcommits.org/
122
+ [git-cliff]: https://git-cliff.org/
Cargo.lock ADDED
The diff for this file is too large to render. See raw diff
 
Cargo.toml ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "deltachat"
3
+ version = "2.36.0"
4
+ edition = "2024"
5
+ license = "MPL-2.0"
6
+ rust-version = "1.88"
7
+ repository = "https://github.com/chatmail/core"
8
+
9
+ [profile.dev]
10
+ debug = 0
11
+ panic = 'abort'
12
+ opt-level = 1
13
+
14
+ [profile.test]
15
+ # Make anyhow `backtrace` feature useful.
16
+ # With `debug = 0` there are no line numbers in the backtrace
17
+ # produced with RUST_BACKTRACE=1.
18
+ debug = 1
19
+ opt-level = 0
20
+
21
+ [profile.fuzz]
22
+ inherits = "test"
23
+
24
+ # Always optimize dependencies.
25
+ # This does not apply to crates in the workspace.
26
+ # <https://doc.rust-lang.org/cargo/reference/profiles.html#overrides>
27
+ [profile.dev.package."*"]
28
+ opt-level = "z"
29
+
30
+ [profile.release]
31
+ lto = true
32
+ panic = 'abort'
33
+ opt-level = "z"
34
+ codegen-units = 1
35
+ strip = true
36
+
37
+ [dependencies]
38
+ deltachat_derive = { path = "./deltachat_derive" }
39
+ deltachat-time = { path = "./deltachat-time" }
40
+ deltachat-contact-tools = { workspace = true }
41
+ format-flowed = { path = "./format-flowed" }
42
+ ratelimit = { path = "./deltachat-ratelimit" }
43
+
44
+ anyhow = { workspace = true }
45
+ async-broadcast = "0.7.2"
46
+ async-channel = { workspace = true }
47
+ async-imap = { version = "0.11.1", default-features = false, features = ["runtime-tokio", "compress"] }
48
+ async-native-tls = { version = "0.5", default-features = false, features = ["runtime-tokio"] }
49
+ async-smtp = { version = "0.10.2", default-features = false, features = ["runtime-tokio"] }
50
+ async_zip = { version = "0.0.18", default-features = false, features = ["deflate", "tokio-fs"] }
51
+ base64 = { workspace = true }
52
+ blake3 = "1.8.2"
53
+ brotli = { version = "8", default-features=false, features = ["std"] }
54
+ bytes = "1"
55
+ chrono = { workspace = true, features = ["alloc", "clock", "std"] }
56
+ colorutils-rs = { version = "0.7.5", default-features = false }
57
+ data-encoding = "2.9.0"
58
+ escaper = "0.1"
59
+ fast-socks5 = "0.10"
60
+ fd-lock = "4"
61
+ futures-lite = { workspace = true }
62
+ futures = { workspace = true }
63
+ hex = "0.4.0"
64
+ http-body-util = "0.1.3"
65
+ humansize = "2"
66
+ hyper = "1"
67
+ hyper-util = "0.1.16"
68
+ image = { version = "0.25.6", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
69
+ iroh-gossip = { version = "0.35", default-features = false, features = ["net"] }
70
+ iroh = { version = "0.35", default-features = false }
71
+ kamadak-exif = "0.6.1"
72
+ libc = { workspace = true }
73
+ mail-builder = { version = "0.4.4", default-features = false }
74
+ mailparse = { workspace = true }
75
+ mime = "0.3.17"
76
+ num_cpus = "1.17"
77
+ num-derive = "0.4"
78
+ num-traits = { workspace = true }
79
+ parking_lot = "0.12.4"
80
+ percent-encoding = "2.3"
81
+ pgp = { version = "0.18.0", default-features = false }
82
+ pin-project = "1"
83
+ qrcodegen = "1.7.0"
84
+ quick-xml = { version = "0.38", features = ["escape-html"] }
85
+ rand-old = { package = "rand", version = "0.8" }
86
+ rand = { workspace = true }
87
+ regex = { workspace = true }
88
+ rusqlite = { workspace = true, features = ["sqlcipher"] }
89
+ rustls-pki-types = "1.12.0"
90
+ sanitize-filename = { workspace = true }
91
+ sdp = "0.10.0"
92
+ serde_json = { workspace = true }
93
+ serde_urlencoded = "0.7.1"
94
+ serde = { workspace = true, features = ["derive"] }
95
+ sha-1 = "0.10"
96
+ sha2 = "0.10"
97
+ shadowsocks = { version = "1.23.1", default-features = false, features = ["aead-cipher", "aead-cipher-2022"] }
98
+ smallvec = "1.15.1"
99
+ strum = "0.27"
100
+ strum_macros = "0.27"
101
+ tagger = "4.3.4"
102
+ textwrap = "0.16.2"
103
+ thiserror = { workspace = true }
104
+ tokio-io-timeout = "1.2.1"
105
+ tokio-rustls = { version = "0.26.2", default-features = false }
106
+ tokio-stream = { version = "0.1.17", features = ["fs"] }
107
+ astral-tokio-tar = { version = "0.5.6", default-features = false }
108
+ tokio-util = { workspace = true }
109
+ tokio = { workspace = true, features = ["fs", "rt-multi-thread", "macros"] }
110
+ toml = "0.9"
111
+ tracing = "0.1.41"
112
+ url = "2"
113
+ uuid = { version = "1", features = ["serde", "v4"] }
114
+ walkdir = "2.5.0"
115
+ webpki-roots = "0.26.8"
116
+
117
+ [dev-dependencies]
118
+ anyhow = { workspace = true, features = ["backtrace"] } # Enable `backtrace` feature in tests.
119
+ criterion = { version = "0.8.1", features = ["async_tokio"] }
120
+ futures-lite = { workspace = true }
121
+ log = { workspace = true }
122
+ nu-ansi-term = { workspace = true }
123
+ pretty_assertions = "1.4.1"
124
+ proptest = { version = "1", default-features = false, features = ["std"] }
125
+ tempfile = { workspace = true }
126
+ testdir = "0.9.3"
127
+ tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
128
+
129
+ [workspace]
130
+ members = [
131
+ "deltachat-ffi",
132
+ "deltachat_derive",
133
+ "deltachat-jsonrpc",
134
+ "deltachat-rpc-server",
135
+ "deltachat-ratelimit",
136
+ "deltachat-repl",
137
+ "deltachat-time",
138
+ "format-flowed",
139
+ "deltachat-contact-tools",
140
+ "fuzz",
141
+ ]
142
+
143
+ [[bench]]
144
+ name = "create_account"
145
+ harness = false
146
+
147
+ [[bench]]
148
+ name = "contacts"
149
+ harness = false
150
+
151
+ [[bench]]
152
+ name = "search_msgs"
153
+ harness = false
154
+
155
+ [[bench]]
156
+ name = "receive_emails"
157
+ required-features = ["internals"]
158
+ harness = false
159
+
160
+ [[bench]]
161
+ name = "decrypting"
162
+ required-features = ["internals"]
163
+ harness = false
164
+
165
+ [[bench]]
166
+ name = "get_chat_msgs"
167
+ harness = false
168
+
169
+ [[bench]]
170
+ name = "marknoticed_chat"
171
+ harness = false
172
+
173
+ [[bench]]
174
+ name = "get_chatlist"
175
+ harness = false
176
+
177
+ [[bench]]
178
+ name = "send_events"
179
+ harness = false
180
+
181
+ [workspace.dependencies]
182
+ anyhow = "1"
183
+ async-channel = "2.5.0"
184
+ base64 = "0.22"
185
+ chrono = { version = "0.4.42", default-features = false }
186
+ deltachat-contact-tools = { path = "deltachat-contact-tools" }
187
+ deltachat-jsonrpc = { path = "deltachat-jsonrpc", default-features = false }
188
+ deltachat = { path = ".", default-features = false }
189
+ futures = "0.3.31"
190
+ futures-lite = "2.6.1"
191
+ libc = "0.2"
192
+ log = "0.4"
193
+ mailparse = "0.16.1"
194
+ nu-ansi-term = "0.50"
195
+ num-traits = "0.2"
196
+ rand = "0.9"
197
+ regex = "1.10"
198
+ rusqlite = "0.37"
199
+ sanitize-filename = "0.6"
200
+ serde = "1.0"
201
+ serde_json = "1"
202
+ tempfile = "3.24.0"
203
+ thiserror = "2"
204
+ tokio = "1"
205
+ tokio-util = "0.7.17"
206
+ tracing-subscriber = "0.3"
207
+ yerpc = "0.6.4"
208
+
209
+ [features]
210
+ default = ["vendored"]
211
+ internals = []
212
+ vendored = [
213
+ "rusqlite/bundled-sqlcipher-vendored-openssl",
214
+ "async-native-tls/vendored"
215
+ ]
216
+
217
+ [lints.rust]
218
+ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
LICENSE ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The files in this directory and under its subdirectories
2
+ are (c) 2019 by Bjoern Petersen and contributors and released under the
3
+ Mozilla Public License Version 2.0, see below for a copy.
4
+
5
+ Mozilla Public License Version 2.0
6
+ ==================================
7
+
8
+ 1. Definitions
9
+ --------------
10
+
11
+ 1.1. "Contributor"
12
+ means each individual or legal entity that creates, contributes to
13
+ the creation of, or owns Covered Software.
14
+
15
+ 1.2. "Contributor Version"
16
+ means the combination of the Contributions of others (if any) used
17
+ by a Contributor and that particular Contributor's Contribution.
18
+
19
+ 1.3. "Contribution"
20
+ means Covered Software of a particular Contributor.
21
+
22
+ 1.4. "Covered Software"
23
+ means Source Code Form to which the initial Contributor has attached
24
+ the notice in Exhibit A, the Executable Form of such Source Code
25
+ Form, and Modifications of such Source Code Form, in each case
26
+ including portions thereof.
27
+
28
+ 1.5. "Incompatible With Secondary Licenses"
29
+ means
30
+
31
+ (a) that the initial Contributor has attached the notice described
32
+ in Exhibit B to the Covered Software; or
33
+
34
+ (b) that the Covered Software was made available under the terms of
35
+ version 1.1 or earlier of the License, but not also under the
36
+ terms of a Secondary License.
37
+
38
+ 1.6. "Executable Form"
39
+ means any form of the work other than Source Code Form.
40
+
41
+ 1.7. "Larger Work"
42
+ means a work that combines Covered Software with other material, in
43
+ a separate file or files, that is not Covered Software.
44
+
45
+ 1.8. "License"
46
+ means this document.
47
+
48
+ 1.9. "Licensable"
49
+ means having the right to grant, to the maximum extent possible,
50
+ whether at the time of the initial grant or subsequently, any and
51
+ all of the rights conveyed by this License.
52
+
53
+ 1.10. "Modifications"
54
+ means any of the following:
55
+
56
+ (a) any file in Source Code Form that results from an addition to,
57
+ deletion from, or modification of the contents of Covered
58
+ Software; or
59
+
60
+ (b) any new file in Source Code Form that contains any Covered
61
+ Software.
62
+
63
+ 1.11. "Patent Claims" of a Contributor
64
+ means any patent claim(s), including without limitation, method,
65
+ process, and apparatus claims, in any patent Licensable by such
66
+ Contributor that would be infringed, but for the grant of the
67
+ License, by the making, using, selling, offering for sale, having
68
+ made, import, or transfer of either its Contributions or its
69
+ Contributor Version.
70
+
71
+ 1.12. "Secondary License"
72
+ means either the GNU General Public License, Version 2.0, the GNU
73
+ Lesser General Public License, Version 2.1, the GNU Affero General
74
+ Public License, Version 3.0, or any later versions of those
75
+ licenses.
76
+
77
+ 1.13. "Source Code Form"
78
+ means the form of the work preferred for making modifications.
79
+
80
+ 1.14. "You" (or "Your")
81
+ means an individual or a legal entity exercising rights under this
82
+ License. For legal entities, "You" includes any entity that
83
+ controls, is controlled by, or is under common control with You. For
84
+ purposes of this definition, "control" means (a) the power, direct
85
+ or indirect, to cause the direction or management of such entity,
86
+ whether by contract or otherwise, or (b) ownership of more than
87
+ fifty percent (50%) of the outstanding shares or beneficial
88
+ ownership of such entity.
89
+
90
+ 2. License Grants and Conditions
91
+ --------------------------------
92
+
93
+ 2.1. Grants
94
+
95
+ Each Contributor hereby grants You a world-wide, royalty-free,
96
+ non-exclusive license:
97
+
98
+ (a) under intellectual property rights (other than patent or trademark)
99
+ Licensable by such Contributor to use, reproduce, make available,
100
+ modify, display, perform, distribute, and otherwise exploit its
101
+ Contributions, either on an unmodified basis, with Modifications, or
102
+ as part of a Larger Work; and
103
+
104
+ (b) under Patent Claims of such Contributor to make, use, sell, offer
105
+ for sale, have made, import, and otherwise transfer either its
106
+ Contributions or its Contributor Version.
107
+
108
+ 2.2. Effective Date
109
+
110
+ The licenses granted in Section 2.1 with respect to any Contribution
111
+ become effective for each Contribution on the date the Contributor first
112
+ distributes such Contribution.
113
+
114
+ 2.3. Limitations on Grant Scope
115
+
116
+ The licenses granted in this Section 2 are the only rights granted under
117
+ this License. No additional rights or licenses will be implied from the
118
+ distribution or licensing of Covered Software under this License.
119
+ Notwithstanding Section 2.1(b) above, no patent license is granted by a
120
+ Contributor:
121
+
122
+ (a) for any code that a Contributor has removed from Covered Software;
123
+ or
124
+
125
+ (b) for infringements caused by: (i) Your and any other third party's
126
+ modifications of Covered Software, or (ii) the combination of its
127
+ Contributions with other software (except as part of its Contributor
128
+ Version); or
129
+
130
+ (c) under Patent Claims infringed by Covered Software in the absence of
131
+ its Contributions.
132
+
133
+ This License does not grant any rights in the trademarks, service marks,
134
+ or logos of any Contributor (except as may be necessary to comply with
135
+ the notice requirements in Section 3.4).
136
+
137
+ 2.4. Subsequent Licenses
138
+
139
+ No Contributor makes additional grants as a result of Your choice to
140
+ distribute the Covered Software under a subsequent version of this
141
+ License (see Section 10.2) or under the terms of a Secondary License (if
142
+ permitted under the terms of Section 3.3).
143
+
144
+ 2.5. Representation
145
+
146
+ Each Contributor represents that the Contributor believes its
147
+ Contributions are its original creation(s) or it has sufficient rights
148
+ to grant the rights to its Contributions conveyed by this License.
149
+
150
+ 2.6. Fair Use
151
+
152
+ This License is not intended to limit any rights You have under
153
+ applicable copyright doctrines of fair use, fair dealing, or other
154
+ equivalents.
155
+
156
+ 2.7. Conditions
157
+
158
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
159
+ in Section 2.1.
160
+
161
+ 3. Responsibilities
162
+ -------------------
163
+
164
+ 3.1. Distribution of Source Form
165
+
166
+ All distribution of Covered Software in Source Code Form, including any
167
+ Modifications that You create or to which You contribute, must be under
168
+ the terms of this License. You must inform recipients that the Source
169
+ Code Form of the Covered Software is governed by the terms of this
170
+ License, and how they can obtain a copy of this License. You may not
171
+ attempt to alter or restrict the recipients' rights in the Source Code
172
+ Form.
173
+
174
+ 3.2. Distribution of Executable Form
175
+
176
+ If You distribute Covered Software in Executable Form then:
177
+
178
+ (a) such Covered Software must also be made available in Source Code
179
+ Form, as described in Section 3.1, and You must inform recipients of
180
+ the Executable Form how they can obtain a copy of such Source Code
181
+ Form by reasonable means in a timely manner, at a charge no more
182
+ than the cost of distribution to the recipient; and
183
+
184
+ (b) You may distribute such Executable Form under the terms of this
185
+ License, or sublicense it under different terms, provided that the
186
+ license for the Executable Form does not attempt to limit or alter
187
+ the recipients' rights in the Source Code Form under this License.
188
+
189
+ 3.3. Distribution of a Larger Work
190
+
191
+ You may create and distribute a Larger Work under terms of Your choice,
192
+ provided that You also comply with the requirements of this License for
193
+ the Covered Software. If the Larger Work is a combination of Covered
194
+ Software with a work governed by one or more Secondary Licenses, and the
195
+ Covered Software is not Incompatible With Secondary Licenses, this
196
+ License permits You to additionally distribute such Covered Software
197
+ under the terms of such Secondary License(s), so that the recipient of
198
+ the Larger Work may, at their option, further distribute the Covered
199
+ Software under the terms of either this License or such Secondary
200
+ License(s).
201
+
202
+ 3.4. Notices
203
+
204
+ You may not remove or alter the substance of any license notices
205
+ (including copyright notices, patent notices, disclaimers of warranty,
206
+ or limitations of liability) contained within the Source Code Form of
207
+ the Covered Software, except that You may alter any license notices to
208
+ the extent required to remedy known factual inaccuracies.
209
+
210
+ 3.5. Application of Additional Terms
211
+
212
+ You may choose to offer, and to charge a fee for, warranty, support,
213
+ indemnity or liability obligations to one or more recipients of Covered
214
+ Software. However, You may do so only on Your own behalf, and not on
215
+ behalf of any Contributor. You must make it absolutely clear that any
216
+ such warranty, support, indemnity, or liability obligation is offered by
217
+ You alone, and You hereby agree to indemnify every Contributor for any
218
+ liability incurred by such Contributor as a result of warranty, support,
219
+ indemnity or liability terms You offer. You may include additional
220
+ disclaimers of warranty and limitations of liability specific to any
221
+ jurisdiction.
222
+
223
+ 4. Inability to Comply Due to Statute or Regulation
224
+ ---------------------------------------------------
225
+
226
+ If it is impossible for You to comply with any of the terms of this
227
+ License with respect to some or all of the Covered Software due to
228
+ statute, judicial order, or regulation then You must: (a) comply with
229
+ the terms of this License to the maximum extent possible; and (b)
230
+ describe the limitations and the code they affect. Such description must
231
+ be placed in a text file included with all distributions of the Covered
232
+ Software under this License. Except to the extent prohibited by statute
233
+ or regulation, such description must be sufficiently detailed for a
234
+ recipient of ordinary skill to be able to understand it.
235
+
236
+ 5. Termination
237
+ --------------
238
+
239
+ 5.1. The rights granted under this License will terminate automatically
240
+ if You fail to comply with any of its terms. However, if You become
241
+ compliant, then the rights granted under this License from a particular
242
+ Contributor are reinstated (a) provisionally, unless and until such
243
+ Contributor explicitly and finally terminates Your grants, and (b) on an
244
+ ongoing basis, if such Contributor fails to notify You of the
245
+ non-compliance by some reasonable means prior to 60 days after You have
246
+ come back into compliance. Moreover, Your grants from a particular
247
+ Contributor are reinstated on an ongoing basis if such Contributor
248
+ notifies You of the non-compliance by some reasonable means, this is the
249
+ first time You have received notice of non-compliance with this License
250
+ from such Contributor, and You become compliant prior to 30 days after
251
+ Your receipt of the notice.
252
+
253
+ 5.2. If You initiate litigation against any entity by asserting a patent
254
+ infringement claim (excluding declaratory judgment actions,
255
+ counter-claims, and cross-claims) alleging that a Contributor Version
256
+ directly or indirectly infringes any patent, then the rights granted to
257
+ You by any and all Contributors for the Covered Software under Section
258
+ 2.1 of this License shall terminate.
259
+
260
+ 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
261
+ end user license agreements (excluding distributors and resellers) which
262
+ have been validly granted by You or Your distributors under this License
263
+ prior to termination shall survive termination.
264
+
265
+ ************************************************************************
266
+ * *
267
+ * 6. Disclaimer of Warranty *
268
+ * ------------------------- *
269
+ * *
270
+ * Covered Software is provided under this License on an "as is" *
271
+ * basis, without warranty of any kind, either expressed, implied, or *
272
+ * statutory, including, without limitation, warranties that the *
273
+ * Covered Software is free of defects, merchantable, fit for a *
274
+ * particular purpose or non-infringing. The entire risk as to the *
275
+ * quality and performance of the Covered Software is with You. *
276
+ * Should any Covered Software prove defective in any respect, You *
277
+ * (not any Contributor) assume the cost of any necessary servicing, *
278
+ * repair, or correction. This disclaimer of warranty constitutes an *
279
+ * essential part of this License. No use of any Covered Software is *
280
+ * authorized under this License except under this disclaimer. *
281
+ * *
282
+ ************************************************************************
283
+
284
+ ************************************************************************
285
+ * *
286
+ * 7. Limitation of Liability *
287
+ * -------------------------- *
288
+ * *
289
+ * Under no circumstances and under no legal theory, whether tort *
290
+ * (including negligence), contract, or otherwise, shall any *
291
+ * Contributor, or anyone who distributes Covered Software as *
292
+ * permitted above, be liable to You for any direct, indirect, *
293
+ * special, incidental, or consequential damages of any character *
294
+ * including, without limitation, damages for lost profits, loss of *
295
+ * goodwill, work stoppage, computer failure or malfunction, or any *
296
+ * and all other commercial damages or losses, even if such party *
297
+ * shall have been informed of the possibility of such damages. This *
298
+ * limitation of liability shall not apply to liability for death or *
299
+ * personal injury resulting from such party's negligence to the *
300
+ * extent applicable law prohibits such limitation. Some *
301
+ * jurisdictions do not allow the exclusion or limitation of *
302
+ * incidental or consequential damages, so this exclusion and *
303
+ * limitation may not apply to You. *
304
+ * *
305
+ ************************************************************************
306
+
307
+ 8. Litigation
308
+ -------------
309
+
310
+ Any litigation relating to this License may be brought only in the
311
+ courts of a jurisdiction where the defendant maintains its principal
312
+ place of business and such litigation shall be governed by laws of that
313
+ jurisdiction, without reference to its conflict-of-law provisions.
314
+ Nothing in this Section shall prevent a party's ability to bring
315
+ cross-claims or counter-claims.
316
+
317
+ 9. Miscellaneous
318
+ ----------------
319
+
320
+ This License represents the complete agreement concerning the subject
321
+ matter hereof. If any provision of this License is held to be
322
+ unenforceable, such provision shall be reformed only to the extent
323
+ necessary to make it enforceable. Any law or regulation which provides
324
+ that the language of a contract shall be construed against the drafter
325
+ shall not be used to construe this License against a Contributor.
326
+
327
+ 10. Versions of the License
328
+ ---------------------------
329
+
330
+ 10.1. New Versions
331
+
332
+ Mozilla Foundation is the license steward. Except as provided in Section
333
+ 10.3, no one other than the license steward has the right to modify or
334
+ publish new versions of this License. Each version will be given a
335
+ distinguishing version number.
336
+
337
+ 10.2. Effect of New Versions
338
+
339
+ You may distribute the Covered Software under the terms of the version
340
+ of the License under which You originally received the Covered Software,
341
+ or under the terms of any subsequent version published by the license
342
+ steward.
343
+
344
+ 10.3. Modified Versions
345
+
346
+ If you create software not governed by this License, and you want to
347
+ create a new license for such software, you may create and use a
348
+ modified version of this License if you rename the license and remove
349
+ any references to the name of the license steward (except to note that
350
+ such modified license differs from this License).
351
+
352
+ 10.4. Distributing Source Code Form that is Incompatible With Secondary
353
+ Licenses
354
+
355
+ If You choose to distribute Source Code Form that is Incompatible With
356
+ Secondary Licenses under the terms of this version of the License, the
357
+ notice described in Exhibit B of this License must be attached.
358
+
359
+ Exhibit A - Source Code Form License Notice
360
+ -------------------------------------------
361
+
362
+ This Source Code Form is subject to the terms of the Mozilla Public
363
+ License, v. 2.0. If a copy of the MPL was not distributed with this
364
+ file, You can obtain one at https://mozilla.org/MPL/2.0/.
365
+
366
+ If it is not possible or desirable to put the notice in a particular
367
+ file, then You may include the notice in a location (such as a LICENSE
368
+ file in a relevant directory) where a recipient would be likely to look
369
+ for such a notice.
370
+
371
+ You may add additional accurate notices of copyright ownership.
372
+
373
+ Exhibit B - "Incompatible With Secondary Licenses" Notice
374
+ ---------------------------------------------------------
375
+
376
+ This Source Code Form is "Incompatible With Secondary Licenses", as
377
+ defined by the Mozilla Public License, v. 2.0.
README.md ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <p align="center">
2
+ <img alt="Chatmail logo" src="https://github.com/user-attachments/assets/25742da7-a837-48cd-a503-b303af55f10d" width="300" style="float:middle;" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://github.com/chatmail/core/actions/workflows/ci.yml">
7
+ <img alt="Rust CI" src="https://github.com/chatmail/core/actions/workflows/ci.yml/badge.svg">
8
+ </a>
9
+ <a href="https://deps.rs/repo/github/chatmail/core">
10
+ <img alt="dependency status" src="https://deps.rs/repo/github/chatmail/core/status.svg">
11
+ </a>
12
+ </p>
13
+
14
+ The chatmail core library implements low-level network and encryption protocols,
15
+ integrated by many chat bots and higher level applications,
16
+ allowing to securely participate in the globally scaled e-mail server network.
17
+ We provide reproducibly-built `deltachat-rpc-server` static binaries
18
+ that offer a stdio-based high-level JSON-RPC API for instant messaging purposes.
19
+
20
+ The following protocols are handled without requiring API users to know much about them:
21
+
22
+ - secure TLS setup with DNS caching and shadowsocks/proxy support
23
+
24
+ - robust [SMTP](https://github.com/chatmail/async-imap)
25
+ and [IMAP](https://github.com/chatmail/async-smtp) handling
26
+
27
+ - safe and interoperable [MIME parsing](https://github.com/staktrace/mailparse)
28
+ and [MIME building](https://github.com/stalwartlabs/mail-builder).
29
+
30
+ - security-audited end-to-end encryption with [rPGP](https://github.com/rpgp/rpgp)
31
+ and [Autocrypt and SecureJoin protocols](https://securejoin.rtfd.io)
32
+
33
+ - ephemeral [Peer-to-Peer networking using Iroh](https://iroh.computer) for multi-device setup and
34
+ [webxdc realtime data](https://delta.chat/en/2024-11-20-webxdc-realtime).
35
+
36
+ - a simulation- and real-world tested [P2P group membership
37
+ protocol without requiring server state](https://github.com/chatmail/models/tree/main/group-membership).
38
+
39
+
40
+ ## Installing Rust and Cargo
41
+
42
+ To download and install the official compiler for the Rust programming language, and the Cargo package manager, run the command in your user environment:
43
+
44
+ ```
45
+ $ curl https://sh.rustup.rs -sSf | sh
46
+ ```
47
+
48
+ > On Windows, you may need to also install **Perl** to be able to compile deltachat-core.
49
+
50
+ ## Using the CLI client
51
+
52
+ Compile and run the command line utility, using `cargo`:
53
+
54
+ ```
55
+ $ cargo run --locked -p deltachat-repl -- ~/profile-db
56
+ ```
57
+ where ~/profile-db is the database file. The utility will create it if it does not exist.
58
+
59
+ Optionally, install `deltachat-repl` binary with
60
+ ```
61
+ $ cargo install --locked --path deltachat-repl/
62
+ ```
63
+ and run as
64
+ ```
65
+ $ deltachat-repl ~/profile-db
66
+ ```
67
+
68
+ Configure your account (if not already configured):
69
+
70
+ ```
71
+ Chatmail is awaiting your commands.
72
+ > set addr your@email.org
73
+ > set mail_pw yourpassword
74
+ > configure
75
+ ```
76
+
77
+ Connect to your mail server (if already configured):
78
+
79
+ ```
80
+ > connect
81
+ ```
82
+
83
+ Export your public key to a vCard file:
84
+
85
+ ```
86
+ > make-vcard my.vcard 1
87
+ ```
88
+
89
+ Create contacts by address or vCard file:
90
+
91
+ ```
92
+ > addcontact yourfriends@email.org
93
+ > import-vcard key-contact.vcard
94
+ ```
95
+
96
+ List contacts:
97
+
98
+ ```
99
+ > listcontacts
100
+ Contact#Contact#11: key-contact@email.org <key-contact@email.org>
101
+ Contact#Contact#Self: Me √ <your@email.org>
102
+ 2 key contacts.
103
+ Contact#Contact#10: yourfriends@email.org <yourfriends@email.org>
104
+ 1 address contacts.
105
+ ```
106
+
107
+ Create a chat with your friend and send a message:
108
+
109
+ ```
110
+ > createchat 10
111
+ Single#Chat#12 created successfully.
112
+ > chat 12
113
+ Selecting chat Chat#12
114
+ Single#Chat#12: yourfriends@email.org [yourfriends@email.org] Icon: profile-db-blobs/4138c52e5bc1c576cda7dd44d088c07.png
115
+ 0 messages.
116
+ 81.252µs to create this list, 123.625µs to mark all messages as noticed.
117
+ > send hi
118
+ ```
119
+
120
+ List messages when inside a chat:
121
+
122
+ ```
123
+ > chat
124
+ ```
125
+
126
+ For more commands type:
127
+
128
+ ```
129
+ > help
130
+ ```
131
+
132
+ ## Installing libdeltachat system wide
133
+
134
+ ```
135
+ $ git clone https://github.com/chatmail/core.git
136
+ $ cd deltachat-core-rust
137
+ $ cmake -B build . -DCMAKE_INSTALL_PREFIX=/usr
138
+ $ cmake --build build
139
+ $ sudo cmake --install build
140
+ ```
141
+
142
+ ## Development
143
+
144
+ ```sh
145
+ # run tests
146
+ $ cargo test --all
147
+ # build c-ffi
148
+ $ cargo build -p deltachat_ffi --release
149
+ ```
150
+
151
+ ## Debugging environment variables
152
+
153
+ - `DCC_MIME_DEBUG`: if set outgoing and incoming message will be printed
154
+
155
+ - `RUST_LOG=async_imap=trace,async_smtp=trace`: enable IMAP and
156
+ SMTP tracing in addition to info messages.
157
+
158
+ ### Expensive tests
159
+
160
+ Some tests are expensive and marked with `#[ignore]`, to run these
161
+ use the `--ignored` argument to the test binary (not to cargo itself):
162
+ ```sh
163
+ $ cargo test -- --ignored
164
+ ```
165
+
166
+ ### Fuzzing
167
+
168
+ Install [`cargo-bolero`](https://github.com/camshaft/bolero) with
169
+ ```sh
170
+ $ cargo install cargo-bolero
171
+ ```
172
+
173
+ Run fuzzing tests with
174
+ ```sh
175
+ $ cd fuzz
176
+ $ cargo bolero test fuzz_mailparse -s NONE
177
+ ```
178
+
179
+ Corpus is created at `fuzz/fuzz_targets/corpus`,
180
+ you can add initial inputs there.
181
+ For `fuzz_mailparse` target corpus can be populated with
182
+ `../test-data/message/*.eml`.
183
+
184
+ ## Features
185
+
186
+ - `vendored`: When using Openssl for TLS, this bundles a vendored version.
187
+
188
+ ## Update Provider Data
189
+
190
+ To add the updates from the
191
+ [provider-db](https://github.com/chatmail/provider-db) to the core,
192
+ check line `REV=` inside `./scripts/update-provider-database.sh`
193
+ and then run the script.
194
+
195
+ ## Language bindings and frontend projects
196
+
197
+ Language bindings are available for:
198
+
199
+ - **C** \[[📂 source](./deltachat-ffi) | [📚 docs](https://c.delta.chat)\]
200
+ - -> libdeltachat is going to be deprecated and only exists because Android, iOS and Ubuntu Touch are still using it. If you build a new project, then please use the jsonrpc api instead.
201
+ - **JS**: \[[📂 source](./deltachat-rpc-client) | [📦 npm](https://www.npmjs.com/package/@deltachat/jsonrpc-client) | [📚 docs](https://js.jsonrpc.delta.chat/)\]
202
+ - **Python** \[[📂 source](./python) | [📦 pypi](https://pypi.org/project/deltachat) | [📚 docs](https://py.delta.chat)\]
203
+ - **Go** \[[📂 source](https://github.com/deltachat/deltachat-rpc-client-go/)\]
204
+ - **Java** and **Swift** (contained in the Android/iOS repos)
205
+
206
+ The following "frontend" projects make use of the Rust-library
207
+ or its language bindings:
208
+
209
+ - [Android](https://github.com/deltachat/deltachat-android)
210
+ - [iOS](https://github.com/deltachat/deltachat-ios)
211
+ - [Desktop](https://github.com/deltachat/deltachat-desktop)
212
+ - [Pidgin](https://code.ur.gs/lupine/purple-plugin-delta/)
213
+ - [Telepathy](https://code.ur.gs/lupine/telepathy-padfoot/)
214
+ - [Ubuntu Touch](https://codeberg.org/lk108/deltatouch)
215
+ - several **Bots**
RELEASE.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Releasing a new version of DeltaChat core
2
+
3
+ For example, to release version 1.116.0 of the core, do the following steps.
4
+
5
+ 1. Resolve all [blocker issues](https://github.com/chatmail/core/labels/blocker).
6
+
7
+ 2. Update the changelog: `git cliff --unreleased --tag 1.116.0 --prepend CHANGELOG.md` or `git cliff -u -t 1.116.0 -p CHANGELOG.md`.
8
+
9
+ 3. add a link to compare previous with current version to the end of CHANGELOG.md:
10
+ `[1.116.0]: https://github.com/chatmail/core/compare/v1.115.2...v1.116.0`
11
+
12
+ 4. Update the version by running `scripts/set_core_version.py 1.116.0`.
13
+
14
+ 5. Commit the changes as `chore(release): prepare for 1.116.0`.
15
+ Optionally, use a separate branch like `prep-1.116.0` for this commit and open a PR for review.
16
+
17
+ 6. Tag the release: `git tag --annotate v1.116.0`.
18
+
19
+ 7. Push the release tag: `git push origin v1.116.0`.
20
+
21
+ 8. Create a GitHub release: `gh release create v1.116.0 --notes ''`.
STYLE.md ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Coding conventions
2
+
3
+ We format the code using `rustfmt`. Run `cargo fmt` prior to committing the code.
4
+ Run `scripts/clippy.sh` to check the code for common mistakes with [Clippy].
5
+
6
+ [Clippy]: https://doc.rust-lang.org/clippy/
7
+
8
+ ## SQL
9
+
10
+ Multi-line SQL statements should be formatted using string literals,
11
+ for example
12
+ ```
13
+ sql.execute(
14
+ "CREATE TABLE messages (
15
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
16
+ text TEXT DEFAULT '' NOT NULL -- message text
17
+ ) STRICT",
18
+ )
19
+ .await
20
+ .context("CREATE TABLE messages")?;
21
+ ```
22
+
23
+ Do not use macros like [`concat!`](https://doc.rust-lang.org/std/macro.concat.html)
24
+ or [`indoc!](https://docs.rs/indoc).
25
+ Do not escape newlines like this:
26
+ ```
27
+ sql.execute(
28
+ "CREATE TABLE messages ( \
29
+ id INTEGER PRIMARY KEY AUTOINCREMENT, \
30
+ text TEXT DEFAULT '' NOT NULL \
31
+ ) STRICT",
32
+ )
33
+ .await
34
+ .context("CREATE TABLE messages")?;
35
+ ```
36
+ Escaping newlines
37
+ is prone to errors like this if space before backslash is missing:
38
+ ```
39
+ "SELECT foo\
40
+ FROM bar"
41
+ ```
42
+ Literal above results in `SELECT fooFROM bar` string.
43
+ This style also does not allow using `--` comments.
44
+
45
+ ---
46
+
47
+ Declare new SQL tables with [`STRICT`](https://sqlite.org/stricttables.html) keyword
48
+ to make SQLite check column types.
49
+
50
+ Declare primary keys with [`AUTOINCREMENT`](https://www.sqlite.org/autoinc.html) keyword.
51
+ This avoids reuse of the row IDs and can avoid dangerous bugs
52
+ like forwarding wrong message because the message was deleted
53
+ and another message took its row ID.
54
+
55
+ Declare all new columns as `NOT NULL`
56
+ and set the `DEFAULT` value if it is optional so the column can be skipped in `INSERT` statements.
57
+ Dealing with `NULL` values both in SQL and in Rust is tricky and we try to avoid it.
58
+ If column is already declared without `NOT NULL`, use `IFNULL` function to provide default value when selecting it.
59
+ Use `HAVING COUNT(*) > 0` clause
60
+ to [prevent aggregate functions such as `MIN` and `MAX` from returning `NULL`](https://stackoverflow.com/questions/66527856/aggregate-functions-max-etc-return-null-instead-of-no-rows).
61
+
62
+ Don't delete unused columns too early, but maybe after several months/releases, unused columns are
63
+ still used by older versions, so deleting them breaks downgrading the core or importing a backup in
64
+ an older version. Also don't change the column type, consider adding a new column with another name
65
+ instead. Finally, never change column semantics, this is especially dangerous because the `STRICT`
66
+ keyword doesn't help here.
67
+
68
+ Consider adding context to `anyhow` errors for SQL statements using `.context()` so that it's
69
+ possible to understand from logs which statement failed. See [Errors](#errors) for more info.
70
+
71
+ ## Errors
72
+
73
+ Delta Chat core mostly uses [`anyhow`](https://docs.rs/anyhow/) errors.
74
+ When using [`Context`](https://docs.rs/anyhow/latest/anyhow/trait.Context.html),
75
+ capitalize it but do not add a full stop as the contexts will be separated by `:`.
76
+ For example:
77
+ ```
78
+ .with_context(|| format!("Unable to trash message {msg_id}"))
79
+ ```
80
+
81
+ All errors should be handled in one of these ways:
82
+ - With `if let Err() =` (incl. logging them into `warn!()`/`err!()`).
83
+ - With `.log_err().ok()`.
84
+ - Bubbled up with `?`.
85
+
86
+ When working with [async streams](https://docs.rs/futures/0.3.31/futures/stream/index.html),
87
+ prefer [`try_next`](https://docs.rs/futures/0.3.31/futures/stream/trait.TryStreamExt.html#method.try_next) over `next()`, e.g. do
88
+ ```
89
+ while let Some(event) = stream.try_next().await? {
90
+ todo!();
91
+ }
92
+ ```
93
+ instead of
94
+ ```
95
+ while let Some(event_res) = stream.next().await {
96
+ todo!();
97
+ }
98
+ ```
99
+ as it allows bubbling up the error early with `?`
100
+ with no way to accidentally skip error processing
101
+ with early `continue` or `break`.
102
+ Some streams reading from a connection
103
+ return infinite number of `Some(Err(_))`
104
+ items when connection breaks and not processing
105
+ errors may result in infinite loop.
106
+
107
+ `backtrace` feature is enabled for `anyhow` crate
108
+ and `debug = 1` option is set in the test profile.
109
+ This allows to run `RUST_BACKTRACE=1 cargo test`
110
+ and get a backtrace with line numbers in resultified tests
111
+ which return `anyhow::Result`.
112
+
113
+ `unwrap` and `expect` are not used in the library
114
+ because panics are difficult to debug on user devices.
115
+ However, in the tests `.expect` may be used.
116
+ Follow
117
+ <https://doc.rust-lang.org/core/error/index.html#common-message-styles>
118
+ for `.expect` message style.
119
+
120
+ ## BTreeMap vs HashMap
121
+
122
+ Prefer [BTreeMap](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html)
123
+ over [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html)
124
+ and [BTreeSet](https://doc.rust-lang.org/std/collections/struct.BTreeSet.html)
125
+ over [HashSet](https://doc.rust-lang.org/std/collections/struct.HashSet.html)
126
+ as iterating over these structures returns items in deterministic order.
127
+
128
+ Non-deterministic code may result in difficult to reproduce bugs,
129
+ flaky tests, regression tests that miss bugs
130
+ or different behavior on different devices when processing the same messages.
131
+
132
+ ## Logging
133
+
134
+ For logging, use `info!`, `warn!` and `error!` macros.
135
+ Log messages should be capitalized and have a full stop in the end. For example:
136
+ ```
137
+ info!(context, "Ignoring addition of {added_addr:?} to {chat_id}.");
138
+ ```
139
+
140
+ Format anyhow errors with `{:#}` to print all the contexts like this:
141
+ ```
142
+ error!(context, "Failed to set selfavatar timestamp: {err:#}.");
143
+ ```
144
+
145
+ ## Documentation comments
146
+
147
+ All public modules, methods and fields should be documented.
148
+ This is checked by [`missing_docs`](https://doc.rust-lang.org/rustdoc/lints.html#missing_docs) lint.
149
+
150
+ Private items do not have to be documented,
151
+ but CI uses `cargo doc --document-private-items`
152
+ to build the documentation,
153
+ so it is preferred that new items
154
+ are documented.
155
+
156
+ Follow Rust guidelines for the documentation comments:
157
+ <https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#summary-sentence>
assets/icon-archive.png ADDED
assets/icon-archive.svg ADDED
assets/icon-broadcast.png ADDED
assets/icon-broadcast.svg ADDED
assets/icon-device.png ADDED
assets/icon-device.svg ADDED
assets/icon-saved-messages.png ADDED
assets/icon-saved-messages.svg ADDED
assets/icon-unencrypted.png ADDED
assets/icon-unencrypted.svg ADDED
assets/icon-webxdc.png ADDED
assets/icon-webxdc.svg ADDED
assets/qr_overlay_delta.svg-part ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <path
2
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
3
+ d="m 24.015419,1.2870249 c -12.549421,0 -22.7283936,10.1789711 -22.7283936,22.7283931 0,12.549422 10.1789726,22.728395 22.7283936,22.728395 14.337742,-0.342877 9.614352,-4.702705 23.697556,0.969161 -7.545453,-13.001555 -1.082973,-13.32964 -0.969161,-23.697556 0,-12.549422 -10.178973,-22.7283931 -22.728395,-22.7283931 z" />
4
+ <path
5
+ style="fill:#000000;fill-opacity:1;stroke:none"
6
+ d="M 23.982249,5.3106163 C 13.645822,5.4364005 5.2618355,13.92999 5.2618355,24.275753 c 0,10.345764 8.3839865,18.635301 18.7204135,18.509516 9.827724,-0.03951 7.516769,-5.489695 18.380082,-0.443187 -5.950849,-9.296115 0.201753,-10.533667 0.340336,-18.521947 0,-10.345766 -8.383989,-18.6353031 -18.720418,-18.5095187 z" />
7
+ <g
8
+ style="fill:#ffffff"
9
+ transform="scale(1.1342891,0.88160947)">
10
+ <path
11
+ d="m 21.360141,23.513382 q -1.218487,-1.364705 -3.387392,-3.265543 -2.388233,-2.095797 -3.216804,-3.289913 -0.828571,-1.218486 -0.828571,-2.6563 0,-2.144536 1.998318,-3.363022 1.998317,-1.2428565 5.215121,-1.2428565 3.216804,0 5.605037,1.0966375 2.412603,1.096638 2.412603,3.021846 0,0.92605 -0.584873,1.535293 -0.584874,0.609243 -1.364705,0.609243 -1.121008,0 -2.631931,-1.681511 -1.535292,-1.705881 -2.60756,-2.388233 -1.047898,-0.706722 -2.461343,-0.706722 -1.803359,0 -2.973106,0.804201 -1.145377,0.804201 -1.145377,2.047057 0,1.169747 0.950419,2.193275 0.950419,1.023529 4.898315,3.728568 4.215963,2.899998 5.946213,4.532769 1.75462,1.632772 2.851258,3.972265 1.096638,2.339494 1.096638,4.947055 0,4.581508 -3.241174,8.090749 -3.216804,3.484871 -7.530245,3.484871 -3.923526,0 -6.628566,-2.802519 -2.705039,-2.802518 -2.705039,-7.481506 0,-4.508399 2.973106,-7.530245 2.997477,-3.021846 7.359658,-3.655459 z m 1.072268,1.121008 q -6.994112,1.145377 -6.994112,9.601672 0,4.36218 1.730251,6.774783 1.75462,2.412603 4.069744,2.412603 2.412603,0 3.972265,-2.315124 1.559663,-2.339493 1.559663,-6.311759 0,-5.751255 -4.337811,-10.162175 z" />
12
+ </g>
assets/qrcode_logo_footer.svg ADDED
assets/statistics-bot.vcf ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ BEGIN:VCARD
2
+ VERSION:4.0
3
+ EMAIL:self_reporting@testrun.org
4
+ FN:Statistics bot
5
+ KEY:data:application/pgp-keys;base64,xjMEZbfBlBYJKwYBBAHaRw8BAQdABpLWS2PUIGGo4pslVt4R8sylP5wZihmhf1DTDr3oCMPNHDxzZWxmX3JlcG9ydGluZ0B0ZXN0cnVuLm9yZz7CiwQQFggAMwIZAQUCZbfBlAIbAwQLCQgHBhUICQoLAgMWAgEWIQTS2i16sHeYTckGn284K3M5Z4oohAAKCRA4K3M5Z4oohD8dAQCQV7CoH6UP4PD+NqI4kW5tbbqdh2AnDROg60qotmLExAEAxDfd3QHAK9f8b9qQUbLmHIztCLxhEuVbWPBEYeVW0gvOOARlt8GUEgorBgEEAZdVAQUBAQdAMBUhYoAAcI625vGZqnM5maPX4sGJ7qvJxPAFILPy6AcDAQgHwngEGBYIACAFAmW3wZQCGwwWIQTS2i16sHeYTckGn284K3M5Z4oohAAKCRA4K3M5Z4oohPwCAQCvzk1ObIkj2GqsuIfaULlgdnfdZY8LNary425CEfHZDQD5AblXVrlMO1frdlc/Vo9z3pEeCrfYdD7ITD3/OeVoiQ4=
6
+ REV:20250412T195751Z
7
+ END:VCARD
assets/welcome-image.jpg ADDED

Git LFS Details

  • SHA256: 33295a21c664603a96f82bbc16c3a398de5cc53e7ee99a37af2342d964179485
  • Pointer size: 131 Bytes
  • Size of remote file: 124 kB
benches/contacts.rs ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+
4
+ use criterion::{Criterion, criterion_group, criterion_main};
5
+ use deltachat::Events;
6
+ use deltachat::contact::Contact;
7
+ use deltachat::context::Context;
8
+ use deltachat::stock_str::StockStrings;
9
+ use tempfile::tempdir;
10
+
11
+ async fn address_book_benchmark(n: u32, read_count: u32) {
12
+ let dir = tempdir().unwrap();
13
+ let dbfile = dir.path().join("db.sqlite");
14
+ let id = 100;
15
+ let context = Context::new(&dbfile, id, Events::new(), StockStrings::new())
16
+ .await
17
+ .unwrap();
18
+
19
+ let book = (0..n)
20
+ .map(|i| format!("Name {i}\naddr{i}@example.org\n"))
21
+ .collect::<Vec<String>>()
22
+ .join("");
23
+
24
+ Contact::add_address_book(&context, &book).await.unwrap();
25
+
26
+ let query: Option<&str> = None;
27
+ for _ in 0..read_count {
28
+ Contact::get_all(&context, 0, query).await.unwrap();
29
+ }
30
+ }
31
+
32
+ fn criterion_benchmark(c: &mut Criterion) {
33
+ let rt = tokio::runtime::Runtime::new().unwrap();
34
+
35
+ c.bench_function("create 500 contacts", |b| {
36
+ b.to_async(&rt)
37
+ .iter(|| async { address_book_benchmark(black_box(500), black_box(0)).await })
38
+ });
39
+
40
+ c.bench_function("create 100 contacts and read it 1000 times", |b| {
41
+ b.to_async(&rt)
42
+ .iter(|| async { address_book_benchmark(black_box(100), black_box(1000)).await })
43
+ });
44
+ }
45
+
46
+ criterion_group!(benches, criterion_benchmark);
47
+ criterion_main!(benches);
benches/create_account.rs ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+ use std::path::PathBuf;
4
+
5
+ use criterion::{Criterion, criterion_group, criterion_main};
6
+ use deltachat::accounts::Accounts;
7
+ use tempfile::tempdir;
8
+
9
+ async fn create_accounts(n: u32) {
10
+ let dir = tempdir().unwrap();
11
+ let p: PathBuf = dir.path().join("accounts");
12
+
13
+ let writable = true;
14
+ let mut accounts = Accounts::new(p.clone(), writable).await.unwrap();
15
+
16
+ for expected_id in 2..n {
17
+ let id = accounts.add_account().await.unwrap();
18
+ assert_eq!(id, expected_id);
19
+ }
20
+ }
21
+
22
+ fn criterion_benchmark(c: &mut Criterion) {
23
+ c.bench_function("create 1 account", |b| {
24
+ let rt = tokio::runtime::Runtime::new().unwrap();
25
+ b.to_async(&rt).iter(|| create_accounts(black_box(1)))
26
+ });
27
+ }
28
+
29
+ criterion_group!(benches, criterion_benchmark);
30
+ criterion_main!(benches);
benches/decrypting.rs ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! Benchmarks for message decryption,
2
+ //! comparing decryption of symmetrically-encrypted messages
3
+ //! to decryption of asymmetrically-encrypted messages.
4
+ //!
5
+ //! Call with
6
+ //!
7
+ //! ```text
8
+ //! cargo bench --bench decrypting --features="internals"
9
+ //! ```
10
+ //!
11
+ //! or, if you want to only run e.g. the 'Decrypt a symmetrically encrypted message' benchmark:
12
+ //!
13
+ //! ```text
14
+ //! cargo bench --bench decrypting --features="internals" -- 'Decrypt a symmetrically encrypted message'
15
+ //! ```
16
+ //!
17
+ //! You can also pass a substring.
18
+ //! So, you can run all 'Decrypt and parse' benchmarks with:
19
+ //!
20
+ //! ```text
21
+ //! cargo bench --bench decrypting --features="internals" -- 'Decrypt and parse'
22
+ //! ```
23
+ //!
24
+ //! Symmetric decryption has to try out all known secrets,
25
+ //! You can benchmark this by adapting the `NUM_SECRETS` variable.
26
+
27
+ use std::hint::black_box;
28
+
29
+ use criterion::{Criterion, criterion_group, criterion_main};
30
+ use deltachat::internals_for_benches::create_broadcast_secret;
31
+ use deltachat::internals_for_benches::create_dummy_keypair;
32
+ use deltachat::internals_for_benches::save_broadcast_secret;
33
+ use deltachat::{
34
+ Events,
35
+ chat::ChatId,
36
+ config::Config,
37
+ context::Context,
38
+ internals_for_benches::key_from_asc,
39
+ internals_for_benches::parse_and_get_text,
40
+ internals_for_benches::store_self_keypair,
41
+ pgp::{KeyPair, SeipdVersion, decrypt, pk_encrypt, symm_encrypt_message},
42
+ stock_str::StockStrings,
43
+ };
44
+ use rand::{Rng, rng};
45
+ use tempfile::tempdir;
46
+
47
+ const NUM_SECRETS: usize = 500;
48
+
49
+ async fn create_context() -> Context {
50
+ let dir = tempdir().unwrap();
51
+ let dbfile = dir.path().join("db.sqlite");
52
+ let context = Context::new(dbfile.as_path(), 100, Events::new(), StockStrings::new())
53
+ .await
54
+ .unwrap();
55
+
56
+ context
57
+ .set_config(Config::ConfiguredAddr, Some("bob@example.net"))
58
+ .await
59
+ .unwrap();
60
+ let secret = key_from_asc(include_str!("../test-data/key/bob-secret.asc")).unwrap();
61
+ let public = secret.signed_public_key();
62
+ let key_pair = KeyPair { public, secret };
63
+ store_self_keypair(&context, &key_pair)
64
+ .await
65
+ .expect("Failed to save key");
66
+
67
+ context
68
+ }
69
+
70
+ fn criterion_benchmark(c: &mut Criterion) {
71
+ let mut group = c.benchmark_group("Decrypt");
72
+
73
+ // ===========================================================================================
74
+ // Benchmarks for decryption only, without any other parsing
75
+ // ===========================================================================================
76
+
77
+ group.sample_size(10);
78
+
79
+ group.bench_function("Decrypt a symmetrically encrypted message", |b| {
80
+ let plain = generate_plaintext();
81
+ let secrets = generate_secrets();
82
+ let encrypted = tokio::runtime::Runtime::new().unwrap().block_on(async {
83
+ let secret = secrets[NUM_SECRETS / 2].clone();
84
+ symm_encrypt_message(
85
+ plain.clone(),
86
+ create_dummy_keypair("alice@example.org").unwrap().secret,
87
+ black_box(&secret),
88
+ true,
89
+ )
90
+ .await
91
+ .unwrap()
92
+ });
93
+
94
+ b.iter(|| {
95
+ let mut msg =
96
+ decrypt(encrypted.clone().into_bytes(), &[], black_box(&secrets)).unwrap();
97
+ let decrypted = msg.as_data_vec().unwrap();
98
+
99
+ assert_eq!(black_box(decrypted), plain);
100
+ });
101
+ });
102
+
103
+ group.bench_function("Decrypt a public-key encrypted message", |b| {
104
+ let plain = generate_plaintext();
105
+ let key_pair = create_dummy_keypair("alice@example.org").unwrap();
106
+ let secrets = generate_secrets();
107
+ let encrypted = tokio::runtime::Runtime::new().unwrap().block_on(async {
108
+ pk_encrypt(
109
+ plain.clone(),
110
+ vec![black_box(key_pair.public.clone())],
111
+ key_pair.secret.clone(),
112
+ true,
113
+ true,
114
+ SeipdVersion::V2,
115
+ )
116
+ .await
117
+ .unwrap()
118
+ });
119
+
120
+ b.iter(|| {
121
+ let mut msg = decrypt(
122
+ encrypted.clone().into_bytes(),
123
+ std::slice::from_ref(&key_pair.secret),
124
+ black_box(&secrets),
125
+ )
126
+ .unwrap();
127
+ let decrypted = msg.as_data_vec().unwrap();
128
+
129
+ assert_eq!(black_box(decrypted), plain);
130
+ });
131
+ });
132
+
133
+ // ===========================================================================================
134
+ // Benchmarks for the whole parsing pipeline, incl. decryption (but excl. receive_imf())
135
+ // ===========================================================================================
136
+
137
+ let rt = tokio::runtime::Runtime::new().unwrap();
138
+ let mut secrets = generate_secrets();
139
+
140
+ // "secret" is the shared secret that was used to encrypt text_symmetrically_encrypted.eml.
141
+ // Put it into the middle of our secrets:
142
+ secrets[NUM_SECRETS / 2] = "secret".to_string();
143
+
144
+ let context = rt.block_on(async {
145
+ let context = create_context().await;
146
+ for (i, secret) in secrets.iter().enumerate() {
147
+ save_broadcast_secret(&context, ChatId::new(10 + i as u32), secret)
148
+ .await
149
+ .unwrap();
150
+ }
151
+ context
152
+ });
153
+
154
+ group.bench_function("Decrypt and parse a symmetrically encrypted message", |b| {
155
+ b.to_async(&rt).iter(|| {
156
+ let ctx = context.clone();
157
+ async move {
158
+ let text = parse_and_get_text(
159
+ &ctx,
160
+ include_bytes!("../test-data/message/text_symmetrically_encrypted.eml"),
161
+ )
162
+ .await
163
+ .unwrap();
164
+ assert_eq!(text, "Symmetrically encrypted message");
165
+ }
166
+ });
167
+ });
168
+
169
+ group.bench_function("Decrypt and parse a public-key encrypted message", |b| {
170
+ b.to_async(&rt).iter(|| {
171
+ let ctx = context.clone();
172
+ async move {
173
+ let text = parse_and_get_text(
174
+ &ctx,
175
+ include_bytes!("../test-data/message/text_from_alice_encrypted.eml"),
176
+ )
177
+ .await
178
+ .unwrap();
179
+ assert_eq!(text, "hi");
180
+ }
181
+ });
182
+ });
183
+
184
+ group.finish();
185
+ }
186
+
187
+ fn generate_secrets() -> Vec<String> {
188
+ let secrets: Vec<String> = (0..NUM_SECRETS)
189
+ .map(|_| create_broadcast_secret())
190
+ .collect();
191
+ secrets
192
+ }
193
+
194
+ fn generate_plaintext() -> Vec<u8> {
195
+ let mut plain: Vec<u8> = vec![0; 500];
196
+ rng().fill(&mut plain[..]);
197
+ plain
198
+ }
199
+
200
+ criterion_group!(benches, criterion_benchmark);
201
+ criterion_main!(benches);
benches/get_chat_msgs.rs ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+ use std::path::Path;
4
+
5
+ use criterion::{Criterion, criterion_group, criterion_main};
6
+ use deltachat::Events;
7
+ use deltachat::chat::{self, ChatId};
8
+ use deltachat::chatlist::Chatlist;
9
+ use deltachat::context::Context;
10
+ use deltachat::stock_str::StockStrings;
11
+
12
+ async fn get_chat_msgs_benchmark(dbfile: &Path, chats: &[ChatId]) {
13
+ let id = 100;
14
+ let context = Context::new(dbfile, id, Events::new(), StockStrings::new())
15
+ .await
16
+ .unwrap();
17
+
18
+ for c in chats.iter().take(10) {
19
+ black_box(chat::get_chat_msgs(&context, *c).await.ok());
20
+ }
21
+ }
22
+
23
+ fn criterion_benchmark(c: &mut Criterion) {
24
+ // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many
25
+ // messages, such as your primary account.
26
+ if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") {
27
+ let rt = tokio::runtime::Runtime::new().unwrap();
28
+
29
+ let chats: Vec<_> = rt.block_on(async {
30
+ let context = Context::new(Path::new(&path), 100, Events::new(), StockStrings::new())
31
+ .await
32
+ .unwrap();
33
+ let chatlist = Chatlist::try_load(&context, 0, None, None).await.unwrap();
34
+ let len = chatlist.len();
35
+ (0..len).map(|i| chatlist.get_chat_id(i).unwrap()).collect()
36
+ });
37
+
38
+ c.bench_function("chat::get_chat_msgs (load messages from 10 chats)", |b| {
39
+ b.to_async(&rt)
40
+ .iter(|| get_chat_msgs_benchmark(black_box(path.as_ref()), black_box(&chats)))
41
+ });
42
+ } else {
43
+ println!("env var not set: DELTACHAT_BENCHMARK_DATABASE");
44
+ }
45
+ }
46
+
47
+ criterion_group!(benches, criterion_benchmark);
48
+ criterion_main!(benches);
benches/get_chatlist.rs ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+ use std::path::Path;
4
+
5
+ use criterion::{Criterion, criterion_group, criterion_main};
6
+ use deltachat::Events;
7
+ use deltachat::chatlist::Chatlist;
8
+ use deltachat::context::Context;
9
+ use deltachat::stock_str::StockStrings;
10
+
11
+ async fn get_chat_list_benchmark(context: &Context) {
12
+ Chatlist::try_load(context, 0, None, None).await.unwrap();
13
+ }
14
+
15
+ fn criterion_benchmark(c: &mut Criterion) {
16
+ // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many
17
+ // messages, such as your primary account.
18
+ if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") {
19
+ let rt = tokio::runtime::Runtime::new().unwrap();
20
+ let context = rt.block_on(async {
21
+ Context::new(Path::new(&path), 100, Events::new(), StockStrings::new())
22
+ .await
23
+ .unwrap()
24
+ });
25
+ c.bench_function("chatlist:try_load (Get Chatlist)", |b| {
26
+ b.to_async(&rt)
27
+ .iter(|| get_chat_list_benchmark(black_box(&context)))
28
+ });
29
+ } else {
30
+ println!("env var not set: DELTACHAT_BENCHMARK_DATABASE");
31
+ }
32
+ }
33
+
34
+ criterion_group!(benches, criterion_benchmark);
35
+ criterion_main!(benches);
benches/marknoticed_chat.rs ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+ use std::path::Path;
4
+
5
+ use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
6
+ use deltachat::Events;
7
+ use deltachat::chat::{self, ChatId};
8
+ use deltachat::chatlist::Chatlist;
9
+ use deltachat::context::Context;
10
+ use deltachat::stock_str::StockStrings;
11
+ use futures_lite::future::block_on;
12
+ use tempfile::tempdir;
13
+
14
+ async fn marknoticed_chat_benchmark(context: &Context, chats: &[ChatId]) {
15
+ for c in chats.iter().take(20) {
16
+ chat::marknoticed_chat(context, *c).await.unwrap();
17
+ }
18
+ }
19
+
20
+ fn criterion_benchmark(c: &mut Criterion) {
21
+ // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many
22
+ // messages, such as your primary account.
23
+ if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") {
24
+ let rt = tokio::runtime::Runtime::new().unwrap();
25
+
26
+ let chats: Vec<_> = rt.block_on(async {
27
+ let context = Context::new(Path::new(&path), 100, Events::new(), StockStrings::new())
28
+ .await
29
+ .unwrap();
30
+ let chatlist = Chatlist::try_load(&context, 0, None, None).await.unwrap();
31
+ let len = chatlist.len();
32
+ (1..len).map(|i| chatlist.get_chat_id(i).unwrap()).collect()
33
+ });
34
+
35
+ // This mainly tests the performance of marknoticed_chat()
36
+ // when nothing has to be done
37
+ c.bench_function(
38
+ "chat::marknoticed_chat (mark 20 chats as noticed repeatedly)",
39
+ |b| {
40
+ let dir = tempdir().unwrap();
41
+ let dir = dir.path();
42
+ let new_db = dir.join("dc.db");
43
+ std::fs::copy(&path, &new_db).unwrap();
44
+
45
+ let context = block_on(async {
46
+ Context::new(Path::new(&new_db), 100, Events::new(), StockStrings::new())
47
+ .await
48
+ .unwrap()
49
+ });
50
+
51
+ b.to_async(&rt)
52
+ .iter(|| marknoticed_chat_benchmark(&context, black_box(&chats)))
53
+ },
54
+ );
55
+
56
+ // If the first 20 chats contain fresh messages or reactions,
57
+ // this tests the performance of marking them as noticed.
58
+ c.bench_function(
59
+ "chat::marknoticed_chat (mark 20 chats as noticed, resetting after every iteration)",
60
+ |b| {
61
+ b.to_async(&rt).iter_batched(
62
+ || {
63
+ let dir = tempdir().unwrap();
64
+ let new_db = dir.path().join("dc.db");
65
+ std::fs::copy(&path, &new_db).unwrap();
66
+
67
+ let context = block_on(async {
68
+ Context::new(
69
+ Path::new(&new_db),
70
+ 100,
71
+ Events::new(),
72
+ StockStrings::new(),
73
+ )
74
+ .await
75
+ .unwrap()
76
+ });
77
+ (dir, context)
78
+ },
79
+ |(_dir, context)| {
80
+ let chats = &chats;
81
+ async move {
82
+ marknoticed_chat_benchmark(black_box(&context), black_box(chats)).await
83
+ }
84
+ },
85
+ BatchSize::PerIteration,
86
+ );
87
+ },
88
+ );
89
+ } else {
90
+ println!("env var not set: DELTACHAT_BENCHMARK_DATABASE");
91
+ }
92
+ }
93
+
94
+ criterion_group!(benches, criterion_benchmark);
95
+ criterion_main!(benches);
benches/receive_emails.rs ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #![recursion_limit = "256"]
2
+ use std::hint::black_box;
3
+ use std::path::PathBuf;
4
+
5
+ use criterion::{Criterion, criterion_group, criterion_main};
6
+ use deltachat::{
7
+ Events,
8
+ config::Config,
9
+ context::Context,
10
+ imex::{ImexMode, imex},
11
+ receive_imf::receive_imf,
12
+ stock_str::StockStrings,
13
+ };
14
+ use tempfile::tempdir;
15
+
16
+ async fn recv_all_emails(context: Context, iteration: u32) -> Context {
17
+ for i in 0..100 {
18
+ let imf_raw = format!(
19
+ "Subject: Benchmark
20
+ Message-ID: Mr.{iteration}.{i}@testrun.org
21
+ Date: Sat, 07 Dec 2019 19:00:27 +0000
22
+ To: alice@example.com
23
+ From: sender@testrun.org
24
+ Chat-Version: 1.0
25
+ Chat-Disposition-Notification-To: sender@testrun.org
26
+ Chat-User-Avatar: 0
27
+ In-Reply-To: Mr.{iteration}.{i_dec}@testrun.org
28
+ MIME-Version: 1.0
29
+
30
+ Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
31
+
32
+ Hello {i}",
33
+ i = i,
34
+ i_dec = i - 1,
35
+ );
36
+ receive_imf(&context, black_box(imf_raw.as_bytes()), false)
37
+ .await
38
+ .unwrap();
39
+ }
40
+ context
41
+ }
42
+
43
+ /// Receive 100 emails that remove charlie@example.com and add
44
+ /// him back
45
+ async fn recv_groupmembership_emails(context: Context, iteration: u32) -> Context {
46
+ for i in 0..50 {
47
+ let imf_raw = format!(
48
+ "Subject: Benchmark
49
+ Message-ID: Gr.{iteration}.ADD.{i}@testrun.org
50
+ Date: Sat, 07 Dec 2019 19:00:27 +0000
51
+ To: alice@example.com, b@example.com, c@example.com, d@example.com, e@example.com, f@example.com
52
+ From: sender@testrun.org
53
+ Chat-Version: 1.0
54
+ Chat-Disposition-Notification-To: sender@testrun.org
55
+ Chat-User-Avatar: 0
56
+ Chat-Group-Member-Added: charlie@example.com
57
+ In-Reply-To: Gr.{iteration}.REMOVE.{i_dec}@testrun.org
58
+ MIME-Version: 1.0
59
+
60
+ Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
61
+
62
+ Hello {i}",
63
+ i_dec = i - 1,
64
+ );
65
+ receive_imf(&context, black_box(imf_raw.as_bytes()), false)
66
+ .await
67
+ .unwrap();
68
+
69
+ let imf_raw = format!(
70
+ "Subject: Benchmark
71
+ Message-ID: Gr.{iteration}.REMOVE.{i}@testrun.org
72
+ Date: Sat, 07 Dec 2019 19:00:27 +0000
73
+ To: alice@example.com, b@example.com, c@example.com, d@example.com, e@example.com, f@example.com
74
+ From: sender@testrun.org
75
+ Chat-Version: 1.0
76
+ Chat-Disposition-Notification-To: sender@testrun.org
77
+ Chat-User-Avatar: 0
78
+ Chat-Group-Member-Removed: charlie@example.com
79
+ In-Reply-To: Gr.{iteration}.ADD.{i}@testrun.org
80
+ MIME-Version: 1.0
81
+
82
+ Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
83
+
84
+ Hello {i}"
85
+ );
86
+ receive_imf(&context, black_box(imf_raw.as_bytes()), false)
87
+ .await
88
+ .unwrap();
89
+ }
90
+ context
91
+ }
92
+
93
+ async fn create_context() -> Context {
94
+ let dir = tempdir().unwrap();
95
+ let dbfile = dir.path().join("db.sqlite");
96
+ let id = 100;
97
+ let context = Context::new(dbfile.as_path(), id, Events::new(), StockStrings::new())
98
+ .await
99
+ .unwrap();
100
+
101
+ let backup: PathBuf = std::env::current_dir()
102
+ .unwrap()
103
+ .join("delta-chat-backup.tar");
104
+
105
+ if backup.exists() {
106
+ println!("Importing backup");
107
+ imex(&context, ImexMode::ImportBackup, backup.as_path(), None)
108
+ .await
109
+ .unwrap();
110
+ }
111
+
112
+ let addr = "alice@example.com";
113
+ context.set_config(Config::Addr, Some(addr)).await.unwrap();
114
+ context
115
+ .set_config(Config::ConfiguredAddr, Some(addr))
116
+ .await
117
+ .unwrap();
118
+ context
119
+ .set_config(Config::Configured, Some("1"))
120
+ .await
121
+ .unwrap();
122
+ context
123
+ }
124
+
125
+ fn criterion_benchmark(c: &mut Criterion) {
126
+ let mut group = c.benchmark_group("Receive messages");
127
+ group.bench_function("Receive 100 simple text msgs", |b| {
128
+ let rt = tokio::runtime::Runtime::new().unwrap();
129
+ let context = rt.block_on(create_context());
130
+ let mut i = 0;
131
+
132
+ b.to_async(&rt).iter(|| {
133
+ let ctx = context.clone();
134
+ i += 1;
135
+ async move {
136
+ recv_all_emails(black_box(ctx), i).await;
137
+ }
138
+ });
139
+ });
140
+ group.bench_function(
141
+ "Receive 100 Chat-Group-Member-{Added|Removed} messages",
142
+ |b| {
143
+ let rt = tokio::runtime::Runtime::new().unwrap();
144
+ let context = rt.block_on(create_context());
145
+ let mut i = 0;
146
+
147
+ b.to_async(&rt).iter(|| {
148
+ let ctx = context.clone();
149
+ i += 1;
150
+ async move {
151
+ recv_groupmembership_emails(black_box(ctx), i).await;
152
+ }
153
+ });
154
+ },
155
+ );
156
+ group.finish();
157
+ }
158
+
159
+ criterion_group!(benches, criterion_benchmark);
160
+ criterion_main!(benches);