Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/dapp-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,26 @@ jobs:
else
echo "clean_tag=dev" | tee -a $GITHUB_OUTPUT
fi
read-ipfs-gateway:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
outputs:
web3telegram_ipfs_gateway: ${{ vars.WEB3TELEGRAM_IPFS_GATEWAY }}
steps:
- name: WEB3TELEGRAM_IPFS_GATEWAY
run: echo "WEB3TELEGRAM_IPFS_GATEWAY=$WEB3TELEGRAM_IPFS_GATEWAY"
env:
WEB3TELEGRAM_IPFS_GATEWAY: ${{ vars.WEB3TELEGRAM_IPFS_GATEWAY }}

Comment thread
abbesBenayache marked this conversation as resolved.
docker-publish:
uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/docker-build.yml@docker-build-v3.3.0
needs: [extract-tag]
needs: [extract-tag, read-ipfs-gateway]
Comment thread
abbesBenayache marked this conversation as resolved.
with:
image-name: 'iexechub/web3telegram-dapp'
registry: 'docker.io'
dockerfile: 'dapp/Dockerfile'
context: 'dapp'
build-args: WEB3TELEGRAM_IPFS_GATEWAY=${{ needs.read-ipfs-gateway.outputs.web3telegram_ipfs_gateway }}
Comment thread
abbesBenayache marked this conversation as resolved.
security-scan: false
hadolint: true
push: true
Expand Down
1 change: 1 addition & 0 deletions dapp/.env.override
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
WEB3TELEGRAM_IPFS_GATEWAY=https://ipfs-gateway.v8-bellecour.iex.ec
IEXEC_IN=/path/to/input/directory
IEXEC_OUT=/path/to/output/directory
IEXEC_DATASET_FILENAME="protectedData.zip"
Expand Down
2 changes: 2 additions & 0 deletions dapp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM node:22-alpine3.22
ARG WEB3TELEGRAM_IPFS_GATEWAY
ENV WEB3TELEGRAM_IPFS_GATEWAY=$WEB3TELEGRAM_IPFS_GATEWAY
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
Expand Down
7 changes: 6 additions & 1 deletion dapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fill in the environment variables:
- **IEXEC_DATASET\_\<index\>\_FILENAME**: The name of the data file for dataset at index <index> (starting from 1) that you place in the **IEXEC_IN** directory.
- **IEXEC_APP_DEVELOPER_SECRET**: A JSON string with the following keys:
- **TELEGRAM_BOT_TOKEN**: The API key of the telegram bot used to send the message.
- **WEB3TELEGRAM_IPFS_GATEWAY**: Base URL of the iExec IPFS gateway used to download encrypted message content (must match the chain where content was pinned, e.g. `https://ipfs-gateway.v8-bellecour.iex.ec` or `https://ipfs-gateway.arbitrum-mainnet.iex.ec`). Baked into release images via the deploy workflow; required for local runs.
- **IEXEC_REQUESTER_SECRET_1**: A JSON string with the following keys:
- **telegramContentMultiAddr**: Multiaddress pointing to the encrypted message content to send.
- **telegramContentEncryptionKey**: The encryption key used to encrypt the content.
Expand All @@ -43,9 +44,12 @@ The Dapp will send a telegram message using the object and content specified in
1. **Build the Docker image**: Navigate to the `/web3telegram/dapp` directory of the project and run the following command to build the Docker image:

```sh
docker build . --tag web3telegram-dapp
docker build . --tag web3telegram-dapp \
--build-arg WEB3TELEGRAM_IPFS_GATEWAY=https://ipfs-gateway.v8-bellecour.iex.ec
```

Use the gateway URL for the same chain as your pinned content (see `src/config/config.ts` `ipfsGateway` per chain).

2. **Create local directories**: In your terminal, execute the following commands to create two local directories on your machine:

```sh
Expand All @@ -69,6 +73,7 @@ The Dapp will send a telegram message using the object and content specified in
-e IEXEC_IN=/iexec_in \
-e IEXEC_OUT=/iexec_out \
-e IEXEC_DATASET_FILENAME=data.zip \
-e WEB3TELEGRAM_IPFS_GATEWAY=https://ipfs-gateway.v8-bellecour.iex.ec \
IEXEC_REQUESTER_SECRET_1='{"telegramContentEncryptionKey":"telegram_content_encryption_key","telegramContentMultiAddr":"encrypted_telegram_content_multiaddress","senderName":"sender_name","contentType":"text/plain"}' \
web3telegram-dapp
```
Expand Down
12 changes: 10 additions & 2 deletions dapp/src/decryptContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { Buffer } from 'buffer';
import fetch from 'node-fetch';
import forge from 'node-forge';

