Skip to content

Commit

Permalink
feat: create asset activity
Browse files Browse the repository at this point in the history
  • Loading branch information
beeman committed Apr 8, 2024
1 parent 6509314 commit ab0cd04
Show file tree
Hide file tree
Showing 20 changed files with 404 additions and 85 deletions.
18 changes: 10 additions & 8 deletions api-schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ type AppConfig {

type Asset {
account: String!
activities: [PresetActivity!]!
attributes: [[String!]!]!
description: String!
image: String!
lists: [AssetActivityType!]!
name: String!
}

Expand All @@ -99,7 +99,7 @@ type AssetActivity {
pointsLabel: String!
pointsTotal: Float!
startDate: DateTime!
type: AssetActivityType!
type: PresetActivity!
}

type AssetActivityEntry {
Expand All @@ -109,11 +109,6 @@ type AssetActivityEntry {
url: String
}

enum AssetActivityType {
Payouts
Points
}

type Claim {
account: String!
amount: String!
Expand Down Expand Up @@ -316,6 +311,7 @@ type Mutation {
adminUpdateUser(input: AdminUpdateUserInput!, userId: String!): User
adminUpdateWallet(input: WalletAdminUpdateInput!, walletId: String!): Wallet
anonVerifyIdentityChallenge(input: VerifyIdentityChallengeInput!): IdentityChallenge
createAssetActivity(account: String!, type: PresetActivity!): AssetActivity
login(input: LoginInput!): User
logout: Boolean
register(input: RegisterInput!): User
Expand Down Expand Up @@ -355,6 +351,7 @@ type PagingMeta {
}

type Preset {
activities: [PresetActivity!]
color: String!
config: JSON
createdAt: DateTime
Expand All @@ -365,6 +362,11 @@ type Preset {
updatedAt: DateTime
}

enum PresetActivity {
Payouts
Points
}

input PresetAdminCreateInput {
description: String
name: String!
Expand Down Expand Up @@ -464,7 +466,7 @@ type Query {
appConfig: AppConfig!
currencies: [Currency!]!
getAsset(account: String!): Asset!
getAssetActivity(account: String!, type: AssetActivityType!): AssetActivity!
getAssetActivity(account: String!, type: PresetActivity!): AssetActivity
me: User
metadataAll(account: String!): JSON
solanaGetBalance(account: String!): String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Module } from '@nestjs/common'
import { ApiCoreDataAccessModule } from '@tokengator/api-core-data-access'
import { ApiMetadataDataAccessModule } from '@tokengator/api-metadata-data-access'
import { ApiPresetDataAccessModule } from '@tokengator/api-preset-data-access'
import { ApiAssetService } from './api-asset.service'

@Module({
imports: [ApiCoreDataAccessModule, ApiMetadataDataAccessModule],
imports: [ApiCoreDataAccessModule, ApiMetadataDataAccessModule, ApiPresetDataAccessModule],
providers: [ApiAssetService],
exports: [ApiAssetService],
})
Expand Down
72 changes: 58 additions & 14 deletions libs/api/asset/data-access/src/lib/api-asset.service.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,76 @@
import { Injectable } from '@nestjs/common'
import { PublicKey } from '@solana/web3.js'
import { ApiMetadataService } from '@tokengator/api-metadata-data-access'
import { AssetActivity, AssetActivityType } from './entity/asset-activity.entity'
import { ApiPresetService, PresetActivity } from '@tokengator/api-preset-data-access'
import { AssetActivity } from './entity/asset-activity.entity'
import { Asset } from './entity/asset.entity'

@Injectable()
export class ApiAssetService {
constructor(private readonly metadata: ApiMetadataService) {}
constructor(private readonly metadata: ApiMetadataService, private readonly preset: ApiPresetService) {}

async getAsset(account: string): Promise<Asset> {
const { json } = await this.metadata.getAll(account)
async getAsset(account: string): Promise<Asset & { mint: PublicKey }> {
const { json, accountMetadata } = await this.metadata.getAll(account)

if (!json) {
throw new Error('Asset metadata not found')
}

const mint = accountMetadata?.state.updateAuthority
if (!mint) {
throw new Error('Asset minter not found')
}

const presetId = json.attributes.find((attr) => attr.trait_type === 'preset' && attr.value)?.value
if (!presetId) {
throw new Error('Asset preset not found')
}

const preset = await this.preset.data.findOne(presetId)

return {
account,
name: json.name,
description: json.description,
image: json.image,
lists: this.getLists('business-visa'),
activities: preset.activities ?? [],
attributes: json.attributes.map((attr) => [attr.trait_type, attr.value]),
mint,
}
}

async getAssetActivity(account: string, type: AssetActivityType): Promise<AssetActivity> {
async getAssetActivity(account: string, type: PresetActivity): Promise<AssetActivity | null> {
const { accountMetadata } = await this.metadata.getAll(account)

const mint = accountMetadata?.state.updateAuthority
if (!mint) {
throw new Error('Asset minter not found')
}

const activityPda = this.preset.minter.getActivityPda({
mint: new PublicKey(mint),
label: type.toLowerCase(),
})

const activity = await this.preset.minter.getActivity({ account: activityPda })

if (typeof activity === 'boolean') {
//
// console.log('Creating activity...')
// await this.createAssetActivity(account, type)
// throw new Error('Activity not found')
return null
}
// this.preset.minter.getCommunityPda()
console.log(`Account, type: ${account}, ${type}`, activity)

const listAccount = `pda-${account}-${type}`
const found = {
label: `${type}`,
startDate: new Date(),
endDate: new Date().getTime() + 30 * 24 * 60 * 60 * 1000,
entries:
type === AssetActivityType.Payouts
type === PresetActivity.Payouts
? [
{ timestamp: new Date(2024, 0, 1), message: 'Payout for December 2023', points: 100 },
{ timestamp: new Date(2024, 1, 1), message: 'Payout for January 2024', points: 100 },
Expand All @@ -50,7 +89,7 @@ export class ApiAssetService {
}

const pointsTotal = found.entries.reduce((acc, entry) => acc + (entry.points ?? 0), 0)
const pointsLabel = type === AssetActivityType.Payouts ? 'USD' : 'Points'
const pointsLabel = type === PresetActivity.Payouts ? 'USD' : 'Points'

return {
account: listAccount,
Expand All @@ -64,11 +103,16 @@ export class ApiAssetService {
}
}

private getLists(preset: string): AssetActivityType[] {
// TODO: Specify per preset what activity lists are available
if (preset === 'business-visa') {
return [AssetActivityType.Payouts, AssetActivityType.Points]
}
return [AssetActivityType.Points]
async createAssetActivity(account: string, activity: PresetActivity) {
const asset = await this.getAsset(account)
const minter = await this.preset.minter.getMinter(asset.mint.toString())
console.log('minter', minter)
// const activity = await this.getAssetActivity(account, type)
//
// if (activity) {
// return activity
// }

return this.preset.minter.createActivity({ minter, asset: account, activity })
}
}
14 changes: 4 additions & 10 deletions libs/api/asset/data-access/src/lib/entity/asset-activity.entity.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql'

export enum AssetActivityType {
Payouts = 'Payouts',
Points = 'Points',
}

registerEnumType(AssetActivityType, { name: 'AssetActivityType' })
import { Field, ObjectType } from '@nestjs/graphql'
import { PresetActivity } from '@tokengator/api-preset-data-access'

@ObjectType()
export class AssetActivity {
@Field()
account!: string
@Field(() => AssetActivityType)
type!: AssetActivityType
@Field(() => PresetActivity)
type!: PresetActivity
@Field()
label!: string
@Field()
Expand Down
6 changes: 3 additions & 3 deletions libs/api/asset/data-access/src/lib/entity/asset.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Field, ObjectType } from '@nestjs/graphql'
import { AssetActivityType } from './asset-activity.entity'
import { PresetActivity } from '@tokengator/api-preset-data-access'

@ObjectType()
export class Asset {
Expand All @@ -11,8 +11,8 @@ export class Asset {
description!: string
@Field()
image!: string
@Field(() => [AssetActivityType])
lists!: AssetActivityType[]
@Field(() => [PresetActivity])
activities!: PresetActivity[]
@Field(() => [[String]])
attributes!: [string, string][]
}
17 changes: 13 additions & 4 deletions libs/api/asset/feature/src/lib/api-asset.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { UseGuards } from '@nestjs/common'
import { Args, Query, Resolver } from '@nestjs/graphql'
import { ApiAssetService, Asset, AssetActivity, AssetActivityType } from '@tokengator/api-asset-data-access'
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'
import { ApiAssetService, Asset, AssetActivity } from '@tokengator/api-asset-data-access'
import { ApiAuthGraphQLUserGuard } from '@tokengator/api-auth-data-access'
import { PresetActivity } from '@tokengator/api-preset-data-access'

@Resolver(() => Asset)
@UseGuards(ApiAuthGraphQLUserGuard)
Expand All @@ -13,11 +14,19 @@ export class ApiAssetResolver {
return this.service.getAsset(account)
}

@Query(() => AssetActivity)
@Query(() => AssetActivity, { nullable: true })
getAssetActivity(
@Args('account') account: string,
@Args({ name: 'type', type: () => AssetActivityType }) type: AssetActivityType,
@Args({ name: 'type', type: () => PresetActivity }) type: PresetActivity,
) {
return this.service.getAssetActivity(account, type)
}

@Mutation(() => AssetActivity, { nullable: true })
createAssetActivity(
@Args('account') account: string,
@Args({ name: 'type', type: () => PresetActivity }) type: PresetActivity,
) {
return this.service.createAssetActivity(account, type)
}
}
4 changes: 3 additions & 1 deletion libs/api/preset/data-access/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ export * from './lib/api-preset.service'
export * from './lib/dto/preset-admin-create.input'
export * from './lib/dto/preset-admin-find-many.input'
export * from './lib/dto/preset-admin-update.input'
export * from './lib/dto/preset-user-find-many.input'
export * from './lib/dto/preset-user-mint-from-minter'
export * from './lib/dto/preset-user-mint-from-preset'
export * from './lib/dto/preset-user-find-many.input'
export * from './lib/entity/preset-activity.enum'
export * from './lib/entity/preset.entity'
export * from './lib/entity/token-gator-activity.entity'
export * from './lib/entity/token-gator-minter-application-config.entity'
export * from './lib/entity/token-gator-minter-config.entity'
export * from './lib/entity/token-gator-minter-metadata-config.entity'
Expand Down
Loading

0 comments on commit ab0cd04

Please sign in to comment.