Skip to content
Draft
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
9 changes: 8 additions & 1 deletion src/web3telegram/sendTelegram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const sendTelegram = async ({
workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
protectedData,
useVoucher = false,
allowDeposit = false,
}: IExecConsumer &
SubgraphConsumer &
DappAddressConsumer &
Expand Down Expand Up @@ -94,6 +95,9 @@ export const sendTelegram = async ({
const vUseVoucher = booleanSchema()
.label('useVoucher')
.validateSync(useVoucher);
const vAllowDeposit = booleanSchema()
.label('allowDeposit')
.validateSync(allowDeposit);

// Check protected data validity through subgraph
const isValidProtectedData = await checkProtectedDataValidity(
Expand Down Expand Up @@ -286,7 +290,10 @@ export const sendTelegram = async ({
workerpoolorder: workerpoolorder,
requestorder: requestorder,
},
{ useVoucher: vUseVoucher }
// TODO: Remove @ts-ignore once iexec SDK is updated to a version that includes allowDeposit in matchOrders types
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - allowDeposit is supported at runtime but not yet in TypeScript types
{ useVoucher: vUseVoucher, allowDeposit: vAllowDeposit }
);
const taskId = await iexec.deal.computeTaskId(dealId, 0);
return {
Expand Down
10 changes: 10 additions & 0 deletions src/web3telegram/sendTelegramCampaign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
addressOrEnsSchema,
throwIfMissing,
campaignRequestSchema,
booleanSchema,
} from '../utils/validators.js';
import { DataProtectorConsumer } from './internalTypes.js';
import {
Expand All @@ -23,6 +24,7 @@ export const sendTelegramCampaign = async ({
dataProtector = throwIfMissing(),
workerpoolAddressOrEns = throwIfMissing(),
campaignRequest,
allowDeposit = false,
}: DataProtectorConsumer &
SendTelegramCampaignParams): Promise<SendTelegramCampaignResponse> => {
try {
Expand All @@ -36,6 +38,10 @@ export const sendTelegramCampaign = async ({
.label('WorkerpoolAddressOrEns')
.validateSync(workerpoolAddressOrEns);

const vAllowDeposit = booleanSchema()
.label('allowDeposit')
.validateSync(allowDeposit);

if (
vCampaignRequest.workerpool !== NULL_ADDRESS &&
vCampaignRequest.workerpool.toLowerCase() !==
Expand All @@ -47,10 +53,14 @@ export const sendTelegramCampaign = async ({
}

// Process bulk request
// TODO: Remove @ts-ignore once @iexec/dataprotector is updated to a version that includes allowDeposit in ProcessBulkRequestParams types
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - allowDeposit is supported at runtime but not yet in TypeScript types
const processBulkRequestResponse: ProcessBulkRequestResponse<ProcessBulkRequestParams> =
await dataProtector.processBulkRequest({
bulkRequest: vCampaignRequest,
workerpool: vWorkerpoolAddressOrEns,
allowDeposit: vAllowDeposit,
});

return processBulkRequestResponse;
Expand Down
6 changes: 6 additions & 0 deletions src/web3telegram/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export type SendTelegramParams = {
appMaxPrice?: number;
workerpoolMaxPrice?: number;
useVoucher?: boolean;
allowDeposit?: boolean;
};

export type SendTelegramResponse = {
Expand Down Expand Up @@ -119,6 +120,11 @@ export type SendTelegramCampaignParams = {
* Workerpool address or ENS to use for processing
*/
workerpoolAddressOrEns?: string;
/**
* If true, allows automatic deposit of funds when balance is insufficient
* @default false
*/
allowDeposit?: boolean;
};

export type SendTelegramCampaignResponse = {
Expand Down
77 changes: 73 additions & 4 deletions tests/e2e/sendTelegram.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
} from '@iexec/dataprotector';
import { beforeAll, describe, expect, it } from '@jest/globals';
import { HDNodeWallet } from 'ethers';
import { IExec } from 'iexec';
import { NULL_ADDRESS } from 'iexec/utils';
import {
DEFAULT_CHAIN_ID,
getChainDefaultConfig,
Expand All @@ -30,8 +32,6 @@ import {
getTestWeb3SignerProvider,
waitSubgraphIndexing,
} from '../test-utils.js';
import { IExec } from 'iexec';
import { NULL_ADDRESS } from 'iexec/utils';

describe('web3telegram.sendTelegram()', () => {
let consumerWallet: HDNodeWallet;
Expand All @@ -46,14 +46,14 @@ describe('web3telegram.sendTelegram()', () => {
const iexecOptions = getTestIExecOption();
const prodWorkerpoolPublicPrice = 1000;
const defaultConfig = getChainDefaultConfig(DEFAULT_CHAIN_ID);

const workerpoolprice = 1_000;
beforeAll(async () => {
// (default) prod workerpool (not free) always available
await createAndPublishWorkerpoolOrder(
TEST_CHAIN.prodWorkerpool,
TEST_CHAIN.prodWorkerpoolOwnerWallet,
NULL_ADDRESS,
1_000,
workerpoolprice,
prodWorkerpoolPublicPrice
);
// learn prod pool (free) assumed always available
Expand Down Expand Up @@ -613,4 +613,73 @@ describe('web3telegram.sendTelegram()', () => {
});
});
});

describe('allowDeposit', () => {
let protectData: ProtectedDataWithSecretProps;
consumerWallet = getRandomWallet();
const dataPricePerAccess = 1000;
let web3telegramConsumerInstance: IExecWeb3telegram;
beforeAll(async () => {
protectData = await dataProtector.protectData({
data: { telegram_chatId: '12345' },
name: 'test do not use',
});
await dataProtector.grantAccess({
authorizedApp: getChainDefaultConfig(DEFAULT_CHAIN_ID).dappAddress,
protectedData: protectData.address,
authorizedUser: consumerWallet.address, // consumer wallet
numberOfAccess: 1000,
pricePerAccess: dataPricePerAccess,
});
await waitSubgraphIndexing();
web3telegramConsumerInstance = new IExecWeb3telegram(
...getTestConfig(consumerWallet.privateKey)
);
}, 2 * MAX_EXPECTED_BLOCKTIME);
it(
'should throw error if insufficient total balance to cover task cost and allowDeposit is false',
async () => {
let error;
try {
await web3telegramConsumerInstance.sendTelegram({
telegramContent: 'e2e telegram content for test',
protectedData: protectData.address,
dataMaxPrice: dataPricePerAccess,
workerpoolMaxPrice: workerpoolprice,
allowDeposit: false,
});
} catch (err) {
error = err;
}
expect(error).toBeInstanceOf(Web3TelegramWorkflowError);
expect(error).toBeInstanceOf(Error);
expect(error.message).toBe('Failed to sendTelegram');
const causeMsg =
error.errorCause?.message ||
error.cause?.message ||
error.cause ||
error.errorCause;
expect(String(causeMsg)).toContain(
"is greater than requester account stake (0). Orders can't be matched. If you are the requester, you should deposit to top up your account"
);
},
3 * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME
);
it.skip(
'should send telegram after depositing sufficient funds to cover task cost when allowDeposit is true',
async () => {
const result = await web3telegramConsumerInstance.sendTelegram({
telegramContent: 'e2e telegram content for test',
protectedData: protectData.address,
dataMaxPrice: dataPricePerAccess,
workerpoolMaxPrice: workerpoolprice,
allowDeposit: true,
});
expect(result).toBeDefined();
expect(result).toHaveProperty('taskId');
expect(result).toHaveProperty('dealId');
},
3 * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME
);
});
});
2 changes: 2 additions & 0 deletions tests/unit/sendTelegramCampaign.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe('sendTelegramCampaign', () => {
expect(mockDataprotector.processBulkRequest).toHaveBeenCalledWith({
bulkRequest: mockCampaignRequest,
workerpool: defaultConfig.prodWorkerpoolAddress,
allowDeposit: false,
});
expect(result).toEqual(mockResponse);
expect('tasks' in result).toBe(true);
Expand Down Expand Up @@ -171,6 +172,7 @@ describe('sendTelegramCampaign', () => {
expect(mockDataprotector.processBulkRequest).toHaveBeenCalledWith({
bulkRequest: mockCampaignRequest,
workerpool: defaultConfig.prodWorkerpoolAddress,
allowDeposit: false,
});
});

Expand Down