const DEFAULT_IPFS_GATEWAY = 'https://ipfs-gateway.v8-bellecour.iex.ec';
export const resolveIpfsGatewayUrl = () => {
const url = process.env.WEB3TELEGRAM_IPFS_GATEWAY;
if (url == null || String(url).trim() === '') {
throw new Error(
'WEB3TELEGRAM_IPFS_GATEWAY environment variable is not set.'
);
}
return String(url).trim();
};

export const downloadEncryptedContent = async (
multiaddr,
{ ipfsGateway = DEFAULT_IPFS_GATEWAY } = {}
{ ipfsGateway = resolveIpfsGatewayUrl() } = {}
) => {
try {
const publicUrl = `${ipfsGateway}${multiaddr.replace('/p2p/', '/ipfs/')}`;
Expand Down
3 changes: 3 additions & 0 deletions dapp/tests/e2e/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ describe('sendTelegram', () => {
beforeEach(() => {
// protected data setup
process.env.IEXEC_DATASET_FILENAME = 'data-chatId.zip';
process.env.WEB3TELEGRAM_IPFS_GATEWAY =
process.env.WEB3TELEGRAM_IPFS_GATEWAY ||
'https://ipfs-gateway.v8-bellecour.iex.ec';
// developer secret setup
process.env.IEXEC_APP_DEVELOPER_SECRET = JSON.stringify({
TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN,
Expand Down
32 changes: 28 additions & 4 deletions dapp/tests/unit/decryptContent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import { IExec } from 'iexec';
import {
decryptContent,
downloadEncryptedContent,
resolveIpfsGatewayUrl,
} from '../../src/decryptContent';

const TEST_IPFS_GATEWAY = 'https://ipfs-gateway.v8-bellecour.iex.ec';

describe('decryptContent', () => {
it('should decrypt message correctly', async () => {
const iexec = new IExec({
Expand All @@ -33,21 +36,42 @@ describe('decryptContent', () => {
});
});

describe('resolveIpfsGatewayUrl', () => {
const prev = process.env.WEB3TELEGRAM_IPFS_GATEWAY;

afterAll(() => {
if (prev === undefined) {
delete process.env.WEB3TELEGRAM_IPFS_GATEWAY;
} else {
process.env.WEB3TELEGRAM_IPFS_GATEWAY = prev;
}
});

it('should throw if WEB3TELEGRAM_IPFS_GATEWAY is not set', () => {
delete process.env.WEB3TELEGRAM_IPFS_GATEWAY;
expect(() => resolveIpfsGatewayUrl()).toThrow(
Error('WEB3TELEGRAM_IPFS_GATEWAY environment variable is not set.')
);
});
});

describe('downloadEncryptedContent', () => {
it('should return the encrypted content', async () => {
const content = `{"JSONPath":"$['rates']['GBP']","body":"","dataType":"number","dataset":"0x0000000000000000000000000000000000000000","headers":{},"method":"GET","url":"https://api.exchangerate.host/latest?base=USD&symbols=GBP"}`;
const textEncoder = new TextEncoder();
const actualContent = await textEncoder.encode(content);
const multiaddr = '/ipfs/Qmb1JLTVp4zfRMPaori9htzzM9D3B1tG8pGbZYTRC1favA';
const expectedContent = await downloadEncryptedContent(multiaddr);
const expectedContent = await downloadEncryptedContent(multiaddr, {
ipfsGateway: TEST_IPFS_GATEWAY,
});
expect(actualContent).toEqual(expectedContent);
});

it('should throw an error if the content cannot be loaded', async () => {
const multiaddr =
'/ipfs/QmYhXeg4p4D729m432t8b9877b35e756a82749723456789invalid';
await expect(downloadEncryptedContent(multiaddr)).rejects.toThrow(
Error('Failed to download encrypted content')
);
await expect(
downloadEncryptedContent(multiaddr, { ipfsGateway: TEST_IPFS_GATEWAY })
).rejects.toThrow(Error('Failed to download encrypted content'));
});
});
Loading