Skip to content

Commit

Permalink
[SDK] Enable User to User Grants [PAY-2544] (#7889)
Browse files Browse the repository at this point in the history
Co-authored-by: Nikki Kang <kangaroo233@gmail.com>
  • Loading branch information
nicoback2 and nicoback authored Mar 20, 2024
1 parent 184c576 commit 8fb1fd9
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 5 deletions.
94 changes: 91 additions & 3 deletions packages/libs/src/sdk/api/grants/GrantsApi.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import type { UsersApi, Configuration, User } from '../../api/generated/default'
import type { AuthService, EntityManagerService } from '../../services'
import { Action, EntityType } from '../../services/EntityManager/types'
import { encodeHashId } from '../../utils/hashId'
import { parseParams } from '../../utils/parseParams'
import type { Configuration } from '../generated/default'

import {
ApproveGrantSchema,
ApproveGrantRequest,
AddManagerRequest,
AddManagerSchema,
RejectGrantRequest,
RejectGrantSchema,
CreateGrantRequest,
CreateGrantSchema,
RevokeGrantRequest,
Expand All @@ -15,11 +22,13 @@ export class GrantsApi {
constructor(
_config: Configuration,
private readonly entityManager: EntityManagerService,
private readonly auth: AuthService
private readonly auth: AuthService,
private readonly usersApi: UsersApi
) {}

/**
* When user authorizes app to perform actions on their behalf
* When user authorizes app to perform actions on their behalf.
* For user-to-user grants, use `addManager`.
*/
async createGrant(params: CreateGrantRequest) {
const { userId, appApiKey } = await parseParams(
Expand All @@ -39,6 +48,43 @@ export class GrantsApi {
})
}

/**
* When user authorizes another user to perform actions on their behalf.
* The grant has to be approved by the proposed manager.
*/
async addManager(params: AddManagerRequest) {
const { userId, managerUserId } = await parseParams(
'addManager',
AddManagerSchema
)(params)
let managerUser: User | undefined
try {
managerUser = (
await this.usersApi.getUser({
id: encodeHashId(managerUserId)!
})
).data
if (!managerUser) {
throw new Error()
}
} catch (e) {
throw new Error(
'`managerUserId` passed to `addManager` method is invalid.'
)
}

return await this.entityManager.manageEntity({
userId,
entityType: EntityType.GRANT,
entityId: 0, // Contract requires uint, but we don't actually need this field for this action. Just use 0.
action: Action.CREATE,
metadata: JSON.stringify({
grantee_address: managerUser!.ercWallet
}),
auth: this.auth
})
}

/**
* When user revokes an app's authorization to perform actions on their behalf
*/
Expand All @@ -59,4 +105,46 @@ export class GrantsApi {
auth: this.auth
})
}

/**
* Approve manager request
*/
async approveGrant(params: ApproveGrantRequest) {
const { userId, grantorUserId } = await parseParams(
'approveGrant',
ApproveGrantSchema
)(params)

return await this.entityManager.manageEntity({
userId,
entityType: EntityType.GRANT,
entityId: 0,
action: Action.APPROVE,
metadata: JSON.stringify({
grantor_user_id: grantorUserId
}),
auth: this.auth
})
}

/**
* Reject manager request
*/
async rejectGrant(params: RejectGrantRequest) {
const { userId, grantorUserId } = await parseParams(
'rejectGrant',
RejectGrantSchema
)(params)

return await this.entityManager.manageEntity({
userId,
entityType: EntityType.GRANT,
entityId: 0,
action: Action.REJECT,
metadata: JSON.stringify({
grantor_user_id: grantorUserId
}),
auth: this.auth
})
}
}
21 changes: 21 additions & 0 deletions packages/libs/src/sdk/api/grants/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export const CreateGrantSchema = z.object({

export type CreateGrantRequest = z.input<typeof CreateGrantSchema>

export const AddManagerSchema = z.object({
userId: HashId,
managerUserId: HashId
})

export type AddManagerRequest = z.input<typeof AddManagerSchema>

export const RevokeGrantSchema = z.object({
userId: HashId,
appApiKey: z.custom<string>((data: unknown) => {
Expand All @@ -20,3 +27,17 @@ export const RevokeGrantSchema = z.object({
})

export type RevokeGrantRequest = z.input<typeof RevokeGrantSchema>

export const ApproveGrantSchema = z.object({
userId: HashId,
grantorUserId: HashId
})

export type ApproveGrantRequest = z.input<typeof ApproveGrantSchema>

export const RejectGrantSchema = z.object({
userId: HashId,
grantorUserId: HashId
})

export type RejectGrantRequest = z.input<typeof RejectGrantSchema>
3 changes: 2 additions & 1 deletion packages/libs/src/sdk/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ const initializeApis = ({
const grants = new GrantsApi(
generatedApiClientConfig,
services.entityManager,
services.auth
services.auth,
users
)

const developerApps = new DeveloperAppsApi(
Expand Down
4 changes: 3 additions & 1 deletion packages/libs/src/sdk/services/EntityManager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export enum Action {
SUBSCRIBE = 'Subscribe',
UNSUBSCRIBE = 'Unsubscribe',
VIEW = 'View',
VIEW_PLAYLIST = 'ViewPlaylist'
VIEW_PLAYLIST = 'ViewPlaylist',
APPROVE = 'Approve',
REJECT = 'Reject'
}

export enum EntityType {
Expand Down

0 comments on commit 8fb1fd9

Please sign in to comment.