diff --git a/api-schema.graphql b/api-schema.graphql index 5864c6f..ce012d3 100644 --- a/api-schema.graphql +++ b/api-schema.graphql @@ -95,7 +95,7 @@ type IndexEntry { label: String program: String! updatedAt: DateTime - wallet: String! + walletId: String! } input IndexEntryAdminFindManyInput { @@ -137,6 +137,43 @@ input IndexUserFindManyInput { type: IndexType } +type IndexWallet { + createdAt: DateTime + id: String! + index: Index + indexId: String! + updatedAt: DateTime + wallet: Wallet + walletId: String! +} + +input IndexWalletAdminFindManyInput { + limit: Int = 10 + page: Int = 1 + search: String + walletId: String! +} + +input IndexWalletAdminUpdateInput { + updatedAt: String +} + +type IndexWalletPaging { + data: [IndexWallet!]! + meta: PagingMeta! +} + +input IndexWalletUserFindManyInput { + limit: Int = 10 + page: Int = 1 + search: String + walletId: String! +} + +input IndexWalletUserUpdateInput { + updatedAt: String +} + """ The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). """ @@ -151,17 +188,27 @@ type Mutation { adminCreateIdentity(input: IdentityAdminCreateInput!): Identity adminCreateIndex(input: IndexAdminCreateInput!): Index adminCreateUser(input: UserAdminCreateInput!): User + adminCreateWallet(input: WalletAdminCreateInput!): Wallet adminDeleteIdentity(identityId: String!): Boolean adminDeleteIndex(indexId: String!): Boolean adminDeleteIndexEntry(indexEntryId: String!): Boolean + adminDeleteIndexWallet(indexWalletId: String!): Boolean adminDeleteUser(userId: String!): Boolean + adminDeleteWallet(walletId: String!): Boolean adminUpdateIndex(indexId: String!, input: IndexAdminUpdateInput!): Index + adminUpdateIndexWallet(indexWalletId: String!, input: IndexWalletAdminUpdateInput!): IndexWallet adminUpdateUser(input: UserAdminUpdateInput!, userId: String!): User + adminUpdateWallet(input: WalletAdminUpdateInput!, walletId: String!): Wallet login(input: LoginInput!): User logout: Boolean register(input: RegisterInput!): User + userCreateWallet(input: WalletUserCreateInput!): Wallet userDeleteIdentity(identityId: String!): Boolean + userDeleteIndexWallet(indexWalletId: String!): Boolean + userDeleteWallet(walletId: String!): Boolean + userUpdateIndexWallet(indexWalletId: String!, input: IndexWalletUserUpdateInput!): IndexWallet userUpdateUser(input: UserUserUpdateInput!): User + userUpdateWallet(input: WalletUserUpdateInput!, walletId: String!): Wallet } enum NetworkCluster { @@ -185,10 +232,14 @@ type Query { adminFindManyIdentity(input: IdentityAdminFindManyInput!): [Identity!] adminFindManyIndex(input: IndexAdminFindManyInput!): IndexPaging! adminFindManyIndexEntry(input: IndexEntryAdminFindManyInput!): IndexEntryPaging! + adminFindManyIndexWallet(input: IndexWalletAdminFindManyInput!): IndexWalletPaging! adminFindManyUser(input: UserAdminFindManyInput!): UserPaging! + adminFindManyWallet(input: WalletAdminFindManyInput!): WalletPaging! adminFindOneIndex(indexId: String!): Index adminFindOneIndexEntry(indexEntryId: String!): IndexEntry + adminFindOneIndexWallet(indexWalletId: String!): IndexWallet adminFindOneUser(userId: String!): User + adminFindOneWallet(walletId: String!): Wallet adminGetAccountInfo(input: IndexAdminResolveInput!): JSON adminResolveIndex(input: IndexAdminResolveInput!): JSON adminResolveWallet(input: IndexAdminResolveInput!, wallet: String!): JSON @@ -198,10 +249,14 @@ type Query { userFindManyIdentity(input: IdentityUserFindManyInput!): [Identity!] userFindManyIndex(input: IndexUserFindManyInput!): IndexPaging! userFindManyIndexEntry(input: IndexEntryUserFindManyInput!): IndexEntryPaging! + userFindManyIndexWallet(input: IndexWalletUserFindManyInput!): IndexWalletPaging! userFindManyUser(input: UserUserFindManyInput!): UserPaging! + userFindManyWallet(input: WalletUserFindManyInput!): WalletPaging! userFindOneIndex(indexId: String!): Index userFindOneIndexEntry(indexEntryId: String!): IndexEntry + userFindOneIndexWallet(indexWalletId: String!): IndexWallet userFindOneUser(username: String!): User + userFindOneWallet(walletId: String!): Wallet } input RegisterInput { @@ -272,3 +327,45 @@ input UserUserUpdateInput { developer: Boolean name: String } + +type Wallet { + createdAt: DateTime + id: String! + label: String! + updatedAt: DateTime +} + +input WalletAdminCreateInput { + id: String! + label: String +} + +input WalletAdminFindManyInput { + limit: Int = 10 + page: Int = 1 + search: String +} + +input WalletAdminUpdateInput { + label: String +} + +type WalletPaging { + data: [Wallet!]! + meta: PagingMeta! +} + +input WalletUserCreateInput { + id: String! + label: String +} + +input WalletUserFindManyInput { + limit: Int = 10 + page: Int = 1 + search: String +} + +input WalletUserUpdateInput { + label: String +} diff --git a/apps/api-e2e/src/api/api-index-wallet-admin-feature.spec.ts b/apps/api-e2e/src/api/api-index-wallet-admin-feature.spec.ts new file mode 100644 index 0000000..cf9057e --- /dev/null +++ b/apps/api-e2e/src/api/api-index-wallet-admin-feature.spec.ts @@ -0,0 +1,155 @@ +import { + IndexWalletAdminCreateInput, + IndexWalletAdminFindManyInput, + IndexWalletAdminUpdateInput, + IndexWallet, +} from '@pubkey-resolver/sdk' +import { getAliceCookie, getBobCookie, sdk, uniqueId } from '../support' + +describe('api-index-wallet-feature', () => { + describe('api-index-wallet-admin-resolver', () => { + const indexWalletName = uniqueId('acme-index-wallet') + + let indexWalletId: string + let cookie: string + + beforeAll(async () => { + cookie = await getAliceCookie() + const created = await sdk.adminCreateIndexWallet({ input: { name: indexWalletName } }, { cookie }) + indexWalletId = created.data.created.id + }) + + describe('authorized', () => { + beforeAll(async () => { + cookie = await getAliceCookie() + }) + + it('should create a index-wallet', async () => { + const input: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + + const res = await sdk.adminCreateIndexWallet({ input }, { cookie }) + + const item: IndexWallet = res.data.created + expect(item.name).toBe(input.name) + expect(item.id).toBeDefined() + expect(item.createdAt).toBeDefined() + expect(item.updatedAt).toBeDefined() + }) + + it('should update a index-wallet', async () => { + const createInput: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.adminCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + const input: IndexWalletAdminUpdateInput = { + name: uniqueId('index-wallet'), + } + + const res = await sdk.adminUpdateIndexWallet({ indexWalletId, input }, { cookie }) + + const item: IndexWallet = res.data.updated + expect(item.name).toBe(input.name) + }) + + it('should find a list of indexWallets (find all)', async () => { + const createInput: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.adminCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const input: IndexWalletAdminFindManyInput = {} + + const res = await sdk.adminFindManyIndexWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBeGreaterThan(1) + expect(res.data.paging.data.length).toBeGreaterThan(1) + // First item should be the one we created above + expect(res.data.paging.data[0].id).toBe(indexWalletId) + }) + + it('should find a list of indexWallets (find new one)', async () => { + const createInput: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.adminCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const input: IndexWalletAdminFindManyInput = { + search: indexWalletId, + } + + const res = await sdk.adminFindManyIndexWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBe(1) + expect(res.data.paging.data.length).toBe(1) + expect(res.data.paging.data[0].id).toBe(indexWalletId) + }) + + it('should find a index-wallet by id', async () => { + const createInput: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.adminCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const res = await sdk.adminFindOneIndexWallet({ indexWalletId }, { cookie }) + + expect(res.data.item.id).toBe(indexWalletId) + }) + + it('should delete a index-wallet', async () => { + const createInput: IndexWalletAdminCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.adminCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const res = await sdk.adminDeleteIndexWallet({ indexWalletId }, { cookie }) + + expect(res.data.deleted).toBe(true) + + const findRes = await sdk.adminFindManyIndexWallet({ input: { search: indexWalletId } }, { cookie }) + expect(findRes.data.paging.meta.totalCount).toBe(0) + expect(findRes.data.paging.data.length).toBe(0) + }) + }) + + describe('unauthorized', () => { + let cookie: string + beforeAll(async () => { + cookie = await getBobCookie() + }) + + it('should not update a index-wallet', async () => { + expect.assertions(1) + try { + await sdk.adminUpdateIndexWallet({ indexWalletId, input: {} }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + + it('should not find a index-wallet by id', async () => { + expect.assertions(1) + try { + await sdk.adminFindOneIndexWallet({ indexWalletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + + it('should not delete a index-wallet', async () => { + expect.assertions(1) + try { + await sdk.adminDeleteIndexWallet({ indexWalletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + }) + }) +}) diff --git a/apps/api-e2e/src/api/api-index-wallet-user-feature.spec.ts b/apps/api-e2e/src/api/api-index-wallet-user-feature.spec.ts new file mode 100644 index 0000000..9d6bf32 --- /dev/null +++ b/apps/api-e2e/src/api/api-index-wallet-user-feature.spec.ts @@ -0,0 +1,155 @@ +import { + IndexWalletUserCreateInput, + IndexWalletUserFindManyInput, + IndexWalletUserUpdateInput, + IndexWallet, +} from '@pubkey-resolver/sdk' +import { getAliceCookie, getBobCookie, sdk, uniqueId } from '../support' + +describe('api-index-wallet-feature', () => { + describe('api-index-wallet-user-resolver', () => { + const indexWalletName = uniqueId('acme-index-wallet') + + let indexWalletId: string + let cookie: string + + beforeAll(async () => { + cookie = await getAliceCookie() + const created = await sdk.userCreateIndexWallet({ input: { name: indexWalletName } }, { cookie }) + indexWalletId = created.data.created.id + }) + + describe('authorized', () => { + beforeAll(async () => { + cookie = await getAliceCookie() + }) + + it('should create a index-wallet', async () => { + const input: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + + const res = await sdk.userCreateIndexWallet({ input }, { cookie }) + + const item: IndexWallet = res.data.created + expect(item.name).toBe(input.name) + expect(item.id).toBeDefined() + expect(item.createdAt).toBeDefined() + expect(item.updatedAt).toBeDefined() + }) + + it('should update a index-wallet', async () => { + const createInput: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.userCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + const input: IndexWalletUserUpdateInput = { + name: uniqueId('index-wallet'), + } + + const res = await sdk.userUpdateIndexWallet({ indexWalletId, input }, { cookie }) + + const item: IndexWallet = res.data.updated + expect(item.name).toBe(input.name) + }) + + it('should find a list of indexWallets (find all)', async () => { + const createInput: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.userCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const input: IndexWalletUserFindManyInput = {} + + const res = await sdk.userFindManyIndexWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBeGreaterThan(1) + expect(res.data.paging.data.length).toBeGreaterThan(1) + // First item should be the one we created above + expect(res.data.paging.data[0].id).toBe(indexWalletId) + }) + + it('should find a list of indexWallets (find new one)', async () => { + const createInput: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.userCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const input: IndexWalletUserFindManyInput = { + search: indexWalletId, + } + + const res = await sdk.userFindManyIndexWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBe(1) + expect(res.data.paging.data.length).toBe(1) + expect(res.data.paging.data[0].id).toBe(indexWalletId) + }) + + it('should find a index-wallet by id', async () => { + const createInput: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.userCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const res = await sdk.userFindOneIndexWallet({ indexWalletId }, { cookie }) + + expect(res.data.item.id).toBe(indexWalletId) + }) + + it('should delete a index-wallet', async () => { + const createInput: IndexWalletUserCreateInput = { + name: uniqueId('index-wallet'), + } + const createdRes = await sdk.userCreateIndexWallet({ input: createInput }, { cookie }) + const indexWalletId = createdRes.data.created.id + + const res = await sdk.userDeleteIndexWallet({ indexWalletId }, { cookie }) + + expect(res.data.deleted).toBe(true) + + const findRes = await sdk.userFindManyIndexWallet({ input: { search: indexWalletId } }, { cookie }) + expect(findRes.data.paging.meta.totalCount).toBe(0) + expect(findRes.data.paging.data.length).toBe(0) + }) + }) + + describe('unauthorized', () => { + let cookie: string + beforeAll(async () => { + cookie = await getBobCookie() + }) + + it('should not update a index-wallet', async () => { + expect.assertions(1) + try { + await sdk.userUpdateIndexWallet({ indexWalletId, input: {} }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to update this IndexWallet') + } + }) + + it('should not find a index-wallet by id', async () => { + expect.assertions(1) + try { + await sdk.userFindOneIndexWallet({ indexWalletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to view this IndexWallet') + } + }) + + it('should not delete a index-wallet', async () => { + expect.assertions(1) + try { + await sdk.userDeleteIndexWallet({ indexWalletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to delete this IndexWallet') + } + }) + }) + }) +}) diff --git a/apps/api-e2e/src/api/api-wallet-admin-feature.spec.ts b/apps/api-e2e/src/api/api-wallet-admin-feature.spec.ts new file mode 100644 index 0000000..033c297 --- /dev/null +++ b/apps/api-e2e/src/api/api-wallet-admin-feature.spec.ts @@ -0,0 +1,150 @@ +import { WalletAdminCreateInput, WalletAdminFindManyInput, WalletAdminUpdateInput, Wallet } from '@pubkey-resolver/sdk' +import { getAliceCookie, getBobCookie, sdk, uniqueId } from '../support' + +describe('api-wallet-feature', () => { + describe('api-wallet-admin-resolver', () => { + const walletName = uniqueId('acme-wallet') + + let walletId: string + let cookie: string + + beforeAll(async () => { + cookie = await getAliceCookie() + const created = await sdk.adminCreateWallet({ input: { name: walletName } }, { cookie }) + walletId = created.data.created.id + }) + + describe('authorized', () => { + beforeAll(async () => { + cookie = await getAliceCookie() + }) + + it('should create a wallet', async () => { + const input: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + + const res = await sdk.adminCreateWallet({ input }, { cookie }) + + const item: Wallet = res.data.created + expect(item.name).toBe(input.name) + expect(item.id).toBeDefined() + expect(item.createdAt).toBeDefined() + expect(item.updatedAt).toBeDefined() + }) + + it('should update a wallet', async () => { + const createInput: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.adminCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + const input: WalletAdminUpdateInput = { + name: uniqueId('wallet'), + } + + const res = await sdk.adminUpdateWallet({ walletId, input }, { cookie }) + + const item: Wallet = res.data.updated + expect(item.name).toBe(input.name) + }) + + it('should find a list of wallets (find all)', async () => { + const createInput: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.adminCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const input: WalletAdminFindManyInput = {} + + const res = await sdk.adminFindManyWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBeGreaterThan(1) + expect(res.data.paging.data.length).toBeGreaterThan(1) + // First item should be the one we created above + expect(res.data.paging.data[0].id).toBe(walletId) + }) + + it('should find a list of wallets (find new one)', async () => { + const createInput: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.adminCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const input: WalletAdminFindManyInput = { + search: walletId, + } + + const res = await sdk.adminFindManyWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBe(1) + expect(res.data.paging.data.length).toBe(1) + expect(res.data.paging.data[0].id).toBe(walletId) + }) + + it('should find a wallet by id', async () => { + const createInput: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.adminCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const res = await sdk.adminFindOneWallet({ walletId }, { cookie }) + + expect(res.data.item.id).toBe(walletId) + }) + + it('should delete a wallet', async () => { + const createInput: WalletAdminCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.adminCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const res = await sdk.adminDeleteWallet({ walletId }, { cookie }) + + expect(res.data.deleted).toBe(true) + + const findRes = await sdk.adminFindManyWallet({ input: { search: walletId } }, { cookie }) + expect(findRes.data.paging.meta.totalCount).toBe(0) + expect(findRes.data.paging.data.length).toBe(0) + }) + }) + + describe('unauthorized', () => { + let cookie: string + beforeAll(async () => { + cookie = await getBobCookie() + }) + + it('should not update a wallet', async () => { + expect.assertions(1) + try { + await sdk.adminUpdateWallet({ walletId, input: {} }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + + it('should not find a wallet by id', async () => { + expect.assertions(1) + try { + await sdk.adminFindOneWallet({ walletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + + it('should not delete a wallet', async () => { + expect.assertions(1) + try { + await sdk.adminDeleteWallet({ walletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('Unauthorized: User is not Admin') + } + }) + }) + }) +}) diff --git a/apps/api-e2e/src/api/api-wallet-user-feature.spec.ts b/apps/api-e2e/src/api/api-wallet-user-feature.spec.ts new file mode 100644 index 0000000..cf311f0 --- /dev/null +++ b/apps/api-e2e/src/api/api-wallet-user-feature.spec.ts @@ -0,0 +1,150 @@ +import { WalletUserCreateInput, WalletUserFindManyInput, WalletUserUpdateInput, Wallet } from '@pubkey-resolver/sdk' +import { getAliceCookie, getBobCookie, sdk, uniqueId } from '../support' + +describe('api-wallet-feature', () => { + describe('api-wallet-user-resolver', () => { + const walletName = uniqueId('acme-wallet') + + let walletId: string + let cookie: string + + beforeAll(async () => { + cookie = await getAliceCookie() + const created = await sdk.userCreateWallet({ input: { name: walletName } }, { cookie }) + walletId = created.data.created.id + }) + + describe('authorized', () => { + beforeAll(async () => { + cookie = await getAliceCookie() + }) + + it('should create a wallet', async () => { + const input: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + + const res = await sdk.userCreateWallet({ input }, { cookie }) + + const item: Wallet = res.data.created + expect(item.name).toBe(input.name) + expect(item.id).toBeDefined() + expect(item.createdAt).toBeDefined() + expect(item.updatedAt).toBeDefined() + }) + + it('should update a wallet', async () => { + const createInput: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.userCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + const input: WalletUserUpdateInput = { + name: uniqueId('wallet'), + } + + const res = await sdk.userUpdateWallet({ walletId, input }, { cookie }) + + const item: Wallet = res.data.updated + expect(item.name).toBe(input.name) + }) + + it('should find a list of wallets (find all)', async () => { + const createInput: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.userCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const input: WalletUserFindManyInput = {} + + const res = await sdk.userFindManyWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBeGreaterThan(1) + expect(res.data.paging.data.length).toBeGreaterThan(1) + // First item should be the one we created above + expect(res.data.paging.data[0].id).toBe(walletId) + }) + + it('should find a list of wallets (find new one)', async () => { + const createInput: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.userCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const input: WalletUserFindManyInput = { + search: walletId, + } + + const res = await sdk.userFindManyWallet({ input }, { cookie }) + + expect(res.data.paging.meta.totalCount).toBe(1) + expect(res.data.paging.data.length).toBe(1) + expect(res.data.paging.data[0].id).toBe(walletId) + }) + + it('should find a wallet by id', async () => { + const createInput: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.userCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const res = await sdk.userFindOneWallet({ walletId }, { cookie }) + + expect(res.data.item.id).toBe(walletId) + }) + + it('should delete a wallet', async () => { + const createInput: WalletUserCreateInput = { + name: uniqueId('wallet'), + } + const createdRes = await sdk.userCreateWallet({ input: createInput }, { cookie }) + const walletId = createdRes.data.created.id + + const res = await sdk.userDeleteWallet({ walletId }, { cookie }) + + expect(res.data.deleted).toBe(true) + + const findRes = await sdk.userFindManyWallet({ input: { search: walletId } }, { cookie }) + expect(findRes.data.paging.meta.totalCount).toBe(0) + expect(findRes.data.paging.data.length).toBe(0) + }) + }) + + describe('unauthorized', () => { + let cookie: string + beforeAll(async () => { + cookie = await getBobCookie() + }) + + it('should not update a wallet', async () => { + expect.assertions(1) + try { + await sdk.userUpdateWallet({ walletId, input: {} }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to update this Wallet') + } + }) + + it('should not find a wallet by id', async () => { + expect.assertions(1) + try { + await sdk.userFindOneWallet({ walletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to view this Wallet') + } + }) + + it('should not delete a wallet', async () => { + expect.assertions(1) + try { + await sdk.userDeleteWallet({ walletId }, { cookie }) + } catch (e) { + expect(e.message).toBe('You are not authorized to delete this Wallet') + } + }) + }) + }) +}) diff --git a/libs/api/core/data-access/src/lib/api-core-network.service.ts b/libs/api/core/data-access/src/lib/api-core-network.service.ts index c859a38..1d5501e 100644 --- a/libs/api/core/data-access/src/lib/api-core-network.service.ts +++ b/libs/api/core/data-access/src/lib/api-core-network.service.ts @@ -39,7 +39,7 @@ export class ApiCoreNetworkService { const connection = this.ensureConnection(cluster as NetworkCluster) try { const version = await connection.getVersion() - this.logger.debug(`[${cluster}] Connected to cluster version ${version['solana-core']}`) + this.logger.debug(`[${cluster}] Connected to cluster ${cluster} version ${version['solana-core']}`) } catch (error) { this.logger.error(`[${cluster}] Error connecting to cluster, ${error}`) } @@ -108,12 +108,17 @@ export class ApiCoreNetworkService { private listWebhooks(cluster: NetworkCluster) { const helius = this.ensureHelius(cluster) - helius.getAllWebhooks().then((webhooks) => { - this.logger.debug(`[${cluster}] Helius Webhooks: ${webhooks.length} configured`) - for (const webhook of webhooks) { - this.logger.debug(`[${cluster}] - Webhook: ${webhook.accountAddresses.length} addresses`) - } - }) + helius + .getAllWebhooks() + .then((webhooks) => { + this.logger.debug(`[${cluster}] Helius Webhooks: ${webhooks.length} configured`) + for (const webhook of webhooks) { + this.logger.debug(`[${cluster}] - Webhook: ${webhook.accountAddresses.length} addresses`) + } + }) + .catch((err) => { + this.logger.error(`[${cluster}] Error listing webhooks: ${err}`) + }) } async getTokenAccountsByMint({ diff --git a/libs/api/core/feature/src/lib/api-core-feature.module.ts b/libs/api/core/feature/src/lib/api-core-feature.module.ts index e1b60db..aa71831 100644 --- a/libs/api/core/feature/src/lib/api-core-feature.module.ts +++ b/libs/api/core/feature/src/lib/api-core-feature.module.ts @@ -1,12 +1,14 @@ import { Module } from '@nestjs/common' -import { ApiIndexFeatureModule } from '@pubkey-resolver/api-index-feature' import { ApiAuthFeatureModule } from '@pubkey-resolver/api-auth-feature' import { ApiCoreDataAccessModule } from '@pubkey-resolver/api-core-data-access' import { ApiIdentityFeatureModule } from '@pubkey-resolver/api-identity-feature' +import { ApiIndexEntryFeatureModule } from '@pubkey-resolver/api-index-entry-feature' +import { ApiIndexFeatureModule } from '@pubkey-resolver/api-index-feature' import { ApiUserFeatureModule } from '@pubkey-resolver/api-user-feature' +import { ApiWalletFeatureModule } from '@pubkey-resolver/api-wallet-feature' import { ApiCoreController } from './api-core.controller' import { ApiCoreResolver } from './api-core.resolver' -import { ApiIndexEntryFeatureModule } from '@pubkey-resolver/api-index-entry-feature' +import { ApiIndexWalletFeatureModule } from '@pubkey-resolver/api-index-wallet-feature' const imports = [ // The api-feature generator will add the imports here @@ -16,6 +18,8 @@ const imports = [ ApiUserFeatureModule, ApiIndexFeatureModule, ApiIndexEntryFeatureModule, + ApiWalletFeatureModule, + ApiIndexWalletFeatureModule, ] @Module({ diff --git a/libs/api/index-entry/data-access/src/lib/api-index-entry-data.service.ts b/libs/api/index-entry/data-access/src/lib/api-index-entry-data.service.ts index 9e1454a..2ffa134 100644 --- a/libs/api/index-entry/data-access/src/lib/api-index-entry-data.service.ts +++ b/libs/api/index-entry/data-access/src/lib/api-index-entry-data.service.ts @@ -65,7 +65,7 @@ export class ApiIndexEntryDataService { const dataHash = hash(data) const program = tokenAccount.account.owner.toString() const amount = tokenAccount.account.data.parsed.info.tokenAmount.uiAmountString ?? '0' - const wallet = tokenAccount.account.data.parsed.info.owner.toString() + const walletId = tokenAccount.account.data.parsed.info.owner.toString() if (!found) { this.logger.verbose(`[${index.id}] Creating token account ${tokenAccount.pubkey.toString()}`) @@ -78,7 +78,7 @@ export class ApiIndexEntryDataService { indexAddress: index.address, label: index.label, program, - wallet, + walletId, }) items.push(created) continue @@ -92,7 +92,7 @@ export class ApiIndexEntryDataService { } this.logger.verbose(`[${index.id}] Updating token account ${tokenAccount.pubkey.toString()}`) - const updated = await this.update(found.id, { amount, data, dataHash, wallet }) + const updated = await this.update(found.id, { amount, data, dataHash, walletId }) items.push(updated) } return items diff --git a/libs/api/index-entry/data-access/src/lib/entity/index-entry.entity.ts b/libs/api/index-entry/data-access/src/lib/entity/index-entry.entity.ts index 41ef507..49cf4b1 100644 --- a/libs/api/index-entry/data-access/src/lib/entity/index-entry.entity.ts +++ b/libs/api/index-entry/data-access/src/lib/entity/index-entry.entity.ts @@ -22,7 +22,7 @@ export class IndexEntry { @Field() program!: string @Field() - wallet!: string + walletId!: string @Field(() => GraphQLJSON, { nullable: true }) data?: Prisma.JsonValue | null @Field({ nullable: true }) diff --git a/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-admin.input.ts b/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-admin.input.ts index b52e6c5..83a7491 100644 --- a/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-admin.input.ts +++ b/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-admin.input.ts @@ -11,7 +11,7 @@ export function getIndexEntryWhereAdminInput(input: IndexEntryAdminFindManyInput where.OR = [ { id: { contains: input.search, mode: 'insensitive' } }, { address: { contains: input.search, mode: 'insensitive' } }, - { wallet: { contains: input.search, mode: 'insensitive' } }, + { walletId: { contains: input.search, mode: 'insensitive' } }, { label: { contains: input.search, mode: 'insensitive' } }, ] } diff --git a/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-user.input.ts b/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-user.input.ts index 274f77e..10d69e6 100644 --- a/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-user.input.ts +++ b/libs/api/index-entry/data-access/src/lib/helpers/get-index-entry-where-user.input.ts @@ -11,7 +11,7 @@ export function getIndexEntryWhereUserInput(input: IndexEntryUserFindManyInput): where.OR = [ { id: { contains: input.search, mode: 'insensitive' } }, { address: { contains: input.search, mode: 'insensitive' } }, - { wallet: { contains: input.search, mode: 'insensitive' } }, + { walletId: { contains: input.search, mode: 'insensitive' } }, { label: { contains: input.search, mode: 'insensitive' } }, ] } diff --git a/libs/api/index-wallet/data-access/.eslintrc.json b/libs/api/index-wallet/data-access/.eslintrc.json new file mode 100644 index 0000000..632e9b0 --- /dev/null +++ b/libs/api/index-wallet/data-access/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/api/index-wallet/data-access/README.md b/libs/api/index-wallet/data-access/README.md new file mode 100644 index 0000000..5b32793 --- /dev/null +++ b/libs/api/index-wallet/data-access/README.md @@ -0,0 +1,7 @@ +# api-index-wallet-data-access + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test api-index-wallet-data-access` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/api/index-wallet/data-access/jest.config.ts b/libs/api/index-wallet/data-access/jest.config.ts new file mode 100644 index 0000000..4d45229 --- /dev/null +++ b/libs/api/index-wallet/data-access/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'api-index-wallet-data-access', + preset: '../../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../../coverage/libs/api/index-wallet/data-access', +} diff --git a/libs/api/index-wallet/data-access/project.json b/libs/api/index-wallet/data-access/project.json new file mode 100644 index 0000000..72bef75 --- /dev/null +++ b/libs/api/index-wallet/data-access/project.json @@ -0,0 +1,19 @@ +{ + "name": "api-index-wallet-data-access", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/api/index-wallet/data-access/src", + "projectType": "library", + "tags": ["app:api", "type:data-access"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/api/index-wallet/data-access/jest.config.ts" + } + } + } +} diff --git a/libs/api/index-wallet/data-access/src/index.ts b/libs/api/index-wallet/data-access/src/index.ts new file mode 100644 index 0000000..478268a --- /dev/null +++ b/libs/api/index-wallet/data-access/src/index.ts @@ -0,0 +1,7 @@ +export * from './lib/api-index-wallet.data-access.module' +export * from './lib/api-index-wallet.service' +export * from './lib/entity/index-wallet.entity' +export * from './lib/dto/index-wallet-admin-find-many.input' +export * from './lib/dto/index-wallet-admin-update.input' +export * from './lib/dto/index-wallet-user-find-many.input' +export * from './lib/dto/index-wallet-user-update.input' diff --git a/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-admin.service.ts b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-admin.service.ts new file mode 100644 index 0000000..7dd5157 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-admin.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@nestjs/common' +import { ApiIndexWalletDataService } from './api-index-wallet-data.service' +import { IndexWalletAdminFindManyInput } from './dto/index-wallet-admin-find-many.input' +import { IndexWalletAdminUpdateInput } from './dto/index-wallet-admin-update.input' +import { IndexWalletPaging } from './entity/index-wallet.entity' +import { getIndexWalletWhereAdminInput } from './helpers/get-index-wallet-where-admin.input' + +@Injectable() +export class ApiIndexWalletDataAdminService { + constructor(private readonly data: ApiIndexWalletDataService) {} + + async deleteIndexWallet(indexWalletId: string) { + return this.data.delete(indexWalletId) + } + + async findManyIndexWallet(input: IndexWalletAdminFindManyInput): Promise { + return this.data.findMany({ + orderBy: [{ index: { type: 'asc' } }, { index: { label: 'asc' } }], + where: getIndexWalletWhereAdminInput(input), + limit: input.limit, + page: input.page, + include: { + index: { include: { entries: { where: { walletId: input.walletId } } } }, + }, + }) + } + + async findOneIndexWallet(indexWalletId: string) { + return this.data.findOne(indexWalletId) + } + + async updateIndexWallet(indexWalletId: string, input: IndexWalletAdminUpdateInput) { + return this.data.update(indexWalletId, input) + } +} diff --git a/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-user.service.ts b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-user.service.ts new file mode 100644 index 0000000..eb85966 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data-user.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common' +import { ApiIndexWalletDataService } from './api-index-wallet-data.service' +import { IndexWalletUserFindManyInput } from './dto/index-wallet-user-find-many.input' +import { IndexWalletUserUpdateInput } from './dto/index-wallet-user-update.input' +import { IndexWalletPaging } from './entity/index-wallet.entity' +import { getIndexWalletWhereUserInput } from './helpers/get-index-wallet-where-user.input' + +@Injectable() +export class ApiIndexWalletDataUserService { + constructor(private readonly data: ApiIndexWalletDataService) {} + + async deleteIndexWallet(indexWalletId: string) { + return this.data.delete(indexWalletId) + } + + async findManyIndexWallet(input: IndexWalletUserFindManyInput): Promise { + return this.data.findMany({ + orderBy: { createdAt: 'desc' }, + where: getIndexWalletWhereUserInput(input), + limit: input.limit, + page: input.page, + include: { index: true }, + }) + } + + async findOneIndexWallet(indexWalletId: string) { + return this.data.findOne(indexWalletId) + } + + async updateIndexWallet(indexWalletId: string, input: IndexWalletUserUpdateInput) { + return this.data.update(indexWalletId, input) + } +} diff --git a/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data.service.ts b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data.service.ts new file mode 100644 index 0000000..e02ef60 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/api-index-wallet-data.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common' +import { Prisma } from '@prisma/client' +import { ApiCoreService, PagingInputFields } from '@pubkey-resolver/api-core-data-access' +import { IndexWalletPaging } from './entity/index-wallet.entity' + +@Injectable() +export class ApiIndexWalletDataService { + constructor(private readonly core: ApiCoreService) {} + + async delete(indexWalletId: string) { + await this.findOne(indexWalletId) + const deleted = await this.core.data.indexWallet.delete({ where: { id: indexWalletId } }) + return !!deleted + } + + async findMany({ + limit = 10, + page = 1, + ...input + }: Prisma.IndexWalletFindManyArgs & PagingInputFields): Promise { + return this.core.data.indexWallet + .paginate(input) + .withPages({ limit, page }) + .then(([data, meta]) => ({ data, meta })) + } + + async findOne(indexWalletId: string) { + const found = await this.core.data.indexWallet.findUnique({ + where: { id: indexWalletId }, + include: { index: true }, + }) + if (!found) { + throw new Error('IndexWallet not found') + } + return found + } + + async update(indexWalletId: string, input: Prisma.IndexWalletUpdateInput) { + return this.core.data.indexWallet.update({ where: { id: indexWalletId }, data: input }) + } +} diff --git a/libs/api/index-wallet/data-access/src/lib/api-index-wallet.data-access.module.ts b/libs/api/index-wallet/data-access/src/lib/api-index-wallet.data-access.module.ts new file mode 100644 index 0000000..fd862d6 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/api-index-wallet.data-access.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common' +import { ApiCoreDataAccessModule } from '@pubkey-resolver/api-core-data-access' +import { ApiIndexWalletService } from './api-index-wallet.service' +import { ApiIndexWalletDataService } from './api-index-wallet-data.service' +import { ApiIndexWalletDataAdminService } from './api-index-wallet-data-admin.service' +import { ApiIndexWalletDataUserService } from './api-index-wallet-data-user.service' + +@Module({ + imports: [ApiCoreDataAccessModule], + providers: [ + ApiIndexWalletService, + ApiIndexWalletDataService, + ApiIndexWalletDataAdminService, + ApiIndexWalletDataUserService, + ], + exports: [ApiIndexWalletService], +}) +export class ApiIndexWalletDataAccessModule {} diff --git a/libs/api/index-wallet/data-access/src/lib/api-index-wallet.service.ts b/libs/api/index-wallet/data-access/src/lib/api-index-wallet.service.ts new file mode 100644 index 0000000..8c7bc1d --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/api-index-wallet.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@nestjs/common' +import { ApiIndexWalletDataService } from './api-index-wallet-data.service' +import { ApiIndexWalletDataAdminService } from './api-index-wallet-data-admin.service' +import { ApiIndexWalletDataUserService } from './api-index-wallet-data-user.service' + +@Injectable() +export class ApiIndexWalletService { + constructor( + readonly data: ApiIndexWalletDataService, + readonly admin: ApiIndexWalletDataAdminService, + readonly user: ApiIndexWalletDataUserService, + ) {} +} diff --git a/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-find-many.input.ts b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-find-many.input.ts new file mode 100644 index 0000000..04b40a1 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-find-many.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType } from '@nestjs/graphql' +import { PagingInput } from '@pubkey-resolver/api-core-data-access' + +@InputType() +export class IndexWalletAdminFindManyInput extends PagingInput() { + @Field() + walletId!: string + @Field({ nullable: true }) + search?: string +} diff --git a/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-update.input.ts b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-update.input.ts new file mode 100644 index 0000000..2fb6216 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-admin-update.input.ts @@ -0,0 +1,7 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class IndexWalletAdminUpdateInput { + @Field({ nullable: true }) + updatedAt?: string +} diff --git a/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-find-many.input.ts b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-find-many.input.ts new file mode 100644 index 0000000..983f584 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-find-many.input.ts @@ -0,0 +1,11 @@ +import { Field, InputType } from '@nestjs/graphql' +import { PagingInput } from '@pubkey-resolver/api-core-data-access' + +@InputType() +export class IndexWalletUserFindManyInput extends PagingInput() { + @Field() + walletId!: string + + @Field({ nullable: true }) + search?: string +} diff --git a/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-update.input.ts b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-update.input.ts new file mode 100644 index 0000000..09ffd8a --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/dto/index-wallet-user-update.input.ts @@ -0,0 +1,7 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class IndexWalletUserUpdateInput { + @Field({ nullable: true }) + updatedAt?: string +} diff --git a/libs/api/index-wallet/data-access/src/lib/entity/index-wallet.entity.ts b/libs/api/index-wallet/data-access/src/lib/entity/index-wallet.entity.ts new file mode 100644 index 0000000..8b645c8 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/entity/index-wallet.entity.ts @@ -0,0 +1,25 @@ +import { Field, ObjectType } from '@nestjs/graphql' +import { PagingResponse } from '@pubkey-resolver/api-core-data-access' +import { Index } from '@pubkey-resolver/api-index-data-access' +import { Wallet } from '@pubkey-resolver/api-wallet-data-access' + +@ObjectType() +export class IndexWallet { + @Field() + id!: string + @Field({ nullable: true }) + createdAt?: Date + @Field({ nullable: true }) + updatedAt?: Date + @Field() + indexId!: string + @Field(() => Index, { nullable: true }) + index?: Index + @Field() + walletId!: string + @Field(() => Wallet, { nullable: true }) + wallet?: Wallet +} + +@ObjectType() +export class IndexWalletPaging extends PagingResponse(IndexWallet) {} diff --git a/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-admin.input.ts b/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-admin.input.ts new file mode 100644 index 0000000..8e80d17 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-admin.input.ts @@ -0,0 +1,20 @@ +import { Prisma } from '@prisma/client' +import { IndexWalletAdminFindManyInput } from '../dto/index-wallet-admin-find-many.input' + +export function getIndexWalletWhereAdminInput(input: IndexWalletAdminFindManyInput): Prisma.IndexWalletWhereInput { + const where: Prisma.IndexWalletWhereInput = { + walletId: input.walletId, + } + + if (input.search) { + where.OR = [ + { id: { contains: input.search, mode: 'insensitive' } }, + { index: { id: { contains: input.search, mode: 'insensitive' } } }, + { index: { label: { contains: input.search, mode: 'insensitive' } } }, + { wallet: { id: { contains: input.search, mode: 'insensitive' } } }, + { wallet: { label: { contains: input.search, mode: 'insensitive' } } }, + ] + } + + return where +} diff --git a/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-user.input.ts b/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-user.input.ts new file mode 100644 index 0000000..be56d89 --- /dev/null +++ b/libs/api/index-wallet/data-access/src/lib/helpers/get-index-wallet-where-user.input.ts @@ -0,0 +1,20 @@ +import { Prisma } from '@prisma/client' +import { IndexWalletUserFindManyInput } from '../dto/index-wallet-user-find-many.input' + +export function getIndexWalletWhereUserInput(input: IndexWalletUserFindManyInput): Prisma.IndexWalletWhereInput { + const where: Prisma.IndexWalletWhereInput = { + walletId: input.walletId, + } + + if (input.search) { + where.OR = [ + { id: { contains: input.search, mode: 'insensitive' } }, + { index: { id: { contains: input.search, mode: 'insensitive' } } }, + { index: { label: { contains: input.search, mode: 'insensitive' } } }, + { wallet: { id: { contains: input.search, mode: 'insensitive' } } }, + { wallet: { label: { contains: input.search, mode: 'insensitive' } } }, + ] + } + + return where +} diff --git a/libs/api/index-wallet/data-access/tsconfig.json b/libs/api/index-wallet/data-access/tsconfig.json new file mode 100644 index 0000000..4022fd4 --- /dev/null +++ b/libs/api/index-wallet/data-access/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/api/index-wallet/data-access/tsconfig.lib.json b/libs/api/index-wallet/data-access/tsconfig.lib.json new file mode 100644 index 0000000..c6b908a --- /dev/null +++ b/libs/api/index-wallet/data-access/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es6", + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/api/index-wallet/data-access/tsconfig.spec.json b/libs/api/index-wallet/data-access/tsconfig.spec.json new file mode 100644 index 0000000..56497b8 --- /dev/null +++ b/libs/api/index-wallet/data-access/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/libs/api/index-wallet/feature/.eslintrc.json b/libs/api/index-wallet/feature/.eslintrc.json new file mode 100644 index 0000000..632e9b0 --- /dev/null +++ b/libs/api/index-wallet/feature/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/api/index-wallet/feature/README.md b/libs/api/index-wallet/feature/README.md new file mode 100644 index 0000000..c653506 --- /dev/null +++ b/libs/api/index-wallet/feature/README.md @@ -0,0 +1,7 @@ +# api-index-wallet-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test api-index-wallet-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/api/index-wallet/feature/jest.config.ts b/libs/api/index-wallet/feature/jest.config.ts new file mode 100644 index 0000000..f938a9d --- /dev/null +++ b/libs/api/index-wallet/feature/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'api-index-wallet-feature', + preset: '../../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../../coverage/libs/api/index-wallet/feature', +} diff --git a/libs/api/index-wallet/feature/project.json b/libs/api/index-wallet/feature/project.json new file mode 100644 index 0000000..dc60f61 --- /dev/null +++ b/libs/api/index-wallet/feature/project.json @@ -0,0 +1,19 @@ +{ + "name": "api-index-wallet-feature", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/api/index-wallet/feature/src", + "projectType": "library", + "tags": ["app:api", "type:feature"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/api/index-wallet/feature/jest.config.ts" + } + } + } +} diff --git a/libs/api/index-wallet/feature/src/index.ts b/libs/api/index-wallet/feature/src/index.ts new file mode 100644 index 0000000..f7634d0 --- /dev/null +++ b/libs/api/index-wallet/feature/src/index.ts @@ -0,0 +1 @@ +export * from './lib/api-index-wallet.feature.module' diff --git a/libs/api/index-wallet/feature/src/lib/api-index-wallet-admin.resolver.ts b/libs/api/index-wallet/feature/src/lib/api-index-wallet-admin.resolver.ts new file mode 100644 index 0000000..9ebd19e --- /dev/null +++ b/libs/api/index-wallet/feature/src/lib/api-index-wallet-admin.resolver.ts @@ -0,0 +1,39 @@ +import { UseGuards } from '@nestjs/common' +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' +import { ApiAuthGraphQLAdminGuard } from '@pubkey-resolver/api-auth-data-access' +import { + ApiIndexWalletService, + IndexWallet, + IndexWalletAdminFindManyInput, + IndexWalletAdminUpdateInput, + IndexWalletPaging, +} from '@pubkey-resolver/api-index-wallet-data-access' + +@Resolver() +@UseGuards(ApiAuthGraphQLAdminGuard) +export class ApiIndexWalletAdminResolver { + constructor(private readonly service: ApiIndexWalletService) {} + + @Mutation(() => Boolean, { nullable: true }) + adminDeleteIndexWallet(@Args('indexWalletId') indexWalletId: string) { + return this.service.admin.deleteIndexWallet(indexWalletId) + } + + @Query(() => IndexWalletPaging) + adminFindManyIndexWallet(@Args('input') input: IndexWalletAdminFindManyInput) { + return this.service.admin.findManyIndexWallet(input) + } + + @Query(() => IndexWallet, { nullable: true }) + adminFindOneIndexWallet(@Args('indexWalletId') indexWalletId: string) { + return this.service.admin.findOneIndexWallet(indexWalletId) + } + + @Mutation(() => IndexWallet, { nullable: true }) + adminUpdateIndexWallet( + @Args('indexWalletId') indexWalletId: string, + @Args('input') input: IndexWalletAdminUpdateInput, + ) { + return this.service.admin.updateIndexWallet(indexWalletId, input) + } +} diff --git a/libs/api/index-wallet/feature/src/lib/api-index-wallet-user.resolver.ts b/libs/api/index-wallet/feature/src/lib/api-index-wallet-user.resolver.ts new file mode 100644 index 0000000..156784f --- /dev/null +++ b/libs/api/index-wallet/feature/src/lib/api-index-wallet-user.resolver.ts @@ -0,0 +1,39 @@ +import { UseGuards } from '@nestjs/common' +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' +import { ApiAuthGraphQLUserGuard } from '@pubkey-resolver/api-auth-data-access' +import { + ApiIndexWalletService, + IndexWallet, + IndexWalletPaging, + IndexWalletUserFindManyInput, + IndexWalletUserUpdateInput, +} from '@pubkey-resolver/api-index-wallet-data-access' + +@Resolver() +@UseGuards(ApiAuthGraphQLUserGuard) +export class ApiIndexWalletUserResolver { + constructor(private readonly service: ApiIndexWalletService) {} + + @Mutation(() => Boolean, { nullable: true }) + userDeleteIndexWallet(@Args('indexWalletId') indexWalletId: string) { + return this.service.user.deleteIndexWallet(indexWalletId) + } + + @Query(() => IndexWalletPaging) + userFindManyIndexWallet(@Args('input') input: IndexWalletUserFindManyInput) { + return this.service.user.findManyIndexWallet(input) + } + + @Query(() => IndexWallet, { nullable: true }) + userFindOneIndexWallet(@Args('indexWalletId') indexWalletId: string) { + return this.service.user.findOneIndexWallet(indexWalletId) + } + + @Mutation(() => IndexWallet, { nullable: true }) + userUpdateIndexWallet( + @Args('indexWalletId') indexWalletId: string, + @Args('input') input: IndexWalletUserUpdateInput, + ) { + return this.service.user.updateIndexWallet(indexWalletId, input) + } +} diff --git a/libs/api/index-wallet/feature/src/lib/api-index-wallet.feature.module.ts b/libs/api/index-wallet/feature/src/lib/api-index-wallet.feature.module.ts new file mode 100644 index 0000000..79ae220 --- /dev/null +++ b/libs/api/index-wallet/feature/src/lib/api-index-wallet.feature.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common' +import { ApiIndexWalletDataAccessModule } from '@pubkey-resolver/api-index-wallet-data-access' +import { ApiIndexWalletResolver } from './api-index-wallet.resolver' +import { ApiIndexWalletAdminResolver } from './api-index-wallet-admin.resolver' +import { ApiIndexWalletUserResolver } from './api-index-wallet-user.resolver' + +@Module({ + imports: [ApiIndexWalletDataAccessModule], + providers: [ApiIndexWalletResolver, ApiIndexWalletAdminResolver, ApiIndexWalletUserResolver], +}) +export class ApiIndexWalletFeatureModule {} diff --git a/libs/api/index-wallet/feature/src/lib/api-index-wallet.resolver.ts b/libs/api/index-wallet/feature/src/lib/api-index-wallet.resolver.ts new file mode 100644 index 0000000..d1d4260 --- /dev/null +++ b/libs/api/index-wallet/feature/src/lib/api-index-wallet.resolver.ts @@ -0,0 +1,8 @@ +import { Resolver } from '@nestjs/graphql' +import { ApiIndexWalletService } from '@pubkey-resolver/api-index-wallet-data-access' +import { IndexWallet } from '@pubkey-resolver/api-index-wallet-data-access' + +@Resolver(() => IndexWallet) +export class ApiIndexWalletResolver { + constructor(private readonly service: ApiIndexWalletService) {} +} diff --git a/libs/api/index-wallet/feature/tsconfig.json b/libs/api/index-wallet/feature/tsconfig.json new file mode 100644 index 0000000..4022fd4 --- /dev/null +++ b/libs/api/index-wallet/feature/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/api/index-wallet/feature/tsconfig.lib.json b/libs/api/index-wallet/feature/tsconfig.lib.json new file mode 100644 index 0000000..c6b908a --- /dev/null +++ b/libs/api/index-wallet/feature/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es6", + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/api/index-wallet/feature/tsconfig.spec.json b/libs/api/index-wallet/feature/tsconfig.spec.json new file mode 100644 index 0000000..56497b8 --- /dev/null +++ b/libs/api/index-wallet/feature/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/libs/api/index/data-access/src/lib/api-index-data-admin.service.ts b/libs/api/index/data-access/src/lib/api-index-data-admin.service.ts index 61ecb04..07fe52b 100644 --- a/libs/api/index/data-access/src/lib/api-index-data-admin.service.ts +++ b/libs/api/index/data-access/src/lib/api-index-data-admin.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@nestjs/common' +import { ApiIndexDataService } from './api-index-data.service' import { IndexAdminCreateInput } from './dto/index-admin-create.input' import { IndexAdminFindManyInput } from './dto/index-admin-find-many.input' import { IndexAdminUpdateInput } from './dto/index-admin-update.input' import { IndexPaging } from './entity/index.entity' import { getIndexWhereAdminInput } from './helpers/get-index-where-admin.input' -import { ApiIndexDataService } from './api-index-data.service' @Injectable() export class ApiIndexDataAdminService { @@ -20,7 +20,7 @@ export class ApiIndexDataAdminService { async findManyIndex(input: IndexAdminFindManyInput): Promise { return this.data.findMany({ - orderBy: { createdAt: 'desc' }, + orderBy: [{ type: 'asc' }, { label: 'asc' }], where: getIndexWhereAdminInput(input), limit: input.limit, page: input.page, diff --git a/libs/api/index/data-access/src/lib/api-index-data-user.service.ts b/libs/api/index/data-access/src/lib/api-index-data-user.service.ts index cc8d713..b6ac852 100644 --- a/libs/api/index/data-access/src/lib/api-index-data-user.service.ts +++ b/libs/api/index/data-access/src/lib/api-index-data-user.service.ts @@ -10,7 +10,7 @@ export class ApiIndexDataUserService { async findManyIndex(input: IndexUserFindManyInput): Promise { return this.data.findMany({ - orderBy: { createdAt: 'desc' }, + orderBy: [{ type: 'asc' }, { label: 'asc' }], where: getIndexWhereUserInput(input), limit: input.limit, page: input.page, diff --git a/libs/api/index/data-access/src/lib/api-index-resolver.service.ts b/libs/api/index/data-access/src/lib/api-index-resolver.service.ts index 03a0553..02ad13d 100644 --- a/libs/api/index/data-access/src/lib/api-index-resolver.service.ts +++ b/libs/api/index/data-access/src/lib/api-index-resolver.service.ts @@ -3,6 +3,7 @@ import { publicKey } from '@metaplex-foundation/umi' import { Injectable, Logger } from '@nestjs/common' import { ApiCoreService, NetworkCluster, SolanaAccountInfo } from '@pubkey-resolver/api-core-data-access' import { ApiIndexEntryService } from '@pubkey-resolver/api-index-entry-data-access' +import { ApiWalletService } from '@pubkey-resolver/api-wallet-data-access' import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token' import { AccountInfo, ParsedAccountData, PublicKey } from '@solana/web3.js' import { IndexType } from './entity/index-type.enum' @@ -12,7 +13,12 @@ import { ensureValidSolanaAddress } from './helpers/ensure-valid-solana-address' export class ApiIndexResolverService { private readonly logger = new Logger(ApiIndexResolverService.name) - constructor(private readonly core: ApiCoreService, private readonly indexEntry: ApiIndexEntryService) {} + constructor( + // + private readonly core: ApiCoreService, + private readonly indexEntry: ApiIndexEntryService, + private readonly wallet: ApiWalletService, + ) {} async resolveIndex({ address, cluster }: IndexResolveInput) { ensureValidSolanaAddress(address) @@ -47,38 +53,35 @@ export class ApiIndexResolverService { ensureValidSolanaAddress(address) ensureValidSolanaAddress(wallet) - const found = await this.ensureIndex({ address, cluster }) + const found = await this.ensureIndexWallet({ address, cluster, wallet }) - if (![IndexType.SolanaCollection, IndexType.SolanaMint].includes(found.type)) { + if (![IndexType.SolanaCollection, IndexType.SolanaMint].includes(found.index.type)) { throw new Error(`Index ${address} is not a collection or mint on ${cluster}`) } - if (found.type === IndexType.SolanaMint) { - this.logger.verbose(`Resolving mint ${address} on ${cluster} for wallet ${wallet}`) - const tokenAccounts = await this.core.network.getTokenAccountsByMint({ - cluster, - wallet, - programId: found.program, - mint: found.address, - }) - const result = await this.indexEntry.data.storeTokenAccounts({ - index: found, - tokenAccounts, - }) - - return { - found, - tokenAccounts, - result, + switch (found.index.type) { + case IndexType.SolanaMint: { + this.logger.verbose(`Resolving mint ${address} on ${cluster} for wallet ${wallet}`) + const tokenAccounts = await this.core.network.getTokenAccountsByMint({ + cluster, + wallet, + programId: found.index.program, + mint: found.index.address, + }) + const result = await this.indexEntry.data.storeTokenAccounts({ + index: found.index, + tokenAccounts, + }) + + return { + found, + tokenAccounts, + result, + } } - } - - // getTokenAccountsByMint - - this.logger.verbose(`Resolving wallet ${address} on ${cluster}`) - - return { - found, + default: + // Not implemented + throw new Error(`Index type ${found.index.type} is not implemented`) } } @@ -106,6 +109,33 @@ export class ApiIndexResolverService { } return found } + + private async ensureIndexWallet(input: IndexResolveInput & { wallet: string }) { + const index = await this.ensureIndex(input) + const wallet = await this.wallet.data.findOrCreate(input.wallet) + const found = await this.core.data.indexWallet.findUnique({ + where: { indexId_walletId: { indexId: index.id, walletId: wallet.id } }, + include: { index: true, wallet: true }, + }) + if (found) { + return found + } + this.logger.verbose(`Creating index wallet ${index.id} for wallet ${wallet.id}`) + return this.core.data.indexWallet.create({ + data: { indexId: index.id, walletId: wallet.id }, + include: { index: true, wallet: true }, + }) + } + + private async ensureWallet({ wallet }: { wallet: string }) { + const found = await this.core.data.wallet.findUnique({ + where: { id: wallet }, + }) + if (!found) { + return this.wallet.data.create({ id: wallet }) + } + return found + } } export interface IndexResolveInput { diff --git a/libs/api/index/data-access/src/lib/api-index.data-access.module.ts b/libs/api/index/data-access/src/lib/api-index.data-access.module.ts index 0148489..f3f3173 100644 --- a/libs/api/index/data-access/src/lib/api-index.data-access.module.ts +++ b/libs/api/index/data-access/src/lib/api-index.data-access.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common' import { ApiCoreDataAccessModule } from '@pubkey-resolver/api-core-data-access' import { ApiIndexEntryDataAccessModule } from '@pubkey-resolver/api-index-entry-data-access' +import { ApiWalletDataAccessModule } from '@pubkey-resolver/api-wallet-data-access' import { ApiIndexDataAdminService } from './api-index-data-admin.service' import { ApiIndexDataUserService } from './api-index-data-user.service' import { ApiIndexDataService } from './api-index-data.service' @@ -9,7 +10,7 @@ import { ApiIndexResolverService } from './api-index-resolver.service' import { ApiIndexService } from './api-index.service' @Module({ - imports: [ApiCoreDataAccessModule, ApiIndexEntryDataAccessModule], + imports: [ApiCoreDataAccessModule, ApiIndexEntryDataAccessModule, ApiWalletDataAccessModule], providers: [ ApiIndexService, ApiIndexDataService, diff --git a/libs/api/wallet/data-access/.eslintrc.json b/libs/api/wallet/data-access/.eslintrc.json new file mode 100644 index 0000000..632e9b0 --- /dev/null +++ b/libs/api/wallet/data-access/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/api/wallet/data-access/README.md b/libs/api/wallet/data-access/README.md new file mode 100644 index 0000000..5074369 --- /dev/null +++ b/libs/api/wallet/data-access/README.md @@ -0,0 +1,7 @@ +# api-wallet-data-access + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test api-wallet-data-access` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/api/wallet/data-access/jest.config.ts b/libs/api/wallet/data-access/jest.config.ts new file mode 100644 index 0000000..e262605 --- /dev/null +++ b/libs/api/wallet/data-access/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'api-wallet-data-access', + preset: '../../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../../coverage/libs/api/wallet/data-access', +} diff --git a/libs/api/wallet/data-access/project.json b/libs/api/wallet/data-access/project.json new file mode 100644 index 0000000..181c631 --- /dev/null +++ b/libs/api/wallet/data-access/project.json @@ -0,0 +1,19 @@ +{ + "name": "api-wallet-data-access", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/api/wallet/data-access/src", + "projectType": "library", + "tags": ["app:api", "type:data-access"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/api/wallet/data-access/jest.config.ts" + } + } + } +} diff --git a/libs/api/wallet/data-access/src/index.ts b/libs/api/wallet/data-access/src/index.ts new file mode 100644 index 0000000..b6b1e6e --- /dev/null +++ b/libs/api/wallet/data-access/src/index.ts @@ -0,0 +1,9 @@ +export * from './lib/api-wallet.data-access.module' +export * from './lib/api-wallet.service' +export * from './lib/entity/wallet.entity' +export * from './lib/dto/wallet-admin-create.input' +export * from './lib/dto/wallet-admin-find-many.input' +export * from './lib/dto/wallet-admin-update.input' +export * from './lib/dto/wallet-user-create.input' +export * from './lib/dto/wallet-user-find-many.input' +export * from './lib/dto/wallet-user-update.input' diff --git a/libs/api/wallet/data-access/src/lib/api-wallet-data-admin.service.ts b/libs/api/wallet/data-access/src/lib/api-wallet-data-admin.service.ts new file mode 100644 index 0000000..56d3dfc --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/api-wallet-data-admin.service.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common' +import { WalletAdminCreateInput } from './dto/wallet-admin-create.input' +import { WalletAdminFindManyInput } from './dto/wallet-admin-find-many.input' +import { WalletAdminUpdateInput } from './dto/wallet-admin-update.input' +import { WalletPaging } from './entity/wallet.entity' +import { getWalletWhereAdminInput } from './helpers/get-wallet-where-admin.input' +import { ApiWalletDataService } from './api-wallet-data.service' + +@Injectable() +export class ApiWalletDataAdminService { + constructor(private readonly data: ApiWalletDataService) {} + + async createWallet(input: WalletAdminCreateInput) { + return this.data.create(input) + } + + async deleteWallet(walletId: string) { + return this.data.delete(walletId) + } + + async findManyWallet(input: WalletAdminFindManyInput): Promise { + return this.data.findMany({ + orderBy: { createdAt: 'desc' }, + where: getWalletWhereAdminInput(input), + limit: input.limit, + page: input.page, + }) + } + + async findOneWallet(walletId: string) { + return this.data.findOne(walletId) + } + + async updateWallet(walletId: string, input: WalletAdminUpdateInput) { + return this.data.update(walletId, input) + } +} diff --git a/libs/api/wallet/data-access/src/lib/api-wallet-data-user.service.ts b/libs/api/wallet/data-access/src/lib/api-wallet-data-user.service.ts new file mode 100644 index 0000000..9cb307e --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/api-wallet-data-user.service.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common' +import { WalletUserCreateInput } from './dto/wallet-user-create.input' +import { WalletUserFindManyInput } from './dto/wallet-user-find-many.input' +import { WalletUserUpdateInput } from './dto/wallet-user-update.input' +import { WalletPaging } from './entity/wallet.entity' +import { getWalletWhereUserInput } from './helpers/get-wallet-where-user.input' +import { ApiWalletDataService } from './api-wallet-data.service' + +@Injectable() +export class ApiWalletDataUserService { + constructor(private readonly data: ApiWalletDataService) {} + + async createWallet(input: WalletUserCreateInput) { + return this.data.create(input) + } + + async deleteWallet(walletId: string) { + return this.data.delete(walletId) + } + + async findManyWallet(input: WalletUserFindManyInput): Promise { + return this.data.findMany({ + orderBy: { createdAt: 'desc' }, + where: getWalletWhereUserInput(input), + limit: input.limit, + page: input.page, + }) + } + + async findOneWallet(walletId: string) { + return this.data.findOne(walletId) + } + + async updateWallet(walletId: string, input: WalletUserUpdateInput) { + return this.data.update(walletId, input) + } +} diff --git a/libs/api/wallet/data-access/src/lib/api-wallet-data.service.ts b/libs/api/wallet/data-access/src/lib/api-wallet-data.service.ts new file mode 100644 index 0000000..7f88c83 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/api-wallet-data.service.ts @@ -0,0 +1,54 @@ +import { Injectable, Logger } from '@nestjs/common' +import { Prisma } from '@prisma/client' +import { ApiCoreService, ellipsify, PagingInputFields } from '@pubkey-resolver/api-core-data-access' +import { WalletPaging } from './entity/wallet.entity' + +@Injectable() +export class ApiWalletDataService { + private readonly logger = new Logger(ApiWalletDataService.name) + constructor(private readonly core: ApiCoreService) {} + + async create(input: Omit & { id: string; label?: string }) { + return this.core.data.wallet.create({ + data: { ...input, label: input.label?.trim()?.length ? input.label : ellipsify(input.id) }, + }) + } + + async delete(walletId: string) { + await this.findOne(walletId) + const deleted = await this.core.data.wallet.delete({ where: { id: walletId } }) + return !!deleted + } + + async findMany({ + limit = 10, + page = 1, + ...input + }: Prisma.WalletFindManyArgs & PagingInputFields): Promise { + return this.core.data.wallet + .paginate(input) + .withPages({ limit, page }) + .then(([data, meta]) => ({ data, meta })) + } + + async findOne(walletId: string) { + const found = await this.core.data.wallet.findUnique({ where: { id: walletId } }) + if (!found) { + throw new Error('Wallet not found') + } + return found + } + + async findOrCreate(walletId: string) { + const found = await this.core.data.wallet.findUnique({ where: { id: walletId } }) + if (found) { + return found + } + this.logger.verbose(`Creating wallet ${walletId}`) + return this.create({ id: walletId }) + } + + async update(walletId: string, input: Prisma.WalletUpdateInput) { + return this.core.data.wallet.update({ where: { id: walletId }, data: input }) + } +} diff --git a/libs/api/wallet/data-access/src/lib/api-wallet.data-access.module.ts b/libs/api/wallet/data-access/src/lib/api-wallet.data-access.module.ts new file mode 100644 index 0000000..31aca20 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/api-wallet.data-access.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common' +import { ApiCoreDataAccessModule } from '@pubkey-resolver/api-core-data-access' +import { ApiWalletService } from './api-wallet.service' +import { ApiWalletDataService } from './api-wallet-data.service' +import { ApiWalletDataAdminService } from './api-wallet-data-admin.service' +import { ApiWalletDataUserService } from './api-wallet-data-user.service' + +@Module({ + imports: [ApiCoreDataAccessModule], + providers: [ApiWalletService, ApiWalletDataService, ApiWalletDataAdminService, ApiWalletDataUserService], + exports: [ApiWalletService], +}) +export class ApiWalletDataAccessModule {} diff --git a/libs/api/wallet/data-access/src/lib/api-wallet.service.ts b/libs/api/wallet/data-access/src/lib/api-wallet.service.ts new file mode 100644 index 0000000..1452bb1 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/api-wallet.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@nestjs/common' +import { ApiWalletDataService } from './api-wallet-data.service' +import { ApiWalletDataAdminService } from './api-wallet-data-admin.service' +import { ApiWalletDataUserService } from './api-wallet-data-user.service' + +@Injectable() +export class ApiWalletService { + constructor( + readonly data: ApiWalletDataService, + readonly admin: ApiWalletDataAdminService, + readonly user: ApiWalletDataUserService, + ) {} +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-admin-create.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-create.input.ts new file mode 100644 index 0000000..81884eb --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-create.input.ts @@ -0,0 +1,9 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class WalletAdminCreateInput { + @Field() + id!: string + @Field({ nullable: true }) + label?: string +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-admin-find-many.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-find-many.input.ts new file mode 100644 index 0000000..2dab241 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-find-many.input.ts @@ -0,0 +1,8 @@ +import { Field, InputType } from '@nestjs/graphql' +import { PagingInput } from '@pubkey-resolver/api-core-data-access' + +@InputType() +export class WalletAdminFindManyInput extends PagingInput() { + @Field({ nullable: true }) + search?: string +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-admin-update.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-update.input.ts new file mode 100644 index 0000000..da1421b --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-admin-update.input.ts @@ -0,0 +1,7 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class WalletAdminUpdateInput { + @Field({ nullable: true }) + label?: string +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-user-create.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-user-create.input.ts new file mode 100644 index 0000000..cf909bc --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-user-create.input.ts @@ -0,0 +1,9 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class WalletUserCreateInput { + @Field() + id!: string + @Field({ nullable: true }) + label?: string +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-user-find-many.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-user-find-many.input.ts new file mode 100644 index 0000000..a9a7781 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-user-find-many.input.ts @@ -0,0 +1,8 @@ +import { Field, InputType } from '@nestjs/graphql' +import { PagingInput } from '@pubkey-resolver/api-core-data-access' + +@InputType() +export class WalletUserFindManyInput extends PagingInput() { + @Field({ nullable: true }) + search?: string +} diff --git a/libs/api/wallet/data-access/src/lib/dto/wallet-user-update.input.ts b/libs/api/wallet/data-access/src/lib/dto/wallet-user-update.input.ts new file mode 100644 index 0000000..ffe7326 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/dto/wallet-user-update.input.ts @@ -0,0 +1,7 @@ +import { Field, InputType } from '@nestjs/graphql' + +@InputType() +export class WalletUserUpdateInput { + @Field({ nullable: true }) + label?: string +} diff --git a/libs/api/wallet/data-access/src/lib/entity/wallet.entity.ts b/libs/api/wallet/data-access/src/lib/entity/wallet.entity.ts new file mode 100644 index 0000000..9271e2e --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/entity/wallet.entity.ts @@ -0,0 +1,17 @@ +import { Field, ObjectType } from '@nestjs/graphql' +import { PagingResponse } from '@pubkey-resolver/api-core-data-access' + +@ObjectType() +export class Wallet { + @Field() + id!: string + @Field({ nullable: true }) + createdAt?: Date + @Field({ nullable: true }) + updatedAt?: Date + @Field() + label!: string +} + +@ObjectType() +export class WalletPaging extends PagingResponse(Wallet) {} diff --git a/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-admin.input.ts b/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-admin.input.ts new file mode 100644 index 0000000..6bc2a52 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-admin.input.ts @@ -0,0 +1,15 @@ +import { Prisma } from '@prisma/client' +import { WalletAdminFindManyInput } from '../dto/wallet-admin-find-many.input' + +export function getWalletWhereAdminInput(input: WalletAdminFindManyInput): Prisma.WalletWhereInput { + const where: Prisma.WalletWhereInput = {} + + if (input.search) { + where.OR = [ + { id: { contains: input.search, mode: 'insensitive' } }, + { label: { contains: input.search, mode: 'insensitive' } }, + ] + } + + return where +} diff --git a/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-user.input.ts b/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-user.input.ts new file mode 100644 index 0000000..3c37a87 --- /dev/null +++ b/libs/api/wallet/data-access/src/lib/helpers/get-wallet-where-user.input.ts @@ -0,0 +1,15 @@ +import { Prisma } from '@prisma/client' +import { WalletUserFindManyInput } from '../dto/wallet-user-find-many.input' + +export function getWalletWhereUserInput(input: WalletUserFindManyInput): Prisma.WalletWhereInput { + const where: Prisma.WalletWhereInput = {} + + if (input.search) { + where.OR = [ + { id: { contains: input.search, mode: 'insensitive' } }, + { label: { contains: input.search, mode: 'insensitive' } }, + ] + } + + return where +} diff --git a/libs/api/wallet/data-access/tsconfig.json b/libs/api/wallet/data-access/tsconfig.json new file mode 100644 index 0000000..4022fd4 --- /dev/null +++ b/libs/api/wallet/data-access/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/api/wallet/data-access/tsconfig.lib.json b/libs/api/wallet/data-access/tsconfig.lib.json new file mode 100644 index 0000000..c6b908a --- /dev/null +++ b/libs/api/wallet/data-access/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es6", + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/api/wallet/data-access/tsconfig.spec.json b/libs/api/wallet/data-access/tsconfig.spec.json new file mode 100644 index 0000000..56497b8 --- /dev/null +++ b/libs/api/wallet/data-access/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/libs/api/wallet/feature/.eslintrc.json b/libs/api/wallet/feature/.eslintrc.json new file mode 100644 index 0000000..632e9b0 --- /dev/null +++ b/libs/api/wallet/feature/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/api/wallet/feature/README.md b/libs/api/wallet/feature/README.md new file mode 100644 index 0000000..798131f --- /dev/null +++ b/libs/api/wallet/feature/README.md @@ -0,0 +1,7 @@ +# api-wallet-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test api-wallet-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/api/wallet/feature/jest.config.ts b/libs/api/wallet/feature/jest.config.ts new file mode 100644 index 0000000..f734b7c --- /dev/null +++ b/libs/api/wallet/feature/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'api-wallet-feature', + preset: '../../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../../coverage/libs/api/wallet/feature', +} diff --git a/libs/api/wallet/feature/project.json b/libs/api/wallet/feature/project.json new file mode 100644 index 0000000..945411a --- /dev/null +++ b/libs/api/wallet/feature/project.json @@ -0,0 +1,19 @@ +{ + "name": "api-wallet-feature", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/api/wallet/feature/src", + "projectType": "library", + "tags": ["app:api", "type:feature"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/api/wallet/feature/jest.config.ts" + } + } + } +} diff --git a/libs/api/wallet/feature/src/index.ts b/libs/api/wallet/feature/src/index.ts new file mode 100644 index 0000000..8a06ab4 --- /dev/null +++ b/libs/api/wallet/feature/src/index.ts @@ -0,0 +1 @@ +export * from './lib/api-wallet.feature.module' diff --git a/libs/api/wallet/feature/src/lib/api-wallet-admin.resolver.ts b/libs/api/wallet/feature/src/lib/api-wallet-admin.resolver.ts new file mode 100644 index 0000000..78470a3 --- /dev/null +++ b/libs/api/wallet/feature/src/lib/api-wallet-admin.resolver.ts @@ -0,0 +1,43 @@ +import { Resolver } from '@nestjs/graphql' +import { ApiWalletService } from '@pubkey-resolver/api-wallet-data-access' +import { ApiAuthGraphQLAdminGuard } from '@pubkey-resolver/api-auth-data-access' +import { Mutation, Query, Args } from '@nestjs/graphql' +import { UseGuards } from '@nestjs/common' +import { + WalletAdminCreateInput, + WalletAdminFindManyInput, + Wallet, + WalletPaging, + WalletAdminUpdateInput, +} from '@pubkey-resolver/api-wallet-data-access' + +@Resolver() +@UseGuards(ApiAuthGraphQLAdminGuard) +export class ApiWalletAdminResolver { + constructor(private readonly service: ApiWalletService) {} + + @Mutation(() => Wallet, { nullable: true }) + adminCreateWallet(@Args('input') input: WalletAdminCreateInput) { + return this.service.admin.createWallet(input) + } + + @Mutation(() => Boolean, { nullable: true }) + adminDeleteWallet(@Args('walletId') walletId: string) { + return this.service.admin.deleteWallet(walletId) + } + + @Query(() => WalletPaging) + adminFindManyWallet(@Args('input') input: WalletAdminFindManyInput) { + return this.service.admin.findManyWallet(input) + } + + @Query(() => Wallet, { nullable: true }) + adminFindOneWallet(@Args('walletId') walletId: string) { + return this.service.admin.findOneWallet(walletId) + } + + @Mutation(() => Wallet, { nullable: true }) + adminUpdateWallet(@Args('walletId') walletId: string, @Args('input') input: WalletAdminUpdateInput) { + return this.service.admin.updateWallet(walletId, input) + } +} diff --git a/libs/api/wallet/feature/src/lib/api-wallet-user.resolver.ts b/libs/api/wallet/feature/src/lib/api-wallet-user.resolver.ts new file mode 100644 index 0000000..23e835a --- /dev/null +++ b/libs/api/wallet/feature/src/lib/api-wallet-user.resolver.ts @@ -0,0 +1,43 @@ +import { Resolver } from '@nestjs/graphql' +import { ApiWalletService } from '@pubkey-resolver/api-wallet-data-access' +import { ApiAuthGraphQLUserGuard } from '@pubkey-resolver/api-auth-data-access' +import { Mutation, Query, Args } from '@nestjs/graphql' +import { UseGuards } from '@nestjs/common' +import { + WalletUserCreateInput, + WalletUserFindManyInput, + Wallet, + WalletPaging, + WalletUserUpdateInput, +} from '@pubkey-resolver/api-wallet-data-access' + +@Resolver() +@UseGuards(ApiAuthGraphQLUserGuard) +export class ApiWalletUserResolver { + constructor(private readonly service: ApiWalletService) {} + + @Mutation(() => Wallet, { nullable: true }) + userCreateWallet(@Args('input') input: WalletUserCreateInput) { + return this.service.user.createWallet(input) + } + + @Mutation(() => Boolean, { nullable: true }) + userDeleteWallet(@Args('walletId') walletId: string) { + return this.service.user.deleteWallet(walletId) + } + + @Query(() => WalletPaging) + userFindManyWallet(@Args('input') input: WalletUserFindManyInput) { + return this.service.user.findManyWallet(input) + } + + @Query(() => Wallet, { nullable: true }) + userFindOneWallet(@Args('walletId') walletId: string) { + return this.service.user.findOneWallet(walletId) + } + + @Mutation(() => Wallet, { nullable: true }) + userUpdateWallet(@Args('walletId') walletId: string, @Args('input') input: WalletUserUpdateInput) { + return this.service.user.updateWallet(walletId, input) + } +} diff --git a/libs/api/wallet/feature/src/lib/api-wallet.feature.module.ts b/libs/api/wallet/feature/src/lib/api-wallet.feature.module.ts new file mode 100644 index 0000000..7050ef2 --- /dev/null +++ b/libs/api/wallet/feature/src/lib/api-wallet.feature.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common' +import { ApiWalletDataAccessModule } from '@pubkey-resolver/api-wallet-data-access' +import { ApiWalletResolver } from './api-wallet.resolver' +import { ApiWalletAdminResolver } from './api-wallet-admin.resolver' +import { ApiWalletUserResolver } from './api-wallet-user.resolver' + +@Module({ + imports: [ApiWalletDataAccessModule], + providers: [ApiWalletResolver, ApiWalletAdminResolver, ApiWalletUserResolver], +}) +export class ApiWalletFeatureModule {} diff --git a/libs/api/wallet/feature/src/lib/api-wallet.resolver.ts b/libs/api/wallet/feature/src/lib/api-wallet.resolver.ts new file mode 100644 index 0000000..dcddf40 --- /dev/null +++ b/libs/api/wallet/feature/src/lib/api-wallet.resolver.ts @@ -0,0 +1,8 @@ +import { Resolver } from '@nestjs/graphql' +import { ApiWalletService } from '@pubkey-resolver/api-wallet-data-access' +import { Wallet } from '@pubkey-resolver/api-wallet-data-access' + +@Resolver(() => Wallet) +export class ApiWalletResolver { + constructor(private readonly service: ApiWalletService) {} +} diff --git a/libs/api/wallet/feature/tsconfig.json b/libs/api/wallet/feature/tsconfig.json new file mode 100644 index 0000000..4022fd4 --- /dev/null +++ b/libs/api/wallet/feature/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/api/wallet/feature/tsconfig.lib.json b/libs/api/wallet/feature/tsconfig.lib.json new file mode 100644 index 0000000..c6b908a --- /dev/null +++ b/libs/api/wallet/feature/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es6", + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/api/wallet/feature/tsconfig.spec.json b/libs/api/wallet/feature/tsconfig.spec.json new file mode 100644 index 0000000..56497b8 --- /dev/null +++ b/libs/api/wallet/feature/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/libs/sdk/src/generated/graphql-sdk.ts b/libs/sdk/src/generated/graphql-sdk.ts index e4b63c2..87df150 100644 --- a/libs/sdk/src/generated/graphql-sdk.ts +++ b/libs/sdk/src/generated/graphql-sdk.ts @@ -116,7 +116,7 @@ export type IndexEntry = { label?: Maybe program: Scalars['String']['output'] updatedAt?: Maybe - wallet: Scalars['String']['output'] + walletId: Scalars['String']['output'] } export type IndexEntryAdminFindManyInput = { @@ -160,6 +160,45 @@ export type IndexUserFindManyInput = { type?: InputMaybe } +export type IndexWallet = { + __typename?: 'IndexWallet' + createdAt?: Maybe + id: Scalars['String']['output'] + index?: Maybe + indexId: Scalars['String']['output'] + updatedAt?: Maybe + wallet?: Maybe + walletId: Scalars['String']['output'] +} + +export type IndexWalletAdminFindManyInput = { + limit?: InputMaybe + page?: InputMaybe + search?: InputMaybe + walletId: Scalars['String']['input'] +} + +export type IndexWalletAdminUpdateInput = { + updatedAt?: InputMaybe +} + +export type IndexWalletPaging = { + __typename?: 'IndexWalletPaging' + data: Array + meta: PagingMeta +} + +export type IndexWalletUserFindManyInput = { + limit?: InputMaybe + page?: InputMaybe + search?: InputMaybe + walletId: Scalars['String']['input'] +} + +export type IndexWalletUserUpdateInput = { + updatedAt?: InputMaybe +} + export type LoginInput = { password: Scalars['String']['input'] username: Scalars['String']['input'] @@ -170,17 +209,27 @@ export type Mutation = { adminCreateIdentity?: Maybe adminCreateIndex?: Maybe adminCreateUser?: Maybe + adminCreateWallet?: Maybe adminDeleteIdentity?: Maybe adminDeleteIndex?: Maybe adminDeleteIndexEntry?: Maybe + adminDeleteIndexWallet?: Maybe adminDeleteUser?: Maybe + adminDeleteWallet?: Maybe adminUpdateIndex?: Maybe + adminUpdateIndexWallet?: Maybe adminUpdateUser?: Maybe + adminUpdateWallet?: Maybe login?: Maybe logout?: Maybe register?: Maybe + userCreateWallet?: Maybe userDeleteIdentity?: Maybe + userDeleteIndexWallet?: Maybe + userDeleteWallet?: Maybe + userUpdateIndexWallet?: Maybe userUpdateUser?: Maybe + userUpdateWallet?: Maybe } export type MutationAdminCreateIdentityArgs = { @@ -195,6 +244,10 @@ export type MutationAdminCreateUserArgs = { input: UserAdminCreateInput } +export type MutationAdminCreateWalletArgs = { + input: WalletAdminCreateInput +} + export type MutationAdminDeleteIdentityArgs = { identityId: Scalars['String']['input'] } @@ -207,20 +260,38 @@ export type MutationAdminDeleteIndexEntryArgs = { indexEntryId: Scalars['String']['input'] } +export type MutationAdminDeleteIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] +} + export type MutationAdminDeleteUserArgs = { userId: Scalars['String']['input'] } +export type MutationAdminDeleteWalletArgs = { + walletId: Scalars['String']['input'] +} + export type MutationAdminUpdateIndexArgs = { indexId: Scalars['String']['input'] input: IndexAdminUpdateInput } +export type MutationAdminUpdateIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] + input: IndexWalletAdminUpdateInput +} + export type MutationAdminUpdateUserArgs = { input: UserAdminUpdateInput userId: Scalars['String']['input'] } +export type MutationAdminUpdateWalletArgs = { + input: WalletAdminUpdateInput + walletId: Scalars['String']['input'] +} + export type MutationLoginArgs = { input: LoginInput } @@ -229,14 +300,36 @@ export type MutationRegisterArgs = { input: RegisterInput } +export type MutationUserCreateWalletArgs = { + input: WalletUserCreateInput +} + export type MutationUserDeleteIdentityArgs = { identityId: Scalars['String']['input'] } +export type MutationUserDeleteIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] +} + +export type MutationUserDeleteWalletArgs = { + walletId: Scalars['String']['input'] +} + +export type MutationUserUpdateIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] + input: IndexWalletUserUpdateInput +} + export type MutationUserUpdateUserArgs = { input: UserUserUpdateInput } +export type MutationUserUpdateWalletArgs = { + input: WalletUserUpdateInput + walletId: Scalars['String']['input'] +} + export enum NetworkCluster { SolanaCustom = 'SolanaCustom', SolanaDevnet = 'SolanaDevnet', @@ -260,10 +353,14 @@ export type Query = { adminFindManyIdentity?: Maybe> adminFindManyIndex: IndexPaging adminFindManyIndexEntry: IndexEntryPaging + adminFindManyIndexWallet: IndexWalletPaging adminFindManyUser: UserPaging + adminFindManyWallet: WalletPaging adminFindOneIndex?: Maybe adminFindOneIndexEntry?: Maybe + adminFindOneIndexWallet?: Maybe adminFindOneUser?: Maybe + adminFindOneWallet?: Maybe adminGetAccountInfo?: Maybe adminResolveIndex?: Maybe adminResolveWallet?: Maybe @@ -273,10 +370,14 @@ export type Query = { userFindManyIdentity?: Maybe> userFindManyIndex: IndexPaging userFindManyIndexEntry: IndexEntryPaging + userFindManyIndexWallet: IndexWalletPaging userFindManyUser: UserPaging + userFindManyWallet: WalletPaging userFindOneIndex?: Maybe userFindOneIndexEntry?: Maybe + userFindOneIndexWallet?: Maybe userFindOneUser?: Maybe + userFindOneWallet?: Maybe } export type QueryAdminFindManyIdentityArgs = { @@ -291,10 +392,18 @@ export type QueryAdminFindManyIndexEntryArgs = { input: IndexEntryAdminFindManyInput } +export type QueryAdminFindManyIndexWalletArgs = { + input: IndexWalletAdminFindManyInput +} + export type QueryAdminFindManyUserArgs = { input: UserAdminFindManyInput } +export type QueryAdminFindManyWalletArgs = { + input: WalletAdminFindManyInput +} + export type QueryAdminFindOneIndexArgs = { indexId: Scalars['String']['input'] } @@ -303,10 +412,18 @@ export type QueryAdminFindOneIndexEntryArgs = { indexEntryId: Scalars['String']['input'] } +export type QueryAdminFindOneIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] +} + export type QueryAdminFindOneUserArgs = { userId: Scalars['String']['input'] } +export type QueryAdminFindOneWalletArgs = { + walletId: Scalars['String']['input'] +} + export type QueryAdminGetAccountInfoArgs = { input: IndexAdminResolveInput } @@ -332,10 +449,18 @@ export type QueryUserFindManyIndexEntryArgs = { input: IndexEntryUserFindManyInput } +export type QueryUserFindManyIndexWalletArgs = { + input: IndexWalletUserFindManyInput +} + export type QueryUserFindManyUserArgs = { input: UserUserFindManyInput } +export type QueryUserFindManyWalletArgs = { + input: WalletUserFindManyInput +} + export type QueryUserFindOneIndexArgs = { indexId: Scalars['String']['input'] } @@ -344,10 +469,18 @@ export type QueryUserFindOneIndexEntryArgs = { indexEntryId: Scalars['String']['input'] } +export type QueryUserFindOneIndexWalletArgs = { + indexWalletId: Scalars['String']['input'] +} + export type QueryUserFindOneUserArgs = { username: Scalars['String']['input'] } +export type QueryUserFindOneWalletArgs = { + walletId: Scalars['String']['input'] +} + export type RegisterInput = { password: Scalars['String']['input'] username: Scalars['String']['input'] @@ -419,6 +552,50 @@ export type UserUserUpdateInput = { name?: InputMaybe } +export type Wallet = { + __typename?: 'Wallet' + createdAt?: Maybe + id: Scalars['String']['output'] + label: Scalars['String']['output'] + updatedAt?: Maybe +} + +export type WalletAdminCreateInput = { + id: Scalars['String']['input'] + label?: InputMaybe +} + +export type WalletAdminFindManyInput = { + limit?: InputMaybe + page?: InputMaybe + search?: InputMaybe +} + +export type WalletAdminUpdateInput = { + label?: InputMaybe +} + +export type WalletPaging = { + __typename?: 'WalletPaging' + data: Array + meta: PagingMeta +} + +export type WalletUserCreateInput = { + id: Scalars['String']['input'] + label?: InputMaybe +} + +export type WalletUserFindManyInput = { + limit?: InputMaybe + page?: InputMaybe + search?: InputMaybe +} + +export type WalletUserUpdateInput = { + label?: InputMaybe +} + export type LoginMutationVariables = Exact<{ input: LoginInput }> @@ -632,7 +809,7 @@ export type IndexEntryDetailsFragment = { data?: any | null dataHash?: string | null program: string - wallet: string + walletId: string updatedAt?: Date | null } @@ -656,7 +833,7 @@ export type AdminFindManyIndexEntryQuery = { data?: any | null dataHash?: string | null program: string - wallet: string + walletId: string updatedAt?: Date | null }> meta: { @@ -690,7 +867,7 @@ export type AdminFindOneIndexEntryQuery = { data?: any | null dataHash?: string | null program: string - wallet: string + walletId: string updatedAt?: Date | null } | null } @@ -721,7 +898,7 @@ export type UserFindManyIndexEntryQuery = { data?: any | null dataHash?: string | null program: string - wallet: string + walletId: string updatedAt?: Date | null }> meta: { @@ -755,8 +932,244 @@ export type UserFindOneIndexEntryQuery = { data?: any | null dataHash?: string | null program: string - wallet: string + walletId: string + updatedAt?: Date | null + } | null +} + +export type IndexWalletDetailsFragment = { + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null +} + +export type AdminFindManyIndexWalletQueryVariables = Exact<{ + input: IndexWalletAdminFindManyInput +}> + +export type AdminFindManyIndexWalletQuery = { + __typename?: 'Query' + paging: { + __typename?: 'IndexWalletPaging' + data: Array<{ + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null + }> + meta: { + __typename?: 'PagingMeta' + currentPage: number + isFirstPage: boolean + isLastPage: boolean + nextPage?: number | null + pageCount?: number | null + previousPage?: number | null + totalCount?: number | null + } + } +} + +export type AdminFindOneIndexWalletQueryVariables = Exact<{ + indexWalletId: Scalars['String']['input'] +}> + +export type AdminFindOneIndexWalletQuery = { + __typename?: 'Query' + item?: { + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null + } | null +} + +export type AdminDeleteIndexWalletMutationVariables = Exact<{ + indexWalletId: Scalars['String']['input'] +}> + +export type AdminDeleteIndexWalletMutation = { __typename?: 'Mutation'; deleted?: boolean | null } + +export type AdminUpdateIndexWalletMutationVariables = Exact<{ + indexWalletId: Scalars['String']['input'] + input: IndexWalletAdminUpdateInput +}> + +export type AdminUpdateIndexWalletMutation = { + __typename?: 'Mutation' + updated?: { + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null + } | null +} + +export type UserFindManyIndexWalletQueryVariables = Exact<{ + input: IndexWalletUserFindManyInput +}> + +export type UserFindManyIndexWalletQuery = { + __typename?: 'Query' + paging: { + __typename?: 'IndexWalletPaging' + data: Array<{ + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null + }> + meta: { + __typename?: 'PagingMeta' + currentPage: number + isFirstPage: boolean + isLastPage: boolean + nextPage?: number | null + pageCount?: number | null + previousPage?: number | null + totalCount?: number | null + } + } +} + +export type UserFindOneIndexWalletQueryVariables = Exact<{ + indexWalletId: Scalars['String']['input'] +}> + +export type UserFindOneIndexWalletQuery = { + __typename?: 'Query' + item?: { + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string + updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null + } | null +} + +export type UserDeleteIndexWalletMutationVariables = Exact<{ + indexWalletId: Scalars['String']['input'] +}> + +export type UserDeleteIndexWalletMutation = { __typename?: 'Mutation'; deleted?: boolean | null } + +export type UserUpdateIndexWalletMutationVariables = Exact<{ + indexWalletId: Scalars['String']['input'] + input: IndexWalletUserUpdateInput +}> + +export type UserUpdateIndexWalletMutation = { + __typename?: 'Mutation' + updated?: { + __typename?: 'IndexWallet' + createdAt?: Date | null + id: string + indexId: string + walletId: string updatedAt?: Date | null + index?: { + __typename?: 'Index' + createdAt?: Date | null + id: string + type: IndexType + cluster: NetworkCluster + address: string + label?: string | null + data?: any | null + dataHash?: string | null + program: string + updatedAt?: Date | null + } | null } | null } @@ -1159,17 +1572,161 @@ export type UserUpdateUserMutation = { } | null } -export const AppConfigDetailsFragmentDoc = gql` - fragment AppConfigDetails on AppConfig { - authGithubEnabled - authPasswordEnabled - authRegisterEnabled - } -` -export const PagingMetaDetailsFragmentDoc = gql` - fragment PagingMetaDetails on PagingMeta { - currentPage - isFirstPage +export type WalletDetailsFragment = { + __typename?: 'Wallet' + createdAt?: Date | null + id: string + label: string + updatedAt?: Date | null +} + +export type AdminFindManyWalletQueryVariables = Exact<{ + input: WalletAdminFindManyInput +}> + +export type AdminFindManyWalletQuery = { + __typename?: 'Query' + paging: { + __typename?: 'WalletPaging' + data: Array<{ __typename?: 'Wallet'; createdAt?: Date | null; id: string; label: string; updatedAt?: Date | null }> + meta: { + __typename?: 'PagingMeta' + currentPage: number + isFirstPage: boolean + isLastPage: boolean + nextPage?: number | null + pageCount?: number | null + previousPage?: number | null + totalCount?: number | null + } + } +} + +export type AdminFindOneWalletQueryVariables = Exact<{ + walletId: Scalars['String']['input'] +}> + +export type AdminFindOneWalletQuery = { + __typename?: 'Query' + item?: { __typename?: 'Wallet'; createdAt?: Date | null; id: string; label: string; updatedAt?: Date | null } | null +} + +export type AdminCreateWalletMutationVariables = Exact<{ + input: WalletAdminCreateInput +}> + +export type AdminCreateWalletMutation = { + __typename?: 'Mutation' + created?: { + __typename?: 'Wallet' + createdAt?: Date | null + id: string + label: string + updatedAt?: Date | null + } | null +} + +export type AdminUpdateWalletMutationVariables = Exact<{ + walletId: Scalars['String']['input'] + input: WalletAdminUpdateInput +}> + +export type AdminUpdateWalletMutation = { + __typename?: 'Mutation' + updated?: { + __typename?: 'Wallet' + createdAt?: Date | null + id: string + label: string + updatedAt?: Date | null + } | null +} + +export type AdminDeleteWalletMutationVariables = Exact<{ + walletId: Scalars['String']['input'] +}> + +export type AdminDeleteWalletMutation = { __typename?: 'Mutation'; deleted?: boolean | null } + +export type UserFindManyWalletQueryVariables = Exact<{ + input: WalletUserFindManyInput +}> + +export type UserFindManyWalletQuery = { + __typename?: 'Query' + paging: { + __typename?: 'WalletPaging' + data: Array<{ __typename?: 'Wallet'; createdAt?: Date | null; id: string; label: string; updatedAt?: Date | null }> + meta: { + __typename?: 'PagingMeta' + currentPage: number + isFirstPage: boolean + isLastPage: boolean + nextPage?: number | null + pageCount?: number | null + previousPage?: number | null + totalCount?: number | null + } + } +} + +export type UserFindOneWalletQueryVariables = Exact<{ + walletId: Scalars['String']['input'] +}> + +export type UserFindOneWalletQuery = { + __typename?: 'Query' + item?: { __typename?: 'Wallet'; createdAt?: Date | null; id: string; label: string; updatedAt?: Date | null } | null +} + +export type UserCreateWalletMutationVariables = Exact<{ + input: WalletUserCreateInput +}> + +export type UserCreateWalletMutation = { + __typename?: 'Mutation' + created?: { + __typename?: 'Wallet' + createdAt?: Date | null + id: string + label: string + updatedAt?: Date | null + } | null +} + +export type UserUpdateWalletMutationVariables = Exact<{ + walletId: Scalars['String']['input'] + input: WalletUserUpdateInput +}> + +export type UserUpdateWalletMutation = { + __typename?: 'Mutation' + updated?: { + __typename?: 'Wallet' + createdAt?: Date | null + id: string + label: string + updatedAt?: Date | null + } | null +} + +export type UserDeleteWalletMutationVariables = Exact<{ + walletId: Scalars['String']['input'] +}> + +export type UserDeleteWalletMutation = { __typename?: 'Mutation'; deleted?: boolean | null } + +export const AppConfigDetailsFragmentDoc = gql` + fragment AppConfigDetails on AppConfig { + authGithubEnabled + authPasswordEnabled + authRegisterEnabled + } +` +export const PagingMetaDetailsFragmentDoc = gql` + fragment PagingMetaDetails on PagingMeta { + currentPage + isFirstPage isLastPage nextPage pageCount @@ -1203,7 +1760,7 @@ export const IndexEntryDetailsFragmentDoc = gql` data dataHash program - wallet + walletId updatedAt } ` @@ -1221,6 +1778,19 @@ export const IndexDetailsFragmentDoc = gql` updatedAt } ` +export const IndexWalletDetailsFragmentDoc = gql` + fragment IndexWalletDetails on IndexWallet { + createdAt + id + index { + ...IndexDetails + } + indexId + walletId + updatedAt + } + ${IndexDetailsFragmentDoc} +` export const UserDetailsFragmentDoc = gql` fragment UserDetails on User { avatarUrl @@ -1235,6 +1805,14 @@ export const UserDetailsFragmentDoc = gql` username } ` +export const WalletDetailsFragmentDoc = gql` + fragment WalletDetails on Wallet { + createdAt + id + label + updatedAt + } +` export const LoginDocument = gql` mutation login($input: LoginInput!) { login(input: $input) { @@ -1364,6 +1942,76 @@ export const UserFindOneIndexEntryDocument = gql` } ${IndexEntryDetailsFragmentDoc} ` +export const AdminFindManyIndexWalletDocument = gql` + query adminFindManyIndexWallet($input: IndexWalletAdminFindManyInput!) { + paging: adminFindManyIndexWallet(input: $input) { + data { + ...IndexWalletDetails + } + meta { + ...PagingMetaDetails + } + } + } + ${IndexWalletDetailsFragmentDoc} + ${PagingMetaDetailsFragmentDoc} +` +export const AdminFindOneIndexWalletDocument = gql` + query adminFindOneIndexWallet($indexWalletId: String!) { + item: adminFindOneIndexWallet(indexWalletId: $indexWalletId) { + ...IndexWalletDetails + } + } + ${IndexWalletDetailsFragmentDoc} +` +export const AdminDeleteIndexWalletDocument = gql` + mutation adminDeleteIndexWallet($indexWalletId: String!) { + deleted: adminDeleteIndexWallet(indexWalletId: $indexWalletId) + } +` +export const AdminUpdateIndexWalletDocument = gql` + mutation adminUpdateIndexWallet($indexWalletId: String!, $input: IndexWalletAdminUpdateInput!) { + updated: adminUpdateIndexWallet(indexWalletId: $indexWalletId, input: $input) { + ...IndexWalletDetails + } + } + ${IndexWalletDetailsFragmentDoc} +` +export const UserFindManyIndexWalletDocument = gql` + query userFindManyIndexWallet($input: IndexWalletUserFindManyInput!) { + paging: userFindManyIndexWallet(input: $input) { + data { + ...IndexWalletDetails + } + meta { + ...PagingMetaDetails + } + } + } + ${IndexWalletDetailsFragmentDoc} + ${PagingMetaDetailsFragmentDoc} +` +export const UserFindOneIndexWalletDocument = gql` + query userFindOneIndexWallet($indexWalletId: String!) { + item: userFindOneIndexWallet(indexWalletId: $indexWalletId) { + ...IndexWalletDetails + } + } + ${IndexWalletDetailsFragmentDoc} +` +export const UserDeleteIndexWalletDocument = gql` + mutation userDeleteIndexWallet($indexWalletId: String!) { + deleted: userDeleteIndexWallet(indexWalletId: $indexWalletId) + } +` +export const UserUpdateIndexWalletDocument = gql` + mutation userUpdateIndexWallet($indexWalletId: String!, $input: IndexWalletUserUpdateInput!) { + updated: userUpdateIndexWallet(indexWalletId: $indexWalletId, input: $input) { + ...IndexWalletDetails + } + } + ${IndexWalletDetailsFragmentDoc} +` export const AdminFindManyIndexDocument = gql` query adminFindManyIndex($input: IndexAdminFindManyInput!) { paging: adminFindManyIndex(input: $input) { @@ -1521,6 +2169,92 @@ export const UserUpdateUserDocument = gql` } ${UserDetailsFragmentDoc} ` +export const AdminFindManyWalletDocument = gql` + query adminFindManyWallet($input: WalletAdminFindManyInput!) { + paging: adminFindManyWallet(input: $input) { + data { + ...WalletDetails + } + meta { + ...PagingMetaDetails + } + } + } + ${WalletDetailsFragmentDoc} + ${PagingMetaDetailsFragmentDoc} +` +export const AdminFindOneWalletDocument = gql` + query adminFindOneWallet($walletId: String!) { + item: adminFindOneWallet(walletId: $walletId) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const AdminCreateWalletDocument = gql` + mutation adminCreateWallet($input: WalletAdminCreateInput!) { + created: adminCreateWallet(input: $input) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const AdminUpdateWalletDocument = gql` + mutation adminUpdateWallet($walletId: String!, $input: WalletAdminUpdateInput!) { + updated: adminUpdateWallet(walletId: $walletId, input: $input) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const AdminDeleteWalletDocument = gql` + mutation adminDeleteWallet($walletId: String!) { + deleted: adminDeleteWallet(walletId: $walletId) + } +` +export const UserFindManyWalletDocument = gql` + query userFindManyWallet($input: WalletUserFindManyInput!) { + paging: userFindManyWallet(input: $input) { + data { + ...WalletDetails + } + meta { + ...PagingMetaDetails + } + } + } + ${WalletDetailsFragmentDoc} + ${PagingMetaDetailsFragmentDoc} +` +export const UserFindOneWalletDocument = gql` + query userFindOneWallet($walletId: String!) { + item: userFindOneWallet(walletId: $walletId) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const UserCreateWalletDocument = gql` + mutation userCreateWallet($input: WalletUserCreateInput!) { + created: userCreateWallet(input: $input) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const UserUpdateWalletDocument = gql` + mutation userUpdateWallet($walletId: String!, $input: WalletUserUpdateInput!) { + updated: userUpdateWallet(walletId: $walletId, input: $input) { + ...WalletDetails + } + } + ${WalletDetailsFragmentDoc} +` +export const UserDeleteWalletDocument = gql` + mutation userDeleteWallet($walletId: String!) { + deleted: userDeleteWallet(walletId: $walletId) + } +` export type SdkFunctionWrapper = ( action: (requestHeaders?: Record) => Promise, @@ -1546,6 +2280,14 @@ const AdminFindOneIndexEntryDocumentString = print(AdminFindOneIndexEntryDocumen const AdminDeleteIndexEntryDocumentString = print(AdminDeleteIndexEntryDocument) const UserFindManyIndexEntryDocumentString = print(UserFindManyIndexEntryDocument) const UserFindOneIndexEntryDocumentString = print(UserFindOneIndexEntryDocument) +const AdminFindManyIndexWalletDocumentString = print(AdminFindManyIndexWalletDocument) +const AdminFindOneIndexWalletDocumentString = print(AdminFindOneIndexWalletDocument) +const AdminDeleteIndexWalletDocumentString = print(AdminDeleteIndexWalletDocument) +const AdminUpdateIndexWalletDocumentString = print(AdminUpdateIndexWalletDocument) +const UserFindManyIndexWalletDocumentString = print(UserFindManyIndexWalletDocument) +const UserFindOneIndexWalletDocumentString = print(UserFindOneIndexWalletDocument) +const UserDeleteIndexWalletDocumentString = print(UserDeleteIndexWalletDocument) +const UserUpdateIndexWalletDocumentString = print(UserUpdateIndexWalletDocument) const AdminFindManyIndexDocumentString = print(AdminFindManyIndexDocument) const AdminFindOneIndexDocumentString = print(AdminFindOneIndexDocument) const AdminGetAccountInfoDocumentString = print(AdminGetAccountInfoDocument) @@ -1564,6 +2306,16 @@ const AdminUpdateUserDocumentString = print(AdminUpdateUserDocument) const UserFindManyUserDocumentString = print(UserFindManyUserDocument) const UserFindOneUserDocumentString = print(UserFindOneUserDocument) const UserUpdateUserDocumentString = print(UserUpdateUserDocument) +const AdminFindManyWalletDocumentString = print(AdminFindManyWalletDocument) +const AdminFindOneWalletDocumentString = print(AdminFindOneWalletDocument) +const AdminCreateWalletDocumentString = print(AdminCreateWalletDocument) +const AdminUpdateWalletDocumentString = print(AdminUpdateWalletDocument) +const AdminDeleteWalletDocumentString = print(AdminDeleteWalletDocument) +const UserFindManyWalletDocumentString = print(UserFindManyWalletDocument) +const UserFindOneWalletDocumentString = print(UserFindOneWalletDocument) +const UserCreateWalletDocumentString = print(UserCreateWalletDocument) +const UserUpdateWalletDocumentString = print(UserUpdateWalletDocument) +const UserDeleteWalletDocumentString = print(UserDeleteWalletDocument) export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) { return { login( @@ -1869,11 +2621,11 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = variables, ) }, - adminFindManyIndex( - variables: AdminFindManyIndexQueryVariables, + adminFindManyIndexWallet( + variables: AdminFindManyIndexWalletQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminFindManyIndexQuery + data: AdminFindManyIndexWalletQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -1881,20 +2633,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminFindManyIndexDocumentString, variables, { + client.rawRequest(AdminFindManyIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminFindManyIndex', + 'adminFindManyIndexWallet', 'query', variables, ) }, - adminFindOneIndex( - variables: AdminFindOneIndexQueryVariables, + adminFindOneIndexWallet( + variables: AdminFindOneIndexWalletQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminFindOneIndexQuery + data: AdminFindOneIndexWalletQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -1902,20 +2654,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminFindOneIndexDocumentString, variables, { + client.rawRequest(AdminFindOneIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminFindOneIndex', + 'adminFindOneIndexWallet', 'query', variables, ) }, - adminGetAccountInfo( - variables: AdminGetAccountInfoQueryVariables, + adminDeleteIndexWallet( + variables: AdminDeleteIndexWalletMutationVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminGetAccountInfoQuery + data: AdminDeleteIndexWalletMutation errors?: GraphQLError[] extensions?: any headers: Headers @@ -1923,20 +2675,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminGetAccountInfoDocumentString, variables, { + client.rawRequest(AdminDeleteIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminGetAccountInfo', - 'query', + 'adminDeleteIndexWallet', + 'mutation', variables, ) }, - adminResolveIndex( - variables: AdminResolveIndexQueryVariables, + adminUpdateIndexWallet( + variables: AdminUpdateIndexWalletMutationVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminResolveIndexQuery + data: AdminUpdateIndexWalletMutation errors?: GraphQLError[] extensions?: any headers: Headers @@ -1944,20 +2696,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminResolveIndexDocumentString, variables, { + client.rawRequest(AdminUpdateIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminResolveIndex', - 'query', + 'adminUpdateIndexWallet', + 'mutation', variables, ) }, - adminResolveWallet( - variables: AdminResolveWalletQueryVariables, + userFindManyIndexWallet( + variables: UserFindManyIndexWalletQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminResolveWalletQuery + data: UserFindManyIndexWalletQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -1965,20 +2717,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminResolveWalletDocumentString, variables, { + client.rawRequest(UserFindManyIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminResolveWallet', + 'userFindManyIndexWallet', 'query', variables, ) }, - adminCreateIndex( - variables: AdminCreateIndexMutationVariables, + userFindOneIndexWallet( + variables: UserFindOneIndexWalletQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminCreateIndexMutation + data: UserFindOneIndexWalletQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -1986,20 +2738,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminCreateIndexDocumentString, variables, { + client.rawRequest(UserFindOneIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminCreateIndex', - 'mutation', + 'userFindOneIndexWallet', + 'query', variables, ) }, - adminUpdateIndex( - variables: AdminUpdateIndexMutationVariables, + userDeleteIndexWallet( + variables: UserDeleteIndexWalletMutationVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminUpdateIndexMutation + data: UserDeleteIndexWalletMutation errors?: GraphQLError[] extensions?: any headers: Headers @@ -2007,20 +2759,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminUpdateIndexDocumentString, variables, { + client.rawRequest(UserDeleteIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminUpdateIndex', + 'userDeleteIndexWallet', 'mutation', variables, ) }, - adminDeleteIndex( - variables: AdminDeleteIndexMutationVariables, + userUpdateIndexWallet( + variables: UserUpdateIndexWalletMutationVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: AdminDeleteIndexMutation + data: UserUpdateIndexWalletMutation errors?: GraphQLError[] extensions?: any headers: Headers @@ -2028,20 +2780,20 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(AdminDeleteIndexDocumentString, variables, { + client.rawRequest(UserUpdateIndexWalletDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'adminDeleteIndex', + 'userUpdateIndexWallet', 'mutation', variables, ) }, - userFindManyIndex( - variables: UserFindManyIndexQueryVariables, + adminFindManyIndex( + variables: AdminFindManyIndexQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: UserFindManyIndexQuery + data: AdminFindManyIndexQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -2049,20 +2801,188 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }> { return withWrapper( (wrappedRequestHeaders) => - client.rawRequest(UserFindManyIndexDocumentString, variables, { + client.rawRequest(AdminFindManyIndexDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders, }), - 'userFindManyIndex', + 'adminFindManyIndex', 'query', variables, ) }, - userFindOneIndex( - variables: UserFindOneIndexQueryVariables, + adminFindOneIndex( + variables: AdminFindOneIndexQueryVariables, requestHeaders?: GraphQLClientRequestHeaders, ): Promise<{ - data: UserFindOneIndexQuery + data: AdminFindOneIndexQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminFindOneIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminFindOneIndex', + 'query', + variables, + ) + }, + adminGetAccountInfo( + variables: AdminGetAccountInfoQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminGetAccountInfoQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminGetAccountInfoDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminGetAccountInfo', + 'query', + variables, + ) + }, + adminResolveIndex( + variables: AdminResolveIndexQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminResolveIndexQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminResolveIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminResolveIndex', + 'query', + variables, + ) + }, + adminResolveWallet( + variables: AdminResolveWalletQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminResolveWalletQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminResolveWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminResolveWallet', + 'query', + variables, + ) + }, + adminCreateIndex( + variables: AdminCreateIndexMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminCreateIndexMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminCreateIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminCreateIndex', + 'mutation', + variables, + ) + }, + adminUpdateIndex( + variables: AdminUpdateIndexMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminUpdateIndexMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminUpdateIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminUpdateIndex', + 'mutation', + variables, + ) + }, + adminDeleteIndex( + variables: AdminDeleteIndexMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminDeleteIndexMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminDeleteIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminDeleteIndex', + 'mutation', + variables, + ) + }, + userFindManyIndex( + variables: UserFindManyIndexQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserFindManyIndexQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserFindManyIndexDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userFindManyIndex', + 'query', + variables, + ) + }, + userFindOneIndex( + variables: UserFindOneIndexQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserFindOneIndexQuery errors?: GraphQLError[] extensions?: any headers: Headers @@ -2247,6 +3167,216 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = variables, ) }, + adminFindManyWallet( + variables: AdminFindManyWalletQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminFindManyWalletQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminFindManyWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminFindManyWallet', + 'query', + variables, + ) + }, + adminFindOneWallet( + variables: AdminFindOneWalletQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminFindOneWalletQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminFindOneWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminFindOneWallet', + 'query', + variables, + ) + }, + adminCreateWallet( + variables: AdminCreateWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminCreateWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminCreateWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminCreateWallet', + 'mutation', + variables, + ) + }, + adminUpdateWallet( + variables: AdminUpdateWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminUpdateWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminUpdateWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminUpdateWallet', + 'mutation', + variables, + ) + }, + adminDeleteWallet( + variables: AdminDeleteWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: AdminDeleteWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(AdminDeleteWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'adminDeleteWallet', + 'mutation', + variables, + ) + }, + userFindManyWallet( + variables: UserFindManyWalletQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserFindManyWalletQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserFindManyWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userFindManyWallet', + 'query', + variables, + ) + }, + userFindOneWallet( + variables: UserFindOneWalletQueryVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserFindOneWalletQuery + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserFindOneWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userFindOneWallet', + 'query', + variables, + ) + }, + userCreateWallet( + variables: UserCreateWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserCreateWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserCreateWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userCreateWallet', + 'mutation', + variables, + ) + }, + userUpdateWallet( + variables: UserUpdateWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserUpdateWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserUpdateWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userUpdateWallet', + 'mutation', + variables, + ) + }, + userDeleteWallet( + variables: UserDeleteWalletMutationVariables, + requestHeaders?: GraphQLClientRequestHeaders, + ): Promise<{ + data: UserDeleteWalletMutation + errors?: GraphQLError[] + extensions?: any + headers: Headers + status: number + }> { + return withWrapper( + (wrappedRequestHeaders) => + client.rawRequest(UserDeleteWalletDocumentString, variables, { + ...requestHeaders, + ...wrappedRequestHeaders, + }), + 'userDeleteWallet', + 'mutation', + variables, + ) + }, } } export type Sdk = ReturnType @@ -2354,6 +3484,36 @@ export function IndexUserFindManyInputSchema(): z.ZodObject> { + return z.object({ + limit: z.number().default(10).nullish(), + page: z.number().default(1).nullish(), + search: z.string().nullish(), + walletId: z.string(), + }) +} + +export function IndexWalletAdminUpdateInputSchema(): z.ZodObject> { + return z.object({ + updatedAt: z.string().nullish(), + }) +} + +export function IndexWalletUserFindManyInputSchema(): z.ZodObject> { + return z.object({ + limit: z.number().default(10).nullish(), + page: z.number().default(1).nullish(), + search: z.string().nullish(), + walletId: z.string(), + }) +} + +export function IndexWalletUserUpdateInputSchema(): z.ZodObject> { + return z.object({ + updatedAt: z.string().nullish(), + }) +} + export function LoginInputSchema(): z.ZodObject> { return z.object({ password: z.string(), @@ -2411,3 +3571,45 @@ export function UserUserUpdateInputSchema(): z.ZodObject> { + return z.object({ + id: z.string(), + label: z.string().nullish(), + }) +} + +export function WalletAdminFindManyInputSchema(): z.ZodObject> { + return z.object({ + limit: z.number().default(10).nullish(), + page: z.number().default(1).nullish(), + search: z.string().nullish(), + }) +} + +export function WalletAdminUpdateInputSchema(): z.ZodObject> { + return z.object({ + label: z.string().nullish(), + }) +} + +export function WalletUserCreateInputSchema(): z.ZodObject> { + return z.object({ + id: z.string(), + label: z.string().nullish(), + }) +} + +export function WalletUserFindManyInputSchema(): z.ZodObject> { + return z.object({ + limit: z.number().default(10).nullish(), + page: z.number().default(1).nullish(), + search: z.string().nullish(), + }) +} + +export function WalletUserUpdateInputSchema(): z.ZodObject> { + return z.object({ + label: z.string().nullish(), + }) +} diff --git a/libs/sdk/src/graphql/feature-index-entry.graphql b/libs/sdk/src/graphql/feature-index-entry.graphql index 3a1dfad..2bd94b0 100644 --- a/libs/sdk/src/graphql/feature-index-entry.graphql +++ b/libs/sdk/src/graphql/feature-index-entry.graphql @@ -9,7 +9,7 @@ fragment IndexEntryDetails on IndexEntry { data dataHash program - wallet + walletId updatedAt } diff --git a/libs/sdk/src/graphql/feature-index-wallet.graphql b/libs/sdk/src/graphql/feature-index-wallet.graphql new file mode 100644 index 0000000..3335a57 --- /dev/null +++ b/libs/sdk/src/graphql/feature-index-wallet.graphql @@ -0,0 +1,64 @@ +fragment IndexWalletDetails on IndexWallet { + createdAt + id + index { + ...IndexDetails + } + indexId + walletId + updatedAt +} + +query adminFindManyIndexWallet($input: IndexWalletAdminFindManyInput!) { + paging: adminFindManyIndexWallet(input: $input) { + data { + ...IndexWalletDetails + } + meta { + ...PagingMetaDetails + } + } +} + +query adminFindOneIndexWallet($indexWalletId: String!) { + item: adminFindOneIndexWallet(indexWalletId: $indexWalletId) { + ...IndexWalletDetails + } +} + +mutation adminDeleteIndexWallet($indexWalletId: String!) { + deleted: adminDeleteIndexWallet(indexWalletId: $indexWalletId) +} + +mutation adminUpdateIndexWallet($indexWalletId: String!, $input: IndexWalletAdminUpdateInput!) { + updated: adminUpdateIndexWallet(indexWalletId: $indexWalletId, input: $input) { + ...IndexWalletDetails + } +} + +query userFindManyIndexWallet($input: IndexWalletUserFindManyInput!) { + paging: userFindManyIndexWallet(input: $input) { + data { + ...IndexWalletDetails + } + meta { + ...PagingMetaDetails + } + } +} + +query userFindOneIndexWallet($indexWalletId: String!) { + item: userFindOneIndexWallet(indexWalletId: $indexWalletId) { + ...IndexWalletDetails + } +} + +mutation userDeleteIndexWallet($indexWalletId: String!) { + deleted: userDeleteIndexWallet(indexWalletId: $indexWalletId) +} + +mutation userUpdateIndexWallet($indexWalletId: String!, $input: IndexWalletUserUpdateInput!) { + updated: userUpdateIndexWallet(indexWalletId: $indexWalletId, input: $input) { + ...IndexWalletDetails + } +} diff --git a/libs/sdk/src/graphql/feature-wallet.graphql b/libs/sdk/src/graphql/feature-wallet.graphql new file mode 100644 index 0000000..f3da28b --- /dev/null +++ b/libs/sdk/src/graphql/feature-wallet.graphql @@ -0,0 +1,72 @@ +fragment WalletDetails on Wallet { + createdAt + id + label + updatedAt +} + +query adminFindManyWallet($input: WalletAdminFindManyInput!) { + paging: adminFindManyWallet(input: $input) { + data { + ...WalletDetails + } + meta { + ...PagingMetaDetails + } + } +} + +query adminFindOneWallet($walletId: String!) { + item: adminFindOneWallet(walletId: $walletId) { + ...WalletDetails + } +} + +mutation adminCreateWallet($input: WalletAdminCreateInput!) { + created: adminCreateWallet(input: $input) { + ...WalletDetails + } +} + +mutation adminUpdateWallet($walletId: String!, $input: WalletAdminUpdateInput!) { + updated: adminUpdateWallet(walletId: $walletId, input: $input) { + ...WalletDetails + } +} + +mutation adminDeleteWallet($walletId: String!) { + deleted: adminDeleteWallet(walletId: $walletId) +} + +query userFindManyWallet($input: WalletUserFindManyInput!) { + paging: userFindManyWallet(input: $input) { + data { + ...WalletDetails + } + meta { + ...PagingMetaDetails + } + } +} + +query userFindOneWallet($walletId: String!) { + item: userFindOneWallet(walletId: $walletId) { + ...WalletDetails + } +} + +mutation userCreateWallet($input: WalletUserCreateInput!) { + created: userCreateWallet(input: $input) { + ...WalletDetails + } +} + +mutation userUpdateWallet($walletId: String!, $input: WalletUserUpdateInput!) { + updated: userUpdateWallet(walletId: $walletId, input: $input) { + ...WalletDetails + } +} + +mutation userDeleteWallet($walletId: String!) { + deleted: userDeleteWallet(walletId: $walletId) +} diff --git a/libs/web/core/feature/src/lib/web-core-layout.tsx b/libs/web/core/feature/src/lib/web-core-layout.tsx index 4b35924..801cc9c 100644 --- a/libs/web/core/feature/src/lib/web-core-layout.tsx +++ b/libs/web/core/feature/src/lib/web-core-layout.tsx @@ -18,6 +18,8 @@ export function WebCoreLayout({ children }: { children: ReactNode }) { links={[ { link: '/dashboard', label: 'Dashboard' }, { link: '/indexes', label: 'Indexes' }, + { link: '/wallets', label: 'Wallets' }, + { link: '/admin', label: 'Admin' }, ]} profile={ diff --git a/libs/web/core/feature/src/lib/web-core-routes-admin.tsx b/libs/web/core/feature/src/lib/web-core-routes-admin.tsx index 70fe82c..5a6c943 100644 --- a/libs/web/core/feature/src/lib/web-core-routes-admin.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes-admin.tsx @@ -2,14 +2,16 @@ import { UiDashboard } from '@pubkey-resolver/web-core-ui' import { DevAdminRoutes } from '@pubkey-resolver/web-dev-feature' import { AdminIndexFeature } from '@pubkey-resolver/web-index-feature' import { AdminUserFeature } from '@pubkey-resolver/web-user-feature' +import { AdminWalletFeature } from '@pubkey-resolver/web-wallet-feature' import { UiDashboardItem, UiNotFound } from '@pubkey-ui/core' -import { IconFileText, IconUsers } from '@tabler/icons-react' +import { IconFileText, IconUsers, IconWallet } from '@tabler/icons-react' import { Navigate, RouteObject, useRoutes } from 'react-router-dom' const links: UiDashboardItem[] = [ // Admin Dashboard Links are added by the web-crud generator { label: 'Indexes', icon: IconFileText, to: '/admin/indexes' }, { label: 'Users', icon: IconUsers, to: '/admin/users' }, + { label: 'Wallets', icon: IconWallet, to: '/admin/wallets' }, ] const routes: RouteObject[] = [ @@ -17,6 +19,7 @@ const routes: RouteObject[] = [ { path: 'development/*', element: }, { path: 'users/*', element: }, { path: '/indexes/*', element: }, + { path: '/wallets/*', element: }, ] export default function WebCoreRoutesAdmin() { diff --git a/libs/web/core/feature/src/lib/web-core-routes-user.tsx b/libs/web/core/feature/src/lib/web-core-routes-user.tsx index 7ca9964..a4ed243 100644 --- a/libs/web/core/feature/src/lib/web-core-routes-user.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes-user.tsx @@ -2,14 +2,16 @@ import { UiDashboard } from '@pubkey-resolver/web-core-ui' import { UserIndexFeature } from '@pubkey-resolver/web-index-feature' import { SettingsFeature } from '@pubkey-resolver/web-settings-feature' import { UserFeature } from '@pubkey-resolver/web-user-feature' +import { UserWalletFeature } from '@pubkey-resolver/web-wallet-feature' import { UiDashboardItem, UiNotFound } from '@pubkey-ui/core' -import { IconFileText, IconSettings } from '@tabler/icons-react' +import { IconFileText, IconSettings, IconWallet } from '@tabler/icons-react' import { Navigate, RouteObject, useRoutes } from 'react-router-dom' const links: UiDashboardItem[] = [ // User Dashboard Links are added by the web-crud generator { label: 'Indexes', icon: IconFileText, to: '/indexes' }, { label: 'Settings', icon: IconSettings, to: '/settings' }, + { label: 'Wallets', icon: IconWallet, to: '/wallets' }, ] const routes: RouteObject[] = [ @@ -17,6 +19,7 @@ const routes: RouteObject[] = [ { path: '/settings/*', element: }, { path: '/u/*', element: }, { path: '/indexes/*', element: }, + { path: '/wallets/*', element: }, ] export default function WebCoreRoutesUser() { diff --git a/libs/web/index-entry/ui/src/lib/index-entry-ui-avatar.tsx b/libs/web/index-entry/ui/src/lib/index-entry-ui-avatar.tsx index 9965614..b027afa 100644 --- a/libs/web/index-entry/ui/src/lib/index-entry-ui-avatar.tsx +++ b/libs/web/index-entry/ui/src/lib/index-entry-ui-avatar.tsx @@ -6,5 +6,5 @@ export type IndexEntryUiAvatarProps = UiAvatarProps & { } export function IndexEntryUiAvatar({ indexEntry, ...props }: IndexEntryUiAvatarProps) { - return + return } diff --git a/libs/web/index-entry/ui/src/lib/index-entry-ui-item.tsx b/libs/web/index-entry/ui/src/lib/index-entry-ui-item.tsx index 391ad6e..7d635fe 100644 --- a/libs/web/index-entry/ui/src/lib/index-entry-ui-item.tsx +++ b/libs/web/index-entry/ui/src/lib/index-entry-ui-item.tsx @@ -20,12 +20,15 @@ export function IndexEntryUiItem({ return ( - + {indexEntry?.label} + + {indexEntry?.walletId} + diff --git a/libs/web/index-wallet/data-access/.babelrc b/libs/web/index-wallet/data-access/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/index-wallet/data-access/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/index-wallet/data-access/.eslintrc.json b/libs/web/index-wallet/data-access/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/index-wallet/data-access/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/index-wallet/data-access/README.md b/libs/web/index-wallet/data-access/README.md new file mode 100644 index 0000000..b2ace47 --- /dev/null +++ b/libs/web/index-wallet/data-access/README.md @@ -0,0 +1,7 @@ +# web-index-wallet-data-access + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-index-wallet-data-access` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/index-wallet/data-access/project.json b/libs/web/index-wallet/data-access/project.json new file mode 100644 index 0000000..67f4c80 --- /dev/null +++ b/libs/web/index-wallet/data-access/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-index-wallet-data-access", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/index-wallet/data-access/src", + "projectType": "library", + "tags": ["app:web", "type:data-access"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/index-wallet/data-access/src/index.ts b/libs/web/index-wallet/data-access/src/index.ts new file mode 100644 index 0000000..3f16c92 --- /dev/null +++ b/libs/web/index-wallet/data-access/src/index.ts @@ -0,0 +1,4 @@ +export * from './lib/use-admin-find-many-index-wallet' +export * from './lib/use-admin-find-one-index-wallet' +export * from './lib/use-user-find-many-index-wallet' +export * from './lib/use-user-find-one-index-wallet' diff --git a/libs/web/index-wallet/data-access/src/lib/use-admin-find-many-index-wallet.ts b/libs/web/index-wallet/data-access/src/lib/use-admin-find-many-index-wallet.ts new file mode 100644 index 0000000..f9dcfce --- /dev/null +++ b/libs/web/index-wallet/data-access/src/lib/use-admin-find-many-index-wallet.ts @@ -0,0 +1,36 @@ +import { IndexWalletAdminFindManyInput, sdk } from '@pubkey-resolver/sdk' +import { toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' +import { useState } from 'react' + +export function useAdminFindManyIndexWallet(props: Partial & { walletId: string }) { + const [limit, setLimit] = useState(props?.limit ?? 10) + const [page, setPage] = useState(props?.page ?? 1) + const [search, setSearch] = useState(props?.search ?? '') + + const input: IndexWalletAdminFindManyInput = { page, limit, search, walletId: props.walletId } + const query = useQuery({ + queryKey: ['admin', 'find-many-index-wallet', input], + queryFn: () => sdk.adminFindManyIndexWallet({ input }).then((res) => res.data), + }) + const total = query.data?.paging?.meta?.totalCount ?? 0 + const items = query.data?.paging.data ?? [] + + return { + items, + query, + pagination: { + page, + setPage, + limit, + setLimit, + total, + }, + setSearch, + deleteIndexWallet: (indexWalletId: string) => + sdk.adminDeleteIndexWallet({ indexWalletId }).then(() => { + toastSuccess('IndexWallet deleted') + return query.refetch() + }), + } +} diff --git a/libs/web/index-wallet/data-access/src/lib/use-admin-find-one-index-wallet.ts b/libs/web/index-wallet/data-access/src/lib/use-admin-find-one-index-wallet.ts new file mode 100644 index 0000000..31ddd70 --- /dev/null +++ b/libs/web/index-wallet/data-access/src/lib/use-admin-find-one-index-wallet.ts @@ -0,0 +1,34 @@ +import { IndexWalletAdminUpdateInput, sdk } from '@pubkey-resolver/sdk' +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' + +export function useAdminFindOneIndexWallet({ indexWalletId }: { indexWalletId: string }) { + const query = useQuery({ + queryKey: ['admin', 'find-one-index-wallet', indexWalletId], + queryFn: () => sdk.adminFindOneIndexWallet({ indexWalletId }).then((res) => res.data), + retry: 0, + }) + const item = query.data?.item ?? undefined + + return { + item, + query, + updateIndexWallet: async (input: IndexWalletAdminUpdateInput) => + sdk + .adminUpdateIndexWallet({ indexWalletId, input }) + .then((res) => res.data) + .then(async (res) => { + if (res) { + toastSuccess('IndexWallet updated') + await query.refetch() + return true + } + toastError('IndexWallet not updated') + return false + }) + .catch((err) => { + toastError(err.message) + return false + }), + } +} diff --git a/libs/web/index-wallet/data-access/src/lib/use-user-find-many-index-wallet.ts b/libs/web/index-wallet/data-access/src/lib/use-user-find-many-index-wallet.ts new file mode 100644 index 0000000..7e83ee0 --- /dev/null +++ b/libs/web/index-wallet/data-access/src/lib/use-user-find-many-index-wallet.ts @@ -0,0 +1,36 @@ +import { IndexWalletUserFindManyInput, sdk } from '@pubkey-resolver/sdk' +import { toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' +import { useState } from 'react' + +export function useUserFindManyIndexWallet(props: Partial & { walletId: string }) { + const [limit, setLimit] = useState(props?.limit ?? 10) + const [page, setPage] = useState(props?.page ?? 1) + const [search, setSearch] = useState(props?.search ?? '') + + const input: IndexWalletUserFindManyInput = { page, limit, search, walletId: props.walletId } + const query = useQuery({ + queryKey: ['user', 'find-many-index-wallet', input], + queryFn: () => sdk.userFindManyIndexWallet({ input }).then((res) => res.data), + }) + const total = query.data?.paging?.meta?.totalCount ?? 0 + const items = query.data?.paging.data ?? [] + + return { + items, + query, + pagination: { + page, + setPage, + limit, + setLimit, + total, + }, + setSearch, + deleteIndexWallet: (indexWalletId: string) => + sdk.userDeleteIndexWallet({ indexWalletId }).then(() => { + toastSuccess('IndexWallet deleted') + return query.refetch() + }), + } +} diff --git a/libs/web/index-wallet/data-access/src/lib/use-user-find-one-index-wallet.ts b/libs/web/index-wallet/data-access/src/lib/use-user-find-one-index-wallet.ts new file mode 100644 index 0000000..28fc87d --- /dev/null +++ b/libs/web/index-wallet/data-access/src/lib/use-user-find-one-index-wallet.ts @@ -0,0 +1,34 @@ +import { IndexWalletUserUpdateInput, sdk } from '@pubkey-resolver/sdk' +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' + +export function useUserFindOneIndexWallet({ indexWalletId }: { indexWalletId: string }) { + const query = useQuery({ + queryKey: ['user', 'find-one-index-wallet', indexWalletId], + queryFn: () => sdk.userFindOneIndexWallet({ indexWalletId }).then((res) => res.data), + retry: 0, + }) + const item = query.data?.item ?? undefined + + return { + item, + query, + updateIndexWallet: async (input: IndexWalletUserUpdateInput) => + sdk + .userUpdateIndexWallet({ indexWalletId, input }) + .then((res) => res.data) + .then(async (res) => { + if (res) { + toastSuccess('IndexWallet updated') + await query.refetch() + return true + } + toastError('IndexWallet not updated') + return false + }) + .catch((err) => { + toastError(err.message) + return false + }), + } +} diff --git a/libs/web/index-wallet/data-access/tsconfig.json b/libs/web/index-wallet/data-access/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/index-wallet/data-access/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/index-wallet/data-access/tsconfig.lib.json b/libs/web/index-wallet/data-access/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/index-wallet/data-access/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/web/index-wallet/feature/.babelrc b/libs/web/index-wallet/feature/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/index-wallet/feature/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/index-wallet/feature/.eslintrc.json b/libs/web/index-wallet/feature/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/index-wallet/feature/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/index-wallet/feature/README.md b/libs/web/index-wallet/feature/README.md new file mode 100644 index 0000000..a9e625a --- /dev/null +++ b/libs/web/index-wallet/feature/README.md @@ -0,0 +1,7 @@ +# web-index-wallet-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-index-wallet-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/index-wallet/feature/project.json b/libs/web/index-wallet/feature/project.json new file mode 100644 index 0000000..bb91347 --- /dev/null +++ b/libs/web/index-wallet/feature/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-index-wallet-feature", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/index-wallet/feature/src", + "projectType": "library", + "tags": ["app:web", "type:feature"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/index-wallet/feature/src/index.ts b/libs/web/index-wallet/feature/src/index.ts new file mode 100644 index 0000000..d7eb358 --- /dev/null +++ b/libs/web/index-wallet/feature/src/index.ts @@ -0,0 +1,5 @@ +import { lazy } from 'react' + +export const AdminIndexWalletFeature = lazy(() => import('./lib/admin-index-wallet.routes')) + +export const UserIndexWalletFeature = lazy(() => import('./lib/user-index-wallet.routes')) diff --git a/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-info.tab.tsx b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-info.tab.tsx new file mode 100644 index 0000000..7a04141 --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-info.tab.tsx @@ -0,0 +1,20 @@ +import { useAdminFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { IndexWalletUiInfo } from '@pubkey-resolver/web-index-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function AdminIndexWalletDetailInfoTab({ indexWalletId }: { indexWalletId: string }) { + const { item, query } = useAdminFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-settings.tab.tsx b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-settings.tab.tsx new file mode 100644 index 0000000..b1c97d6 --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail-settings.tab.tsx @@ -0,0 +1,20 @@ +import { useAdminFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { AdminIndexWalletUiUpdateForm } from '@pubkey-resolver/web-index-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function AdminIndexWalletDetailSettingsTab({ indexWalletId }: { indexWalletId: string }) { + const { item, query, updateIndexWallet } = useAdminFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail.feature.tsx b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail.feature.tsx new file mode 100644 index 0000000..2b58227 --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-detail.feature.tsx @@ -0,0 +1,37 @@ +import { Group } from '@mantine/core' +import { IndexUiItem } from '@pubkey-resolver/web-index-ui' +import { useAdminFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { AdminIndexWalletUiUpdateForm, IndexWalletUiInfo } from '@pubkey-resolver/web-index-wallet-ui' +import { UiBack, UiCard, UiDebugModal, UiError, UiLoader, UiPage } from '@pubkey-ui/core' +import { useParams } from 'react-router-dom' + +export default function AdminIndexWalletDetailFeature() { + const { indexWalletId } = useParams<{ indexWalletId: string }>() as { indexWalletId: string } + const { item, query, updateIndexWallet } = useAdminFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + : null} + leftAction={} + rightAction={ + + + + } + > + + + + + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/admin-index-wallet-list.feature.tsx b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-list.feature.tsx new file mode 100644 index 0000000..8033bbd --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/admin-index-wallet-list.feature.tsx @@ -0,0 +1,61 @@ +import { Group } from '@mantine/core' +import { UiPageLimit, UiSearchField } from '@pubkey-resolver/web-core-ui' +import { useAdminFindManyIndex } from '@pubkey-resolver/web-index-data-access' +import { useAdminFindManyIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { AdminIndexWalletUiTable } from '@pubkey-resolver/web-index-wallet-ui' +import { UiDebugModal, UiInfo, UiLoader, UiStack } from '@pubkey-ui/core' +import { IndexWalletButton } from './index-wallet-button' + +export default function AdminIndexWalletListFeature({ walletId }: { walletId: string }) { + const { items: indexes } = useAdminFindManyIndex({ + limit: 1000, + }) + const { deleteIndexWallet, items, pagination, query, setSearch } = useAdminFindManyIndexWallet({ + limit: 10, + walletId, + }) + + const missingIndexes = indexes.filter((index) => !items.find((item) => item.indexId === index.id)) + + return ( + + + + + + + + + {query.isLoading ? ( + + ) : ( + + {items?.length ? ( + + { + if (!window.confirm('Are you sure?')) return + return deleteIndexWallet(indexWallet.id) + }} + indexWallets={items} + page={pagination.page} + totalRecords={pagination.total} + recordsPerPage={pagination.limit} + onPageChange={(page) => void pagination.setPage(page)} + /> + + ) : ( + + )} + {missingIndexes.length ? ( + + {missingIndexes.map((index) => ( + query.refetch()} key={index.id} index={index} walletId={walletId} /> + ))} + + ) : null} + + )} + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/admin-index-wallet.routes.tsx b/libs/web/index-wallet/feature/src/lib/admin-index-wallet.routes.tsx new file mode 100644 index 0000000..cdeff2b --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/admin-index-wallet.routes.tsx @@ -0,0 +1,12 @@ +import { lazy } from 'react' +import { useRoutes } from 'react-router-dom' + +const Detail = lazy(() => import('./admin-index-wallet-detail.feature')) +const List = lazy(() => import('./admin-index-wallet-list.feature')) + +export default function AdminIndexWalletRoutes({ walletId }: { walletId: string }) { + return useRoutes([ + { path: '', element: }, + { path: ':indexWalletId/*', element: }, + ]) +} diff --git a/libs/web/index-wallet/feature/src/lib/index-wallet-button.tsx b/libs/web/index-wallet/feature/src/lib/index-wallet-button.tsx new file mode 100644 index 0000000..de0fff2 --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/index-wallet-button.tsx @@ -0,0 +1,38 @@ +import { Box, Button } from '@mantine/core' +import { Index } from '@pubkey-resolver/sdk' +import { useAdminResolveWallet } from '@pubkey-resolver/web-index-data-access' +import { toastError, toastSuccess } from '@pubkey-ui/core' + +export function IndexWalletButton({ + index, + refresh, + walletId, +}: { + index: Index + refresh: () => void + walletId: string +}) { + const mutation = useAdminResolveWallet({ address: index.address, cluster: index.cluster }) + + return ( + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-info.tab.tsx b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-info.tab.tsx new file mode 100644 index 0000000..d9c1954 --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-info.tab.tsx @@ -0,0 +1,20 @@ +import { useUserFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { IndexWalletUiInfo } from '@pubkey-resolver/web-index-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function UserIndexWalletDetailInfoTab({ indexWalletId }: { indexWalletId: string }) { + const { item, query } = useUserFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-settings.tab.tsx b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-settings.tab.tsx new file mode 100644 index 0000000..7dbc3ac --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail-settings.tab.tsx @@ -0,0 +1,20 @@ +import { useUserFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { UserIndexWalletUiUpdateForm } from '@pubkey-resolver/web-index-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function UserIndexWalletDetailSettingsTab({ indexWalletId }: { indexWalletId: string }) { + const { item, query, updateIndexWallet } = useUserFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail.feature.tsx b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail.feature.tsx new file mode 100644 index 0000000..fe1e1ed --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/user-index-wallet-detail.feature.tsx @@ -0,0 +1,46 @@ +import { Group } from '@mantine/core' +import { IndexUiItem } from '@pubkey-resolver/web-index-ui' +import { useUserFindOneIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' +import { useParams } from 'react-router-dom' +import { UserIndexWalletDetailInfoTab } from './user-index-wallet-detail-info.tab' +import { UserIndexWalletDetailSettingsTab } from './user-index-wallet-detail-settings.tab' + +export default function UserIndexWalletDetailFeature() { + const { indexWalletId } = useParams<{ indexWalletId: string }>() as { indexWalletId: string } + const { item, query } = useUserFindOneIndexWallet({ indexWalletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: , + }, + { + path: 'settings', + label: 'Settings', + element: , + }, + ] + + return ( + : null} + leftAction={} + rightAction={ + + + + } + > + + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/user-index-wallet-list.feature.tsx b/libs/web/index-wallet/feature/src/lib/user-index-wallet-list.feature.tsx new file mode 100644 index 0000000..e32387e --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/user-index-wallet-list.feature.tsx @@ -0,0 +1,37 @@ +import { Group } from '@mantine/core' +import { UiSearchField } from '@pubkey-resolver/web-core-ui' +import { useUserFindManyIndexWallet } from '@pubkey-resolver/web-index-wallet-data-access' +import { IndexWalletUiGrid } from '@pubkey-resolver/web-index-wallet-ui' +import { UiDebugModal, UiInfo, UiLoader, UiStack } from '@pubkey-ui/core' + +export default function UserIndexWalletListFeature({ walletId }: { walletId: string }) { + const { items, pagination, query, setSearch } = useUserFindManyIndexWallet({ + limit: 12, + walletId, + }) + + return ( + + + + + + + {query.isLoading ? ( + + ) : items?.length ? ( + + ) : ( + + )} + + ) +} diff --git a/libs/web/index-wallet/feature/src/lib/user-index-wallet.routes.tsx b/libs/web/index-wallet/feature/src/lib/user-index-wallet.routes.tsx new file mode 100644 index 0000000..6115bec --- /dev/null +++ b/libs/web/index-wallet/feature/src/lib/user-index-wallet.routes.tsx @@ -0,0 +1,12 @@ +import { lazy } from 'react' +import { useRoutes } from 'react-router-dom' + +const Detail = lazy(() => import('./user-index-wallet-detail.feature')) +const List = lazy(() => import('./user-index-wallet-list.feature')) + +export default function UserIndexWalletRoutes({ walletId }: { walletId: string }) { + return useRoutes([ + { path: '', element: }, + { path: ':indexWalletId/*', element: }, + ]) +} diff --git a/libs/web/index-wallet/feature/tsconfig.json b/libs/web/index-wallet/feature/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/index-wallet/feature/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/index-wallet/feature/tsconfig.lib.json b/libs/web/index-wallet/feature/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/index-wallet/feature/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/web/index-wallet/ui/.babelrc b/libs/web/index-wallet/ui/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/index-wallet/ui/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/index-wallet/ui/.eslintrc.json b/libs/web/index-wallet/ui/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/index-wallet/ui/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/index-wallet/ui/README.md b/libs/web/index-wallet/ui/README.md new file mode 100644 index 0000000..93a5d5d --- /dev/null +++ b/libs/web/index-wallet/ui/README.md @@ -0,0 +1,7 @@ +# web-index-wallet-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-index-wallet-ui` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/index-wallet/ui/project.json b/libs/web/index-wallet/ui/project.json new file mode 100644 index 0000000..1a54db5 --- /dev/null +++ b/libs/web/index-wallet/ui/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-index-wallet-ui", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/index-wallet/ui/src", + "projectType": "library", + "tags": ["app:web", "type:ui"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/index-wallet/ui/src/index.ts b/libs/web/index-wallet/ui/src/index.ts new file mode 100644 index 0000000..fd52578 --- /dev/null +++ b/libs/web/index-wallet/ui/src/index.ts @@ -0,0 +1,8 @@ +export * from './lib/admin-index-wallet-ui-table' +export * from './lib/admin-index-wallet-ui-update-form' +export * from './lib/index-wallet-ui-avatar' +export * from './lib/index-wallet-ui-grid' +export * from './lib/index-wallet-ui-grid-item' +export * from './lib/index-wallet-ui-info' +export * from './lib/user-index-wallet-ui-table' +export * from './lib/user-index-wallet-ui-update-form' diff --git a/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-table.tsx b/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-table.tsx new file mode 100644 index 0000000..6026ab1 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-table.tsx @@ -0,0 +1,58 @@ +import { ActionIcon, Group, ScrollArea } from '@mantine/core' +import { IndexWallet } from '@pubkey-resolver/sdk' +import { IndexUiItem } from '@pubkey-resolver/web-index-ui' +import { IconPencil, IconTrash } from '@tabler/icons-react' +import { DataTable, DataTableProps } from 'mantine-datatable' +import { Link } from 'react-router-dom' + +export function AdminIndexWalletUiTable({ + deleteIndexWallet, + indexWallets = [], + onPageChange, + page, + recordsPerPage, + totalRecords, +}: { + deleteIndexWallet: (indexWallet: IndexWallet) => void + indexWallets: IndexWallet[] + page: DataTableProps['page'] + totalRecords: DataTableProps['totalRecords'] + recordsPerPage: DataTableProps['recordsPerPage'] + onPageChange: (page: number) => void +}) { + return ( + + (item.index ? : null), + }, + { + accessor: 'actions', + title: 'Actions', + textAlign: 'right', + render: (item) => ( + + + + + deleteIndexWallet(item)}> + + + + ), + }, + ]} + records={indexWallets} + /> + + ) +} diff --git a/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-update-form.tsx b/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-update-form.tsx new file mode 100644 index 0000000..94be22c --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/admin-index-wallet-ui-update-form.tsx @@ -0,0 +1,29 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { IndexWallet, IndexWalletAdminUpdateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function AdminIndexWalletUiUpdateForm({ + submit, + indexWallet, +}: { + submit: (res: IndexWalletAdminUpdateInput) => Promise + indexWallet: IndexWallet +}) { + const form = useForm({ + initialValues: { + updatedAt: indexWallet.updatedAt?.toString() ?? '', + }, + }) + + return ( +
submit(values))}> + + + + + + +
+ ) +} diff --git a/libs/web/index-wallet/ui/src/lib/index-wallet-ui-avatar.tsx b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-avatar.tsx new file mode 100644 index 0000000..54bf993 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-avatar.tsx @@ -0,0 +1,10 @@ +import { IndexWallet } from '@pubkey-resolver/sdk' +import { UiAvatar, UiAvatarProps } from '@pubkey-ui/core' + +export type IndexWalletUiAvatarProps = UiAvatarProps & { + indexWallet?: IndexWallet +} + +export function IndexWalletUiAvatar({ indexWallet, ...props }: IndexWalletUiAvatarProps) { + return +} diff --git a/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid-item.tsx b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid-item.tsx new file mode 100644 index 0000000..bb2c4b8 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid-item.tsx @@ -0,0 +1,15 @@ +import { Paper } from '@mantine/core' +import { IndexWallet } from '@pubkey-resolver/sdk' +import { IndexUiItem } from '@pubkey-resolver/web-index-ui' +import { UiDebugModal, UiGroup } from '@pubkey-ui/core' + +export function IndexWalletUiGridItem({ indexWallet, to }: { indexWallet: IndexWallet; to?: string }) { + return ( + + + {indexWallet.index ? : null} + + + + ) +} diff --git a/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid.tsx b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid.tsx new file mode 100644 index 0000000..9849a04 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-grid.tsx @@ -0,0 +1,42 @@ +import { Group, Pagination, SimpleGrid } from '@mantine/core' +import { IndexWallet } from '@pubkey-resolver/sdk' +import { gridLimits, UiPageLimit } from '@pubkey-resolver/web-core-ui' +import { UiDebugModal, UiGroup, UiStack } from '@pubkey-ui/core' +import { DataTableProps } from 'mantine-datatable' +import { IndexWalletUiGridItem } from './index-wallet-ui-grid-item' + +export function IndexWalletUiGrid({ + indexWallets = [], + onPageChange, + page, + totalRecords, + limit, + setLimit, + setPage, +}: { + indexWallets: IndexWallet[] + page: DataTableProps['page'] + totalRecords: number + onPageChange: (page: number) => void + limit: number + setLimit: (limit: number) => void + setPage: (page: number) => void +}) { + const totalPages = totalRecords / limit + 1 + return ( + + + {indexWallets.map((indexWallet) => ( + + ))} + + + + + + + + + + ) +} diff --git a/libs/web/index-wallet/ui/src/lib/index-wallet-ui-info.tsx b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-info.tsx new file mode 100644 index 0000000..f833577 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-info.tsx @@ -0,0 +1,15 @@ +import { IndexWallet } from '@pubkey-resolver/sdk' +import { UiInfoItems, UiInfoTable, UiTime } from '@pubkey-ui/core' + +export function IndexWalletUiInfo({ indexWallet }: { indexWallet?: IndexWallet }) { + if (!indexWallet) return null + + const items: UiInfoItems = [ + ['name', indexWallet.index?.label], + + ['Created At', ], + ['Updated At', ], + ] + + return +} diff --git a/libs/web/index-wallet/ui/src/lib/index-wallet-ui-item.tsx b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-item.tsx new file mode 100644 index 0000000..0f752c1 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/index-wallet-ui-item.tsx @@ -0,0 +1,33 @@ +import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core' +import { IndexWallet } from '@pubkey-resolver/sdk' +import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core' +import { IndexWalletUiAvatar } from './index-wallet-ui-avatar' + +export function IndexWalletUiItem({ + anchorProps, + avatarProps, + groupProps, + indexWallet, + to, +}: { + anchorProps?: UiAnchorProps + avatarProps?: Omit + groupProps?: GroupProps + indexWallet?: IndexWallet + to?: string | null +}) { + if (!indexWallet) return null + + return ( + + + + + + {indexWallet?.index?.label} + + + + + ) +} diff --git a/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-table.tsx b/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-table.tsx new file mode 100644 index 0000000..5c012d0 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-table.tsx @@ -0,0 +1,61 @@ +import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core' +import { IndexWallet } from '@pubkey-resolver/sdk' +import { IconPencil, IconTrash } from '@tabler/icons-react' +import { DataTable, DataTableProps } from 'mantine-datatable' +import { Link } from 'react-router-dom' + +export function UserIndexWalletUiTable({ + deleteIndexWallet, + indexWallets = [], + onPageChange, + page, + recordsPerPage, + totalRecords, +}: { + deleteIndexWallet: (indexWallet: IndexWallet) => void + indexWallets: IndexWallet[] + page: DataTableProps['page'] + totalRecords: DataTableProps['totalRecords'] + recordsPerPage: DataTableProps['recordsPerPage'] + onPageChange: (page: number) => void +}) { + return ( + + ( + + {item.index?.label} + + ), + }, + { + accessor: 'actions', + title: 'Actions', + textAlign: 'right', + render: (item) => ( + + + + + deleteIndexWallet(item)}> + + + + ), + }, + ]} + records={indexWallets} + /> + + ) +} diff --git a/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-update-form.tsx b/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-update-form.tsx new file mode 100644 index 0000000..d1a1f07 --- /dev/null +++ b/libs/web/index-wallet/ui/src/lib/user-index-wallet-ui-update-form.tsx @@ -0,0 +1,29 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { IndexWallet, IndexWalletUserUpdateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function UserIndexWalletUiUpdateForm({ + submit, + indexWallet, +}: { + submit: (res: IndexWalletUserUpdateInput) => Promise + indexWallet: IndexWallet +}) { + const form = useForm({ + initialValues: { + updatedAt: indexWallet.updatedAt?.toString() ?? '', + }, + }) + + return ( +
submit(values))}> + + + + + + +
+ ) +} diff --git a/libs/web/index-wallet/ui/tsconfig.json b/libs/web/index-wallet/ui/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/index-wallet/ui/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/index-wallet/ui/tsconfig.lib.json b/libs/web/index-wallet/ui/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/index-wallet/ui/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/web/index/data-access/src/index.ts b/libs/web/index/data-access/src/index.ts index 2199b50..616207d 100644 --- a/libs/web/index/data-access/src/index.ts +++ b/libs/web/index/data-access/src/index.ts @@ -1,5 +1,6 @@ export * from './lib/use-admin-find-many-index' export * from './lib/use-admin-find-one-index' export * from './lib/use-admin-get-account-info' +export * from './lib/use-admin-resolve-wallet' export * from './lib/use-user-find-many-index' export * from './lib/use-user-find-one-index' diff --git a/libs/web/index/data-access/src/lib/use-admin-get-account-info.ts b/libs/web/index/data-access/src/lib/use-admin-get-account-info.ts index d06996b..39cb415 100644 --- a/libs/web/index/data-access/src/lib/use-admin-get-account-info.ts +++ b/libs/web/index/data-access/src/lib/use-admin-get-account-info.ts @@ -1,5 +1,5 @@ import { IndexAdminResolveInput, sdk } from '@pubkey-resolver/sdk' -import { useMutation, useQuery } from '@tanstack/react-query' +import { useQuery } from '@tanstack/react-query' export function useAdminGetAccountInfo(input: IndexAdminResolveInput) { const query = useQuery({ @@ -14,9 +14,3 @@ export function useAdminGetAccountInfo(input: IndexAdminResolveInput) { query, } } - -export function useAdminResolveWallet(input: IndexAdminResolveInput) { - return useMutation({ - mutationFn: (wallet: string) => sdk.adminResolveWallet({ input, wallet }).then((res) => res.data), - }) -} diff --git a/libs/web/index/data-access/src/lib/use-admin-resolve-wallet.ts b/libs/web/index/data-access/src/lib/use-admin-resolve-wallet.ts new file mode 100644 index 0000000..efbb279 --- /dev/null +++ b/libs/web/index/data-access/src/lib/use-admin-resolve-wallet.ts @@ -0,0 +1,8 @@ +import { IndexAdminResolveInput, sdk } from '@pubkey-resolver/sdk' +import { useMutation } from '@tanstack/react-query' + +export function useAdminResolveWallet(input: IndexAdminResolveInput) { + return useMutation({ + mutationFn: (wallet: string) => sdk.adminResolveWallet({ input, wallet }).then((res) => res.data), + }) +} diff --git a/libs/web/index/feature/src/lib/admin-index-detail.feature.tsx b/libs/web/index/feature/src/lib/admin-index-detail.feature.tsx index 8632835..36d6c1a 100644 --- a/libs/web/index/feature/src/lib/admin-index-detail.feature.tsx +++ b/libs/web/index/feature/src/lib/admin-index-detail.feature.tsx @@ -1,24 +1,12 @@ -import { ActionIcon, Group, TextInput } from '@mantine/core' -import { Index } from '@pubkey-resolver/sdk' -import { useAdminFindOneIndex, useAdminResolveWallet } from '@pubkey-resolver/web-index-data-access' +import { Group } from '@mantine/core' +import { useAdminFindOneIndex } from '@pubkey-resolver/web-index-data-access' import { AdminIndexEntryFeature } from '@pubkey-resolver/web-index-entry-feature' import { IndexUiItem } from '@pubkey-resolver/web-index-ui' -import { - UiBack, - UiCard, - UiDebug, - UiDebugModal, - UiError, - UiLoader, - UiPage, - UiTabRoute, - UiTabRoutes, -} from '@pubkey-ui/core' -import { IconSearch } from '@tabler/icons-react' -import { useState } from 'react' +import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' import { useParams } from 'react-router-dom' import { AdminIndexDetailInfoTab } from './admin-index-detail-info.tab' import { AdminIndexDetailSettingsTab } from './admin-index-detail-settings.tab' +import { AdminIndexResolveWalletFeature } from './admin-index-resolve-wallet-feature' export default function AdminIndexDetailFeature() { const { indexId } = useParams<{ indexId: string }>() as { indexId: string } @@ -68,46 +56,3 @@ export default function AdminIndexDetailFeature() { ) } - -function AdminIndexResolveWalletFeature({ item }: { item: Index }) { - const mutation = useAdminResolveWallet({ address: item.address, cluster: item.cluster }) - const [wallet, setWallet] = useState() - const [output, setOutput] = useState(undefined) - - function submit(wallet: string | undefined) { - if (!wallet) { - return - } - setOutput(undefined) - mutation - .mutateAsync(wallet) - .then((res) => { - setOutput({ res: res?.item }) - }) - .catch((err) => { - setOutput({ err: `${err}` }) - }) - } - - return ( - - setWallet(e.currentTarget.value)} - onKeyDown={(e) => { - if (e.key === 'Enter') { - submit(wallet) - } - }} - rightSection={ - submit(wallet)}> - - - } - /> - {mutation.isPending ? : } - - ) -} diff --git a/libs/web/index/feature/src/lib/admin-index-resolve-wallet-feature.tsx b/libs/web/index/feature/src/lib/admin-index-resolve-wallet-feature.tsx new file mode 100644 index 0000000..9e93986 --- /dev/null +++ b/libs/web/index/feature/src/lib/admin-index-resolve-wallet-feature.tsx @@ -0,0 +1,49 @@ +import { ActionIcon, TextInput } from '@mantine/core' +import { Index } from '@pubkey-resolver/sdk' +import { useAdminResolveWallet } from '@pubkey-resolver/web-index-data-access' +import { UiCard, UiDebug, UiLoader } from '@pubkey-ui/core' +import { IconSearch } from '@tabler/icons-react' +import { useState } from 'react' + +export function AdminIndexResolveWalletFeature({ item }: { item: Index }) { + const mutation = useAdminResolveWallet({ address: item.address, cluster: item.cluster }) + const [wallet, setWallet] = useState() + const [output, setOutput] = useState(undefined) + + function submit(wallet: string | undefined) { + if (!wallet) { + return + } + setOutput(undefined) + mutation + .mutateAsync(wallet) + .then((res) => { + setOutput({ res: res?.item }) + }) + .catch((err) => { + setOutput({ err: `${err}` }) + }) + } + + return ( + + setWallet(e.currentTarget.value)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + submit(wallet) + } + }} + rightSection={ + submit(wallet)}> + + + } + /> + {mutation.isPending ? : } + + ) +} diff --git a/libs/web/index/ui/src/lib/admin-index-ui-table.tsx b/libs/web/index/ui/src/lib/admin-index-ui-table.tsx index 2e8a117..9bb8649 100644 --- a/libs/web/index/ui/src/lib/admin-index-ui-table.tsx +++ b/libs/web/index/ui/src/lib/admin-index-ui-table.tsx @@ -1,8 +1,9 @@ -import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core' +import { ActionIcon, Group, ScrollArea } from '@mantine/core' import { Index } from '@pubkey-resolver/sdk' import { IconPencil, IconTrash } from '@tabler/icons-react' import { DataTable, DataTableProps } from 'mantine-datatable' import { Link } from 'react-router-dom' +import { IndexUiItem } from './index-ui-item' export function AdminIndexUiTable({ deleteIndex, @@ -32,15 +33,9 @@ export function AdminIndexUiTable({ columns={[ { accessor: 'address', - render: (item) => ( - - {item.label} - - ), + render: (item) => , }, { accessor: 'address' }, - { accessor: 'cluster' }, - { accessor: 'type' }, { accessor: 'actions', title: 'Actions', diff --git a/libs/web/index/ui/src/lib/index-ui-avatar.tsx b/libs/web/index/ui/src/lib/index-ui-avatar.tsx index fac50ca..2a5f778 100644 --- a/libs/web/index/ui/src/lib/index-ui-avatar.tsx +++ b/libs/web/index/ui/src/lib/index-ui-avatar.tsx @@ -6,5 +6,5 @@ export type IndexUiAvatarProps = UiAvatarProps & { } export function IndexUiAvatar({ index, ...props }: IndexUiAvatarProps) { - return + return } diff --git a/libs/web/index/ui/src/lib/index-ui-item.tsx b/libs/web/index/ui/src/lib/index-ui-item.tsx index cbe9e49..d8ae352 100644 --- a/libs/web/index/ui/src/lib/index-ui-item.tsx +++ b/libs/web/index/ui/src/lib/index-ui-item.tsx @@ -26,9 +26,17 @@ export function IndexUiItem({ {index?.label} - - {index?.cluster?.toString()?.replace('Solana', 'Solana ')} - + + + {index?.cluster?.toString()?.replace('Solana', '')} + + + · + + + {index?.type?.toString()?.replace('Solana', '')} + +
diff --git a/libs/web/index/ui/src/lib/user-index-ui-table.tsx b/libs/web/index/ui/src/lib/user-index-ui-table.tsx index 6a58bc1..bd1f0ff 100644 --- a/libs/web/index/ui/src/lib/user-index-ui-table.tsx +++ b/libs/web/index/ui/src/lib/user-index-ui-table.tsx @@ -1,8 +1,9 @@ -import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core' +import { ActionIcon, Group, ScrollArea } from '@mantine/core' import { Index } from '@pubkey-resolver/sdk' import { IconPencil } from '@tabler/icons-react' import { DataTable, DataTableProps } from 'mantine-datatable' import { Link } from 'react-router-dom' +import { IndexUiItem } from './index-ui-item' export function UserIndexUiTable({ indexes = [], @@ -30,11 +31,7 @@ export function UserIndexUiTable({ columns={[ { accessor: 'address', - render: (item) => ( - - {item.label} - - ), + render: (item) => , }, { accessor: 'actions', diff --git a/libs/web/wallet/data-access/.babelrc b/libs/web/wallet/data-access/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/wallet/data-access/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/wallet/data-access/.eslintrc.json b/libs/web/wallet/data-access/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/wallet/data-access/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/wallet/data-access/README.md b/libs/web/wallet/data-access/README.md new file mode 100644 index 0000000..6df3804 --- /dev/null +++ b/libs/web/wallet/data-access/README.md @@ -0,0 +1,7 @@ +# web-wallet-data-access + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-wallet-data-access` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/wallet/data-access/project.json b/libs/web/wallet/data-access/project.json new file mode 100644 index 0000000..4fd0161 --- /dev/null +++ b/libs/web/wallet/data-access/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-wallet-data-access", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/wallet/data-access/src", + "projectType": "library", + "tags": ["app:web", "type:data-access"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/wallet/data-access/src/index.ts b/libs/web/wallet/data-access/src/index.ts new file mode 100644 index 0000000..9484458 --- /dev/null +++ b/libs/web/wallet/data-access/src/index.ts @@ -0,0 +1,4 @@ +export * from './lib/use-admin-find-many-wallet' +export * from './lib/use-admin-find-one-wallet' +export * from './lib/use-user-find-many-wallet' +export * from './lib/use-user-find-one-wallet' diff --git a/libs/web/wallet/data-access/src/lib/use-admin-find-many-wallet.ts b/libs/web/wallet/data-access/src/lib/use-admin-find-many-wallet.ts new file mode 100644 index 0000000..65eb920 --- /dev/null +++ b/libs/web/wallet/data-access/src/lib/use-admin-find-many-wallet.ts @@ -0,0 +1,52 @@ +import { sdk, WalletAdminCreateInput, WalletAdminFindManyInput } from '@pubkey-resolver/sdk' +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' +import { useState } from 'react' + +export function useAdminFindManyWallet(props: Partial = {}) { + const [limit, setLimit] = useState(props?.limit ?? 10) + const [page, setPage] = useState(props?.page ?? 1) + const [search, setSearch] = useState(props?.search ?? '') + + const input: WalletAdminFindManyInput = { page, limit, search } + const query = useQuery({ + queryKey: ['admin', 'find-many-wallet', input], + queryFn: () => sdk.adminFindManyWallet({ input }).then((res) => res.data), + }) + const total = query.data?.paging?.meta?.totalCount ?? 0 + const items = query.data?.paging.data ?? [] + + return { + items, + query, + pagination: { + page, + setPage, + limit, + setLimit, + total, + }, + setSearch, + createWallet: (input: WalletAdminCreateInput) => + sdk + .adminCreateWallet({ input }) + .then((res) => res.data) + .then((res) => { + if (res.created) { + toastSuccess(`Wallet created`) + } else { + toastError(`Wallet not created`) + } + return res.created + }) + .catch((err) => { + toastError(err.message) + return undefined + }), + deleteWallet: (walletId: string) => + sdk.adminDeleteWallet({ walletId }).then(() => { + toastSuccess('Wallet deleted') + return query.refetch() + }), + } +} diff --git a/libs/web/wallet/data-access/src/lib/use-admin-find-one-wallet.ts b/libs/web/wallet/data-access/src/lib/use-admin-find-one-wallet.ts new file mode 100644 index 0000000..65a33f0 --- /dev/null +++ b/libs/web/wallet/data-access/src/lib/use-admin-find-one-wallet.ts @@ -0,0 +1,34 @@ +import { sdk, WalletAdminUpdateInput } from '@pubkey-resolver/sdk' +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' + +export function useAdminFindOneWallet({ walletId }: { walletId: string }) { + const query = useQuery({ + queryKey: ['admin', 'find-one-wallet', walletId], + queryFn: () => sdk.adminFindOneWallet({ walletId }).then((res) => res.data), + retry: 0, + }) + const item = query.data?.item ?? undefined + + return { + item, + query, + updateWallet: async (input: WalletAdminUpdateInput) => + sdk + .adminUpdateWallet({ walletId, input }) + .then((res) => res.data) + .then(async (res) => { + if (res) { + toastSuccess('Wallet updated') + await query.refetch() + return true + } + toastError('Wallet not updated') + return false + }) + .catch((err) => { + toastError(err.message) + return false + }), + } +} diff --git a/libs/web/wallet/data-access/src/lib/use-user-find-many-wallet.ts b/libs/web/wallet/data-access/src/lib/use-user-find-many-wallet.ts new file mode 100644 index 0000000..3f51279 --- /dev/null +++ b/libs/web/wallet/data-access/src/lib/use-user-find-many-wallet.ts @@ -0,0 +1,53 @@ +import { sdk, WalletUserCreateInput, WalletUserFindManyInput } from '@pubkey-resolver/sdk' + +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' +import { useState } from 'react' + +export function useUserFindManyWallet(props: Partial = {}) { + const [limit, setLimit] = useState(props?.limit ?? 10) + const [page, setPage] = useState(props?.page ?? 1) + const [search, setSearch] = useState(props?.search ?? '') + + const input: WalletUserFindManyInput = { page, limit, search } + const query = useQuery({ + queryKey: ['user', 'find-many-wallet', input], + queryFn: () => sdk.userFindManyWallet({ input }).then((res) => res.data), + }) + const total = query.data?.paging?.meta?.totalCount ?? 0 + const items = query.data?.paging.data ?? [] + + return { + items, + query, + pagination: { + page, + setPage, + limit, + setLimit, + total, + }, + setSearch, + createWallet: (input: WalletUserCreateInput) => + sdk + .userCreateWallet({ input }) + .then((res) => res.data) + .then((res) => { + if (res.created) { + toastSuccess(`Wallet created`) + } else { + toastError(`Wallet not created`) + } + return res.created + }) + .catch((err) => { + toastError(err.message) + return undefined + }), + deleteWallet: (walletId: string) => + sdk.userDeleteWallet({ walletId }).then(() => { + toastSuccess('Wallet deleted') + return query.refetch() + }), + } +} diff --git a/libs/web/wallet/data-access/src/lib/use-user-find-one-wallet.ts b/libs/web/wallet/data-access/src/lib/use-user-find-one-wallet.ts new file mode 100644 index 0000000..74a83d8 --- /dev/null +++ b/libs/web/wallet/data-access/src/lib/use-user-find-one-wallet.ts @@ -0,0 +1,34 @@ +import { sdk, WalletUserUpdateInput } from '@pubkey-resolver/sdk' +import { toastError, toastSuccess } from '@pubkey-ui/core' +import { useQuery } from '@tanstack/react-query' + +export function useUserFindOneWallet({ walletId }: { walletId: string }) { + const query = useQuery({ + queryKey: ['user', 'find-one-wallet', walletId], + queryFn: () => sdk.userFindOneWallet({ walletId }).then((res) => res.data), + retry: 0, + }) + const item = query.data?.item ?? undefined + + return { + item, + query, + updateWallet: async (input: WalletUserUpdateInput) => + sdk + .userUpdateWallet({ walletId, input }) + .then((res) => res.data) + .then(async (res) => { + if (res) { + toastSuccess('Wallet updated') + await query.refetch() + return true + } + toastError('Wallet not updated') + return false + }) + .catch((err) => { + toastError(err.message) + return false + }), + } +} diff --git a/libs/web/wallet/data-access/tsconfig.json b/libs/web/wallet/data-access/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/wallet/data-access/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/wallet/data-access/tsconfig.lib.json b/libs/web/wallet/data-access/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/wallet/data-access/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/web/wallet/feature/.babelrc b/libs/web/wallet/feature/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/wallet/feature/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/wallet/feature/.eslintrc.json b/libs/web/wallet/feature/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/wallet/feature/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/wallet/feature/README.md b/libs/web/wallet/feature/README.md new file mode 100644 index 0000000..46e94ae --- /dev/null +++ b/libs/web/wallet/feature/README.md @@ -0,0 +1,7 @@ +# web-wallet-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-wallet-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/wallet/feature/project.json b/libs/web/wallet/feature/project.json new file mode 100644 index 0000000..7db6986 --- /dev/null +++ b/libs/web/wallet/feature/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-wallet-feature", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/wallet/feature/src", + "projectType": "library", + "tags": ["app:web", "type:feature"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/wallet/feature/src/index.ts b/libs/web/wallet/feature/src/index.ts new file mode 100644 index 0000000..d1b80de --- /dev/null +++ b/libs/web/wallet/feature/src/index.ts @@ -0,0 +1,4 @@ +import { lazy } from 'react' +export const AdminWalletFeature = lazy(() => import('./lib/admin-wallet.routes')) + +export const UserWalletFeature = lazy(() => import('./lib/user-wallet.routes')) diff --git a/libs/web/wallet/feature/src/lib/admin-wallet-create.feature.tsx b/libs/web/wallet/feature/src/lib/admin-wallet-create.feature.tsx new file mode 100644 index 0000000..06fd109 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet-create.feature.tsx @@ -0,0 +1,32 @@ +import { WalletAdminCreateInput } from '@pubkey-resolver/sdk' +import { useAdminFindManyWallet } from '@pubkey-resolver/web-wallet-data-access' +import { AdminWalletUiCreateForm } from '@pubkey-resolver/web-wallet-ui' +import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core' +import { useNavigate } from 'react-router-dom' + +export default function AdminWalletCreateFeature() { + const navigate = useNavigate() + const { createWallet } = useAdminFindManyWallet() + + async function submit(input: WalletAdminCreateInput) { + return createWallet(input) + .then((res) => { + if (res) { + navigate(`../${res?.id}`) + } + }) + .then(() => true) + .catch((err) => { + toastError(err.message) + return false + }) + } + + return ( + } title="Create Wallet"> + + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/admin-wallet-detail-info.tab.tsx b/libs/web/wallet/feature/src/lib/admin-wallet-detail-info.tab.tsx new file mode 100644 index 0000000..48ccc1d --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet-detail-info.tab.tsx @@ -0,0 +1,20 @@ +import { useAdminFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { WalletUiInfo } from '@pubkey-resolver/web-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function AdminWalletDetailInfoTab({ walletId }: { walletId: string }) { + const { item, query } = useAdminFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/admin-wallet-detail-settings.tab.tsx b/libs/web/wallet/feature/src/lib/admin-wallet-detail-settings.tab.tsx new file mode 100644 index 0000000..4d5067a --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet-detail-settings.tab.tsx @@ -0,0 +1,20 @@ +import { useAdminFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { AdminWalletUiUpdateForm } from '@pubkey-resolver/web-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function AdminWalletDetailSettingsTab({ walletId }: { walletId: string }) { + const { item, query, updateWallet } = useAdminFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/admin-wallet-detail.feature.tsx b/libs/web/wallet/feature/src/lib/admin-wallet-detail.feature.tsx new file mode 100644 index 0000000..f64a7bb --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet-detail.feature.tsx @@ -0,0 +1,52 @@ +import { Group } from '@mantine/core' +import { AdminIndexWalletFeature } from '@pubkey-resolver/web-index-wallet-feature' +import { useAdminFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { WalletUiItem } from '@pubkey-resolver/web-wallet-ui' +import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' +import { useParams } from 'react-router-dom' +import { AdminWalletDetailInfoTab } from './admin-wallet-detail-info.tab' +import { AdminWalletDetailSettingsTab } from './admin-wallet-detail-settings.tab' + +export default function AdminWalletDetailFeature() { + const { walletId } = useParams<{ walletId: string }>() as { walletId: string } + const { item, query } = useAdminFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: , + }, + { + path: 'indexes', + label: 'Indexes', + element: , + }, + { + path: 'settings', + label: 'Settings', + element: , + }, + ] + + return ( + } + leftAction={} + rightAction={ + + + + } + > + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/admin-wallet-list.feature.tsx b/libs/web/wallet/feature/src/lib/admin-wallet-list.feature.tsx new file mode 100644 index 0000000..3b1acc7 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet-list.feature.tsx @@ -0,0 +1,50 @@ +import { Button, Group } from '@mantine/core' +import { UiPageLimit, UiSearchField } from '@pubkey-resolver/web-core-ui' +import { useAdminFindManyWallet } from '@pubkey-resolver/web-wallet-data-access' +import { AdminWalletUiTable } from '@pubkey-resolver/web-wallet-ui' +import { UiBack, UiDebugModal, UiInfo, UiLoader, UiPage } from '@pubkey-ui/core' +import { Link } from 'react-router-dom' + +export default function AdminWalletListFeature() { + const { deleteWallet, items, pagination, query, setSearch } = useAdminFindManyWallet({ + limit: 10, + }) + + return ( + } + rightAction={ + + + + + } + > + + + + + + {query.isLoading ? ( + + ) : items?.length ? ( + { + if (!window.confirm('Are you sure?')) return + return deleteWallet(wallet.id) + }} + wallets={items} + page={pagination.page} + totalRecords={pagination.total} + recordsPerPage={pagination.limit} + onPageChange={(page) => void pagination.setPage(page)} + /> + ) : ( + + )} + + ) +} diff --git a/libs/web/wallet/feature/src/lib/admin-wallet.routes.tsx b/libs/web/wallet/feature/src/lib/admin-wallet.routes.tsx new file mode 100644 index 0000000..ae0ad06 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/admin-wallet.routes.tsx @@ -0,0 +1,14 @@ +import { lazy } from 'react' +import { useRoutes } from 'react-router-dom' + +const Create = lazy(() => import('./admin-wallet-create.feature')) +const Detail = lazy(() => import('./admin-wallet-detail.feature')) +const List = lazy(() => import('./admin-wallet-list.feature')) + +export default function AdminWalletRoutes() { + return useRoutes([ + { path: '', element: }, + { path: 'create', element: }, + { path: ':walletId/*', element: }, + ]) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet-create.feature.tsx b/libs/web/wallet/feature/src/lib/user-wallet-create.feature.tsx new file mode 100644 index 0000000..924ed6b --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet-create.feature.tsx @@ -0,0 +1,32 @@ +import { WalletUserCreateInput } from '@pubkey-resolver/sdk' +import { useUserFindManyWallet } from '@pubkey-resolver/web-wallet-data-access' +import { UserWalletUiCreateForm } from '@pubkey-resolver/web-wallet-ui' +import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core' +import { useNavigate } from 'react-router-dom' + +export default function UserWalletCreateFeature() { + const navigate = useNavigate() + const { createWallet } = useUserFindManyWallet() + + async function submit(input: WalletUserCreateInput) { + return createWallet(input) + .then((res) => { + if (res) { + navigate(`../${res?.id}`) + } + }) + .then(() => true) + .catch((err) => { + toastError(err.message) + return false + }) + } + + return ( + } title="Create Wallet"> + + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet-detail-info.tab.tsx b/libs/web/wallet/feature/src/lib/user-wallet-detail-info.tab.tsx new file mode 100644 index 0000000..b53dd24 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet-detail-info.tab.tsx @@ -0,0 +1,20 @@ +import { useUserFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { WalletUiInfo } from '@pubkey-resolver/web-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function UserWalletDetailInfoTab({ walletId }: { walletId: string }) { + const { item, query } = useUserFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet-detail-settings.tab.tsx b/libs/web/wallet/feature/src/lib/user-wallet-detail-settings.tab.tsx new file mode 100644 index 0000000..47bc241 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet-detail-settings.tab.tsx @@ -0,0 +1,20 @@ +import { useUserFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { UserWalletUiUpdateForm } from '@pubkey-resolver/web-wallet-ui' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' + +export function UserWalletDetailSettingsTab({ walletId }: { walletId: string }) { + const { item, query, updateWallet } = useUserFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + return ( + + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet-detail.feature.tsx b/libs/web/wallet/feature/src/lib/user-wallet-detail.feature.tsx new file mode 100644 index 0000000..77050aa --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet-detail.feature.tsx @@ -0,0 +1,52 @@ +import { Group } from '@mantine/core' +import { UserIndexWalletFeature } from '@pubkey-resolver/web-index-wallet-feature' +import { useUserFindOneWallet } from '@pubkey-resolver/web-wallet-data-access' +import { WalletUiItem } from '@pubkey-resolver/web-wallet-ui' +import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' +import { useParams } from 'react-router-dom' +import { UserWalletDetailInfoTab } from './user-wallet-detail-info.tab' +import { UserWalletDetailSettingsTab } from './user-wallet-detail-settings.tab' + +export default function UserWalletDetailFeature() { + const { walletId } = useParams<{ walletId: string }>() as { walletId: string } + const { item, query } = useUserFindOneWallet({ walletId }) + + if (query.isLoading) { + return + } + if (!item) { + return + } + + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: , + }, + { + path: 'indexes', + label: 'Indexes', + element: , + }, + { + path: 'settings', + label: 'Settings', + element: , + }, + ] + + return ( + } + leftAction={} + rightAction={ + + + + } + > + + + ) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet-list.feature.tsx b/libs/web/wallet/feature/src/lib/user-wallet-list.feature.tsx new file mode 100644 index 0000000..50d44e3 --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet-list.feature.tsx @@ -0,0 +1,45 @@ +import { Button, Group } from '@mantine/core' +import { UiSearchField } from '@pubkey-resolver/web-core-ui' +import { useUserFindManyWallet } from '@pubkey-resolver/web-wallet-data-access' +import { UserWalletUiTable } from '@pubkey-resolver/web-wallet-ui' +import { UiBack, UiDebugModal, UiInfo, UiLoader, UiPage } from '@pubkey-ui/core' +import { Link } from 'react-router-dom' + +export default function UserWalletListFeature() { + const { items, pagination, query, setSearch } = useUserFindManyWallet({ + limit: 12, + }) + + return ( + } + rightAction={ + + + + + } + > + + + + + {query.isLoading ? ( + + ) : items?.length ? ( + void pagination.setPage(page)} + /> + ) : ( + + )} + + ) +} diff --git a/libs/web/wallet/feature/src/lib/user-wallet.routes.tsx b/libs/web/wallet/feature/src/lib/user-wallet.routes.tsx new file mode 100644 index 0000000..1faca7c --- /dev/null +++ b/libs/web/wallet/feature/src/lib/user-wallet.routes.tsx @@ -0,0 +1,14 @@ +import { lazy } from 'react' +import { useRoutes } from 'react-router-dom' + +const Create = lazy(() => import('./user-wallet-create.feature')) +const Detail = lazy(() => import('./user-wallet-detail.feature')) +const List = lazy(() => import('./user-wallet-list.feature')) + +export default function UserWalletRoutes() { + return useRoutes([ + { path: '', element: }, + { path: 'create', element: }, + { path: ':walletId/*', element: }, + ]) +} diff --git a/libs/web/wallet/feature/tsconfig.json b/libs/web/wallet/feature/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/wallet/feature/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/wallet/feature/tsconfig.lib.json b/libs/web/wallet/feature/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/wallet/feature/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/web/wallet/ui/.babelrc b/libs/web/wallet/ui/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/libs/web/wallet/ui/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/web/wallet/ui/.eslintrc.json b/libs/web/wallet/ui/.eslintrc.json new file mode 100644 index 0000000..772a43d --- /dev/null +++ b/libs/web/wallet/ui/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/web/wallet/ui/README.md b/libs/web/wallet/ui/README.md new file mode 100644 index 0000000..b4b027f --- /dev/null +++ b/libs/web/wallet/ui/README.md @@ -0,0 +1,7 @@ +# web-wallet-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test web-wallet-ui` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/web/wallet/ui/project.json b/libs/web/wallet/ui/project.json new file mode 100644 index 0000000..e8d4e0d --- /dev/null +++ b/libs/web/wallet/ui/project.json @@ -0,0 +1,12 @@ +{ + "name": "web-wallet-ui", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/web/wallet/ui/src", + "projectType": "library", + "tags": ["app:web", "type:ui"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/web/wallet/ui/src/index.ts b/libs/web/wallet/ui/src/index.ts new file mode 100644 index 0000000..d8de7d6 --- /dev/null +++ b/libs/web/wallet/ui/src/index.ts @@ -0,0 +1,11 @@ +export * from './lib/admin-wallet-ui-create-form' +export * from './lib/admin-wallet-ui-table' +export * from './lib/admin-wallet-ui-update-form' +export * from './lib/wallet-ui-avatar' +export * from './lib/wallet-ui-grid' +export * from './lib/wallet-ui-grid-item' +export * from './lib/wallet-ui-info' +export * from './lib/wallet-ui-item' +export * from './lib/user-wallet-ui-create-form' +export * from './lib/user-wallet-ui-table' +export * from './lib/user-wallet-ui-update-form' diff --git a/libs/web/wallet/ui/src/lib/admin-wallet-ui-create-form.tsx b/libs/web/wallet/ui/src/lib/admin-wallet-ui-create-form.tsx new file mode 100644 index 0000000..3739068 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/admin-wallet-ui-create-form.tsx @@ -0,0 +1,25 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { WalletAdminCreateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function AdminWalletUiCreateForm({ submit }: { submit: (res: WalletAdminCreateInput) => Promise }) { + const form = useForm({ + initialValues: { + id: '', + label: '', + }, + }) + + return ( +
submit(values))}> + + + + + + + +
+ ) +} diff --git a/libs/web/wallet/ui/src/lib/admin-wallet-ui-table.tsx b/libs/web/wallet/ui/src/lib/admin-wallet-ui-table.tsx new file mode 100644 index 0000000..16c129e --- /dev/null +++ b/libs/web/wallet/ui/src/lib/admin-wallet-ui-table.tsx @@ -0,0 +1,58 @@ +import { ActionIcon, Group, ScrollArea } from '@mantine/core' +import { Wallet } from '@pubkey-resolver/sdk' +import { IconPencil, IconTrash } from '@tabler/icons-react' +import { DataTable, DataTableProps } from 'mantine-datatable' +import { Link } from 'react-router-dom' +import { WalletUiItem } from './wallet-ui-item' + +export function AdminWalletUiTable({ + deleteWallet, + wallets = [], + onPageChange, + page, + recordsPerPage, + totalRecords, +}: { + deleteWallet: (wallet: Wallet) => void + wallets: Wallet[] + page: DataTableProps['page'] + totalRecords: DataTableProps['totalRecords'] + recordsPerPage: DataTableProps['recordsPerPage'] + onPageChange: (page: number) => void +}) { + return ( + + , + }, + { + accessor: 'actions', + title: 'Actions', + textAlign: 'right', + render: (item) => ( + + + + + deleteWallet(item)}> + + + + ), + }, + ]} + records={wallets} + /> + + ) +} diff --git a/libs/web/wallet/ui/src/lib/admin-wallet-ui-update-form.tsx b/libs/web/wallet/ui/src/lib/admin-wallet-ui-update-form.tsx new file mode 100644 index 0000000..06ad478 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/admin-wallet-ui-update-form.tsx @@ -0,0 +1,29 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { Wallet, WalletAdminUpdateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function AdminWalletUiUpdateForm({ + submit, + wallet, +}: { + submit: (res: WalletAdminUpdateInput) => Promise + wallet: Wallet +}) { + const form = useForm({ + initialValues: { + label: wallet.label ?? '', + }, + }) + + return ( +
submit(values))}> + + + + + + +
+ ) +} diff --git a/libs/web/wallet/ui/src/lib/user-wallet-ui-create-form.tsx b/libs/web/wallet/ui/src/lib/user-wallet-ui-create-form.tsx new file mode 100644 index 0000000..166011f --- /dev/null +++ b/libs/web/wallet/ui/src/lib/user-wallet-ui-create-form.tsx @@ -0,0 +1,25 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { WalletUserCreateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function UserWalletUiCreateForm({ submit }: { submit: (res: WalletUserCreateInput) => Promise }) { + const form = useForm({ + initialValues: { + id: '', + label: '', + }, + }) + + return ( +
submit(values))}> + + + + + + + +
+ ) +} diff --git a/libs/web/wallet/ui/src/lib/user-wallet-ui-table.tsx b/libs/web/wallet/ui/src/lib/user-wallet-ui-table.tsx new file mode 100644 index 0000000..68081a6 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/user-wallet-ui-table.tsx @@ -0,0 +1,53 @@ +import { ActionIcon, Group, ScrollArea } from '@mantine/core' +import { Wallet } from '@pubkey-resolver/sdk' +import { IconPencil, IconTrash } from '@tabler/icons-react' +import { DataTable, DataTableProps } from 'mantine-datatable' +import { Link } from 'react-router-dom' +import { WalletUiItem } from './wallet-ui-item' + +export function UserWalletUiTable({ + wallets = [], + onPageChange, + page, + recordsPerPage, + totalRecords, +}: { + wallets: Wallet[] + page: DataTableProps['page'] + totalRecords: DataTableProps['totalRecords'] + recordsPerPage: DataTableProps['recordsPerPage'] + onPageChange: (page: number) => void +}) { + return ( + + , + }, + { + accessor: 'actions', + title: 'Actions', + textAlign: 'right', + render: (item) => ( + + + + + + ), + }, + ]} + records={wallets} + /> + + ) +} diff --git a/libs/web/wallet/ui/src/lib/user-wallet-ui-update-form.tsx b/libs/web/wallet/ui/src/lib/user-wallet-ui-update-form.tsx new file mode 100644 index 0000000..856a0fa --- /dev/null +++ b/libs/web/wallet/ui/src/lib/user-wallet-ui-update-form.tsx @@ -0,0 +1,29 @@ +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' +import { Wallet, WalletUserUpdateInput } from '@pubkey-resolver/sdk' +import { UiStack } from '@pubkey-ui/core' + +export function UserWalletUiUpdateForm({ + submit, + wallet, +}: { + submit: (res: WalletUserUpdateInput) => Promise + wallet: Wallet +}) { + const form = useForm({ + initialValues: { + label: wallet.label ?? '', + }, + }) + + return ( +
submit(values))}> + + + + + + +
+ ) +} diff --git a/libs/web/wallet/ui/src/lib/wallet-ui-avatar.tsx b/libs/web/wallet/ui/src/lib/wallet-ui-avatar.tsx new file mode 100644 index 0000000..875eafc --- /dev/null +++ b/libs/web/wallet/ui/src/lib/wallet-ui-avatar.tsx @@ -0,0 +1,10 @@ +import { Wallet } from '@pubkey-resolver/sdk' +import { UiAvatar, UiAvatarProps } from '@pubkey-ui/core' + +export type WalletUiAvatarProps = UiAvatarProps & { + wallet?: Wallet +} + +export function WalletUiAvatar({ wallet, ...props }: WalletUiAvatarProps) { + return +} diff --git a/libs/web/wallet/ui/src/lib/wallet-ui-grid-item.tsx b/libs/web/wallet/ui/src/lib/wallet-ui-grid-item.tsx new file mode 100644 index 0000000..ac00426 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/wallet-ui-grid-item.tsx @@ -0,0 +1,15 @@ +import { Paper } from '@mantine/core' +import { Wallet } from '@pubkey-resolver/sdk' +import { UiDebugModal, UiGroup } from '@pubkey-ui/core' +import { WalletUiItem } from './wallet-ui-item' + +export function WalletUiGridItem({ wallet, to }: { wallet: Wallet; to?: string }) { + return ( + + + + + + + ) +} diff --git a/libs/web/wallet/ui/src/lib/wallet-ui-grid.tsx b/libs/web/wallet/ui/src/lib/wallet-ui-grid.tsx new file mode 100644 index 0000000..ea81e5f --- /dev/null +++ b/libs/web/wallet/ui/src/lib/wallet-ui-grid.tsx @@ -0,0 +1,42 @@ +import { Group, Pagination, SimpleGrid } from '@mantine/core' +import { Wallet } from '@pubkey-resolver/sdk' +import { gridLimits, UiPageLimit } from '@pubkey-resolver/web-core-ui' +import { UiDebugModal, UiGroup, UiStack } from '@pubkey-ui/core' +import { DataTableProps } from 'mantine-datatable' +import { WalletUiGridItem } from './wallet-ui-grid-item' + +export function WalletUiGrid({ + wallets = [], + onPageChange, + page, + totalRecords, + limit, + setLimit, + setPage, +}: { + wallets: Wallet[] + page: DataTableProps['page'] + totalRecords: number + onPageChange: (page: number) => void + limit: number + setLimit: (limit: number) => void + setPage: (page: number) => void +}) { + const totalPages = totalRecords / limit + 1 + return ( + + + {wallets.map((wallet) => ( + + ))} + + + + + + + + + + ) +} diff --git a/libs/web/wallet/ui/src/lib/wallet-ui-info.tsx b/libs/web/wallet/ui/src/lib/wallet-ui-info.tsx new file mode 100644 index 0000000..a013445 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/wallet-ui-info.tsx @@ -0,0 +1,15 @@ +import { Wallet } from '@pubkey-resolver/sdk' +import { UiInfoItems, UiInfoTable, UiTime } from '@pubkey-ui/core' + +export function WalletUiInfo({ wallet }: { wallet?: Wallet }) { + if (!wallet) return null + + const items: UiInfoItems = [ + ['id', wallet.id], + ['label', wallet.label], + ['Created At', ], + ['Updated At', ], + ] + + return +} diff --git a/libs/web/wallet/ui/src/lib/wallet-ui-item.tsx b/libs/web/wallet/ui/src/lib/wallet-ui-item.tsx new file mode 100644 index 0000000..f02b949 --- /dev/null +++ b/libs/web/wallet/ui/src/lib/wallet-ui-item.tsx @@ -0,0 +1,36 @@ +import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core' +import { Wallet } from '@pubkey-resolver/sdk' +import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core' +import { WalletUiAvatar } from './wallet-ui-avatar' + +export function WalletUiItem({ + anchorProps, + avatarProps, + groupProps, + wallet, + to, +}: { + anchorProps?: UiAnchorProps + avatarProps?: Omit + groupProps?: GroupProps + wallet?: Wallet + to?: string | null +}) { + if (!wallet) return null + + return ( + + + + + + {wallet?.label} + + + {wallet?.id} + + + + + ) +} diff --git a/libs/web/wallet/ui/tsconfig.json b/libs/web/wallet/ui/tsconfig.json new file mode 100644 index 0000000..d8c59fe --- /dev/null +++ b/libs/web/wallet/ui/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ], + "extends": "../../../../tsconfig.base.json" +} diff --git a/libs/web/wallet/ui/tsconfig.lib.json b/libs/web/wallet/ui/tsconfig.lib.json new file mode 100644 index 0000000..45b2297 --- /dev/null +++ b/libs/web/wallet/ui/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7cef3f2..d21caeb 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -36,6 +36,7 @@ model Index { dataHash String? label String? entries IndexEntry[] + wallets IndexWallet[] @@unique([address, cluster]) } @@ -50,12 +51,25 @@ model IndexEntry { program String amount String @default("0") address String - wallet String + walletId String data Json? dataHash String? label String? - @@index([cluster, indexAddress, wallet]) + @@index([cluster, indexAddress, walletId]) + @@index([walletId]) +} + +model IndexWallet { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + index Index @relation(fields: [indexId], references: [id], onDelete: Cascade) + indexId String + wallet Wallet @relation(fields: [walletId], references: [id], onDelete: Cascade) + walletId String + + @@unique([indexId, walletId]) } model User { @@ -72,6 +86,14 @@ model User { identities Identity[] } +model Wallet { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + label String + indexes IndexWallet[] +} + enum IdentityProvider { GitHub } diff --git a/tsconfig.base.json b/tsconfig.base.json index bf9eafc..2f4bbc2 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -25,8 +25,12 @@ "@pubkey-resolver/api-index-entry-data-access": ["libs/api/index-entry/data-access/src/index.ts"], "@pubkey-resolver/api-index-entry-feature": ["libs/api/index-entry/feature/src/index.ts"], "@pubkey-resolver/api-index-feature": ["libs/api/index/feature/src/index.ts"], + "@pubkey-resolver/api-index-wallet-data-access": ["libs/api/index-wallet/data-access/src/index.ts"], + "@pubkey-resolver/api-index-wallet-feature": ["libs/api/index-wallet/feature/src/index.ts"], "@pubkey-resolver/api-user-data-access": ["libs/api/user/data-access/src/index.ts"], "@pubkey-resolver/api-user-feature": ["libs/api/user/feature/src/index.ts"], + "@pubkey-resolver/api-wallet-data-access": ["libs/api/wallet/data-access/src/index.ts"], + "@pubkey-resolver/api-wallet-feature": ["libs/api/wallet/feature/src/index.ts"], "@pubkey-resolver/resolvers": ["packages/resolvers/src/index.ts"], "@pubkey-resolver/sdk": ["libs/sdk/src/index.ts"], "@pubkey-resolver/tools": ["libs/tools/src/index.ts"], @@ -46,11 +50,17 @@ "@pubkey-resolver/web-index-entry-ui": ["libs/web/index-entry/ui/src/index.ts"], "@pubkey-resolver/web-index-feature": ["libs/web/index/feature/src/index.ts"], "@pubkey-resolver/web-index-ui": ["libs/web/index/ui/src/index.ts"], + "@pubkey-resolver/web-index-wallet-data-access": ["libs/web/index-wallet/data-access/src/index.ts"], + "@pubkey-resolver/web-index-wallet-feature": ["libs/web/index-wallet/feature/src/index.ts"], + "@pubkey-resolver/web-index-wallet-ui": ["libs/web/index-wallet/ui/src/index.ts"], "@pubkey-resolver/web-settings-feature": ["libs/web/settings/feature/src/index.ts"], "@pubkey-resolver/web-solana-data-access": ["libs/web/solana/data-access/src/index.ts"], "@pubkey-resolver/web-user-data-access": ["libs/web/user/data-access/src/index.ts"], "@pubkey-resolver/web-user-feature": ["libs/web/user/feature/src/index.ts"], - "@pubkey-resolver/web-user-ui": ["libs/web/user/ui/src/index.ts"] + "@pubkey-resolver/web-user-ui": ["libs/web/user/ui/src/index.ts"], + "@pubkey-resolver/web-wallet-data-access": ["libs/web/wallet/data-access/src/index.ts"], + "@pubkey-resolver/web-wallet-feature": ["libs/web/wallet/feature/src/index.ts"], + "@pubkey-resolver/web-wallet-ui": ["libs/web/wallet/ui/src/index.ts"] } }, "exclude": ["node_modules", "tmp"]