Skip to content

Commit

Permalink
Merge pull request tqtezos#36 from tqtezos/lambdahands/nft-queries
Browse files Browse the repository at this point in the history
feat: Implement NFT GraphQL Queries
  • Loading branch information
lambdahands authored Aug 31, 2020
2 parents 67bd392 + 0019b62 commit 12c0f12
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 111 deletions.
22 changes: 12 additions & 10 deletions client/src/generated/graphql_schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ export type MutationCreateNonFungibleTokenArgs = {

export type NonFungibleToken = {
__typename?: 'NonFungibleToken';
id: Scalars['Int'];
name: Scalars['String'];
symbol: Scalars['String'];
token_id: Scalars['String'];
creator_address: Scalars['String'];
operation_address: Scalars['String'];
extras: Scalars['JSON'];
decimals: Scalars['Int'];
owner: Scalars['String'];
};

export type Operation = {
Expand All @@ -165,30 +167,30 @@ export type PublishedOperation = {

export type Query = {
__typename?: 'Query';
nftTokens?: Maybe<Array<Maybe<NonFungibleToken>>>;
nfts?: Maybe<Array<Maybe<NonFungibleToken>>>;
nftByTokenId?: Maybe<NonFungibleToken>;
nftByCreatorAddress?: Maybe<NonFungibleToken>;
nftByOperationAddress?: Maybe<NonFungibleToken>;
nftByOwner?: Maybe<NonFungibleToken>;
nftByOperation?: Maybe<NonFungibleToken>;
publishedOperationByHash?: Maybe<PublishedOperation>;
publishedOperationsByInitiator?: Maybe<Array<Maybe<PublishedOperation>>>;
publishedOperationsByMethod?: Maybe<Array<Maybe<PublishedOperation>>>;
publishedOperationsByStatus?: Maybe<Array<Maybe<PublishedOperation>>>;
settings: Settings;
};

export type QueryNftTokensArgs = {
export type QueryNftsArgs = {
limit?: Maybe<Scalars['Int']>;
};

export type QueryNftByTokenIdArgs = {
token_id: Scalars['String'];
};

export type QueryNftByCreatorAddressArgs = {
creator_address: Scalars['String'];
export type QueryNftByOwnerArgs = {
owner_address: Scalars['String'];
};

export type QueryNftByOperationAddressArgs = {
export type QueryNftByOperationArgs = {
operation_address: Scalars['String'];
};

Expand Down
2 changes: 1 addition & 1 deletion config/minter.sandbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"secret": "edskRpm2mUhvoUjHjXgMoDRxMKhtKfww1ixmWiHCWhHuMEEbGzdnz8Ks4vgarKDtxok7HmrEo1JzkXkdkvyw7Rtw6BNtSd7MJ7"
},
"contracts": {
"nft": "KT1FVT95brPwbuWb6epuqU95hjzwyz2oqdz1"
"nft": "KT1F4ac3hCqK9128MRwkcsPLvvYamGaEsHZL"
}
}
50 changes: 25 additions & 25 deletions server/src/generated/graphql_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@ export type MutationCreateNonFungibleTokenArgs = {

export type NonFungibleToken = {
__typename?: 'NonFungibleToken';
id: Scalars['Int'];
name: Scalars['String'];
symbol: Scalars['String'];
token_id: Scalars['String'];
creator_address: Scalars['String'];
operation_address: Scalars['String'];
extras: Scalars['JSON'];
decimals: Scalars['Int'];
owner: Scalars['String'];
};

export type Operation = {
Expand All @@ -174,30 +176,30 @@ export type PublishedOperation = {

export type Query = {
__typename?: 'Query';
nftTokens?: Maybe<Array<Maybe<NonFungibleToken>>>;
nfts?: Maybe<Array<Maybe<NonFungibleToken>>>;
nftByTokenId?: Maybe<NonFungibleToken>;
nftByCreatorAddress?: Maybe<NonFungibleToken>;
nftByOperationAddress?: Maybe<NonFungibleToken>;
nftByOwner?: Maybe<NonFungibleToken>;
nftByOperation?: Maybe<NonFungibleToken>;
publishedOperationByHash?: Maybe<PublishedOperation>;
publishedOperationsByInitiator?: Maybe<Array<Maybe<PublishedOperation>>>;
publishedOperationsByMethod?: Maybe<Array<Maybe<PublishedOperation>>>;
publishedOperationsByStatus?: Maybe<Array<Maybe<PublishedOperation>>>;
settings: Settings;
};

export type QueryNftTokensArgs = {
export type QueryNftsArgs = {
limit?: Maybe<Scalars['Int']>;
};

export type QueryNftByTokenIdArgs = {
token_id: Scalars['String'];
};

export type QueryNftByCreatorAddressArgs = {
creator_address: Scalars['String'];
export type QueryNftByOwnerArgs = {
owner_address: Scalars['String'];
};

export type QueryNftByOperationAddressArgs = {
export type QueryNftByOperationArgs = {
operation_address: Scalars['String'];
};

Expand Down Expand Up @@ -353,12 +355,12 @@ export type ResolversTypes = ResolversObject<{
Int: ResolverTypeWrapper<Scalars['Int']>;
NonFungibleToken: ResolverTypeWrapper<NonFungibleToken>;
String: ResolverTypeWrapper<Scalars['String']>;
JSON: ResolverTypeWrapper<Scalars['JSON']>;
PublishedOperation: ResolverTypeWrapper<PublishedOperation>;
Boolean: ResolverTypeWrapper<Scalars['Boolean']>;
Settings: ResolverTypeWrapper<Settings>;
Mutation: ResolverTypeWrapper<{}>;
Subscription: ResolverTypeWrapper<{}>;
JSON: ResolverTypeWrapper<Scalars['JSON']>;
ContractStorageMeta: ResolverTypeWrapper<ContractStorageMeta>;
BigMapMeta: ResolverTypeWrapper<BigMapMeta>;
BigMapKV: ResolverTypeWrapper<BigMapKv>;
Expand All @@ -381,12 +383,12 @@ export type ResolversParentTypes = ResolversObject<{
Int: Scalars['Int'];
NonFungibleToken: NonFungibleToken;
String: Scalars['String'];
JSON: Scalars['JSON'];
PublishedOperation: PublishedOperation;
Boolean: Scalars['Boolean'];
Settings: Settings;
Mutation: {};
Subscription: {};
JSON: Scalars['JSON'];
ContractStorageMeta: ContractStorageMeta;
BigMapMeta: BigMapMeta;
BigMapKV: BigMapKv;
Expand Down Expand Up @@ -659,14 +661,12 @@ export type NonFungibleTokenResolvers<
ContextType = Context,
ParentType extends ResolversParentTypes['NonFungibleToken'] = ResolversParentTypes['NonFungibleToken']
> = ResolversObject<{
id?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
symbol?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
token_id?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
creator_address?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
operation_address?: Resolver<
ResolversTypes['String'],
ParentType,
ContextType
>;
extras?: Resolver<ResolversTypes['JSON'], ParentType, ContextType>;
decimals?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
owner?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
}>;

Expand Down Expand Up @@ -697,29 +697,29 @@ export type QueryResolvers<
ContextType = Context,
ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']
> = ResolversObject<{
nftTokens?: Resolver<
nfts?: Resolver<
Maybe<Array<Maybe<ResolversTypes['NonFungibleToken']>>>,
ParentType,
ContextType,
RequireFields<QueryNftTokensArgs, never>
RequireFields<QueryNftsArgs, never>
>;
nftByTokenId?: Resolver<
Maybe<ResolversTypes['NonFungibleToken']>,
ParentType,
ContextType,
RequireFields<QueryNftByTokenIdArgs, 'token_id'>
>;
nftByCreatorAddress?: Resolver<
nftByOwner?: Resolver<
Maybe<ResolversTypes['NonFungibleToken']>,
ParentType,
ContextType,
RequireFields<QueryNftByCreatorAddressArgs, 'creator_address'>
RequireFields<QueryNftByOwnerArgs, 'owner_address'>
>;
nftByOperationAddress?: Resolver<
nftByOperation?: Resolver<
Maybe<ResolversTypes['NonFungibleToken']>,
ParentType,
ContextType,
RequireFields<QueryNftByOperationAddressArgs, 'operation_address'>
RequireFields<QueryNftByOperationArgs, 'operation_address'>
>;
publishedOperationByHash?: Resolver<
Maybe<ResolversTypes['PublishedOperation']>,
Expand Down
41 changes: 0 additions & 41 deletions server/src/models/non_fungible_token.ts

This file was deleted.

13 changes: 9 additions & 4 deletions server/src/resolvers/mutations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@ const Mutation: MutationResolvers = {
const nftStorage = await nftContract.storage<any>();
const adminAddress = await ctx.tzClient.signer.publicKeyHash();

const extras = new MichelsonMap({
prim: 'map',
args: [{ prim: 'string' }, { prim: 'string' }]
});

extras.set('description', args.description);
extras.set('ipfs_hash', args.ipfs_hash);

const params = [
{
metadata: {
token_id: nftStorage.assets.next_token_id,
symbol: args.symbol,
name: args.name,
decimals: new BigNumber(0),
extras: new MichelsonMap({
prim: 'map',
args: [{ prim: 'string' }, { prim: 'string' }]
})
extras
},
owner: adminAddress
}
Expand Down
67 changes: 43 additions & 24 deletions server/src/resolvers/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { Resolvers, QueryResolvers } from '../../generated/graphql_schema';
import { SessionContext } from '../../components/context';
import axios from 'axios';
import NonFungibleToken from '../../models/non_fungible_token';
import { Context } from '../../components/context';
import PublishedOperation from '../../models/published_operation';
import axios from 'axios';

const getTzStats = async (ctx: SessionContext, resource: string) =>
(await axios.get(`${ctx.tzStatsApiUrl}/${resource}`)).data;
async function getTzStats(ctx: Context, resource: string) {
const response = await axios.get(`${ctx.tzStatsApiUrl}/${resource}`);
return response.data;
}

async function extractNftData(ctx: Context) {
const nftContract = await ctx.contractStore.nftContract();
const contractResource = `contract/${nftContract.address}`;
const contractData = await getTzStats(ctx, contractResource);
const nftResource = `bigmap/${contractData.bigmap_ids[0]}/values`;
const nftData = await getTzStats(ctx, nftResource);
const ownerResource = `bigmap/${contractData.bigmap_ids[2]}/values`;
const ownerData = await getTzStats(ctx, ownerResource);
return { nftContract, contractData, nftData, ownerData };
}

const Query: QueryResolvers = {
async publishedOperationByHash(_parent, { hash }, { db }) {
Expand All @@ -14,27 +26,34 @@ const Query: QueryResolvers = {
},

// TODO: Convert to indexer API getters
async nftByTokenId(_parent, { token_id }, { db }) {
const nft = await NonFungibleToken.byTokenId(db, token_id);
return nft || null;
},

async nftByCreatorAddress(_parent, { creator_address }, { db }) {
const nft = await NonFungibleToken.byCreatorAddress(db, creator_address);
return nft || null;
},

async nftByOperationAddress(_parent, { operation_address }, { db }) {
const nft = await NonFungibleToken.byOperationAddress(
db,
operation_address
);
return nft || null;
async nftByTokenId(_parent, { token_id }, ctx) {
const { nftData, ownerData } = await extractNftData(ctx);
const token = nftData.find((kv: any) => kv.value.token_id === token_id);
if (!token) return null;
const owner = ownerData.find((kv: any) => kv.key === token.key);
if (!owner) return null;
return {
name: token.value.name,
symbol: token.value.symbol,
token_id: token.value.token_id,
extras: token.value.extras,
decimals: parseInt(token.value.decimals),
owner: owner.value
};
},

async nftTokens(_parent, { limit }, { db }) {
const nfts = await NonFungibleToken.all(db).limit(limit || 20);
return nfts;
// TODO: Implement paging/limiting - tzindex API supports query params that
// enable this behavior
async nfts(_parent, _args, ctx) {
const { nftData, ownerData } = await extractNftData(ctx);
return nftData.map((token: any) => ({
name: token.value.name,
symbol: token.value.symbol,
token_id: token.value.token_id,
extras: token.value.extras,
decimals: parseInt(token.value.decimals),
owner: ownerData.find((kv: any) => kv.key === token.key).value
}));
},

settings(_parent, _args, { tzStatsUrl }) {
Expand Down
15 changes: 9 additions & 6 deletions server/src/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ type ContractOperation {
## Application Types

type NonFungibleToken {
id: Int!
name: String!
symbol: String!
token_id: String!
creator_address: String!
operation_address: String!
extras: JSON!
decimals: Int!
owner: String!
}

type PublishedOperation {
Expand All @@ -142,10 +144,11 @@ type Settings {
## Toplevel Types

type Query {
nftTokens(limit: Int): [NonFungibleToken]
nfts(limit: Int): [NonFungibleToken]
nftByTokenId(token_id: String!): NonFungibleToken
nftByCreatorAddress(creator_address: String!): NonFungibleToken
nftByOperationAddress(operation_address: String!): NonFungibleToken

nftByOwner(owner_address: String!): NonFungibleToken
nftByOperation(operation_address: String!): NonFungibleToken

publishedOperationByHash(hash: String!): PublishedOperation
publishedOperationsByInitiator(initiator: String!): [PublishedOperation]
Expand Down

0 comments on commit 12c0f12

Please sign in to comment.