diff --git a/.changeset/rich-kids-rush.md b/.changeset/rich-kids-rush.md new file mode 100644 index 0000000000..b24d8b8d45 --- /dev/null +++ b/.changeset/rich-kids-rush.md @@ -0,0 +1,9 @@ +--- +"@human-protocol/sdk": major +--- + +### Changed + +- Created proper Subgraph types and cast values to the interfaces we have for SDK +- Refactor EscrowUtils, TransactionUtils, OperatorUtils and WorkerUtils methods to fix mismatch types with Subgraph +- Created some mappings to remove duplicated code diff --git a/packages/apps/dashboard/server/src/modules/stats/stats.service.ts b/packages/apps/dashboard/server/src/modules/stats/stats.service.ts index 10440c770f..b878ca1375 100644 --- a/packages/apps/dashboard/server/src/modules/stats/stats.service.ts +++ b/packages/apps/dashboard/server/src/modules/stats/stats.service.ts @@ -1,5 +1,4 @@ -import { NETWORKS, StatisticsClient } from '@human-protocol/sdk'; -import { DailyHMTData } from '@human-protocol/sdk/dist/graphql'; +import { IDailyHMT, NETWORKS, StatisticsClient } from '@human-protocol/sdk'; import { HttpService } from '@nestjs/axios'; import { Cache, CACHE_MANAGER } from '@nestjs/cache-manager'; import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; @@ -265,7 +264,7 @@ export class StatsService implements OnModuleInit { } private async isHmtDailyStatsFetched(): Promise { - const data = await this.cacheManager.get( + const data = await this.cacheManager.get( `${HMT_PREFIX}${HMT_STATS_START_DATE}`, ); return !!data; @@ -298,7 +297,7 @@ export class StatsService implements OnModuleInit { operatingNetworks.map(async (network) => { const statisticsClient = new StatisticsClient(NETWORKS[network]); let skip = 0; - let fetchedRecords: DailyHMTData[] = []; + let fetchedRecords: IDailyHMT[] = []; do { fetchedRecords = await statisticsClient.getHMTDailyData({ @@ -310,7 +309,7 @@ export class StatsService implements OnModuleInit { for (const record of fetchedRecords) { const dailyCacheKey = `${HMT_PREFIX}${ - record.timestamp.toISOString().split('T')[0] + new Date(record.timestamp).toISOString().split('T')[0] }`; // Sum daily values diff --git a/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.spec.ts b/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.spec.ts index 36ff3634d6..4bc06a1b4b 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.spec.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.spec.ts @@ -323,6 +323,24 @@ describe('WebhookService', () => { ), ).rejects.toThrow(new NotFoundError('Oracle not found')); }); + + it('should throw NotFoundError if webhook url is not found', async () => { + (EscrowClient.build as any).mockImplementation(() => ({ + getJobLauncherAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS), + })); + + (OperatorUtils.getOperator as any).mockResolvedValue({ + webhookUrl: null, + }); + + await expect( + (webhookService as any).getOracleWebhookUrl( + JOB_LAUNCHER_WEBHOOK_URL, + ChainId.LOCALHOST, + EventType.ESCROW_FAILED, + ), + ).rejects.toThrow(new NotFoundError('Oracle webhook URL not found')); + }); }); describe('handleWebhookError', () => { diff --git a/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.ts b/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.ts index 09193ecc22..f19145aaf1 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/modules/webhook/webhook.service.ts @@ -184,8 +184,10 @@ export class WebhookService { if (!oracle) { throw new NotFoundError('Oracle not found'); } - const oracleWebhookUrl = oracle.webhookUrl; + if (!oracle.webhookUrl) { + throw new NotFoundError('Oracle webhook URL not found'); + } - return oracleWebhookUrl; + return oracle.webhookUrl; } } diff --git a/packages/apps/human-app/server/src/modules/oracle-discovery/model/oracle-discovery.model.ts b/packages/apps/human-app/server/src/modules/oracle-discovery/model/oracle-discovery.model.ts index 2ceadc2123..5d5ad71871 100644 --- a/packages/apps/human-app/server/src/modules/oracle-discovery/model/oracle-discovery.model.ts +++ b/packages/apps/human-app/server/src/modules/oracle-discovery/model/oracle-discovery.model.ts @@ -8,24 +8,24 @@ type DiscoveredOracleCreateProps = { id: string; address: string; chainId: ChainId; - stakedAmount: bigint; - lockedAmount: bigint; - lockedUntilTimestamp: bigint; - withdrawnAmount: bigint; - slashedAmount: bigint; - amountJobsProcessed: bigint; - role?: string; - fee?: bigint; - publicKey?: string; - webhookUrl?: string; - website?: string; + stakedAmount: bigint | null; + lockedAmount: bigint | null; + lockedUntilTimestamp: number | null; + withdrawnAmount: bigint | null; + slashedAmount: bigint | null; + amountJobsProcessed: bigint | null; + role: string; + fee: bigint | null; + publicKey: string | null; + webhookUrl: string | null; + website: string | null; url: string; - jobTypes: string[]; - registrationNeeded?: boolean; - registrationInstructions?: string; - reputationNetworks?: string[]; - name?: string; - category?: string; + jobTypes: string[] | null; + registrationNeeded: boolean | null; + registrationInstructions: string | null; + reputationNetworks: string[]; + name: string; + category: string | null; }; export class DiscoveredOracle { @@ -38,23 +38,31 @@ export class DiscoveredOracle { @ApiProperty({ description: 'Chain ID where the oracle is registered' }) chainId: ChainId; - @ApiProperty({ description: 'Amount staked by the operator' }) - stakedAmount: string; + @ApiPropertyOptional({ description: 'Amount staked by the operator' }) + stakedAmount?: string; - @ApiProperty({ description: 'Amount currently locked by the operator' }) - lockedAmount: string; + @ApiPropertyOptional({ + description: 'Amount currently locked by the operator', + }) + lockedAmount?: string; - @ApiProperty({ description: 'Timestamp until funds are locked' }) - lockedUntilTimestamp: string; + @ApiPropertyOptional({ description: 'Timestamp until funds are locked' }) + lockedUntilTimestamp?: string; - @ApiProperty({ description: 'Total amount withdrawn by the operator' }) - withdrawnAmount: string; + @ApiPropertyOptional({ + description: 'Total amount withdrawn by the operator', + }) + withdrawnAmount?: string; - @ApiProperty({ description: 'Total amount slashed from the operator' }) - slashedAmount: string; + @ApiPropertyOptional({ + description: 'Total amount slashed from the operator', + }) + slashedAmount?: string; - @ApiProperty({ description: 'Number of jobs processed by the operator' }) - amountJobsProcessed: string; + @ApiPropertyOptional({ + description: 'Number of jobs processed by the operator', + }) + amountJobsProcessed?: string; @ApiPropertyOptional({ description: 'Fee charged by the operator' }) fee?: bigint; @@ -81,7 +89,7 @@ export class DiscoveredOracle { jobTypes: string[]; @ApiPropertyOptional({ description: 'Indicates if registration is needed' }) - registrationNeeded: boolean; + registrationNeeded?: boolean; @ApiPropertyOptional({ description: 'Instructions for registration, if needed', @@ -107,14 +115,27 @@ export class DiscoveredOracle { executionsToSkip = 0; constructor(props: DiscoveredOracleCreateProps) { - Object.assign(this, props); - this.registrationNeeded = props.registrationNeeded || false; - this.stakedAmount = this.stakedAmount.toString(); - this.lockedAmount = this.lockedAmount.toString(); - this.withdrawnAmount = this.withdrawnAmount.toString(); - this.slashedAmount = this.slashedAmount.toString(); - this.amountJobsProcessed = this.amountJobsProcessed.toString(); - this.lockedUntilTimestamp = this.lockedUntilTimestamp.toString(); + this.id = props.id; + this.address = props.address; + this.chainId = props.chainId; + this.registrationNeeded = props.registrationNeeded ?? undefined; + this.role = props.role; + this.url = props.url; + this.name = props.name; + this.fee = props.fee ?? undefined; + this.publicKey = props.publicKey ?? undefined; + this.webhookUrl = props.webhookUrl ?? undefined; + this.website = props.website ?? undefined; + this.category = props.category ?? undefined; + this.registrationInstructions = props.registrationInstructions ?? undefined; + this.jobTypes = props.jobTypes ?? []; + this.reputationNetworks = props.reputationNetworks ?? undefined; + this.stakedAmount = props.stakedAmount?.toString(); + this.lockedAmount = props.lockedAmount?.toString(); + this.withdrawnAmount = props.withdrawnAmount?.toString(); + this.slashedAmount = props.slashedAmount?.toString(); + this.amountJobsProcessed = props.amountJobsProcessed?.toString(); + this.lockedUntilTimestamp = props.lockedUntilTimestamp?.toString(); } } diff --git a/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.controller.ts b/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.controller.ts index 6308b142bd..64a8b169c3 100644 --- a/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.controller.ts +++ b/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.controller.ts @@ -55,18 +55,24 @@ export class OracleDiscoveryController { id: 'thisrty-oracle', address: process.env.THIRSTYFI_ORACLE_ADDRESS ?? '', chainId: ChainId.POLYGON, - stakedAmount: '0' as any, - lockedAmount: '0' as any, - lockedUntilTimestamp: '0' as any, - withdrawnAmount: '0' as any, - slashedAmount: '0' as any, - amountJobsProcessed: '0' as any, + stakedAmount: 0n, + lockedAmount: 0n, + lockedUntilTimestamp: 0, + withdrawnAmount: 0n, + slashedAmount: 0n, + amountJobsProcessed: 0n, role: 'exchange_oracle', url: ' ', jobTypes: ['thirstyfi'], name: 'ThirstyFi', registrationNeeded: false, - // registrationInstructions: 'https://www.thisrty.com/', + registrationInstructions: null, + publicKey: null, + webhookUrl: null, + website: null, + fee: null, + reputationNetworks: [], + category: null, }); oracles.push(thisrtyOracle); diff --git a/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.service.ts b/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.service.ts index 1c04b9dae1..c7e93ee143 100644 --- a/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.service.ts +++ b/packages/apps/human-app/server/src/modules/oracle-discovery/oracle-discovery.service.ts @@ -93,8 +93,8 @@ export class OracleDiscoveryService { new DiscoveredOracle({ id: exchangeOracle.id, address: exchangeOracle.address, - name: exchangeOracle.name, - role: exchangeOracle.role, + name: exchangeOracle.name as string, + role: exchangeOracle.role as string, url: exchangeOracle.url as string, jobTypes: exchangeOracle.jobTypes as string[], registrationNeeded: exchangeOracle.registrationNeeded, @@ -106,6 +106,12 @@ export class OracleDiscoveryService { slashedAmount: exchangeOracle.slashedAmount, amountJobsProcessed: exchangeOracle.amountJobsProcessed, lockedUntilTimestamp: exchangeOracle.lockedUntilTimestamp, + fee: exchangeOracle.fee, + publicKey: exchangeOracle.publicKey, + webhookUrl: exchangeOracle.webhookUrl, + website: exchangeOracle.website, + reputationNetworks: exchangeOracle.reputationNetworks, + category: exchangeOracle.category, }), ); } diff --git a/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.spec.ts b/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.spec.ts index bfb4aca116..e7121a703a 100644 --- a/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.spec.ts +++ b/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.spec.ts @@ -8,10 +8,10 @@ import { EscrowClient, EscrowStatus, EscrowUtils, + IStatusEvent, KVStoreUtils, NETWORKS, } from '@human-protocol/sdk'; -import { StatusEvent } from '@human-protocol/sdk/dist/graphql'; import { HttpService } from '@nestjs/axios'; import { ConfigService } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; @@ -1107,7 +1107,7 @@ describe('CronJobService', () => { describe('syncJobStatuses Cron Job', () => { let cronJobEntityMock: Partial; let jobEntityMock: Partial; - let escrowEventMock: Partial; + let escrowEventMock: Partial; beforeEach(() => { cronJobEntityMock = { @@ -1125,7 +1125,7 @@ describe('CronJobService', () => { escrowEventMock = { chainId: ChainId.LOCALHOST, escrowAddress: MOCK_ADDRESS, - status: EscrowStatus[EscrowStatus.Partial], + status: EscrowStatus.Partial, }; jest.spyOn(repository, 'findOneByType').mockResolvedValue(null); diff --git a/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.ts b/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.ts index 6dec225751..33e2552034 100644 --- a/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.ts +++ b/packages/apps/job-launcher/server/src/modules/cron-job/cron-job.service.ts @@ -515,19 +515,19 @@ export class CronJobService { } if (!job || job.status === JobStatus.CANCELED) continue; - if (event.status === EscrowStatus[EscrowStatus.Cancelled]) { + if (event.status === EscrowStatus.Cancelled) { await this.jobService.cancelJob(job); continue; } let newStatus: JobStatus | null = null; if ( - event.status === EscrowStatus[EscrowStatus.Partial] && + event.status === EscrowStatus.Partial && job.status !== JobStatus.PARTIAL ) { newStatus = JobStatus.PARTIAL; } else if ( - event.status === EscrowStatus[EscrowStatus.Complete] && + event.status === EscrowStatus.Complete && job.status !== JobStatus.COMPLETED ) { newStatus = JobStatus.COMPLETED; diff --git a/packages/apps/job-launcher/server/src/modules/job/job.service.spec.ts b/packages/apps/job-launcher/server/src/modules/job/job.service.spec.ts index 5d350aa9ba..f829d0021d 100644 --- a/packages/apps/job-launcher/server/src/modules/job/job.service.spec.ts +++ b/packages/apps/job-launcher/server/src/modules/job/job.service.spec.ts @@ -1745,16 +1745,17 @@ describe('JobService', () => { describe('cancelJob', () => { it('should create a refund payment and set status to CANCELED', async () => { const jobEntity = createJobEntity(); - const refundAmount = faker.number.float({ min: 1, max: 10 }); + const tokenDecimals = (TOKEN_ADDRESSES[jobEntity.chainId as ChainId] ?? + {})[jobEntity.token as EscrowFundToken]?.decimals; + const refundAmount = faker.number.float({ + min: 1, + max: 10, + fractionDigits: tokenDecimals, + }); mockPaymentService.getJobPayments.mockResolvedValueOnce([]); mockedEscrowUtils.getCancellationRefund.mockResolvedValueOnce({ - amount: ethers.parseUnits( - refundAmount.toString(), - (TOKEN_ADDRESSES[jobEntity.chainId as ChainId] ?? {})[ - jobEntity.token as EscrowFundToken - ]?.decimals, - ), + amount: ethers.parseUnits(refundAmount.toString(), tokenDecimals), escrowAddress: jobEntity.escrowAddress!, } as any); mockPaymentService.createRefundPayment.mockResolvedValueOnce(undefined); diff --git a/packages/apps/job-launcher/server/src/modules/routing-protocol/routing-protocol.service.spec.ts b/packages/apps/job-launcher/server/src/modules/routing-protocol/routing-protocol.service.spec.ts index 9893a6d342..01d3e64cbd 100644 --- a/packages/apps/job-launcher/server/src/modules/routing-protocol/routing-protocol.service.spec.ts +++ b/packages/apps/job-launcher/server/src/modules/routing-protocol/routing-protocol.service.spec.ts @@ -147,8 +147,8 @@ describe('RoutingProtocolService', () => { it('should select the first available oracle of specified type', async () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.ExchangeOracle, address: '0xExchangeOracle2' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle2', url: null }, ]; const result = routingProtocolService.selectOracleFromAvailable( @@ -163,8 +163,8 @@ describe('RoutingProtocolService', () => { it('should shuffle oracles and return the first oracle from the shuffled list', () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.ExchangeOracle, address: '0xExchangeOracle2' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle2', url: null }, ]; jest @@ -183,8 +183,8 @@ describe('RoutingProtocolService', () => { it('should update oracle order and select from the newly shuffled list if jobType changes', () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.ExchangeOracle, address: '0xExchangeOracle2' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle2', url: null }, ]; routingProtocolService.oracleOrder = { @@ -218,7 +218,7 @@ describe('RoutingProtocolService', () => { it('should not shuffle if the oracle hash has not changed for the same jobType', () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, ]; const latestOraclesHash = 'hash123'; @@ -257,8 +257,8 @@ describe('RoutingProtocolService', () => { it('should update the oracle order and hash if the list of available oracles changes', () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.ExchangeOracle, address: '0xExchangeOracle2' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle2', url: null }, ]; const previousHash = 'oldHash'; @@ -294,10 +294,18 @@ describe('RoutingProtocolService', () => { it('should select the oracle from available ones and rotate index', async () => { const availableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.ExchangeOracle, address: '0xExchangeOracle2' }, - { role: Role.RecordingOracle, address: '0xRecordingOracle1' }, - { role: Role.RecordingOracle, address: '0xRecordingOracle2' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle2', url: null }, + { + role: Role.RecordingOracle, + address: '0xRecordingOracle1', + url: null, + }, + { + role: Role.RecordingOracle, + address: '0xRecordingOracle2', + url: null, + }, ]; const result1 = routingProtocolService.selectOracleFromAvailable( @@ -342,8 +350,12 @@ describe('RoutingProtocolService', () => { describe('selectOracles', () => { it('should select reputation oracle and find available oracles', async () => { const mockAvailableOracles = [ - { role: Role.ExchangeOracle, address: '0xExchangeOracle1' }, - { role: Role.RecordingOracle, address: '0xRecordingOracle1' }, + { role: Role.ExchangeOracle, address: '0xExchangeOracle1', url: null }, + { + role: Role.RecordingOracle, + address: '0xRecordingOracle1', + url: null, + }, ]; web3Service.findAvailableOracles = jest @@ -386,8 +398,8 @@ describe('RoutingProtocolService', () => { ) .mockReturnValue(`${reputationOracle},otherOracle`); jest.spyOn(web3Service, 'findAvailableOracles').mockResolvedValue([ - { address: exchangeOracle, role: Role.ExchangeOracle }, - { address: recordingOracle, role: Role.RecordingOracle }, + { address: exchangeOracle, role: Role.ExchangeOracle, url: null }, + { address: recordingOracle, role: Role.RecordingOracle, url: null }, ]); await expect( @@ -438,7 +450,7 @@ describe('RoutingProtocolService', () => { jest .spyOn(web3Service, 'findAvailableOracles') .mockResolvedValue([ - { address: 'anotherOracle', role: Role.ExchangeOracle }, + { address: 'anotherOracle', role: Role.ExchangeOracle, url: null }, ]); await expect( @@ -467,7 +479,7 @@ describe('RoutingProtocolService', () => { jest .spyOn(web3Service, 'findAvailableOracles') .mockResolvedValue([ - { address: 'anotherOracle', role: Role.RecordingOracle }, + { address: 'anotherOracle', role: Role.RecordingOracle, url: null }, ]); await expect( diff --git a/packages/apps/job-launcher/server/src/modules/web3/web3.dto.ts b/packages/apps/job-launcher/server/src/modules/web3/web3.dto.ts index 4766e6641c..ea3b2dc6ce 100644 --- a/packages/apps/job-launcher/server/src/modules/web3/web3.dto.ts +++ b/packages/apps/job-launcher/server/src/modules/web3/web3.dto.ts @@ -4,9 +4,9 @@ import { IsString } from 'class-validator'; export class OracleDataDto implements Partial { address: string; - role?: string; - url?: string; - jobTypes?: string[]; + role: string | null; + url: string | null; + jobTypes?: string[] | null; } export class AvailableOraclesDto { diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py index 18dc28bb98..3d1512a04a 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py @@ -52,15 +52,16 @@ def __init__( chain_id: ChainId, id: str, address: str, - amount_paid: int, - balance: int, - count: int, + amount_paid: str, + balance: str, + count: str, factory_address: str, launcher: str, + job_requester_id: Optional[str], status: str, token: str, - total_funded_amount: int, - created_at: datetime, + total_funded_amount: str, + created_at: str, final_results_url: Optional[str] = None, final_results_hash: Optional[str] = None, intermediate_results_url: Optional[str] = None, @@ -70,9 +71,9 @@ def __init__( recording_oracle: Optional[str] = None, reputation_oracle: Optional[str] = None, exchange_oracle: Optional[str] = None, - recording_oracle_fee: Optional[int] = None, - reputation_oracle_fee: Optional[int] = None, - exchange_oracle_fee: Optional[int] = None, + recording_oracle_fee: Optional[str] = None, + reputation_oracle_fee: Optional[str] = None, + exchange_oracle_fee: Optional[str] = None, ): """ Initializes an EscrowData instance. @@ -85,10 +86,11 @@ def __init__( :param count: Count :param factory_address: Factory address :param launcher: Launcher + :param job_requester_id: Job requester identifier :param status: Status :param token: Token :param total_funded_amount: Total funded amount - :param created_at: Creation date + :param created_at: Creation timestamp in milliseconds :param final_results_url: URL for final results. :param final_results_hash: Hash for final results. :param intermediate_results_url: URL for intermediate results. @@ -105,27 +107,34 @@ def __init__( self.id = id self.address = address - self.amount_paid = amount_paid - self.balance = balance - self.count = count + self.amount_paid = int(amount_paid) + self.balance = int(balance) + self.count = int(count) self.factory_address = factory_address self.final_results_url = final_results_url self.final_results_hash = final_results_hash self.intermediate_results_url = intermediate_results_url self.intermediate_results_hash = intermediate_results_hash self.launcher = launcher + self.job_requester_id = job_requester_id self.manifest_hash = manifest_hash self.manifest = manifest self.recording_oracle = recording_oracle self.reputation_oracle = reputation_oracle self.exchange_oracle = exchange_oracle - self.recording_oracle_fee = recording_oracle_fee - self.reputation_oracle_fee = reputation_oracle_fee - self.exchange_oracle_fee = exchange_oracle_fee + self.recording_oracle_fee = ( + int(recording_oracle_fee) if recording_oracle_fee is not None else None + ) + self.reputation_oracle_fee = ( + int(reputation_oracle_fee) if reputation_oracle_fee is not None else None + ) + self.exchange_oracle_fee = ( + int(exchange_oracle_fee) if exchange_oracle_fee is not None else None + ) self.status = status self.token = token - self.total_funded_amount = total_funded_amount - self.created_at = created_at + self.total_funded_amount = int(total_funded_amount) + self.created_at = int(created_at) * 1000 self.chain_id = chain_id @@ -133,7 +142,7 @@ class StatusEvent: """ Initializes a StatusEvent instance. - :param timestamp: The timestamp of the event. + :param timestamp: The timestamp of the event in milliseconds. :param status: The status of the escrow. :param chain_id: The chain identifier where the event occurred. :param escrow_address: The address of the escrow. @@ -142,7 +151,7 @@ class StatusEvent: def __init__( self, timestamp: int, status: str, chain_id: ChainId, escrow_address: str ): - self.timestamp = timestamp + self.timestamp = timestamp * 1000 self.status = status self.chain_id = chain_id self.escrow_address = escrow_address @@ -157,17 +166,17 @@ class Payout: :param escrow_address: The address of the escrow that executed the payout. :param recipient: The address of the recipient. :param amount: The amount of the payout. - :param created_at: The time of creation of the payout. + :param created_at: The time of creation of the payout in milliseconds. """ def __init__( - self, id: str, escrow_address: str, recipient: str, amount: int, created_at: int + self, id: str, escrow_address: str, recipient: str, amount: str, created_at: str ): self.id = id self.escrow_address = escrow_address self.recipient = recipient - self.amount = amount - self.created_at = created_at + self.amount = int(amount) + self.created_at = int(created_at) * 1000 class CancellationRefund: @@ -179,7 +188,7 @@ class CancellationRefund: :param receiver: The address of the recipient receiving the refund. :param amount: The amount being refunded. :param block: The block number in which the refund was processed. - :param timestamp: The timestamp of the refund event. + :param timestamp: The timestamp of the refund event in milliseconds. :param tx_hash: The transaction hash of the refund event. """ @@ -188,17 +197,17 @@ def __init__( id: str, escrow_address: str, receiver: str, - amount: int, - block: int, - timestamp: int, + amount: str, + block: str, + timestamp: str, tx_hash: str, ): self.id = id self.escrow_address = escrow_address self.receiver = receiver - self.amount = amount - self.block = block - self.timestamp = timestamp + self.amount = int(amount) + self.block = int(block) + self.timestamp = int(timestamp) * 1000 self.tx_hash = tx_hash @@ -290,43 +299,30 @@ def get_escrows( [ EscrowData( chain_id=chain_id, - id=escrow.get("id", ""), - address=escrow.get("address", ""), - amount_paid=int(escrow.get("amountPaid", 0)), - balance=int(escrow.get("balance", 0)), - count=int(escrow.get("count", 0)), - factory_address=escrow.get("factoryAddress", ""), - launcher=escrow.get("launcher", ""), - status=escrow.get("status", ""), - token=escrow.get("token", ""), - total_funded_amount=int(escrow.get("totalFundedAmount", 0)), - created_at=datetime.fromtimestamp(int(escrow.get("createdAt", 0))), - final_results_url=escrow.get("finalResultsUrl", None), - final_results_hash=escrow.get("finalResultsHash", None), - intermediate_results_url=escrow.get("intermediateResultsUrl", None), - intermediate_results_hash=escrow.get( - "intermediateResultsHash", None - ), - manifest_hash=escrow.get("manifestHash", None), - manifest=escrow.get("manifest", None), - recording_oracle=escrow.get("recordingOracle", None), - reputation_oracle=escrow.get("reputationOracle", None), - exchange_oracle=escrow.get("exchangeOracle", None), - recording_oracle_fee=( - int(escrow.get("recordingOracleFee")) - if escrow.get("recordingOracleFee", None) not in (None, "") - else None - ), - reputation_oracle_fee=( - int(escrow.get("reputationOracleFee")) - if escrow.get("reputationOracleFee", None) not in (None, "") - else None - ), - exchange_oracle_fee=( - int(escrow.get("exchangeOracleFee")) - if escrow.get("exchangeOracleFee", None) not in (None, "") - else None - ), + id=escrow.get("id"), + address=escrow.get("address"), + amount_paid=escrow.get("amountPaid"), + balance=escrow.get("balance"), + count=escrow.get("count"), + factory_address=escrow.get("factoryAddress"), + launcher=escrow.get("launcher"), + job_requester_id=escrow.get("jobRequesterId"), + status=escrow.get("status"), + token=escrow.get("token"), + total_funded_amount=escrow.get("totalFundedAmount"), + created_at=escrow.get("createdAt"), + final_results_url=escrow.get("finalResultsUrl"), + final_results_hash=escrow.get("finalResultsHash"), + intermediate_results_url=escrow.get("intermediateResultsUrl"), + intermediate_results_hash=escrow.get("intermediateResultsHash"), + manifest_hash=escrow.get("manifestHash"), + manifest=escrow.get("manifest"), + recording_oracle=escrow.get("recordingOracle"), + reputation_oracle=escrow.get("reputationOracle"), + exchange_oracle=escrow.get("exchangeOracle"), + recording_oracle_fee=escrow.get("recordingOracleFee"), + reputation_oracle_fee=escrow.get("reputationOracleFee"), + exchange_oracle_fee=escrow.get("exchangeOracleFee"), ) for escrow in escrows_raw ] @@ -391,41 +387,30 @@ def get_escrow( return EscrowData( chain_id=chain_id, - id=escrow.get("id", ""), - address=escrow.get("address", ""), - amount_paid=int(escrow.get("amountPaid", 0)), - balance=int(escrow.get("balance", 0)), - count=int(escrow.get("count", 0)), - factory_address=escrow.get("factoryAddress", ""), - launcher=escrow.get("launcher", ""), - status=escrow.get("status", ""), - token=escrow.get("token", ""), - total_funded_amount=int(escrow.get("totalFundedAmount", 0)), - created_at=datetime.fromtimestamp(int(escrow.get("createdAt", 0))), - final_results_url=escrow.get("finalResultsUrl", None), - final_results_hash=escrow.get("finalResultsHash", None), - intermediate_results_url=escrow.get("intermediateResultsUrl", None), - intermediate_results_hash=escrow.get("intermediateResultsHash", None), - manifest_hash=escrow.get("manifestHash", None), - manifest=escrow.get("manifest", None), - recording_oracle=escrow.get("recordingOracle", None), - reputation_oracle=escrow.get("reputationOracle", None), - exchange_oracle=escrow.get("exchangeOracle", None), - recording_oracle_fee=( - int(escrow.get("recordingOracleFee")) - if escrow.get("recordingOracleFee", None) not in (None, "") - else None - ), - reputation_oracle_fee=( - int(escrow.get("reputationOracleFee")) - if escrow.get("reputationOracleFee", None) not in (None, "") - else None - ), - exchange_oracle_fee=( - int(escrow.get("exchangeOracleFee")) - if escrow.get("exchangeOracleFee", None) not in (None, "") - else None - ), + id=escrow.get("id"), + address=escrow.get("address"), + amount_paid=escrow.get("amountPaid"), + balance=escrow.get("balance"), + count=escrow.get("count"), + factory_address=escrow.get("factoryAddress"), + launcher=escrow.get("launcher"), + job_requester_id=escrow.get("jobRequesterId"), + status=escrow.get("status"), + token=escrow.get("token"), + total_funded_amount=escrow.get("totalFundedAmount"), + created_at=escrow.get("createdAt"), + final_results_url=escrow.get("finalResultsUrl"), + final_results_hash=escrow.get("finalResultsHash"), + intermediate_results_url=escrow.get("intermediateResultsUrl"), + intermediate_results_hash=escrow.get("intermediateResultsHash"), + manifest_hash=escrow.get("manifestHash"), + manifest=escrow.get("manifest"), + recording_oracle=escrow.get("recordingOracle"), + reputation_oracle=escrow.get("reputationOracle"), + exchange_oracle=escrow.get("exchangeOracle"), + recording_oracle_fee=escrow.get("recordingOracleFee"), + reputation_oracle_fee=escrow.get("reputationOracleFee"), + exchange_oracle_fee=escrow.get("exchangeOracleFee"), ) @staticmethod @@ -476,7 +461,7 @@ def get_status_events(filter: StatusEventFilter) -> List[StatusEvent]: events_with_chain_id = [ StatusEvent( - timestamp=event["timestamp"], + timestamp=int(event["timestamp"]), escrow_address=event["escrowAddress"], status=event["status"], chain_id=filter.chain_id, @@ -540,8 +525,8 @@ def get_payouts(filter: PayoutFilter) -> List[Payout]: id=payout["id"], escrow_address=payout["escrowAddress"], recipient=payout["recipient"], - amount=int(payout["amount"]), - created_at=int(payout["createdAt"]), + amount=payout["amount"], + created_at=payout["createdAt"], ) for payout in payouts_raw ] @@ -604,9 +589,9 @@ def get_cancellation_refunds( id=refund["id"], escrow_address=refund["escrowAddress"], receiver=refund["receiver"], - amount=int(refund["amount"]), - block=int(refund["block"]), - timestamp=int(refund["timestamp"]), + amount=refund["amount"], + block=refund["block"], + timestamp=refund["timestamp"], tx_hash=refund["txHash"], ) for refund in refunds_raw @@ -673,8 +658,8 @@ def get_cancellation_refund( id=refund["id"], escrow_address=refund["escrowAddress"], receiver=refund["receiver"], - amount=int(refund["amount"]), - block=int(refund["block"]), - timestamp=int(refund["timestamp"]), + amount=refund["amount"], + block=refund["block"], + timestamp=refund["timestamp"], tx_hash=refund["txHash"], ) diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/operator/operator_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/operator/operator_utils.py index 55a3752caf..9bed4d8fc6 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/operator/operator_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/operator/operator_utils.py @@ -21,7 +21,7 @@ import logging import os -from typing import List, Optional +from typing import List, Optional, Union from human_protocol_sdk.constants import NETWORKS, ChainId, OrderDirection from human_protocol_sdk.gql.reward import get_reward_added_events_query @@ -89,22 +89,22 @@ def __init__( chain_id: ChainId, id: str, address: str, - staked_amount: int, - locked_amount: int, - locked_until_timestamp: int, - withdrawn_amount: int, - slashed_amount: int, - amount_jobs_processed: int, + amount_jobs_processed: str, + reputation_networks: Union[List[str], str], + staked_amount: Optional[str] = None, + locked_amount: Optional[str] = None, + locked_until_timestamp: Optional[str] = None, + withdrawn_amount: Optional[str] = None, + slashed_amount: Optional[str] = None, role: Optional[str] = None, - fee: Optional[int] = None, + fee: Optional[str] = None, public_key: Optional[str] = None, webhook_url: Optional[str] = None, website: Optional[str] = None, url: Optional[str] = None, - job_types: Optional[List[str]] = None, + job_types: Optional[Union[List[str], str]] = None, registration_needed: Optional[bool] = None, registration_instructions: Optional[str] = None, - reputation_networks: Optional[List[str]] = None, name: Optional[str] = None, category: Optional[str] = None, ): @@ -137,24 +137,42 @@ def __init__( self.chain_id = chain_id self.id = id self.address = address - self.staked_amount = staked_amount - self.locked_amount = locked_amount - self.locked_until_timestamp = locked_until_timestamp - self.withdrawn_amount = withdrawn_amount - self.slashed_amount = slashed_amount - self.amount_jobs_processed = amount_jobs_processed + self.staked_amount = int(staked_amount) if staked_amount is not None else None + self.locked_amount = int(locked_amount) if locked_amount is not None else None + self.locked_until_timestamp = ( + int(locked_until_timestamp) * 1000 + if locked_until_timestamp is not None + else None + ) + self.withdrawn_amount = ( + int(withdrawn_amount) if withdrawn_amount is not None else None + ) + self.slashed_amount = ( + int(slashed_amount) if slashed_amount is not None else None + ) + self.amount_jobs_processed = int(amount_jobs_processed) self.role = role - self.fee = fee + self.fee = int(fee) if fee is not None else None self.public_key = public_key self.webhook_url = webhook_url self.website = website self.url = url - self.job_types = job_types self.registration_needed = registration_needed self.registration_instructions = registration_instructions - self.reputation_networks = reputation_networks + vals = reputation_networks if isinstance(reputation_networks, list) else [] + self.reputation_networks = [ + (rn if isinstance(rn, str) else rn.get("address")) + for rn in vals + if (isinstance(rn, str) and rn) + or (isinstance(rn, dict) and rn.get("address")) + ] self.name = name self.category = category + self.job_types = ( + job_types.split(",") + if isinstance(job_types, str) + else (job_types if isinstance(job_types, list) else []) + ) class RewardData: @@ -232,48 +250,30 @@ def get_operators(filter: OperatorFilter) -> List[OperatorData]: operators_raw = operators_data["data"]["operators"] for operator in operators_raw: - reputation_networks = [] - if operator.get("reputationNetworks") and isinstance( - operator.get("reputationNetworks"), list - ): - reputation_networks = [ - network["address"] for network in operator["reputationNetworks"] - ] - - staker = operator.get("staker", {}) + staker = operator.get("staker") or {} operators.append( OperatorData( chain_id=filter.chain_id, - id=operator.get("id", ""), - address=operator.get("address", ""), - staked_amount=int(staker.get("stakedAmount", 0)), - locked_amount=int(staker.get("lockedAmount", 0)), - locked_until_timestamp=int(staker.get("lockedUntilTimestamp", 0)), - withdrawn_amount=int(staker.get("withdrawnAmount", 0)), - slashed_amount=int(staker.get("slashedAmount", 0)), - amount_jobs_processed=int(operator.get("amountJobsProcessed", 0)), - role=operator.get("role", None), - fee=int(operator.get("fee")) if operator.get("fee", None) else None, - public_key=operator.get("publicKey", None), - webhook_url=operator.get("webhookUrl", None), - website=operator.get("website", None), - url=operator.get("url", None), - job_types=( - operator.get("jobTypes").split(",") - if isinstance(operator.get("jobTypes"), str) - else ( - operator.get("jobTypes", []) - if isinstance(operator.get("jobTypes"), list) - else [] - ) - ), - registration_needed=operator.get("registrationNeeded", None), - registration_instructions=operator.get( - "registrationInstructions", None - ), - reputation_networks=reputation_networks, - name=operator.get("name", None), - category=operator.get("category", None), + id=operator.get("id"), + address=operator.get("address"), + staked_amount=staker.get("stakedAmount"), + locked_amount=staker.get("lockedAmount"), + locked_until_timestamp=staker.get("lockedUntilTimestamp"), + withdrawn_amount=staker.get("withdrawnAmount"), + slashed_amount=staker.get("slashedAmount"), + amount_jobs_processed=operator.get("amountJobsProcessed"), + role=operator.get("role"), + fee=operator.get("fee"), + public_key=operator.get("publicKey"), + webhook_url=operator.get("webhookUrl"), + website=operator.get("website"), + url=operator.get("url"), + job_types=operator.get("jobTypes"), + registration_needed=operator.get("registrationNeeded"), + registration_instructions=operator.get("registrationInstructions"), + reputation_networks=operator.get("reputationNetworks"), + name=operator.get("name"), + category=operator.get("category"), ) ) @@ -329,46 +329,29 @@ def get_operator( return None operator = operator_data["data"]["operator"] - reputation_networks = [] - - if operator.get("reputationNetworks") and isinstance( - operator.get("reputationNetworks"), list - ): - reputation_networks = [ - network["address"] for network in operator["reputationNetworks"] - ] - - staker = operator.get("staker", {}) + staker = operator.get("staker") or {} return OperatorData( chain_id=chain_id, - id=operator.get("id", ""), - address=operator.get("address", ""), - staked_amount=int(staker.get("stakedAmount", 0)), - locked_amount=int(staker.get("lockedAmount", 0)), - locked_until_timestamp=int(staker.get("lockedUntilTimestamp", 0)), - withdrawn_amount=int(staker.get("withdrawnAmount", 0)), - slashed_amount=int(staker.get("slashedAmount", 0)), - amount_jobs_processed=int(operator.get("amountJobsProcessed", 0)), - role=operator.get("role", None), - fee=int(operator.get("fee")) if operator.get("fee", None) else None, - public_key=operator.get("publicKey", None), - webhook_url=operator.get("webhookUrl", None), - website=operator.get("website", None), - url=operator.get("url", None), - job_types=( - operator.get("jobTypes").split(",") - if isinstance(operator.get("jobTypes"), str) - else ( - operator.get("jobTypes", []) - if isinstance(operator.get("jobTypes"), list) - else [] - ) - ), - registration_needed=operator.get("registrationNeeded", None), - registration_instructions=operator.get("registrationInstructions", None), - reputation_networks=reputation_networks, - name=operator.get("name", None), - category=operator.get("category", None), + id=operator.get("id"), + address=operator.get("address"), + staked_amount=staker.get("stakedAmount"), + locked_amount=staker.get("lockedAmount"), + locked_until_timestamp=staker.get("lockedUntilTimestamp"), + withdrawn_amount=staker.get("withdrawnAmount"), + slashed_amount=staker.get("slashedAmount"), + amount_jobs_processed=operator.get("amountJobsProcessed"), + role=operator.get("role"), + fee=operator.get("fee"), + public_key=operator.get("publicKey"), + webhook_url=operator.get("webhookUrl"), + website=operator.get("website"), + url=operator.get("url"), + job_types=operator.get("jobTypes"), + registration_needed=operator.get("registrationNeeded"), + registration_instructions=operator.get("registrationInstructions"), + reputation_networks=operator.get("reputationNetworks"), + name=operator.get("name"), + category=operator.get("category"), ) @staticmethod @@ -423,49 +406,36 @@ def get_reputation_network_operators( return [] operators = reputation_network_data["data"]["reputationNetwork"]["operators"] - return [ - OperatorData( - chain_id=chain_id, - id=operator.get("id", ""), - address=operator.get("address", ""), - staked_amount=int( - (staker := operator.get("staker") or {}).get("stakedAmount", 0) - ), - locked_amount=int(staker.get("lockedAmount", 0)), - locked_until_timestamp=int(staker.get("lockedUntilTimestamp", 0)), - withdrawn_amount=int(staker.get("withdrawnAmount", 0)), - slashed_amount=int(staker.get("slashedAmount", 0)), - amount_jobs_processed=int(operator.get("amountJobsProcessed", 0)), - role=operator.get("role", None), - fee=int(operator.get("fee")) if operator.get("fee", None) else None, - public_key=operator.get("publicKey", None), - webhook_url=operator.get("webhookUrl", None), - website=operator.get("website", None), - url=operator.get("url", None), - job_types=( - operator.get("jobTypes").split(",") - if isinstance(operator.get("jobTypes"), str) - else ( - operator.get("jobTypes", []) - if isinstance(operator.get("jobTypes"), list) - else [] - ) - ), - registration_needed=operator.get("registrationNeeded", None), - registration_instructions=operator.get( - "registrationInstructions", None - ), - reputation_networks=( - [network["address"] for network in operator["reputationNetworks"]] - if operator.get("reputationNetworks") - and isinstance(operator.get("reputationNetworks"), list) - else [] - ), - name=operator.get("name", None), - category=operator.get("category", None), + result: List[OperatorData] = [] + for operator in operators: + staker = operator.get("staker") or {} + result.append( + OperatorData( + chain_id=chain_id, + id=operator.get("id"), + address=operator.get("address"), + staked_amount=staker.get("stakedAmount"), + locked_amount=staker.get("lockedAmount"), + locked_until_timestamp=staker.get("lockedUntilTimestamp"), + withdrawn_amount=staker.get("withdrawnAmount"), + slashed_amount=staker.get("slashedAmount"), + amount_jobs_processed=operator.get("amountJobsProcessed"), + role=operator.get("role"), + fee=operator.get("fee"), + public_key=operator.get("publicKey"), + webhook_url=operator.get("webhookUrl"), + website=operator.get("website"), + url=operator.get("url"), + job_types=operator.get("jobTypes"), + registration_needed=operator.get("registrationNeeded"), + registration_instructions=operator.get("registrationInstructions"), + reputation_networks=operator.get("reputationNetworks"), + name=operator.get("name"), + category=operator.get("category"), + ) ) - for operator in operators - ] + + return result @staticmethod def get_rewards_info(chain_id: ChainId, slasher: str) -> List[RewardData]: @@ -515,8 +485,8 @@ def get_rewards_info(chain_id: ChainId, slasher: str) -> List[RewardData]: return [ RewardData( - escrow_address=reward_added_event.get("escrowAddress", ""), - amount=int(reward_added_event.get("amount", 0)), + escrow_address=reward_added_event.get("escrowAddress"), + amount=int(reward_added_event.get("amount")), ) for reward_added_event in reward_added_events ] diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/staking/staking_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/staking/staking_utils.py index 9579bad428..2da710d030 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/staking/staking_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/staking/staking_utils.py @@ -48,12 +48,12 @@ def __init__( ): self.id = id self.address = address - self.staked_amount = staked_amount - self.locked_amount = locked_amount - self.withdrawn_amount = withdrawn_amount - self.slashed_amount = slashed_amount - self.locked_until_timestamp = locked_until_timestamp - self.last_deposit_timestamp = last_deposit_timestamp + self.staked_amount = int(staked_amount) + self.locked_amount = int(locked_amount) + self.withdrawn_amount = int(withdrawn_amount) + self.slashed_amount = int(slashed_amount) + self.locked_until_timestamp = int(locked_until_timestamp) * 1000 + self.last_deposit_timestamp = int(last_deposit_timestamp) * 1000 class StakingUtilsError(Exception): @@ -82,14 +82,14 @@ def get_staker(chain_id: ChainId, address: str) -> Optional[StakerData]: staker = data["data"]["staker"] return StakerData( - id=staker.get("id", ""), - address=staker.get("address", ""), - staked_amount=staker.get("stakedAmount", ""), - locked_amount=staker.get("lockedAmount", ""), - withdrawn_amount=staker.get("withdrawnAmount", ""), - slashed_amount=staker.get("slashedAmount", ""), - locked_until_timestamp=staker.get("lockedUntilTimestamp", ""), - last_deposit_timestamp=staker.get("lastDepositTimestamp", ""), + id=staker.get("id"), + address=staker.get("address"), + staked_amount=staker.get("stakedAmount"), + locked_amount=staker.get("lockedAmount"), + withdrawn_amount=staker.get("withdrawnAmount"), + slashed_amount=staker.get("slashedAmount"), + locked_until_timestamp=staker.get("lockedUntilTimestamp"), + last_deposit_timestamp=staker.get("lastDepositTimestamp"), ) @staticmethod @@ -127,14 +127,14 @@ def get_stakers(filter: StakersFilter) -> List[StakerData]: stakers_raw = data["data"]["stakers"] return [ StakerData( - id=staker.get("id", ""), - address=staker.get("address", ""), - staked_amount=staker.get("stakedAmount", ""), - locked_amount=staker.get("lockedAmount", ""), - withdrawn_amount=staker.get("withdrawnAmount", ""), - slashed_amount=staker.get("slashedAmount", ""), - locked_until_timestamp=staker.get("lockedUntilTimestamp", ""), - last_deposit_timestamp=staker.get("lastDepositTimestamp", ""), + id=staker.get("id") or "", + address=staker.get("address") or "", + staked_amount=staker.get("stakedAmount"), + locked_amount=staker.get("lockedAmount"), + withdrawn_amount=staker.get("withdrawnAmount"), + slashed_amount=staker.get("slashedAmount"), + locked_until_timestamp=staker.get("lockedUntilTimestamp"), + last_deposit_timestamp=staker.get("lastDepositTimestamp"), ) for staker in stakers_raw ] diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/transaction/transaction_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/transaction/transaction_utils.py index 54b561fc3c..1b88aa89da 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/transaction/transaction_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/transaction/transaction_utils.py @@ -38,11 +38,11 @@ def __init__( self, from_address: str, to_address: str, - value: str, + value: int, method: str, - receiver: str, - escrow: str, - token: str, + receiver: Optional[str], + escrow: Optional[str], + token: Optional[str], ): self.from_address = from_address self.to_address = to_address @@ -62,11 +62,11 @@ def __init__( from_address: str, to_address: str, timestamp: int, - value: str, + value: int, method: str, - receiver: str, - escrow: str, - token: str, + receiver: Optional[str], + escrow: Optional[str], + token: Optional[str], internal_transactions: List[InternalTransaction], ): self.chain_id = chain_id @@ -74,7 +74,7 @@ def __init__( self.tx_hash = tx_hash self.from_address = from_address self.to_address = to_address - self.timestamp = timestamp + self.timestamp = timestamp * 1000 self.value = value self.method = method self.receiver = receiver @@ -141,25 +141,25 @@ def get_transaction(chain_id: ChainId, hash: str) -> Optional[TransactionData]: return TransactionData( chain_id=chain_id, - block=transaction.get("block", 0), - tx_hash=transaction.get("txHash", ""), - from_address=transaction.get("from", ""), - to_address=transaction.get("to", ""), - timestamp=transaction.get("timestamp", 0), - value=transaction.get("value", ""), - method=transaction.get("method", ""), - receiver=transaction.get("receiver", ""), - escrow=transaction.get("escrow", ""), - token=transaction.get("token", ""), + block=int(transaction.get("block")), + tx_hash=transaction.get("txHash"), + from_address=transaction.get("from"), + to_address=transaction.get("to"), + timestamp=int(transaction.get("timestamp")), + value=int(transaction.get("value")), + method=transaction.get("method"), + receiver=transaction.get("receiver"), + escrow=transaction.get("escrow"), + token=transaction.get("token"), internal_transactions=[ InternalTransaction( - from_address=internal_tx.get("from", ""), - to_address=internal_tx.get("to", ""), - value=internal_tx.get("value", ""), - method=internal_tx.get("method", ""), - receiver=internal_tx.get("receiver", ""), - escrow=internal_tx.get("escrow", ""), - token=internal_tx.get("token", ""), + from_address=internal_tx.get("from"), + to_address=internal_tx.get("to"), + value=int(internal_tx.get("value")), + method=internal_tx.get("method"), + receiver=internal_tx.get("receiver"), + escrow=internal_tx.get("escrow"), + token=internal_tx.get("token"), ) for internal_tx in transaction.get("internalTransactions", []) ], @@ -239,25 +239,25 @@ def get_transactions(filter: TransactionFilter) -> List[TransactionData]: [ TransactionData( chain_id=filter.chain_id, - block=transaction.get("block", 0), - tx_hash=transaction.get("txHash", ""), - from_address=transaction.get("from", ""), - to_address=transaction.get("to", ""), - timestamp=transaction.get("timestamp", 0), - value=transaction.get("value", ""), - method=transaction.get("method", ""), - receiver=transaction.get("receiver", ""), - escrow=transaction.get("escrow", ""), - token=transaction.get("token", ""), + block=int(transaction.get("block")), + tx_hash=transaction.get("txHash"), + from_address=transaction.get("from"), + to_address=transaction.get("to"), + timestamp=int(transaction.get("timestamp")), + value=int(transaction.get("value")), + method=transaction.get("method"), + receiver=transaction.get("receiver"), + escrow=transaction.get("escrow"), + token=transaction.get("token"), internal_transactions=[ InternalTransaction( - from_address=internal_tx.get("from", ""), - to_address=internal_tx.get("to", ""), - value=internal_tx.get("value", ""), - method=internal_tx.get("method", ""), - receiver=internal_tx.get("receiver", ""), - escrow=internal_tx.get("escrow", ""), - token=internal_tx.get("token", ""), + from_address=internal_tx.get("from"), + to_address=internal_tx.get("to"), + value=int(internal_tx.get("value")), + method=internal_tx.get("method"), + receiver=internal_tx.get("receiver"), + escrow=internal_tx.get("escrow"), + token=internal_tx.get("token"), ) for internal_tx in transaction.get("internalTransactions", []) ], diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/worker/worker_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/worker/worker_utils.py index 2364d8537e..c363898ce6 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/worker/worker_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/worker/worker_utils.py @@ -23,8 +23,8 @@ def __init__( self, id: str, address: str, - total_amount_received: int, - payout_count: int, + total_amount_received: str, + payout_count: str, ): """ Initializes a WorkerData instance. @@ -37,8 +37,8 @@ def __init__( self.id = id self.address = address - self.total_amount_received = total_amount_received - self.payout_count = payout_count + self.total_amount_received = int(total_amount_received) + self.payout_count = int(payout_count) class WorkerUtils: @@ -87,10 +87,10 @@ def get_workers(filter: WorkerFilter) -> List[WorkerData]: for worker in workers_raw: workers.append( WorkerData( - id=worker.get("id", ""), - address=worker.get("address", ""), - total_amount_received=int(worker.get("totalHMTAmountReceived", 0)), - payout_count=int(worker.get("payoutCount", 0)), + id=worker.get("id"), + address=worker.get("address"), + total_amount_received=worker.get("totalHMTAmountReceived"), + payout_count=worker.get("payoutCount"), ) ) @@ -133,8 +133,8 @@ def get_worker(chain_id: ChainId, worker_address: str) -> Optional[WorkerData]: worker = worker_data["data"]["worker"] return WorkerData( - id=worker.get("id", ""), - address=worker.get("address", ""), - total_amount_received=int(worker.get("totalHMTAmountReceived", 0)), - payout_count=int(worker.get("payoutCount", 0)), + id=worker.get("id"), + address=worker.get("address"), + total_amount_received=worker.get("totalHMTAmountReceived"), + payout_count=worker.get("payoutCount"), ) diff --git a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py index 3f22ee0e4e..88b52db16e 100644 --- a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py +++ b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py @@ -131,7 +131,7 @@ def side_effect(subgraph_url, query, params): filtered[0].total_funded_amount, int(mock_escrow["totalFundedAmount"]) ) self.assertEqual( - int(filtered[0].created_at.timestamp()), int(mock_escrow["createdAt"]) + int(filtered[0].created_at), int(mock_escrow["createdAt"]) * 1000 ) filter = EscrowFilter(chain_id=ChainId.POLYGON_AMOY) @@ -181,6 +181,7 @@ def test_get_escrows_with_status_array(self): "status": "Pending", "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", + "createdAt": "1672531200000", } mock_escrow_2 = { "id": "0x1234567890123456789012345678901234567891", @@ -200,6 +201,7 @@ def test_get_escrows_with_status_array(self): "status": "Complete", "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", + "createdAt": "1672531200000", } def side_effect(subgraph_url, query, params): @@ -318,7 +320,7 @@ def test_get_escrow(self): escrow.total_funded_amount, int(mock_escrow["totalFundedAmount"]) ) self.assertEqual( - int(escrow.created_at.timestamp()), int(mock_escrow["createdAt"]) + int(escrow.created_at), int(mock_escrow["createdAt"]) * 1000 ) def test_get_escrow_empty_data(self): @@ -385,7 +387,7 @@ def test_get_status_events(self): result = EscrowUtils.get_status_events(filter) self.assertEqual(len(result), 1) - self.assertEqual(result[0].timestamp, 1620000000) + self.assertEqual(result[0].timestamp, 1620000000000) self.assertEqual(result[0].escrow_address, "0x123") self.assertEqual(result[0].status, "Pending") self.assertEqual(result[0].chain_id, ChainId.POLYGON_AMOY) @@ -418,7 +420,7 @@ def test_get_status_events_with_date_range(self): result = EscrowUtils.get_status_events(filter) self.assertEqual(len(result), 1) - self.assertEqual(result[0].timestamp, 1620000000) + self.assertEqual(result[0].timestamp, 1620000000000) self.assertEqual(result[0].escrow_address, "0x123") self.assertEqual(result[0].status, "Pending") self.assertEqual(result[0].chain_id, ChainId.POLYGON_AMOY) @@ -460,7 +462,7 @@ def test_get_status_events_with_launcher(self): result = EscrowUtils.get_status_events(filter) self.assertEqual(len(result), 1) - self.assertEqual(result[0].timestamp, 1620000000) + self.assertEqual(result[0].timestamp, 1620000000000) self.assertEqual(result[0].escrow_address, "0x123") self.assertEqual(result[0].status, "Pending") self.assertEqual(result[0].chain_id, ChainId.POLYGON_AMOY) @@ -513,7 +515,7 @@ def test_get_payouts(self): result[0].recipient, "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef" ) self.assertEqual(result[0].amount, 1000000000000000000) - self.assertEqual(result[0].created_at, 1672531200) + self.assertEqual(result[0].created_at, 1672531200000) def test_get_payouts_with_filters(self): with patch( @@ -551,7 +553,7 @@ def test_get_payouts_with_filters(self): result[0].recipient, "0x1234567890123456789012345678901234567892" ) self.assertEqual(result[0].amount, 1000000000000000000) - self.assertEqual(result[0].created_at, 1672531200) + self.assertEqual(result[0].created_at, 1672531200000) def test_get_payouts_no_data(self): with patch( @@ -638,7 +640,7 @@ def side_effect(subgraph_url, query, params): self.assertEqual(refunds[0].receiver, mock_refund["receiver"]) self.assertEqual(refunds[0].amount, int(mock_refund["amount"])) self.assertEqual(refunds[0].block, int(mock_refund["block"])) - self.assertEqual(refunds[0].timestamp, int(mock_refund["timestamp"])) + self.assertEqual(refunds[0].timestamp, int(mock_refund["timestamp"]) * 1000) self.assertEqual(refunds[0].tx_hash, mock_refund["txHash"]) def test_get_cancellation_refunds_invalid_escrow_address(self): @@ -713,7 +715,7 @@ def test_get_cancellation_refund(self): self.assertEqual(refund.receiver, mock_refund["receiver"]) self.assertEqual(refund.amount, int(mock_refund["amount"])) self.assertEqual(refund.block, int(mock_refund["block"])) - self.assertEqual(refund.timestamp, int(mock_refund["timestamp"])) + self.assertEqual(refund.timestamp, int(mock_refund["timestamp"]) * 1000) self.assertEqual(refund.tx_hash, mock_refund["txHash"]) def test_get_cancellation_refund_no_data(self): diff --git a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/operator/test_operator_utils.py b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/operator/test_operator_utils.py index 4c42033a97..b77c23db86 100644 --- a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/operator/test_operator_utils.py +++ b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/operator/test_operator_utils.py @@ -45,8 +45,8 @@ def test_get_operators(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } ], @@ -74,7 +74,7 @@ def test_get_operators(self): self.assertEqual(operators[0].address, DEFAULT_GAS_PAYER) self.assertEqual(operators[0].staked_amount, 100) self.assertEqual(operators[0].locked_amount, 25) - self.assertEqual(operators[0].locked_until_timestamp, 0) + self.assertEqual(operators[0].locked_until_timestamp, 123456789000) self.assertEqual(operators[0].withdrawn_amount, 25) self.assertEqual(operators[0].slashed_amount, 25) self.assertEqual(operators[0].amount_jobs_processed, 25) @@ -121,8 +121,8 @@ def test_get_operators_when_job_types_is_none(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } ], @@ -150,7 +150,7 @@ def test_get_operators_when_job_types_is_none(self): self.assertEqual(operators[0].address, DEFAULT_GAS_PAYER) self.assertEqual(operators[0].staked_amount, 100) self.assertEqual(operators[0].locked_amount, 25) - self.assertEqual(operators[0].locked_until_timestamp, 0) + self.assertEqual(operators[0].locked_until_timestamp, 123456789000) self.assertEqual(operators[0].withdrawn_amount, 25) self.assertEqual(operators[0].slashed_amount, 25) self.assertEqual(operators[0].amount_jobs_processed, 25) @@ -197,8 +197,8 @@ def test_get_operators_when_job_types_is_array(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } ], @@ -226,7 +226,7 @@ def test_get_operators_when_job_types_is_array(self): self.assertEqual(operators[0].address, DEFAULT_GAS_PAYER) self.assertEqual(operators[0].staked_amount, 100) self.assertEqual(operators[0].locked_amount, 25) - self.assertEqual(operators[0].locked_until_timestamp, 0) + self.assertEqual(operators[0].locked_until_timestamp, 123456789000) self.assertEqual(operators[0].withdrawn_amount, 25) self.assertEqual(operators[0].slashed_amount, 25) self.assertEqual(operators[0].amount_jobs_processed, 25) @@ -307,8 +307,8 @@ def test_get_operator(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } } @@ -328,7 +328,7 @@ def test_get_operator(self): self.assertEqual(operator.address, staker_address) self.assertEqual(operator.staked_amount, 100) self.assertEqual(operator.locked_amount, 25) - self.assertEqual(operator.locked_until_timestamp, 0) + self.assertEqual(operator.locked_until_timestamp, 123456789000) self.assertEqual(operator.withdrawn_amount, 25) self.assertEqual(operator.slashed_amount, 25) self.assertEqual(operator.amount_jobs_processed, 25) @@ -375,8 +375,8 @@ def test_get_operator_when_job_types_is_none(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } } @@ -396,7 +396,7 @@ def test_get_operator_when_job_types_is_none(self): self.assertEqual(operator.address, staker_address) self.assertEqual(operator.staked_amount, 100) self.assertEqual(operator.locked_amount, 25) - self.assertEqual(operator.locked_until_timestamp, 0) + self.assertEqual(operator.locked_until_timestamp, 123456789000) self.assertEqual(operator.withdrawn_amount, 25) self.assertEqual(operator.slashed_amount, 25) self.assertEqual(operator.amount_jobs_processed, 25) @@ -443,8 +443,8 @@ def test_get_operator_when_job_types_is_array(self): "lockedAmount": "25", "withdrawnAmount": "25", "slashedAmount": "25", - "lockedUntilTimestamp": "0", - "lastDepositTimestamp": "0", + "lockedUntilTimestamp": "123456789", + "lastDepositTimestamp": "123456789", }, } } @@ -464,7 +464,7 @@ def test_get_operator_when_job_types_is_array(self): self.assertEqual(operator.address, staker_address) self.assertEqual(operator.staked_amount, 100) self.assertEqual(operator.locked_amount, 25) - self.assertEqual(operator.locked_until_timestamp, 0) + self.assertEqual(operator.locked_until_timestamp, 123456789000) self.assertEqual(operator.withdrawn_amount, 25) self.assertEqual(operator.slashed_amount, 25) self.assertEqual(operator.amount_jobs_processed, 25) @@ -525,6 +525,7 @@ def test_get_reputation_network_operators(self): "jobTypes": job_types, "registrationNeeded": True, "registrationInstructions": url, + "amountJobsProcessed": "25", } ], } @@ -576,6 +577,7 @@ def test_get_reputation_network_operators_when_job_types_is_none(self): "jobTypes": job_types, "registrationNeeded": True, "registrationInstructions": url, + "amountJobsProcessed": "25", } ], } @@ -627,6 +629,7 @@ def test_get_reputation_network_operators_when_job_types_is_array(self): "jobTypes": job_types, "registrationNeeded": True, "registrationInstructions": url, + "amountJobsProcessed": "25", } ], } diff --git a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/staking/test_staking_utils.py b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/staking/test_staking_utils.py index 6547858b5e..0f9183eb8b 100644 --- a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/staking/test_staking_utils.py +++ b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/staking/test_staking_utils.py @@ -73,7 +73,50 @@ def test_get_stakers(self): self.assertEqual(len(stakers), 2) self.assertIsInstance(stakers[0], StakerData) self.assertEqual(stakers[0].id, "1") + self.assertEqual(stakers[0].address, mock_staker_1["address"]) + self.assertEqual( + stakers[0].staked_amount, int(mock_staker_1["stakedAmount"]) + ) + self.assertEqual( + stakers[0].locked_amount, int(mock_staker_1["lockedAmount"]) + ) + self.assertEqual( + stakers[0].withdrawn_amount, int(mock_staker_1["withdrawnAmount"]) + ) + self.assertEqual( + stakers[0].slashed_amount, int(mock_staker_1["slashedAmount"]) + ) + self.assertEqual( + stakers[0].locked_until_timestamp, + int(mock_staker_1["lockedUntilTimestamp"]) * 1000, + ) + self.assertEqual( + stakers[0].last_deposit_timestamp, + int(mock_staker_1["lastDepositTimestamp"]) * 1000, + ) + self.assertIsInstance(stakers[1], StakerData) self.assertEqual(stakers[1].id, "2") + self.assertEqual(stakers[1].address, mock_staker_2["address"]) + self.assertEqual( + stakers[1].staked_amount, int(mock_staker_2["stakedAmount"]) + ) + self.assertEqual( + stakers[1].locked_amount, int(mock_staker_2["lockedAmount"]) + ) + self.assertEqual( + stakers[1].withdrawn_amount, int(mock_staker_2["withdrawnAmount"]) + ) + self.assertEqual( + stakers[1].slashed_amount, int(mock_staker_2["slashedAmount"]) + ) + self.assertEqual( + stakers[1].locked_until_timestamp, + int(mock_staker_2["lockedUntilTimestamp"]) * 1000, + ) + self.assertEqual( + stakers[1].last_deposit_timestamp, + int(mock_staker_2["lastDepositTimestamp"]) * 1000, + ) def test_get_stakers_empty_response(self): with patch( @@ -120,7 +163,21 @@ def test_get_staker(self): ) self.assertIsInstance(staker, StakerData) self.assertEqual(staker.id, "1") - self.assertEqual(staker.address, "0x123") + self.assertEqual(staker.address, mock_staker["address"]) + self.assertEqual(staker.staked_amount, int(mock_staker["stakedAmount"])) + self.assertEqual(staker.locked_amount, int(mock_staker["lockedAmount"])) + self.assertEqual( + staker.withdrawn_amount, int(mock_staker["withdrawnAmount"]) + ) + self.assertEqual(staker.slashed_amount, int(mock_staker["slashedAmount"])) + self.assertEqual( + staker.locked_until_timestamp, + int(mock_staker["lockedUntilTimestamp"]) * 1000, + ) + self.assertEqual( + staker.last_deposit_timestamp, + int(mock_staker["lastDepositTimestamp"]) * 1000, + ) def test_get_staker_empty_data(self): with patch( diff --git a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/transaction/test_transaction_utils.py b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/transaction/test_transaction_utils.py index 77c812c759..aee4e3914f 100644 --- a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/transaction/test_transaction_utils.py +++ b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/transaction/test_transaction_utils.py @@ -19,11 +19,11 @@ def test_get_transactions(self): "human_protocol_sdk.transaction.transaction_utils.get_data_from_subgraph" ) as mock_function: mock_transaction_1 = { - "block": 123, + "block": "123", "txHash": "0x1234567890123456789012345678901234567890123456789012345678901234", "from": "0x1234567890123456789012345678901234567890", "to": "0x9876543210987654321098765432109876543210", - "timestamp": 1622700000, + "timestamp": "1622700000", "value": "1000000000000000000", "method": "transfer", "internalTransactions": [ @@ -36,11 +36,11 @@ def test_get_transactions(self): ], } mock_transaction_2 = { - "block": 456, + "block": "456", "txHash": "0x9876543210987654321098765432109876543210987654321098765432109876", "from": "0x9876543210987654321098765432109876543210", "to": "0x1234567890123456789012345678901234567890", - "timestamp": 1622800000, + "timestamp": "1622800000", "value": "2000000000000000000", "method": "transfer", "internalTransactions": [ @@ -151,11 +151,11 @@ def test_get_transaction(self): "human_protocol_sdk.transaction.transaction_utils.get_data_from_subgraph" ) as mock_function: mock_transaction = { - "block": 123, + "block": "123", "txHash": "0x1234567890123456789012345678901234567890123456789012345678901234", "from": "0x1234567890123456789012345678901234567890", "to": "0x9876543210987654321098765432109876543210", - "timestamp": 1622700000, + "timestamp": "1622700000", "value": "1000000000000000000", "method": "transfer", "internalTransactions": [ @@ -184,12 +184,14 @@ def test_get_transaction(self): ) self.assertIsNotNone(transaction) self.assertEqual(transaction.chain_id, ChainId.POLYGON_AMOY) - self.assertEqual(transaction.block, mock_transaction["block"]) + self.assertEqual(transaction.block, int(mock_transaction["block"])) self.assertEqual(transaction.tx_hash, mock_transaction["txHash"]) self.assertEqual(transaction.from_address, mock_transaction["from"]) self.assertEqual(transaction.to_address, mock_transaction["to"]) - self.assertEqual(transaction.timestamp, mock_transaction["timestamp"]) - self.assertEqual(transaction.value, mock_transaction["value"]) + self.assertEqual( + transaction.timestamp, int(mock_transaction["timestamp"]) * 1000 + ) + self.assertEqual(transaction.value, int(mock_transaction["value"])) self.assertEqual(transaction.method, mock_transaction["method"]) def test_get_transaction_empty_data(self): diff --git a/packages/sdk/typescript/human-protocol-sdk/example/staking.ts b/packages/sdk/typescript/human-protocol-sdk/example/staking.ts index f4ca4617cc..8c4f66a6a4 100644 --- a/packages/sdk/typescript/human-protocol-sdk/example/staking.ts +++ b/packages/sdk/typescript/human-protocol-sdk/example/staking.ts @@ -5,7 +5,7 @@ import { ethers } from 'ethers'; const runStakingExamples = async () => { const stakers = await StakingUtils.getStakers({ - chainId: ChainId.LOCALHOST, + chainId: ChainId.POLYGON_AMOY, maxLockedAmount: ethers.parseEther('5').toString(), orderBy: 'lastDepositTimestamp', orderDirection: OrderDirection.ASC, @@ -16,7 +16,7 @@ const runStakingExamples = async () => { try { const staker = await StakingUtils.getStaker( - ChainId.LOCALHOST, + ChainId.POLYGON_AMOY, stakers[0].address ); console.log('Staker info:', staker); diff --git a/packages/sdk/typescript/human-protocol-sdk/src/escrow.ts b/packages/sdk/typescript/human-protocol-sdk/src/escrow.ts index 0a68944b2e..d40c1f0cfe 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/escrow.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/escrow.ts @@ -43,6 +43,7 @@ import { WarnVersionMismatch, } from './error'; import { + CancellationRefundData, EscrowData, GET_CANCELLATION_REFUNDS_QUERY, GET_CANCELLATION_REFUND_BY_ADDRESS_QUERY, @@ -50,6 +51,7 @@ import { GET_ESCROW_BY_ADDRESS_QUERY, GET_PAYOUTS_QUERY, GET_STATUS_UPDATES_QUERY, + PayoutData, StatusEvent, } from './graphql'; import { @@ -58,15 +60,12 @@ import { IEscrowsFilter, IPayoutFilter, IStatusEventFilter, + IStatusEvent, + ICancellationRefund, + IPayout, + IEscrowWithdraw, } from './interfaces'; -import { - EscrowStatus, - EscrowWithdraw, - NetworkData, - TransactionLikeWithNonce, - Payout, - CancellationRefund, -} from './types'; +import { EscrowStatus, NetworkData, TransactionLikeWithNonce } from './types'; import { getSubgraphUrl, getUnixTimestamp, @@ -535,7 +534,7 @@ export class EscrowClient extends BaseEthersClient { const escrowContract = this.getEscrowContract(escrowAddress); const hasFundsToReserveParam = typeof a === 'bigint'; - const fundsToReserve = hasFundsToReserveParam ? (a as bigint) : undefined; + const fundsToReserve = hasFundsToReserveParam ? (a as bigint) : null; const txOptions = (hasFundsToReserveParam ? b : a) || {}; // When fundsToReserve is provided and is 0, allow empty URL. // In this situation not solutions might have been provided so the escrow can be straight cancelled. @@ -557,7 +556,7 @@ export class EscrowClient extends BaseEthersClient { } try { - if (fundsToReserve !== undefined) { + if (fundsToReserve !== null) { await ( await escrowContract['storeResults(string,string,uint256)']( url, @@ -901,7 +900,7 @@ export class EscrowClient extends BaseEthersClient { * @param {string} escrowAddress Address of the escrow to withdraw. * @param {string} tokenAddress Address of the token to withdraw. * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object). - * @returns {EscrowWithdraw} Returns the escrow withdrawal data including transaction hash and withdrawal amount. Throws error if any. + * @returns {IEscrowWithdraw} Returns the escrow withdrawal data including transaction hash and withdrawal amount. Throws error if any. * * * **Code example** @@ -930,7 +929,7 @@ export class EscrowClient extends BaseEthersClient { escrowAddress: string, tokenAddress: string, txOptions: Overrides = {} - ): Promise { + ): Promise { if (!ethers.isAddress(escrowAddress)) { throw ErrorInvalidEscrowAddressProvided; } @@ -969,7 +968,7 @@ export class EscrowClient extends BaseEthersClient { const from = parsedLog?.args[0]; if (parsedLog?.name === 'Transfer' && from === escrowAddress) { - amountTransferred = parsedLog?.args[2]; + amountTransferred = BigInt(parsedLog?.args[2]); break; } } @@ -979,13 +978,11 @@ export class EscrowClient extends BaseEthersClient { throw ErrorTransferEventNotFoundInTransactionLogs; } - const escrowWithdrawData: EscrowWithdraw = { + return { txHash: transactionReceipt?.hash || '', tokenAddress, withdrawnAmount: amountTransferred, }; - - return escrowWithdrawData; } catch (e) { return throwError(e); } @@ -1785,23 +1782,29 @@ export class EscrowUtils { * interface IEscrow { * id: string; * address: string; - * amountPaid: string; - * balance: string; - * count: string; - * jobRequesterId: string; + * amountPaid: bigint; + * balance: bigint; + * count: bigint; * factoryAddress: string; - * finalResultsUrl?: string; - * intermediateResultsUrl?: string; + * finalResultsUrl: string | null; + * finalResultsHash: string | null; + * intermediateResultsUrl: string | null; + * intermediateResultsHash: string | null; * launcher: string; - * manifestHash?: string; - * manifest?: string; - * recordingOracle?: string; - * reputationOracle?: string; - * exchangeOracle?: string; - * status: EscrowStatus; + * jobRequesterId: string | null; + * manifestHash: string | null; + * manifest: string | null; + * recordingOracle: string | null; + * reputationOracle: string | null; + * exchangeOracle: string | null; + * recordingOracleFee: number | null; + * reputationOracleFee: number | null; + * exchangeOracleFee: number | null; + * status: string; * token: string; - * totalFundedAmount: string; - * createdAt: string; + * totalFundedAmount: bigint; + * createdAt: number; + * chainId: number; * }; * ``` * @@ -1873,13 +1876,7 @@ export class EscrowUtils { skip: skip, } ); - escrows.map((escrow) => (escrow.chainId = networkData.chainId)); - - if (!escrows) { - return []; - } - - return escrows; + return (escrows || []).map((e) => mapEscrow(e, networkData.chainId)); } /** @@ -1906,23 +1903,29 @@ export class EscrowUtils { * interface IEscrow { * id: string; * address: string; - * amountPaid: string; - * balance: string; - * count: string; - * jobRequesterId: string; + * amountPaid: bigint; + * balance: bigint; + * count: bigint; * factoryAddress: string; - * finalResultsUrl?: string; - * intermediateResultsUrl?: string; + * finalResultsUrl: string | null; + * finalResultsHash: string | null; + * intermediateResultsUrl: string | null; + * intermediateResultsHash: string | null; * launcher: string; - * manifestHash?: string; - * manifest?: string; - * recordingOracle?: string; - * reputationOracle?: string; - * exchangeOracle?: string; - * status: EscrowStatus; + * jobRequesterId: string | null; + * manifestHash: string | null; + * manifest: string | null; + * recordingOracle: string | null; + * reputationOracle: string | null; + * exchangeOracle: string | null; + * recordingOracleFee: number | null; + * reputationOracleFee: number | null; + * exchangeOracleFee: number | null; + * status: string; * token: string; - * totalFundedAmount: string; - * createdAt: string; + * totalFundedAmount: bigint; + * createdAt: number; + * chainId: number; * }; * ``` * @@ -1953,14 +1956,14 @@ export class EscrowUtils { throw ErrorInvalidAddress; } - const { escrow } = await gqlFetch<{ escrow: EscrowData }>( + const { escrow } = await gqlFetch<{ escrow: EscrowData | null }>( getSubgraphUrl(networkData), GET_ESCROW_BY_ADDRESS_QUERY(), { escrowAddress: escrowAddress.toLowerCase() } ); - escrow.chainId = networkData.chainId; + if (!escrow) return null; - return escrow || null; + return mapEscrow(escrow, networkData.chainId); } /** @@ -2021,7 +2024,7 @@ export class EscrowUtils { */ public static async getStatusEvents( filter: IStatusEventFilter - ): Promise { + ): Promise { const { chainId, statuses, @@ -2074,14 +2077,12 @@ export class EscrowUtils { return []; } - const statusEvents = data['escrowStatusEvents'] as StatusEvent[]; - - const eventsWithChainId = statusEvents.map((event) => ({ - ...event, + return data['escrowStatusEvents'].map((event) => ({ + timestamp: Number(event.timestamp) * 1000, + escrowAddress: event.escrowAddress, + status: EscrowStatus[event.status as keyof typeof EscrowStatus], chainId, })); - - return eventsWithChainId; } /** @@ -2093,7 +2094,7 @@ export class EscrowUtils { * Fetch payouts from the subgraph. * * @param {IPayoutFilter} filter Filter parameters. - * @returns {Promise} List of payouts matching the filters. + * @returns {Promise} List of payouts matching the filters. * * **Code example** * @@ -2110,7 +2111,7 @@ export class EscrowUtils { * console.log(payouts); * ``` */ - public static async getPayouts(filter: IPayoutFilter): Promise { + public static async getPayouts(filter: IPayoutFilter): Promise { const networkData = NETWORKS[filter.chainId]; if (!networkData) { throw ErrorUnsupportedChainID; @@ -2127,7 +2128,7 @@ export class EscrowUtils { const skip = filter.skip || 0; const orderDirection = filter.orderDirection || OrderDirection.DESC; - const { payouts } = await gqlFetch<{ payouts: Payout[] }>( + const { payouts } = await gqlFetch<{ payouts: PayoutData[] }>( getSubgraphUrl(networkData), GET_PAYOUTS_QUERY(filter), { @@ -2140,8 +2141,17 @@ export class EscrowUtils { orderDirection, } ); + if (!payouts) { + return []; + } - return payouts || []; + return payouts.map((payout) => ({ + id: payout.id, + escrowAddress: payout.escrowAddress, + recipient: payout.recipient, + amount: BigInt(payout.amount), + createdAt: Number(payout.createdAt) * 1000, + })); } /** @@ -2165,7 +2175,7 @@ export class EscrowUtils { * ``` * * ```ts - * type CancellationRefund = { + * interface ICancellationRefund { * id: string; * escrowAddress: string; * receiver: string; @@ -2178,7 +2188,7 @@ export class EscrowUtils { * * * @param {Object} filter Filter parameters. - * @returns {Promise} List of cancellation refunds matching the filters. + * @returns {Promise} List of cancellation refunds matching the filters. * * **Code example** * @@ -2201,7 +2211,7 @@ export class EscrowUtils { first?: number; skip?: number; orderDirection?: OrderDirection; - }): Promise { + }): Promise { const networkData = NETWORKS[filter.chainId]; if (!networkData) throw ErrorUnsupportedChainID; if (filter.escrowAddress && !ethers.isAddress(filter.escrowAddress)) { @@ -2217,7 +2227,7 @@ export class EscrowUtils { const orderDirection = filter.orderDirection || OrderDirection.DESC; const { cancellationRefundEvents } = await gqlFetch<{ - cancellationRefundEvents: CancellationRefund[]; + cancellationRefundEvents: CancellationRefundData[]; }>(getSubgraphUrl(networkData), GET_CANCELLATION_REFUNDS_QUERY(filter), { escrowAddress: filter.escrowAddress?.toLowerCase(), receiver: filter.receiver?.toLowerCase(), @@ -2228,7 +2238,19 @@ export class EscrowUtils { orderDirection, }); - return cancellationRefundEvents || []; + if (!cancellationRefundEvents || cancellationRefundEvents.length === 0) { + return []; + } + + return cancellationRefundEvents.map((event) => ({ + id: event.id, + escrowAddress: event.escrowAddress, + receiver: event.receiver, + amount: BigInt(event.amount), + block: Number(event.block), + timestamp: Number(event.timestamp) * 1000, + txHash: event.txHash, + })); } /** @@ -2252,7 +2274,7 @@ export class EscrowUtils { * ``` * * ```ts - * type CancellationRefund = { + * interface ICancellationRefund { * id: string; * escrowAddress: string; * receiver: string; @@ -2266,7 +2288,7 @@ export class EscrowUtils { * * @param {ChainId} chainId Network in which the escrow has been deployed * @param {string} escrowAddress Address of the escrow - * @returns {Promise} Cancellation refund data + * @returns {Promise} Cancellation refund data * * **Code example** * @@ -2279,7 +2301,7 @@ export class EscrowUtils { public static async getCancellationRefund( chainId: ChainId, escrowAddress: string - ): Promise { + ): Promise { const networkData = NETWORKS[chainId]; if (!networkData) throw ErrorUnsupportedChainID; @@ -2288,13 +2310,59 @@ export class EscrowUtils { } const { cancellationRefundEvents } = await gqlFetch<{ - cancellationRefundEvents: any; + cancellationRefundEvents: CancellationRefundData[]; }>( getSubgraphUrl(networkData), GET_CANCELLATION_REFUND_BY_ADDRESS_QUERY(), { escrowAddress: escrowAddress.toLowerCase() } ); - return cancellationRefundEvents?.[0] || null; + if (!cancellationRefundEvents || cancellationRefundEvents.length === 0) { + return null; + } + + return { + id: cancellationRefundEvents[0].id, + escrowAddress: cancellationRefundEvents[0].escrowAddress, + receiver: cancellationRefundEvents[0].receiver, + amount: BigInt(cancellationRefundEvents[0].amount), + block: Number(cancellationRefundEvents[0].block), + timestamp: Number(cancellationRefundEvents[0].timestamp) * 1000, + txHash: cancellationRefundEvents[0].txHash, + }; } } + +function mapEscrow(e: EscrowData, chainId: ChainId | number): IEscrow { + return { + id: e.id, + address: e.address, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + factoryAddress: e.factoryAddress, + finalResultsUrl: e.finalResultsUrl, + finalResultsHash: e.finalResultsHash, + intermediateResultsUrl: e.intermediateResultsUrl, + intermediateResultsHash: e.intermediateResultsHash, + launcher: e.launcher, + jobRequesterId: e.jobRequesterId, + manifestHash: e.manifestHash, + manifest: e.manifest, + recordingOracle: e.recordingOracle, + reputationOracle: e.reputationOracle, + exchangeOracle: e.exchangeOracle, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee ? Number(e.exchangeOracleFee) : null, + status: e.status, + token: e.token, + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + chainId: Number(chainId), + }; +} diff --git a/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts b/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts index 72d018be28..79023a88e4 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts @@ -1,4 +1,4 @@ -import { ChainId } from '../enums'; +import { IReputationNetwork } from '../interfaces'; export type EscrowData = { id: string; @@ -7,24 +7,56 @@ export type EscrowData = { balance: string; count: string; factoryAddress: string; - finalResultsUrl?: string; - finalResultsHash?: string; - intermediateResultsUrl?: string; - intermediateResultsHash?: string; + finalResultsUrl: string | null; + finalResultsHash: string | null; + intermediateResultsUrl: string | null; + intermediateResultsHash: string | null; launcher: string; - manifestHash?: string; - manifestUrl?: string; - recordingOracle?: string; - reputationOracle?: string; - exchangeOracle?: string; - recordingOracleFee?: string; - reputationOracleFee?: string; - exchangeOracleFee?: string; + jobRequesterId: string | null; + manifestHash: string | null; + manifest: string | null; + recordingOracle: string | null; + reputationOracle: string | null; + exchangeOracle: string | null; + recordingOracleFee: string | null; + reputationOracleFee: string | null; + exchangeOracleFee: string | null; status: string; token: string; totalFundedAmount: string; createdAt: string; - chainId: number; +}; + +export type WorkerData = { + id: string; + address: string; + totalHMTAmountReceived: string; + payoutCount: string; +}; + +export type InternalTransactionData = { + from: string; + to: string; + value: string; + method: string; + receiver: string | null; + escrow: string | null; + token: string | null; + id: string | null; +}; + +export type TransactionData = { + block: string; + txHash: string; + from: string; + to: string; + timestamp: string; + value: string; + method: string; + receiver: string | null; + escrow: string | null; + token: string | null; + internalTransactions: InternalTransactionData[]; }; export type HMTStatisticsData = { @@ -77,86 +109,15 @@ export type RewardAddedEventData = { amount: string; }; -export type DailyEscrowData = { - timestamp: Date; - escrowsTotal: number; - escrowsPending: number; - escrowsSolved: number; - escrowsPaid: number; - escrowsCancelled: number; -}; - -export type EscrowStatistics = { - totalEscrows: number; - dailyEscrowsData: DailyEscrowData[]; -}; - -export type DailyWorkerData = { - timestamp: Date; - activeWorkers: number; -}; - -export type WorkerStatistics = { - dailyWorkersData: DailyWorkerData[]; -}; - -export type DailyPaymentData = { - timestamp: Date; - totalAmountPaid: bigint; - totalCount: number; - averageAmountPerWorker: bigint; -}; - -export type PaymentStatistics = { - dailyPaymentsData: DailyPaymentData[]; -}; - export type HMTHolderData = { address: string; balance: string; }; -export type HMTHolder = { - address: string; - balance: bigint; -}; - -export type DailyHMTData = { - timestamp: Date; - totalTransactionAmount: bigint; - totalTransactionCount: number; - dailyUniqueSenders: number; - dailyUniqueReceivers: number; -}; - -export type HMTStatistics = { - totalTransferAmount: bigint; - totalTransferCount: number; - totalHolders: number; -}; - -export type IMDataEntity = { - served: number; - solved: number; -}; - -export type IMData = Record; - -export type DailyTaskData = { - timestamp: Date; - tasksTotal: number; - tasksSolved: number; -}; - -export type TaskStatistics = { - dailyTasksData: DailyTaskData[]; -}; - export type StatusEvent = { - timestamp: number; + timestamp: string; escrowAddress: string; status: string; - chainId: ChainId; }; export type KVStoreData = { @@ -165,5 +126,65 @@ export type KVStoreData = { key: string; value: string; timestamp: Date; - block: number; + block: string; +}; + +export type StakerData = { + id: string; + address: string; + stakedAmount: string; + lockedAmount: string; + withdrawnAmount: string; + slashedAmount: string; + lockedUntilTimestamp: string; + lastDepositTimestamp: string; +}; + +export interface IOperatorSubgraph { + id: string; + address: string; + amountJobsProcessed: string; + role: string | null; + fee: string | null; + publicKey: string | null; + webhookUrl: string | null; + website: string | null; + url: string | null; + registrationNeeded: boolean | null; + registrationInstructions: string | null; + name: string | null; + category: string | null; + jobTypes: string | string[] | null; + reputationNetworks: { address: string }[]; + staker: { + stakedAmount: string; + lockedAmount: string; + lockedUntilTimestamp: string; + withdrawnAmount: string; + slashedAmount: string; + lastDepositTimestamp: string; + } | null; +} + +export interface IReputationNetworkSubgraph + extends Omit { + operators: IOperatorSubgraph[]; +} + +export type PayoutData = { + id: string; + escrowAddress: string; + recipient: string; + amount: string; + createdAt: string; +}; + +export type CancellationRefundData = { + id: string; + escrowAddress: string; + receiver: string; + amount: string; + block: string; + timestamp: string; + txHash: string; }; diff --git a/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts b/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts index bc585f0f94..c47656c690 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts @@ -10,50 +10,24 @@ export interface IOperator { id: string; chainId: ChainId; address: string; - stakedAmount: bigint; - lockedAmount: bigint; - lockedUntilTimestamp: bigint; - withdrawnAmount: bigint; - slashedAmount: bigint; - amountJobsProcessed: bigint; - role?: string; - fee?: bigint; - publicKey?: string; - webhookUrl?: string; - website?: string; - url?: string; - jobTypes?: string[]; - registrationNeeded?: boolean; - registrationInstructions?: string; - reputationNetworks?: string[]; - name?: string; - category?: string; -} - -export interface IOperatorSubgraph { - id: string; - address: string; - amountJobsProcessed: bigint; - role?: string; - fee?: bigint; - publicKey?: string; - webhookUrl?: string; - website?: string; - url?: string; - registrationNeeded?: boolean; - registrationInstructions?: string; - name?: string; - category?: string; - jobTypes?: string | string[]; - reputationNetworks?: { address: string }[]; - staker?: { - stakedAmount: bigint; - lockedAmount: bigint; - lockedUntilTimestamp: bigint; - withdrawnAmount: bigint; - slashedAmount: bigint; - lastDepositTimestamp: bigint; - }; + stakedAmount: bigint | null; + lockedAmount: bigint | null; + lockedUntilTimestamp: number | null; + withdrawnAmount: bigint | null; + slashedAmount: bigint | null; + amountJobsProcessed: bigint | null; + role: string | null; + fee: bigint | null; + publicKey: string | null; + webhookUrl: string | null; + website: string | null; + url: string | null; + jobTypes: string[] | null; + registrationNeeded: boolean | null; + registrationInstructions: string | null; + reputationNetworks: string[]; + name: string | null; + category: string | null; } export interface IOperatorsFilter extends IPagination { @@ -69,35 +43,31 @@ export interface IReputationNetwork { operators: IOperator[]; } -export interface IReputationNetworkSubgraph - extends Omit { - operators: IOperatorSubgraph[]; -} - export interface IEscrow { id: string; address: string; - amountPaid: string; - balance: string; - count: string; + amountPaid: bigint; + balance: bigint; + count: number; factoryAddress: string; - finalResultsUrl?: string; - finalResultsHash?: string; - intermediateResultsUrl?: string; - intermediateResultsHash?: string; + finalResultsUrl: string | null; + finalResultsHash: string | null; + intermediateResultsUrl: string | null; + intermediateResultsHash: string | null; launcher: string; - manifestHash?: string; - manifest?: string; - recordingOracle?: string; - reputationOracle?: string; - exchangeOracle?: string; - recordingOracleFee?: string; - reputationOracleFee?: string; - exchangeOracleFee?: string; + jobRequesterId: string | null; + manifestHash: string | null; + manifest: string | null; + recordingOracle: string | null; + reputationOracle: string | null; + exchangeOracle: string | null; + recordingOracleFee: number | null; + reputationOracleFee: number | null; + exchangeOracleFee: number | null; status: string; token: string; - totalFundedAmount: string; - createdAt: string; + totalFundedAmount: bigint; + createdAt: number; chainId: number; } @@ -156,11 +126,11 @@ export interface IKVStore { export interface InternalTransaction { from: string; to: string; - value: string; + value: bigint; method: string; - receiver?: string; - escrow?: string; - token?: string; + receiver: string | null; + escrow: string | null; + token: string | null; } export interface ITransaction { @@ -168,12 +138,12 @@ export interface ITransaction { txHash: string; from: string; to: string; - timestamp: bigint; - value: string; + timestamp: number; + value: bigint; method: string; - receiver?: string; - escrow?: string; - token?: string; + receiver: string | null; + escrow: string | null; + token: string | null; internalTransactions: InternalTransaction[]; } @@ -214,7 +184,7 @@ export interface IStatusEventFilter extends IPagination { export interface IWorker { id: string; address: string; - totalHMTAmountReceived: number; + totalHMTAmountReceived: bigint; payoutCount: number; } @@ -228,10 +198,10 @@ export interface IStaker { address: string; stakedAmount: bigint; lockedAmount: bigint; - lockedUntil: bigint; withdrawableAmount: bigint; slashedAmount: bigint; - lastDepositTimestamp: bigint; + lockedUntil: number; + lastDepositTimestamp: number; } export interface IStakersFilter extends IPagination { @@ -258,3 +228,87 @@ export interface ICancellationRefundFilter extends IPagination { from?: Date; to?: Date; } + +export interface IDailyEscrow { + timestamp: number; + escrowsTotal: number; + escrowsPending: number; + escrowsSolved: number; + escrowsPaid: number; + escrowsCancelled: number; +} + +export interface IEscrowStatistics { + totalEscrows: number; + dailyEscrowsData: IDailyEscrow[]; +} + +export interface IDailyWorker { + timestamp: number; + activeWorkers: number; +} + +export interface IWorkerStatistics { + dailyWorkersData: IDailyWorker[]; +} + +export interface IDailyPayment { + timestamp: number; + totalAmountPaid: bigint; + totalCount: number; + averageAmountPerWorker: bigint; +} + +export interface IPaymentStatistics { + dailyPaymentsData: IDailyPayment[]; +} + +export interface IHMTStatistics { + totalTransferAmount: bigint; + totalTransferCount: number; + totalHolders: number; +} + +export interface IHMTHolder { + address: string; + balance: bigint; +} + +export interface IDailyHMT { + timestamp: number; + totalTransactionAmount: bigint; + totalTransactionCount: number; + dailyUniqueSenders: number; + dailyUniqueReceivers: number; +} + +export interface IStatusEvent { + timestamp: number; + escrowAddress: string; + status: EscrowStatus; + chainId: ChainId; +} + +export interface ICancellationRefund { + id: string; + escrowAddress: string; + receiver: string; + amount: bigint; + block: number; + timestamp: number; + txHash: string; +} + +export interface IPayout { + id: string; + escrowAddress: string; + recipient: string; + amount: bigint; + createdAt: number; +} + +export interface IEscrowWithdraw { + txHash: string; + tokenAddress: string; + withdrawnAmount: bigint; +} diff --git a/packages/sdk/typescript/human-protocol-sdk/src/operator.ts b/packages/sdk/typescript/human-protocol-sdk/src/operator.ts index 0f4ed7be6c..cbca6e866a 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/operator.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/operator.ts @@ -1,14 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import gqlFetch from 'graphql-request'; +import { IOperator, IOperatorsFilter, IReward } from './interfaces'; +import { GET_REWARD_ADDED_EVENTS_QUERY } from './graphql/queries/reward'; import { - IOperator, IOperatorSubgraph, - IOperatorsFilter, IReputationNetworkSubgraph, - IReward, -} from './interfaces'; -import { GET_REWARD_ADDED_EVENTS_QUERY } from './graphql/queries/reward'; -import { RewardAddedEventData } from './graphql'; + RewardAddedEventData, +} from './graphql'; import { GET_LEADER_QUERY, GET_LEADERS_QUERY, @@ -236,14 +234,20 @@ function mapOperator(operator: IOperatorSubgraph, chainId: ChainId): IOperator { id: operator.id, chainId, address: operator.address, - stakedAmount: BigInt(staker?.stakedAmount || 0), - lockedAmount: BigInt(staker?.lockedAmount || 0), - lockedUntilTimestamp: BigInt(staker?.lockedUntilTimestamp || 0), - withdrawnAmount: BigInt(staker?.withdrawnAmount || 0), - slashedAmount: BigInt(staker?.slashedAmount || 0), - amountJobsProcessed: BigInt(operator.amountJobsProcessed || 0), + stakedAmount: staker?.stakedAmount ? BigInt(staker?.stakedAmount) : null, + lockedAmount: staker?.lockedAmount ? BigInt(staker?.lockedAmount) : null, + lockedUntilTimestamp: staker?.lockedUntilTimestamp + ? Number(staker.lockedUntilTimestamp) * 1000 + : null, + withdrawnAmount: staker?.withdrawnAmount + ? BigInt(staker?.withdrawnAmount) + : null, + slashedAmount: staker?.slashedAmount ? BigInt(staker?.slashedAmount) : null, + amountJobsProcessed: operator.amountJobsProcessed + ? BigInt(operator.amountJobsProcessed) + : null, role: operator.role, - fee: operator.fee ? BigInt(operator.fee) : undefined, + fee: operator.fee ? BigInt(operator.fee) : null, publicKey: operator.publicKey, webhookUrl: operator.webhookUrl, website: operator.website, diff --git a/packages/sdk/typescript/human-protocol-sdk/src/staking.ts b/packages/sdk/typescript/human-protocol-sdk/src/staking.ts index 5dc51374d0..1fab0ed1fd 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/staking.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/staking.ts @@ -24,6 +24,7 @@ import { ErrorUnsupportedChainID, } from './error'; import { IStaker, IStakersFilter, StakerInfo } from './interfaces'; +import { StakerData } from './graphql'; import { NetworkData } from './types'; import { getSubgraphUrl, throwError } from './utils'; import { @@ -509,7 +510,7 @@ export class StakingUtils { throw ErrorUnsupportedChainID; } - const { staker } = await gqlFetch<{ staker: IStaker }>( + const { staker } = await gqlFetch<{ staker: StakerData }>( getSubgraphUrl(networkData), GET_STAKER_BY_ADDRESS_QUERY, { id: stakerAddress.toLowerCase() } @@ -519,7 +520,7 @@ export class StakingUtils { throw ErrorStakerNotFound; } - return staker; + return mapStaker(staker); } /** @@ -539,7 +540,7 @@ export class StakingUtils { throw ErrorUnsupportedChainID; } - const { stakers } = await gqlFetch<{ stakers: IStaker[] }>( + const { stakers } = await gqlFetch<{ stakers: StakerData[] }>( getSubgraphUrl(networkData), GET_STAKERS_QUERY(filter), { @@ -577,6 +578,18 @@ export class StakingUtils { return []; } - return stakers; + return stakers.map((s) => mapStaker(s)); } } + +function mapStaker(s: StakerData): IStaker { + return { + address: s.address, + stakedAmount: BigInt(s.stakedAmount), + lockedAmount: BigInt(s.lockedAmount), + withdrawableAmount: BigInt(s.withdrawnAmount), + slashedAmount: BigInt(s.slashedAmount), + lockedUntil: Number(s.lockedUntilTimestamp) * 1000, + lastDepositTimestamp: Number(s.lastDepositTimestamp) * 1000, + }; +} diff --git a/packages/sdk/typescript/human-protocol-sdk/src/statistics.ts b/packages/sdk/typescript/human-protocol-sdk/src/statistics.ts index b88b228836..715c094621 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/statistics.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/statistics.ts @@ -1,27 +1,29 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { ethers } from 'ethers'; import gqlFetch from 'graphql-request'; +import { OrderDirection } from './enums'; import { + EscrowStatisticsData, + EventDayData, GET_ESCROW_STATISTICS_QUERY, GET_EVENT_DAY_DATA_QUERY, - GET_HOLDERS_QUERY, GET_HMTOKEN_STATISTICS_QUERY, - EscrowStatistics, - EscrowStatisticsData, - EventDayData, - HMTStatistics, - HMTStatisticsData, - PaymentStatistics, - WorkerStatistics, + GET_HOLDERS_QUERY, HMTHolderData, - HMTHolder, - DailyHMTData, + HMTStatisticsData, } from './graphql'; -import { IHMTHoldersParams, IStatisticsFilter } from './interfaces'; +import { + IDailyHMT, + IEscrowStatistics, + IHMTHolder, + IHMTHoldersParams, + IHMTStatistics, + IPaymentStatistics, + IStatisticsFilter, + IWorkerStatistics, +} from './interfaces'; import { NetworkData } from './types'; import { getSubgraphUrl, getUnixTimestamp, throwError } from './utils'; -import { OrderDirection } from './enums'; /** * ## Introduction @@ -85,8 +87,8 @@ export class StatisticsClient { * ``` * * ```ts - * type DailyEscrowsData = { - * timestamp: Date; + * interface IDailyEscrow { + * timestamp: number; * escrowsTotal: number; * escrowsPending: number; * escrowsSolved: number; @@ -94,14 +96,14 @@ export class StatisticsClient { * escrowsCancelled: number; * }; * - * type EscrowStatistics = { + * interface IEscrowStatistics { * totalEscrows: number; - * dailyEscrowsData: DailyEscrowsData[]; + * dailyEscrowsData: IDailyEscrow[]; * }; * ``` * * @param {IStatisticsFilter} filter Statistics params with duration data - * @returns {Promise} Escrow statistics data. + * @returns {Promise} Escrow statistics data. * * **Code example** * @@ -119,7 +121,7 @@ export class StatisticsClient { */ async getEscrowStatistics( filter: IStatisticsFilter = {} - ): Promise { + ): Promise { try { const first = filter.first !== undefined ? Math.min(filter.first, 1000) : 10; @@ -145,7 +147,7 @@ export class StatisticsClient { ? +escrowStatistics.totalEscrowCount : 0, dailyEscrowsData: eventDayDatas.map((eventDayData) => ({ - timestamp: new Date(+eventDayData.timestamp * 1000), + timestamp: +eventDayData.timestamp * 1000, escrowsTotal: +eventDayData.dailyEscrowCount, escrowsPending: +eventDayData.dailyPendingStatusEventCount, escrowsSolved: +eventDayData.dailyCompletedStatusEventCount, @@ -174,18 +176,18 @@ export class StatisticsClient { * ``` * * ```ts - * type DailyWorkerData = { - * timestamp: Date; + * interface IDailyWorker { + * timestamp: number; * activeWorkers: number; * }; * - * type WorkerStatistics = { - * dailyWorkersData: DailyWorkerData[]; + * interface IWorkerStatistics { + * dailyWorkersData: IDailyWorker[]; * }; * ``` * * @param {IStatisticsFilter} filter Statistics params with duration data - * @returns {Promise} Worker statistics data. + * @returns {Promise} Worker statistics data. * * **Code example** * @@ -203,7 +205,7 @@ export class StatisticsClient { */ async getWorkerStatistics( filter: IStatisticsFilter = {} - ): Promise { + ): Promise { try { const first = filter.first !== undefined ? Math.min(filter.first, 1000) : 10; @@ -222,7 +224,7 @@ export class StatisticsClient { return { dailyWorkersData: eventDayDatas.map((eventDayData) => ({ - timestamp: new Date(+eventDayData.timestamp * 1000), + timestamp: +eventDayData.timestamp * 1000, activeWorkers: +eventDayData.dailyWorkerCount, })), }; @@ -247,20 +249,20 @@ export class StatisticsClient { * ``` * * ```ts - * type DailyPaymentData = { - * timestamp: Date; - * totalAmountPaid: BigNumber; + * interface IDailyPayment { + * timestamp: number; + * totalAmountPaid: bigint; * totalCount: number; - * averageAmountPerWorker: BigNumber; + * averageAmountPerWorker: bigint; * }; * - * type PaymentStatistics = { - * dailyPaymentsData: DailyPaymentData[]; + * interface IPaymentStatistics { + * dailyPaymentsData: IDailyPayment[]; * }; * ``` * * @param {IStatisticsFilter} filter Statistics params with duration data - * @returns {Promise} Payment statistics data. + * @returns {Promise} Payment statistics data. * * **Code example** * @@ -299,7 +301,7 @@ export class StatisticsClient { */ async getPaymentStatistics( filter: IStatisticsFilter = {} - ): Promise { + ): Promise { try { const first = filter.first !== undefined ? Math.min(filter.first, 1000) : 10; @@ -318,14 +320,14 @@ export class StatisticsClient { return { dailyPaymentsData: eventDayDatas.map((eventDayData) => ({ - timestamp: new Date(+eventDayData.timestamp * 1000), - totalAmountPaid: ethers.toBigInt(eventDayData.dailyHMTPayoutAmount), + timestamp: +eventDayData.timestamp * 1000, + totalAmountPaid: BigInt(eventDayData.dailyHMTPayoutAmount), totalCount: +eventDayData.dailyPayoutCount, averageAmountPerWorker: eventDayData.dailyWorkerCount === '0' - ? ethers.toBigInt(0) - : ethers.toBigInt(eventDayData.dailyHMTPayoutAmount) / - ethers.toBigInt(eventDayData.dailyWorkerCount), + ? BigInt(0) + : BigInt(eventDayData.dailyHMTPayoutAmount) / + BigInt(eventDayData.dailyWorkerCount), })), }; } catch (e: any) { @@ -337,14 +339,14 @@ export class StatisticsClient { * This function returns the statistical data of HMToken. * * ```ts - * type HMTStatistics = { - * totalTransferAmount: BigNumber; - * totalTransferCount: BigNumber; + * interface IHMTStatistics { + * totalTransferAmount: bigint; + * totalTransferCount: number; * totalHolders: number; * }; * ``` * - * @returns {Promise} HMToken statistics data. + * @returns {Promise} HMToken statistics data. * * **Code example** * @@ -361,17 +363,15 @@ export class StatisticsClient { * }); * ``` */ - async getHMTStatistics(): Promise { + async getHMTStatistics(): Promise { try { const { hmtokenStatistics } = await gqlFetch<{ hmtokenStatistics: HMTStatisticsData; }>(this.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY); return { - totalTransferAmount: ethers.toBigInt( - hmtokenStatistics.totalValueTransfered - ), - totalTransferCount: Number(hmtokenStatistics.totalTransferEventCount), + totalTransferAmount: BigInt(hmtokenStatistics.totalValueTransfered), + totalTransferCount: +hmtokenStatistics.totalTransferEventCount, totalHolders: +hmtokenStatistics.holders, }; } catch (e: any) { @@ -385,7 +385,7 @@ export class StatisticsClient { * **Input parameters** * * @param {IHMTHoldersParams} params HMT Holders params with filters and ordering - * @returns {Promise} List of HMToken holders. + * @returns {Promise} List of HMToken holders. * * **Code example** * @@ -404,7 +404,7 @@ export class StatisticsClient { * }))); * ``` */ - async getHMTHolders(params: IHMTHoldersParams = {}): Promise { + async getHMTHolders(params: IHMTHoldersParams = {}): Promise { try { const { address, orderDirection } = params; const query = GET_HOLDERS_QUERY(address); @@ -421,7 +421,7 @@ export class StatisticsClient { return holders.map((holder) => ({ address: holder.address, - balance: ethers.toBigInt(holder.balance), + balance: BigInt(holder.balance), })); } catch (e: any) { return throwError(e); @@ -444,8 +444,8 @@ export class StatisticsClient { * ``` * * ```ts - * type DailyHMTData = { - * timestamp: Date; + * interface IDailyHMT { + * timestamp: number; * totalTransactionAmount: bigint; * totalTransactionCount: number; * dailyUniqueSenders: number; @@ -454,7 +454,7 @@ export class StatisticsClient { * ``` * * @param {IStatisticsFilter} filter Statistics params with duration data - * @returns {Promise} Daily HMToken statistics data. + * @returns {Promise} Daily HMToken statistics data. * * **Code example** * @@ -475,9 +475,7 @@ export class StatisticsClient { * console.log('HMT statistics from 5/8 - 6/8:', hmtStatisticsRange); * ``` */ - async getHMTDailyData( - filter: IStatisticsFilter = {} - ): Promise { + async getHMTDailyData(filter: IStatisticsFilter = {}): Promise { try { const first = filter.first !== undefined ? Math.min(filter.first, 1000) : 10; @@ -495,10 +493,8 @@ export class StatisticsClient { }); return eventDayDatas.map((eventDayData) => ({ - timestamp: new Date(+eventDayData.timestamp * 1000), - totalTransactionAmount: ethers.toBigInt( - eventDayData.dailyHMTTransferAmount - ), + timestamp: +eventDayData.timestamp * 1000, + totalTransactionAmount: BigInt(eventDayData.dailyHMTTransferAmount), totalTransactionCount: +eventDayData.dailyHMTTransferCount, dailyUniqueSenders: +eventDayData.dailyUniqueSenders, dailyUniqueReceivers: +eventDayData.dailyUniqueReceivers, diff --git a/packages/sdk/typescript/human-protocol-sdk/src/transaction.ts b/packages/sdk/typescript/human-protocol-sdk/src/transaction.ts index 26f5cce107..fc8cd3e987 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/transaction.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/transaction.ts @@ -8,11 +8,16 @@ import { ErrorInvalidHashProvided, ErrorUnsupportedChainID, } from './error'; +import { TransactionData } from './graphql'; import { - GET_TRANSACTIONS_QUERY, GET_TRANSACTION_QUERY, + GET_TRANSACTIONS_QUERY, } from './graphql/queries/transaction'; -import { ITransaction, ITransactionsFilter } from './interfaces'; +import { + InternalTransaction, + ITransaction, + ITransactionsFilter, +} from './interfaces'; import { getSubgraphUrl, getUnixTimestamp } from './utils'; export class TransactionUtils { @@ -26,7 +31,7 @@ export class TransactionUtils { * from: string; * to: string; * timestamp: bigint; - * value: string; + * value: bigint; * method: string; * receiver?: string; * escrow?: string; @@ -35,6 +40,18 @@ export class TransactionUtils { * }; * ``` * + * ```ts + * type InternalTransaction = { + * from: string; + * to: string; + * value: bigint; + * method: string; + * receiver?: string; + * escrow?: string; + * token?: string; + * }; + * ``` + * * @param {ChainId} chainId The chain ID. * @param {string} hash The transaction hash. * @returns {Promise} - Returns the transaction details or null if not found. @@ -61,12 +78,13 @@ export class TransactionUtils { } const { transaction } = await gqlFetch<{ - transaction: ITransaction; + transaction: TransactionData | null; }>(getSubgraphUrl(networkData), GET_TRANSACTION_QUERY, { hash: hash.toLowerCase(), }); + if (!transaction) return null; - return transaction || null; + return mapTransaction(transaction); } /** @@ -92,6 +110,18 @@ export class TransactionUtils { * skip?: number; // (Optional) Number of transactions to skip. Default is 0. * orderDirection?: OrderDirection; // (Optional) Order of the results. Default is DESC. * } + * + * + * ```ts + * type InternalTransaction = { + * from: string; + * to: string; + * value: bigint; + * method: string; + * receiver?: string; + * escrow?: string; + * token?: string; + * }; * ``` * * ```ts @@ -101,7 +131,7 @@ export class TransactionUtils { * from: string; * to: string; * timestamp: bigint; - * value: string; + * value: bigint; * method: string; * receiver?: string; * escrow?: string; @@ -150,7 +180,7 @@ export class TransactionUtils { } const { transactions } = await gqlFetch<{ - transactions: ITransaction[]; + transactions: TransactionData[]; }>(getSubgraphUrl(networkData), GET_TRANSACTIONS_QUERY(filter), { fromAddress: filter?.fromAddress, toAddress: filter?.toAddress, @@ -172,6 +202,34 @@ export class TransactionUtils { return []; } - return transactions; + return transactions.map((transaction) => mapTransaction(transaction)); } } + +function mapTransaction(t: TransactionData): ITransaction { + const internalTransactions: InternalTransaction[] = ( + t.internalTransactions || [] + ).map((itx) => ({ + from: itx.from, + to: itx.to, + value: BigInt(itx.value), + method: itx.method, + receiver: itx.receiver, + escrow: itx.escrow, + token: itx.token, + })); + + return { + block: BigInt(t.block), + txHash: t.txHash, + from: t.from, + to: t.to, + timestamp: Number(t.timestamp) * 1000, + value: BigInt(t.value), + method: t.method, + receiver: t.receiver, + escrow: t.escrow, + token: t.token, + internalTransactions, + }; +} diff --git a/packages/sdk/typescript/human-protocol-sdk/src/types.ts b/packages/sdk/typescript/human-protocol-sdk/src/types.ts index 0b3b6f9811..14497c4bc5 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/types.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/types.ts @@ -143,83 +143,4 @@ export type NetworkData = { oldFactoryAddress: string; }; -/** - * Represents the response data for an escrow withdrawal. - */ -export type EscrowWithdraw = { - /** - * The hash of the transaction associated with the escrow withdrawal. - */ - txHash: string; - /** - * The address of the token used for the withdrawal. - */ - tokenAddress: string; - /** - * The amount withdrawn from the escrow. - */ - withdrawnAmount: bigint; -}; - -/** - * Represents a payout from an escrow. - */ -export type Payout = { - /** - * Unique identifier of the payout. - */ - id: string; - /** - * The address of the escrow associated with the payout. - */ - escrowAddress: string; - /** - * The address of the recipient who received the payout. - */ - recipient: string; - /** - * The amount paid to the recipient. - */ - amount: bigint; - /** - * The timestamp when the payout was created (in UNIX format). - */ - createdAt: number; -}; - -/** - * Represents a cancellation refund event. - */ -export type CancellationRefund = { - /** - * Unique identifier of the cancellation refund event. - */ - id: string; - /** - * The address of the escrow associated with the cancellation refund. - */ - escrowAddress: string; - /** - * The address of the receiver who received the refund. - */ - receiver: string; - /** - * The amount refunded to the receiver. - */ - amount: bigint; - /** - * The block number in which the cancellation refund event occurred. - */ - - block: number; - /** - * The timestamp when the cancellation refund event occurred (in UNIX format). - */ - timestamp: number; - /** - * The transaction hash of the cancellation refund event. - */ - txHash: string; -}; - export type TransactionLikeWithNonce = TransactionLike & { nonce: number }; diff --git a/packages/sdk/typescript/human-protocol-sdk/src/worker.ts b/packages/sdk/typescript/human-protocol-sdk/src/worker.ts index f3d75bac3b..60fa11ed5f 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/worker.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/worker.ts @@ -1,11 +1,12 @@ +import { ethers } from 'ethers'; import gqlFetch from 'graphql-request'; import { NETWORKS } from './constants'; import { ChainId, OrderDirection } from './enums'; import { ErrorInvalidAddress, ErrorUnsupportedChainID } from './error'; +import { WorkerData } from './graphql'; import { GET_WORKER_QUERY, GET_WORKERS_QUERY } from './graphql/queries/worker'; import { IWorker, IWorkersFilter } from './interfaces'; import { getSubgraphUrl } from './utils'; -import { ethers } from 'ethers'; export class WorkerUtils { /** @@ -37,12 +38,14 @@ export class WorkerUtils { } const { worker } = await gqlFetch<{ - worker: IWorker; + worker: WorkerData | null; }>(getSubgraphUrl(networkData), GET_WORKER_QUERY, { address: address.toLowerCase(), }); - return worker || null; + if (!worker) return null; + + return mapWorker(worker); } /** @@ -65,7 +68,7 @@ export class WorkerUtils { * type IWorker = { * id: string; * address: string; - * totalHMTAmountReceived: string; + * totalHMTAmountReceived: bigint; * payoutCount: number; * }; * ``` @@ -102,7 +105,7 @@ export class WorkerUtils { } const { workers } = await gqlFetch<{ - workers: IWorker[]; + workers: WorkerData[]; }>(getSubgraphUrl(networkData), GET_WORKERS_QUERY(filter), { address: filter?.address?.toLowerCase(), first: first, @@ -115,6 +118,15 @@ export class WorkerUtils { return []; } - return workers; + return workers.map((w) => mapWorker(w)); } } + +function mapWorker(w: WorkerData): IWorker { + return { + id: w.id, + address: w.address, + totalHMTAmountReceived: BigInt(w.totalHMTAmountReceived || 0), + payoutCount: Number(w.payoutCount || 0), + }; +} diff --git a/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts index 22790818ec..d97f270ff7 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts @@ -44,6 +44,7 @@ import { } from '../src/error'; import { EscrowClient, EscrowUtils } from '../src/escrow'; import { + EscrowData, GET_ESCROWS_QUERY, GET_ESCROW_BY_ADDRESS_QUERY, GET_PAYOUTS_QUERY, @@ -58,6 +59,7 @@ import { FAKE_URL, VALID_URL, } from './utils/constants'; +import { IEscrow, IPayout } from '../src/interfaces'; describe('EscrowClient', () => { let escrowClient: any, @@ -2808,19 +2810,32 @@ describe('EscrowUtils', () => { }); test('should successfully getEscrows', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Completed', token: '0x0', totalFundedAmount: '3', + createdAt: '1', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, { id: '2', @@ -2828,12 +2843,25 @@ describe('EscrowUtils', () => { amountPaid: '0', balance: '3', count: '2', - jobRequesterId: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Pending', token: '0x0', totalFundedAmount: '3', + createdAt: '1', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, ]; const gqlFetchSpy = vi @@ -2845,7 +2873,25 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getEscrows(filter); - expect(result).toEqual(escrows); + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : null, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_ESCROWS_QUERY(filter), @@ -2866,19 +2912,32 @@ describe('EscrowUtils', () => { }); test('should successfully getEscrows for the filter with status array', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Pending', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, { id: '2', @@ -2886,12 +2945,25 @@ describe('EscrowUtils', () => { amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Complete', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, ]; const gqlFetchSpy = vi @@ -2903,24 +2975,55 @@ describe('EscrowUtils', () => { status: [EscrowStatus.Pending, EscrowStatus.Complete], }); - expect(result).toEqual(escrows); + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : null, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalled(); }); test('should successfully getEscrows for the filter', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Completed', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, ]; const gqlFetchSpy = vi @@ -2932,12 +3035,30 @@ describe('EscrowUtils', () => { launcher: ethers.ZeroAddress, }); - expect(result).toEqual(escrows); + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : null, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalled(); }); test('should successfully getEscrows created by a specific job requester', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', @@ -2945,11 +3066,24 @@ describe('EscrowUtils', () => { balance: '0', count: '1', jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Completed', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, }, ]; const gqlFetchSpy = vi @@ -2961,24 +3095,55 @@ describe('EscrowUtils', () => { jobRequesterId: '1', }); - expect(result).toEqual(escrows); + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : null, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalled(); }); test('should successfully getEscrows with pagination', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Completed', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, { id: '2', @@ -2986,12 +3151,25 @@ describe('EscrowUtils', () => { amountPaid: '0', balance: '3', count: '2', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Pending', token: '0x0', totalFundedAmount: '3', + finalResultsHash: null, + finalResultsUrl: null, + intermediateResultsHash: null, + intermediateResultsUrl: null, + manifestHash: null, + manifest: null, + recordingOracle: null, + recordingOracleFee: null, + reputationOracle: null, + reputationOracleFee: null, + exchangeOracle: null, + exchangeOracleFee: null, + jobRequesterId: null, }, ]; const gqlFetchSpy = vi @@ -3005,7 +3183,25 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getEscrows(filter); - expect(result).toEqual(escrows); + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : null, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : null, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : null, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_ESCROWS_QUERY(filter), @@ -3026,14 +3222,14 @@ describe('EscrowUtils', () => { }); test('should successfully getEscrows with pagination over limits', async () => { - const escrows = [ + const escrows: EscrowData[] = [ { id: '1', address: '0x0', amountPaid: '3', balance: '0', count: '1', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Completed', @@ -3049,6 +3245,9 @@ describe('EscrowUtils', () => { exchangeOracleFee: '1', recordingOracleFee: '1', reputationOracleFee: '1', + jobRequesterId: '1', + manifest: null, + manifestHash: null, }, { id: '2', @@ -3056,7 +3255,7 @@ describe('EscrowUtils', () => { amountPaid: '0', balance: '3', count: '2', - jobRequesterId: '1', + createdAt: '1', factoryAddress: '0x0', launcher: '0x0', status: 'Pending', @@ -3072,6 +3271,9 @@ describe('EscrowUtils', () => { exchangeOracleFee: '1', recordingOracleFee: '1', reputationOracleFee: '1', + jobRequesterId: '1', + manifest: null, + manifestHash: null, }, ]; const gqlFetchSpy = vi @@ -3085,7 +3287,26 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getEscrows(filter); - expect(result).toEqual(escrows); + + const expected = escrows.map((e) => ({ + ...e, + amountPaid: BigInt(e.amountPaid), + balance: BigInt(e.balance), + count: Number(e.count), + totalFundedAmount: BigInt(e.totalFundedAmount), + createdAt: Number(e.createdAt) * 1000, + recordingOracleFee: e.recordingOracleFee + ? Number(e.recordingOracleFee) + : undefined, + reputationOracleFee: e.reputationOracleFee + ? Number(e.reputationOracleFee) + : undefined, + exchangeOracleFee: e.exchangeOracleFee + ? Number(e.exchangeOracleFee) + : undefined, + chainId: ChainId.POLYGON_AMOY, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_ESCROWS_QUERY(filter), @@ -3148,6 +3369,10 @@ describe('EscrowUtils', () => { exchangeOracleFee: '1', recordingOracleFee: '1', reputationOracleFee: '1', + jobRequesterId: null, + manifest: null, + manifestHash: null, + createdAt: '0', }; const gqlFetchSpy = vi .spyOn(gqlFetch, 'default') @@ -3155,7 +3380,22 @@ describe('EscrowUtils', () => { const result = await EscrowUtils.getEscrow(chainId, ethers.ZeroAddress); - expect(result).toEqual({ ...escrow, chainId }); + const expected: IEscrow = { + ...escrow, + amountPaid: 3n, + balance: 0n, + count: 1, + totalFundedAmount: 3n, + recordingOracleFee: 1, + reputationOracleFee: 1, + exchangeOracleFee: 1, + createdAt: 0, + chainId, + jobRequesterId: null, + manifest: null, + manifestHash: null, + }; + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( NETWORKS[ChainId.LOCALHOST]?.subgraphUrl, GET_ESCROW_BY_ADDRESS_QUERY(), @@ -3207,7 +3447,12 @@ describe('EscrowUtils', () => { const result = await EscrowUtils.getStatusEvents({ chainId: ChainId.LOCALHOST, }); - expect(result).toEqual(pendingEvents); + const expectedResults = pendingEvents.map((event) => ({ + ...event, + status: EscrowStatus.Pending, + timestamp: +event.timestamp * 1000, + })); + expect(result).toEqual(expectedResults); expect(gqlFetchSpy).toHaveBeenCalled(); }); @@ -3240,7 +3485,12 @@ describe('EscrowUtils', () => { to: toDate, }); - expect(result).toEqual(pendingEvents); + const expectedResults = pendingEvents.map((event) => ({ + ...event, + status: EscrowStatus.Pending, + timestamp: +event.timestamp * 1000, + })); + expect(result).toEqual(expectedResults); expect(gqlFetchSpy).toHaveBeenCalled(); }); @@ -3274,7 +3524,12 @@ describe('EscrowUtils', () => { to: toDate, }); - expect(result).toEqual(partialEvents); + const expectedResults = partialEvents.map((event) => ({ + ...event, + status: EscrowStatus.Partial, + timestamp: +event.timestamp * 1000, + })); + expect(result).toEqual(expectedResults); expect(gqlFetchSpy).toHaveBeenCalled(); }); @@ -3307,7 +3562,12 @@ describe('EscrowUtils', () => { to: toDate, }); - expect(result).toEqual(pendingEvents); + const expectedResults = pendingEvents.map((event) => ({ + ...event, + status: EscrowStatus.Pending, + timestamp: +event.timestamp * 1000, + })); + expect(result).toEqual(expectedResults); expect(gqlFetchSpy).toHaveBeenCalled(); }); }); @@ -3372,7 +3632,15 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getPayouts(filter); - expect(result).toEqual(payouts); + + const expected: IPayout[] = payouts.map((payout) => ({ + id: payout.id, + escrowAddress: payout.escrowAddress, + recipient: payout.recipient, + amount: BigInt(payout.amount), + createdAt: Number(payout.createdAt) * 1000, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_PAYOUTS_QUERY(filter), @@ -3412,7 +3680,15 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getPayouts(filter); - expect(result).toEqual(payouts); + + const expected: IPayout[] = payouts.map((payout) => ({ + id: payout.id, + escrowAddress: payout.escrowAddress, + recipient: payout.recipient, + amount: BigInt(payout.amount), + createdAt: Number(payout.createdAt) * 1000, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_PAYOUTS_QUERY(filter), @@ -3457,7 +3733,15 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getPayouts(filter); - expect(result).toEqual(payouts); + + const expected: IPayout[] = payouts.map((payout) => ({ + id: payout.id, + escrowAddress: payout.escrowAddress, + recipient: payout.recipient, + amount: BigInt(payout.amount), + createdAt: Number(payout.createdAt) * 1000, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_PAYOUTS_QUERY(filter), @@ -3502,7 +3786,15 @@ describe('EscrowUtils', () => { }; const result = await EscrowUtils.getPayouts(filter); - expect(result).toEqual(payouts); + + const expected: IPayout[] = payouts.map((payout) => ({ + id: payout.id, + escrowAddress: payout.escrowAddress, + recipient: payout.recipient, + amount: BigInt(payout.amount), + createdAt: Number(payout.createdAt) * 1000, + })); + expect(result).toEqual(expected); expect(gqlFetchSpy).toHaveBeenCalledWith( 'https://api.studio.thegraph.com/query/74256/amoy/version/latest', GET_PAYOUTS_QUERY(filter), diff --git a/packages/sdk/typescript/human-protocol-sdk/test/operator.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/operator.test.ts index 16119abd3c..690c700b55 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/operator.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/operator.test.ts @@ -20,14 +20,9 @@ import { GET_LEADERS_QUERY, GET_REPUTATION_NETWORK_QUERY, } from '../src/graphql/queries/operator'; -import { - IOperator, - IOperatorsFilter, - IOperatorSubgraph, - IReputationNetworkSubgraph, - IReward, -} from '../src/interfaces'; +import { IOperator, IOperatorsFilter, IReward } from '../src/interfaces'; import { OperatorUtils } from '../src/operator'; +import { IOperatorSubgraph, IReputationNetworkSubgraph } from '../src/graphql'; vi.mock('graphql-request', () => { return { @@ -42,7 +37,7 @@ describe('OperatorUtils', () => { const mockOperatorSubgraph: IOperatorSubgraph = { id: stakerAddress, address: stakerAddress, - amountJobsProcessed: ethers.parseEther('25'), + amountJobsProcessed: ethers.parseEther('25').toString(), jobTypes: ['type1', 'type2'], registrationNeeded: true, registrationInstructions: 'www.google.com', @@ -53,13 +48,20 @@ describe('OperatorUtils', () => { }, ], staker: { - stakedAmount: ethers.parseEther('100'), - lockedAmount: ethers.parseEther('25'), - lockedUntilTimestamp: ethers.toBigInt(0), - withdrawnAmount: ethers.parseEther('25'), - slashedAmount: ethers.parseEther('25'), - lastDepositTimestamp: ethers.toBigInt(0), + stakedAmount: ethers.parseEther('100').toString(), + lockedAmount: ethers.parseEther('25').toString(), + lockedUntilTimestamp: '0', + withdrawnAmount: ethers.parseEther('25').toString(), + slashedAmount: ethers.parseEther('25').toString(), + lastDepositTimestamp: '0', }, + category: null, + fee: null, + name: null, + publicKey: null, + role: null, + url: null, + webhookUrl: null, }; const operator: IOperator = { id: stakerAddress, @@ -73,9 +75,16 @@ describe('OperatorUtils', () => { chainId: ChainId.LOCALHOST, stakedAmount: ethers.parseEther('100'), lockedAmount: ethers.parseEther('25'), - lockedUntilTimestamp: ethers.toBigInt(0), + lockedUntilTimestamp: 0, withdrawnAmount: ethers.parseEther('25'), slashedAmount: ethers.parseEther('25'), + role: null, + fee: null, + publicKey: null, + webhookUrl: null, + url: null, + name: null, + category: null, }; describe('getOperator', () => { diff --git a/packages/sdk/typescript/human-protocol-sdk/test/staking.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/staking.test.ts index b0eaa4448f..a3e85fa70e 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/staking.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/staking.test.ts @@ -22,6 +22,7 @@ import { } from './utils/constants'; import { IStaker, IStakersFilter } from '../src/interfaces'; import { StakingUtils } from '../src/staking'; +import { StakerData } from '../src/graphql'; vi.mock('graphql-request', () => { return { @@ -564,14 +565,15 @@ describe('StakingUtils', () => { const invalidAddress = 'InvalidAddress'; describe('getStaker', () => { - const mockStaker: IStaker = { + const mockStaker: StakerData = { + id: '0x0987654321098765432109876543210987654320', address: stakerAddress, - stakedAmount: 1000n, - lockedAmount: 100n, - lockedUntil: 1234567890n, - withdrawableAmount: 900n, - slashedAmount: 0n, - lastDepositTimestamp: 1234567890n, + stakedAmount: '1000', + lockedAmount: '100', + lockedUntilTimestamp: '1234567890', + withdrawnAmount: '900', + slashedAmount: '0', + lastDepositTimestamp: '1234567890', }; test('should return staker information', async () => { @@ -589,7 +591,16 @@ describe('StakingUtils', () => { expect.anything(), { id: stakerAddress.toLowerCase() } ); - expect(result).toEqual(mockStaker); + const expectedStaker: IStaker = { + address: mockStaker.address, + stakedAmount: BigInt(mockStaker.stakedAmount), + lockedAmount: BigInt(mockStaker.lockedAmount), + withdrawableAmount: BigInt(mockStaker.withdrawnAmount), + slashedAmount: BigInt(mockStaker.slashedAmount), + lockedUntil: Number(mockStaker.lockedUntilTimestamp) * 1000, + lastDepositTimestamp: Number(mockStaker.lastDepositTimestamp) * 1000, + }; + expect(result).toEqual(expectedStaker); }); test('should throw an error for an invalid staker address', async () => { @@ -621,24 +632,26 @@ describe('StakingUtils', () => { }); describe('getStakers', () => { - const mockStakers: IStaker[] = [ + const mockStakers: StakerData[] = [ { + id: '0x0987654321098765432109876543210987654320', address: stakerAddress, - stakedAmount: 1000n, - lockedAmount: 100n, - lockedUntil: 1234567890n, - withdrawableAmount: 900n, - slashedAmount: 0n, - lastDepositTimestamp: 1234567890n, + stakedAmount: '1000', + lockedAmount: '100', + lockedUntilTimestamp: '1234567890', + withdrawnAmount: '900', + slashedAmount: '0', + lastDepositTimestamp: '1234567890', }, { + id: '0x0987654321098765432109876543210987654321', address: '0x0987654321098765432109876543210987654321', - stakedAmount: 2000n, - lockedAmount: 200n, - lockedUntil: 1234567891n, - withdrawableAmount: 1800n, - slashedAmount: 0n, - lastDepositTimestamp: 1234567890n, + stakedAmount: '2000', + lockedAmount: '200', + lockedUntilTimestamp: '1234567891', + withdrawnAmount: '1800', + slashedAmount: '0', + lastDepositTimestamp: '1234567890', }, ]; @@ -672,7 +685,16 @@ describe('StakingUtils', () => { skip: 0, }) ); - expect(result).toEqual(mockStakers); + const expectedStakers = mockStakers.map((s) => ({ + address: s.address, + stakedAmount: BigInt(s.stakedAmount), + lockedAmount: BigInt(s.lockedAmount), + withdrawableAmount: BigInt(s.withdrawnAmount), + slashedAmount: BigInt(s.slashedAmount), + lockedUntil: Number(s.lockedUntilTimestamp) * 1000, + lastDepositTimestamp: Number(s.lastDepositTimestamp) * 1000, + })); + expect(result).toEqual(expectedStakers); }); test('should return an empty array if no stakers found', async () => { diff --git a/packages/sdk/typescript/human-protocol-sdk/test/statistics.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/statistics.test.ts index 2201383242..8d6a741df2 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/statistics.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/statistics.test.ts @@ -80,7 +80,7 @@ describe('StatisticsClient', () => { totalEscrows: 1, dailyEscrowsData: [ { - timestamp: new Date(1000), + timestamp: 1000, escrowsTotal: 1, escrowsPending: 1, escrowsSolved: 1, @@ -141,7 +141,7 @@ describe('StatisticsClient', () => { expect(result).toEqual({ dailyWorkersData: [ { - timestamp: new Date(1000), + timestamp: 1000, activeWorkers: 4, }, ], @@ -200,7 +200,7 @@ describe('StatisticsClient', () => { expect(result).toEqual({ dailyPaymentsData: [ { - timestamp: new Date(1000), + timestamp: 1000, totalAmountPaid: ethers.toBigInt(100), totalCount: 4, averageAmountPerWorker: ethers.toBigInt(25), @@ -453,7 +453,7 @@ describe('StatisticsClient', () => { expect(result).toEqual([ { - timestamp: new Date(1000), + timestamp: 1000, totalTransactionAmount: ethers.toBigInt(100), totalTransactionCount: 4, dailyUniqueSenders: 100, diff --git a/packages/sdk/typescript/human-protocol-sdk/test/transaction.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/transaction.test.ts index 31b015d41c..3cbea573dc 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/transaction.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/transaction.test.ts @@ -15,6 +15,7 @@ import { ErrorCannotUseDateAndBlockSimultaneously, ErrorInvalidHashProvided, } from '../src/error'; +import { TransactionData } from '../src/graphql'; import { GET_TRANSACTION_QUERY } from '../src/graphql/queries/transaction'; import { ITransaction, ITransactionsFilter } from '../src/interfaces'; import { TransactionUtils } from '../src/transaction'; @@ -24,20 +25,26 @@ describe('TransactionUtils', () => { const txHash = '0x62dD51230A30401C455c8398d06F85e4EaB6309f'; const invalidHash = 'InvalidHash'; - const mockTransaction: ITransaction = { - block: 12345n, + const mockTransaction = { + block: '12345', txHash: txHash, from: '0x1234567890123456789012345678901234567890', to: '0x0987654321098765432109876543210987654321', - timestamp: 1625247600n, + timestamp: '1625247600', value: '1000000000000000000', method: 'transfer', + receiver: null, + escrow: null, + token: null, internalTransactions: [ { from: '0x1234567890123456789012345678901234567890', to: '0x1234567890123456789012345678901234567891', value: '1000000000000000000', method: 'transfer', + receiver: null, + escrow: null, + token: null, }, ], }; @@ -59,7 +66,30 @@ describe('TransactionUtils', () => { hash: txHash.toLowerCase(), } ); - expect(result).toEqual(mockTransaction); + const expected: ITransaction = { + block: 12345n, + txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual(expected); }); test('should throw an error for an invalid transaction hash', async () => { @@ -81,20 +111,27 @@ describe('TransactionUtils', () => { }); describe('getTransactions', () => { - const mockTransaction: ITransaction = { - block: 12345n, + const mockTransaction: TransactionData = { + block: '12345', txHash: '0x62dD51230A30401C455c8398d06F85e4EaB6309f', from: '0x1234567890123456789012345678901234567890', to: '0x0987654321098765432109876543210987654321', - timestamp: 1625247600n, + timestamp: '1625247600', value: '1000000000000000000', method: 'transfer', + receiver: null, + escrow: null, + token: null, internalTransactions: [ { from: '0x1234567890123456789012345678901234567890', to: '0x1234567890123456789012345678901234567891', value: '1000000000000000000', method: 'transfer', + receiver: null, + escrow: null, + token: null, + id: null, }, ], }; @@ -129,7 +166,31 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); + // type assertions (bigint fields) }); test('should return an array of transactions with date filter', async () => { @@ -164,7 +225,30 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); }); test('should return an array of transactions with address filter', async () => { @@ -198,7 +282,30 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); }); test('should return an array of transactions filtered by method', async () => { @@ -232,7 +339,30 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected]); }); test('should return an array of transactions filtered by escrow', async () => { @@ -266,7 +396,30 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected]); }); test('should return an array of transactions filtered by token', async () => { @@ -300,7 +453,30 @@ describe('TransactionUtils', () => { skip: 0, } ); - expect(result).toEqual([mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected]); }); test('should throw an error if both date and block filters are used', async () => { @@ -362,7 +538,30 @@ describe('TransactionUtils', () => { skip: 10, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); }); test('should return an array of transactions with pagination over limits', async () => { @@ -395,7 +594,30 @@ describe('TransactionUtils', () => { skip: 10, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); }); test('should return an array of transactions with pagination and filters', async () => { @@ -431,7 +653,30 @@ describe('TransactionUtils', () => { skip: 5, } ); - expect(result).toEqual([mockTransaction, mockTransaction]); + const expected: ITransaction = { + block: 12345n, + txHash: mockTransaction.txHash, + from: mockTransaction.from, + to: mockTransaction.to, + timestamp: 1625247600000, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + internalTransactions: [ + { + from: mockTransaction.internalTransactions[0].from, + to: mockTransaction.internalTransactions[0].to, + value: 1000000000000000000n, + method: 'transfer', + receiver: null, + escrow: null, + token: null, + }, + ], + }; + expect(result).toEqual([expected, expected]); }); }); }); diff --git a/packages/sdk/typescript/human-protocol-sdk/test/worker.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/worker.test.ts index f9a2b7d04e..e306650345 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/worker.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/worker.test.ts @@ -9,6 +9,7 @@ import { } from '../src/graphql/queries/worker'; import { IWorker, IWorkersFilter } from '../src/interfaces'; import { WorkerUtils } from '../src/worker'; +import { WorkerData } from '../src/graphql'; vi.mock('graphql-request', () => { return { @@ -19,10 +20,10 @@ vi.mock('graphql-request', () => { describe('WorkerUtils', () => { describe('getWorker', () => { const workerAddress = '0x1234567890abcdef1234567890abcdef12345678'; - const mockWorker: IWorker = { + const mockWorker: WorkerData = { id: workerAddress, address: workerAddress, - totalHMTAmountReceived: 1000, + totalHMTAmountReceived: '1000', payoutCount: 10, }; @@ -43,7 +44,11 @@ describe('WorkerUtils', () => { address: workerAddress.toLowerCase(), } ); - expect(result).toEqual(mockWorker); + const expected: IWorker = { + ...mockWorker, + totalHMTAmountReceived: BigInt(mockWorker.totalHMTAmountReceived || 0), + }; + expect(result).toEqual(expected); }); test('should return null if worker is not found', async () => { @@ -85,17 +90,17 @@ describe('WorkerUtils', () => { }); describe('getWorkers', () => { - const mockWorkers: IWorker[] = [ + const mockWorkers: WorkerData[] = [ { id: '0x1234567890abcdef1234567890abcdef12345678', address: '0x1234567890abcdef1234567890abcdef12345678', - totalHMTAmountReceived: 1000, + totalHMTAmountReceived: '1000', payoutCount: 10, }, { id: '0xabcdefabcdefabcdefabcdefabcdefabcdef', address: '0xabcdefabcdefabcdefabcdefabcdefabcdef', - totalHMTAmountReceived: 2000, + totalHMTAmountReceived: '2000', payoutCount: 20, }, ]; @@ -126,7 +131,11 @@ describe('WorkerUtils', () => { orderDirection: 'asc', } ); - expect(result).toEqual(mockWorkers); + const expected: IWorker[] = mockWorkers.map((mockWorker) => ({ + ...mockWorker, + totalHMTAmountReceived: BigInt(mockWorker.totalHMTAmountReceived || 0), + })); + expect(result).toEqual(expected); }); test('should return an empty list if no workers are found', async () => { @@ -194,7 +203,12 @@ describe('WorkerUtils', () => { orderDirection: 'desc', } ); - expect(result).toEqual(mockWorkers); + + const expected: IWorker[] = mockWorkers.map((mockWorker) => ({ + ...mockWorker, + totalHMTAmountReceived: BigInt(mockWorker.totalHMTAmountReceived || 0), + })); + expect(result).toEqual(expected); }); }); });