diff --git a/packages/client/src/escrow/graphql/queries.ts b/packages/client/src/escrow/graphql/queries.ts index e17d9a2..ec670d1 100644 --- a/packages/client/src/escrow/graphql/queries.ts +++ b/packages/client/src/escrow/graphql/queries.ts @@ -2,15 +2,39 @@ export const getProtocolAndPlatformsFees = ( originServicePlatformId: string, originValidatedProposalPlatformId: string, ): string => ` - { - protocols { - protocolEscrowFeeRate - } - servicePlatform: platform(id:${originServicePlatformId}){ - originServiceFeeRate - } - proposalPlatform: platform(id:${originValidatedProposalPlatformId}){ - originValidatedProposalFeeRate - } +{ + protocols { + protocolEscrowFeeRate + } + servicePlatform: platform(id:${originServicePlatformId}){ + originServiceFeeRate + } + proposalPlatform: platform(id:${originValidatedProposalPlatformId}){ + originValidatedProposalFeeRate + } +} +`; + +export const getPaymentsByService = (serviceId: string, paymentType?: string) => { + let condition = `where: {service: "${serviceId}"`; + paymentType ? (condition += `, paymentType: "${paymentType}"`) : ''; + condition += '}, orderBy: id, orderDirection: asc'; + const query = ` +{ + payments(${condition}) { + id + amount + rateToken { + address + decimals + name + symbol } - `; + paymentType + transactionHash + createdAt + } +} +`; + return query; +}; diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index 5264347..b3977d5 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -6,7 +6,7 @@ import { Service } from '../services'; import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; -import { getProtocolAndPlatformsFees } from './graphql/queries'; +import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; export class Escrow { graphQlClient: GraphQLClient; @@ -59,21 +59,21 @@ export class Escrow { let tx, cid = proposal.cid; - const protocolAndPlatformsFeesResponse = await this.graphQlClient.get( - getProtocolAndPlatformsFees(proposal.service.platform.id, proposal.platform.id), + const protocolAndPlatformsFees = await this.getProtocolAndPlatformsFees( + proposal.service.platform.id, proposal.platform.id ); - console.log('SDK: fees', protocolAndPlatformsFeesResponse); + console.log('SDK: fees', protocolAndPlatformsFees); - if (!protocolAndPlatformsFeesResponse.data) { + if (!protocolAndPlatformsFees.data) { throw Error('Unable to fetch fees'); } const approvalAmount = calculateApprovalAmount( proposal.rateAmount, - protocolAndPlatformsFeesResponse.data.servicePlatform.originServiceFeeRate, - protocolAndPlatformsFeesResponse.data.proposalPlatform.originValidatedProposalFeeRate, - protocolAndPlatformsFeesResponse.data.protocols[0].protocolEscrowFeeRate, + protocolAndPlatformsFees.servicePlatform.originServiceFeeRate, + protocolAndPlatformsFees.proposalPlatform.originValidatedProposalFeeRate, + protocolAndPlatformsFees.protocols[0].protocolEscrowFeeRate, ); console.log('SDK: escrow seeking approval for amount: ', approvalAmount); @@ -187,4 +187,24 @@ export class Escrow { return tx; } + + public async getProtocolAndPlatformsFees( + originServicePlatformId: string, + originValidatedProposalPlatformId: string, + ): Promise { + const query = getProtocolAndPlatformsFees(originServicePlatformId, originValidatedProposalPlatformId); + + const response = await this.graphQlClient.get(query); + + return response?.data || null; + } + + public async getByService(serviceId: string, paymentType?: string): Promise { + const query = getPaymentsByService(serviceId, paymentType); + + const response = await this.graphQlClient.get(query); + + return response?.data?.payments || null + } + } diff --git a/packages/client/src/escrow/types/index.ts b/packages/client/src/escrow/types/index.ts index af6fdee..9e74b15 100644 --- a/packages/client/src/escrow/types/index.ts +++ b/packages/client/src/escrow/types/index.ts @@ -8,4 +8,9 @@ export interface IEscrow { ): Promise; release(serviceId: string, amount: bigint, userId: number): Promise; reimburse(serviceId: string, amount: bigint, userId: number): Promise; + getProtocolAndPlatformsFees( + originServicePlatformId: string, + originValidatedProposalPlatformId: string, + ): Promise; + getByService(serviceId: string, paymentType?: string): Promise; } diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 114260b..4ead8ce 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -16,8 +16,8 @@ import { IProfile } from './profile/types'; import { Escrow } from './escrow'; import { IEscrow } from './escrow/types'; import { IService, Service } from './services'; -import { IReview } from './review/types'; -import { Review } from './review'; +import { IReview } from './reviews/types'; +import { Review } from './reviews'; /** * Main client for interacting with the TalentLayer protocol. @@ -93,7 +93,7 @@ export class TalentLayerClient { /** * Provides access to service functionalities. - * @type {IDispute} + * @type {IService} */ // @ts-ignore diff --git a/packages/client/src/profile/graphql/index.ts b/packages/client/src/profile/graphql/index.ts index 1d9b87d..93b889e 100644 --- a/packages/client/src/profile/graphql/index.ts +++ b/packages/client/src/profile/graphql/index.ts @@ -2,31 +2,149 @@ import { Hash } from 'viem'; export const getProfileByAddress = (address: Hash) => ` - { - users(where: {address: "${address.toLocaleLowerCase()}"}, first: 1) { - id - address - handle - rating - delegates - userStats { - numReceivedReviews - } - updatedAt - createdAt - description { - about - role - name - country - headline - id - image_url - video_url - title - timezone - skills_raw - } +{ + users(where: {address: "${address.toLocaleLowerCase()}"}, first: 1) { + id + address + handle + rating + delegates + userStats { + numReceivedReviews + } + updatedAt + createdAt + description { + about + role + name + country + headline + id + image_url + video_url + title + timezone + skills_raw + } + } +} +`; + +export const getProfiles = (numberPerPage?: number, offset?: number, searchQuery?: string) => { + const pagination = numberPerPage ? 'first: ' + numberPerPage + ', skip: ' + offset : ''; + let condition = ', where: {'; + condition += searchQuery ? `, handle_contains_nocase: "${searchQuery}"` : ''; + condition += '}'; + + return ` +{ + users(orderBy: rating, orderDirection: desc ${pagination} ${condition}) { + id + address + handle + userStats { + numReceivedReviews + } + rating + } +} +`; +}; + +export const getProfileById = (id: string) => ` +{ + user(id: "${id}") { + id + address + handle + rating + delegates + userStats { + numReceivedReviews + } + updatedAt + createdAt + description { + about + role + name + country + headline + id + image_url + video_url + title + timezone + skills_raw + web3mailPreferences{ + activeOnNewService + activeOnNewProposal + activeOnProposalValidated + activeOnFundRelease + activeOnReview + activeOnPlatformMarketing + activeOnProtocolMarketing + } + } + } +} +`; + +export const getUserTotalGains = (id: string) => ` +{ + user(id: "${id}") { + totalGains{ + id + totalGain + token { + id + name + symbol + decimals } - } - `; + } + } +} +`; + +export const getPaymentsForUser = ( + userId: string, + numberPerPage?: number, + offset?: number, + startDate?: string, + endDate?: string, +) => { + const pagination = numberPerPage ? 'first: ' + numberPerPage + ', skip: ' + offset : ''; + + const startDataCondition = startDate ? `, createdAt_gte: "${startDate}"` : ''; + const endDateCondition = endDate ? `, createdAt_lte: "${endDate}"` : ''; + + const query = ` +{ + payments(where: { + service_: {seller: "${userId}"} + ${startDataCondition} + ${endDateCondition} + }, + orderBy: createdAt orderDirection: desc ${pagination} ) { + id, + rateToken { + address + decimals + name + symbol + } + amount + transactionHash + paymentType + createdAt + service { + id, + cid + } + } +} +`; + return query; +}; diff --git a/packages/client/src/profile/index.ts b/packages/client/src/profile/index.ts index d9fe239..17094f5 100644 --- a/packages/client/src/profile/index.ts +++ b/packages/client/src/profile/index.ts @@ -4,7 +4,7 @@ import IPFSClient from '../ipfs'; import { getProtocolById } from '../platform/graphql/queries'; import { ClientTransactionResponse } from '../types'; import { ViemClient } from '../viem'; -import { getProfileByAddress } from './graphql'; +import { getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from './graphql'; import { TalentLayerProfile } from './types'; export class Profile { @@ -37,6 +37,14 @@ export class Profile { return null; } + + public async getById(userId: string): Promise { + const query = getProfileById(userId); + + const response = await this.graphQlClient.get(query); + + return response?.data?.user || null; + } public async upload(profileData: TalentLayerProfile): Promise { return this.ipfsClient.post(JSON.stringify(profileData)); @@ -84,4 +92,51 @@ export class Profile { BigInt(fee), ); } + + public async getBy(params: { + numberPerPage?: number; + offset?: number; + searchQuery?: string; + }): Promise { + const query = getProfiles(params.numberPerPage, params.offset, params.searchQuery); + + return this.graphQlClient.get(query); + } + + public async getTotalGains(userId: string): Promise { + const query = getUserTotalGains(userId); + + const response = await this.graphQlClient.get(query); + + return response?.data?.user?.totalGains || null; + } + + public async getPayments( + userId: string, + numberPerPage?: number, + offset?: number, + startDate?: string, + endDate?: string, + ): Promise { + const query = getPaymentsForUser(userId, numberPerPage, offset, startDate, endDate) + + const response = await this.graphQlClient.get(query); + + return response?.data?.payments || null + } + + public async getMintFees(): Promise { + const query = ` + { + protocols { + userMintFee, + shortHandlesMaxPrice + } + } + `; + + const response = await this.graphQlClient.get(query); + + return response?.data || null; + } } diff --git a/packages/client/src/profile/types/index.ts b/packages/client/src/profile/types/index.ts index 55009ad..d6383fa 100644 --- a/packages/client/src/profile/types/index.ts +++ b/packages/client/src/profile/types/index.ts @@ -14,6 +14,15 @@ export type TalentLayerProfile = { export interface IProfile { upload(profileData: TalentLayerProfile): Promise; getByAddress(address: `0x${string}`): Promise; + getById(userId: string): Promise; create(handle: string): Promise; update(profileData: TalentLayerProfile, userId: string): Promise; + getBy(params: { + numberPerPage?: number; + offset?: number; + searchQuery?: string; + }): Promise; + getTotalGains(userId: string): Promise; + getPayments(userId: string, numberPerPage?: number, offset?: number, startDate?: string, endDate?: string): Promise + getMintFees(): Promise; } diff --git a/packages/client/src/proposals/graphql/index.ts b/packages/client/src/proposals/graphql/index.ts index 2d3ba50..0ad8e24 100644 --- a/packages/client/src/proposals/graphql/index.ts +++ b/packages/client/src/proposals/graphql/index.ts @@ -35,3 +35,92 @@ export const getProposalById = (id: string) => ` } } `; + +export const getAllProposalsByServiceId = (id: string) => ` +{ + proposals(where: {service_: {id: "${id}"}}) { + service { + id, + cid + buyer { + id + } + platform { + id + } + } + cid + id + status + rateToken { + address + decimals + name + symbol + } + rateAmount + createdAt + updatedAt + seller { + id + handle + address + cid + rating + userStats { + numReceivedReviews + } + } + description { + id + about + expectedHours + startDate + video_url + } + expirationDate + platform { + id + } + } +} +`; + +export const getAllProposalsByUser = (id: string) => ` +{ + proposals(where: {seller: "${id}", status: "Pending"}) { + id + rateAmount + rateToken { + address + decimals + name + symbol + } + status + cid + createdAt + seller { + id + handle + } + service { + id + cid + createdAt + buyer { + id + handle + } + } + description { + id + about + expectedHours + startDate + video_url + } + expirationDate + } +} +`; diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index f0eb2e6..59143d7 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -4,7 +4,7 @@ import { Platform } from '../platform'; import { ClientTransactionResponse } from '../types'; import { getSignature } from '../utils/signature'; import { ViemClient } from '../viem'; -import { getProposalById } from './graphql'; +import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from './graphql'; import { CreateProposalArgs, ProposalDetails } from './types'; export class Proposal { @@ -40,6 +40,22 @@ export class Proposal { return null; } + public async getByServiceId(serviceId: string): Promise { + const query = getAllProposalsByServiceId(serviceId) + + const response = await this.graphQlClient.get(query); + + return response?.data?.proposals || null + } + + public async getByUser(userId: string): Promise { + const query = getAllProposalsByUser(userId) + + const response = await this.graphQlClient.get(query); + + return response?.data?.proposals || null + } + public async getSignature(args: CreateProposalArgs): Promise { return getSignature('createProposal', args, this.signatureApiUrl); } diff --git a/packages/client/src/proposals/types/index.ts b/packages/client/src/proposals/types/index.ts index 9536ae9..d0f8519 100644 --- a/packages/client/src/proposals/types/index.ts +++ b/packages/client/src/proposals/types/index.ts @@ -1,4 +1,4 @@ -import { ClientTransactionResponse } from '../../types'; +import { ClientTransactionResponse } from "../../types"; export type ProposalDetails = { about: string; @@ -17,13 +17,17 @@ export interface IProposal { getOne(proposalId: string): Promise; + getByServiceId(serviceId: string): Promise; + + getByUser(userId: string): Promise; + create( proposalDetails: ProposalDetails, userId: string, serviceId: string, rateToken: string, rateAmount: string, - expirationDate: string, + expirationDate: string ): Promise; update( @@ -32,7 +36,7 @@ export interface IProposal { serviceId: string, rateToken: string, rateAmount: string, - expirationDate: string, + expirationDate: string ): Promise; upload(proposalDetails: ProposalDetails): Promise; diff --git a/packages/client/src/reviews/graphql/index.ts b/packages/client/src/reviews/graphql/index.ts new file mode 100644 index 0000000..c2bdb8b --- /dev/null +++ b/packages/client/src/reviews/graphql/index.ts @@ -0,0 +1,21 @@ +export const getReviewsByService = (serviceId: string) => ` +{ + reviews(where: { service: "${serviceId}" }, orderBy: id, orderDirection: desc) { + id + rating + createdAt + service { + id + status + } + to { + id + handle + } + description{ + id + content + } + } +} +`; diff --git a/packages/client/src/review/index.ts b/packages/client/src/reviews/index.ts similarity index 83% rename from packages/client/src/review/index.ts rename to packages/client/src/reviews/index.ts index 4dfb5f3..eaab44f 100644 --- a/packages/client/src/review/index.ts +++ b/packages/client/src/reviews/index.ts @@ -2,6 +2,7 @@ import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; import { ClientTransactionResponse } from '../types'; import { ViemClient } from '../viem'; +import { getReviewsByService } from './graphql'; import { ReviewDetails } from './types'; export class Review { @@ -55,4 +56,12 @@ export class Review { throw new Error(Review.CREATE_ERROR); } + + public async getByService(serviceId: string): Promise { + const query = getReviewsByService(serviceId); + + const response = await this.graphQlClient.get(query); + + return response?.data || null; + } } diff --git a/packages/client/src/review/types/index.ts b/packages/client/src/reviews/types/index.ts similarity index 85% rename from packages/client/src/review/types/index.ts rename to packages/client/src/reviews/types/index.ts index 9995345..e0f2c88 100644 --- a/packages/client/src/review/types/index.ts +++ b/packages/client/src/reviews/types/index.ts @@ -12,4 +12,6 @@ export interface IReview { serviceId: string, userId: string, ): Promise; + + getByService(serviceId: string): Promise }