You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Many projects who wish to use the RPC-GraphQL resolver library may wish to
extend the default schema, which is designed around the Solana JSON-RPC API. Currently, the library does
not allow for such customization.
The library should support, at least, the following extension capabilities.
Custom types and type resolvers.
Custom root queries and query resolvers.
Account decoders for fetched encoded accounts.
Instruction decoders for fetched encoded transaction instructions.
Example use case
An example use case for the first two items can be defined as follows, where
a developer wishes to extend the schema to support querying of a custom NftMasterEdition object.
constmasterEditionAddress='B2Srva38aD8bWpjghkU7jKFUqT1Y4KB2ejAnsJbP2ibA';// Define custom type definitions for the GraphQL schema.constcustomTypeDefs=/* GraphQL */` # A Solana Master Edition NFT. type NftMasterEdition { address: Address metadata: Account mint: Account } # Query to retrieve a Solana Master Edition NFT. type Query { masterEdition(address: Address!): NftMasterEdition }`;// Define custom resolvers for the GraphQL schema.constcustomTypeResolvers={// Resolver for the custom `NftMasterEdition` type.NftMasterEdition: {metadata: resolveAccount('metadata'),mint: resolveAccount('mint'),},};// Define custom queries for the GraphQL schema.constcustomQueryResolvers={// Query to retrieve a Solana Master Edition NFT.masterEdition: ()=>{return{// Arbitrary address.address: masterEditionAddress,// See scripts/fixtures/gpa1.json.metadata: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',// See scripts/fixtures/spl-token-mint-account.json.mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',};},};// Create the RPC-GraphQL client with the custom type definitions and// resolvers.constrpcGraphQL=createRpcGraphQL(rpc,{queryResolvers: customQueryResolvers,typeDefs: customTypeDefs,typeResolvers: customTypeResolvers,});// Create a test query for the custom `masterEdition` query.constsource=/* GraphQL */` query ($masterEditionAddress: Address!) { masterEdition(address: $masterEditionAddress) { address metadata { address lamports } mint { address lamports ownerProgram { address } ... on MintAccount { decimals supply } } } }`;// Execute the test query.constresult=awaitrpcGraphQL.query(source,{
masterEditionAddress,});
Another example use case for account decoding can be defined as follows, using the
same custom NftMasterEdition type. Note that this same concept can also be applied
to decoding transaction instructions.
constmasterEditionAddress='B2Srva38aD8bWpjghkU7jKFUqT1Y4KB2ejAnsJbP2ibA';// Define custom type definitions for the GraphQL schema.constcustomTypeDefs=/* GraphQL */` # A Solana Master Edition NFT. type NftMasterEdition implements Account { address: Address data(encoding: AccountEncoding!, dataSlice: DataSlice): String executable: Boolean lamports: BigInt ownerProgram: Account space: BigInt rentEpoch: BigInt metadata: Account mint: Account }`;// Define custom resolvers for the GraphQL schema.constcustomTypeResolvers={// Resolver for the custom `NftMasterEdition` account type.NftMasterEdition: {metadata: resolveAccount('metadata'),mint: resolveAccount('mint'),},};// Create the RPC-GraphQL client with the custom type definitions and// resolvers.constrpcGraphQL=createRpcGraphQL(rpc,{typeDefs: customTypeDefs,typeResolvers: customTypeResolvers,});// Create a test query for the custom `masterEdition` query.constsource=/* GraphQL */` query ($masterEditionAddress: Address!) { account(address: $masterEditionAddress) { address lamports ... on NftMasterEdition { metadata { address lamports } mint { address lamports ownerProgram { address } ... on MintAccount { decimals supply } } } } }`;// Execute the test query.constresult=awaitrpcGraphQL.query(source,{
masterEditionAddress,});
Details
The first example demonstrated above is quite trivial. The resolver library needs
only minimal changes to support new queries, resolvers, and types. However, the
second example is trickier to implement.
When implementing custom account and instruction type support, one must consider
the ramifications of how serialization should be conducted. Specifically, how does the
resolver know which account type to attempt to deserialize from some base64
encoded data? Imagine the developer has provided 30 types of accounts (say, from
multiple IDLs).
It's impractical to simply attempt to deserialize an encoded account's data until one
is successful. Not only is this computationally intensive, but it's also prone to bugs
(imagine two or more account type layouts are highly similar and don't use discriminators).
For this reason, the decision-making aspect of telling RPC-GraphQL how and when to
deserialize account data should be left up to the developer to implement. This way, they
can take into account the use of discriminators or other optimizations for decoding data,
without compromising performance on the base library.
The text was updated successfully, but these errors were encountered:
Motivation
Many projects who wish to use the RPC-GraphQL resolver library may wish to
extend the default schema, which is designed around the
Solana JSON-RPC API. Currently, the library does
not allow for such customization.
The library should support, at least, the following extension capabilities.
Example use case
An example use case for the first two items can be defined as follows, where
a developer wishes to extend the schema to support querying of a custom
NftMasterEdition
object.Another example use case for account decoding can be defined as follows, using the
same custom
NftMasterEdition
type. Note that this same concept can also be appliedto decoding transaction instructions.
Details
The first example demonstrated above is quite trivial. The resolver library needs
only minimal changes to support new queries, resolvers, and types. However, the
second example is trickier to implement.
When implementing custom account and instruction type support, one must consider
the ramifications of how serialization should be conducted. Specifically, how does the
resolver know which account type to attempt to deserialize from some
base64
encoded data? Imagine the developer has provided 30 types of accounts (say, from
multiple IDLs).
It's impractical to simply attempt to deserialize an encoded account's data until one
is successful. Not only is this computationally intensive, but it's also prone to bugs
(imagine two or more account type layouts are highly similar and don't use discriminators).
For this reason, the decision-making aspect of telling RPC-GraphQL how and when to
deserialize account data should be left up to the developer to implement. This way, they
can take into account the use of discriminators or other optimizations for decoding data,
without compromising performance on the base library.
The text was updated successfully, but these errors were encountered: