Skip to content

Commit

Permalink
Deep clone graph query object before modifying for chain (#101)
Browse files Browse the repository at this point in the history
* Deep clone graph query object before modifying

* use klona

* Bump package version
  • Loading branch information
johnpmitsch authored Sep 21, 2023
1 parent 36e70ea commit 43809b5
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 35 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"ethers": "^6.1.0",
"express": "~4.18.2",
"graphql": "^16.5.0",
"klona": "^2.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hooks-global-state": "^2.1.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/examples/sdk-api/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ if (process.env.ADDITIONAL_SDK_HEADER_KEY) {
};
}
export const api = new QuickNode.API(opts);
export const apiPolygon = new QuickNode.API({
...opts,
defaultChain: 'polygon',
});
export const nfts = api.nfts;
export const tokens = api.tokens;
export const utils = api.utils;
Expand Down
51 changes: 50 additions & 1 deletion packages/apps/examples/sdk-api/src/controllers/nft.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response } from 'express';
import { nfts } from '../client';
import { nfts, api, apiPolygon } from '../client';

export default {
getNFTsByWallet: async (req: Request, res: Response) => {
Expand Down Expand Up @@ -79,4 +79,53 @@ export default {
return res.status(500).send({});
}
},

twoChainQuery: async (req: Request, res: Response) => {
function fetchNFTs(
qn: any,
chain: any,
address: any,
contractAddress: any
) {
console.log(`Querying NFTs from ${chain.toUpperCase()}...`);
return qn.nfts.getByWallet({
address: address,
first: 5,
filter: {
contractTokens: [{ contractAddress: contractAddress }],
},
});
}

async function getNFTsByWallet() {
try {
// Define addresses and contract addresses for each chain
const polygonAddress = '0xA23FcB4645cc618549Da1b61b8564429C2C32Ff9';
const polygonContract = '0xaa8c6b9d67149439680b67ce395c4ac2d233b6de';
const ethereumAddress = '0x01cFd327D29d9C6a07b7613494797A67E89570a0';
const ethereumContract = '0xd77e17ecc3942b6e83f67c56999c5230c70a85a4';

const polygonResults = await fetchNFTs(
apiPolygon,
'polygon',
polygonAddress,
polygonContract
);
const ethereumResults = await fetchNFTs(
api,
'ethereum',
ethereumAddress,
ethereumContract
);

console.log('Polygon Results:', polygonResults.results);
console.log('Ethereum Results:', ethereumResults.results);
return res.status(200).send({});
} catch (error) {
console.error('An error occurred:', error);
}
}

getNFTsByWallet();
},
};
1 change: 1 addition & 0 deletions packages/apps/examples/sdk-api/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ router.get(
'/api/verifyOwnership/:walletAddress/:contractAddress',
nftController.verifyOwnershipByAddress
);
router.get('/api/twoChainQuery', nftController.twoChainQuery);
router.get('/api/graphQuery', graphController.graphQuery);
router.get(
'/api/getBalancesByWallet/:address',
Expand Down
3 changes: 2 additions & 1 deletion packages/libs/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"directory": "packages/libs/sdk"
},
"license": "MIT",
"version": "1.1.3",
"version": "1.1.4",
"main": "./cjs/index.js",
"module": "./esm/src/index.js",
"types": "./index.d.ts",
Expand All @@ -16,6 +16,7 @@
"@urql/exchange-graphcache": "^6.0.4",
"cross-fetch": "^3.1.6",
"graphql": "^16.6.0",
"klona": "^2.0.6",
"tslib": "^2.5.3",
"viem": "^1.2.0",
"zod": "^3.21.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
},
"entries": [
{
"_id": "20a50a9e08e6db7d1e71609537b2b4c7",
"_id": "1b8d0d75774c19e27cdab0fb50113d68",
"_order": 0,
"cache": {},
"request": {
"bodySize": 1109,
"bodySize": 1116,
"cookies": [],
"headers": [
{
Expand All @@ -28,7 +28,7 @@
{
"_fromType": "array",
"name": "x-quicknode-sdk-version",
"value": "1.1.1"
"value": "1.1.3"
},
{
"_fromType": "array",
Expand All @@ -38,7 +38,7 @@
{
"_fromType": "array",
"name": "content-length",
"value": "1109"
"value": "1116"
},
{
"_fromType": "array",
Expand Down Expand Up @@ -66,24 +66,24 @@
"postData": {
"mimeType": "application/json",
"params": [],
"text": "{\"operationName\":\"EthMainnetTrendingCollections\",\"query\":\"query EthMainnetTrendingCollections($first: Int, $before: String, $after: String) {\\n ethereum {\\n ...NftTrendingCollections\\n __typename\\n }\\n}\\nfragment Pagination on PageInfo {\\n endCursor\\n hasNextPage\\n hasPreviousPage\\n startCursor\\n __typename\\n}\\nfragment TrendingCollectionInfo on Collection {\\n address\\n baseTokenUri\\n circulatingSupply\\n description\\n externalUrl\\n image {\\n height\\n mimeType\\n url\\n width\\n __typename\\n }\\n name\\n openseaMetadata {\\n isHidden\\n isVerified\\n unsafeSlug\\n __typename\\n }\\n symbol\\n totalSupply\\n twitterUsername\\n __typename\\n}\\nfragment NftTrendingCollections on EVMSchemaType {\\n trendingCollections(first: $first, before: $before, after: $after) {\\n pageInfo {\\n ...Pagination\\n __typename\\n }\\n edges {\\n node {\\n collection {\\n ...TrendingCollectionInfo\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n __typename\\n}\",\"variables\":{\"first\":2}}"
"text": "{\"operationName\":\"EthMainnetTrendingCollections\",\"query\":\"query EthMainnetTrendingCollections($first: Int, $before: String, $after: String) {\\n ethereumSepolia {\\n ...NftTrendingCollections\\n __typename\\n }\\n}\\nfragment Pagination on PageInfo {\\n endCursor\\n hasNextPage\\n hasPreviousPage\\n startCursor\\n __typename\\n}\\nfragment TrendingCollectionInfo on Collection {\\n address\\n baseTokenUri\\n circulatingSupply\\n description\\n externalUrl\\n image {\\n height\\n mimeType\\n url\\n width\\n __typename\\n }\\n name\\n openseaMetadata {\\n isHidden\\n isVerified\\n unsafeSlug\\n __typename\\n }\\n symbol\\n totalSupply\\n twitterUsername\\n __typename\\n}\\nfragment NftTrendingCollections on EVMSchemaType {\\n trendingCollections(first: $first, before: $before, after: $after) {\\n pageInfo {\\n ...Pagination\\n __typename\\n }\\n edges {\\n node {\\n collection {\\n ...TrendingCollectionInfo\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n __typename\\n}\",\"variables\":{\"first\":2}}"
},
"queryString": [],
"url": "https://api.quicknode.com/graphql"
},
"response": {
"bodySize": 1007,
"bodySize": 276,
"content": {
"encoding": "base64",
"mimeType": "application/json",
"size": 1007,
"text": "[\"H4sIAAAAAAAA/8RWXW/bRhD8K8Q+0+KnSIpvhWCkBeLWrWQ/NAiCJW9Jnn0f7N3RlmDovxfUV6wYbRTDcN6o1Wh2Zm9Oyydg6BDKJyDXkaFBjs/OkGJctXMtBNWOa2XHco8t/aYavYUrNh+M1QZKWMZ/yzq+Df+MZ0Mlb+/YB/FQ3ekV+NCh/Z1W7hpbgtKZgbala0MPXA92V25QWPLBOjTue5yP4MOXL27dk0JJUML1QdPGB2ItWSg/PYHSjEaV9dHA+AkZM2QtlBCukqRhaZzNwmkTpbOmSPKM4jhnYT1jSZKGiCzKsYnAhwotLfU9qRvDoVSDED7U3NSDQMdVuxj6XqyhjJLMB0a2NrzfddxBaeXIKBQ3RkAJnXO9LYMgm8azCdfBV4U2cB1dSJJkA/CBy+1wdhx7s8uOvKsR4FVrb2QAH3RPyhJekcPDUXL7K2eM1HG03N6S4Q0ndiwNymJDCzG0UILraNt3T3ky4D96Uotn/Bsf7FpWWhy0Oe1QHIawLz1y58jc2NG4PLo44b38ax5F0+nXiI3MJ4jlixS+gFzeXi3qjiQu1z29xNu5Vmr3eMlago1/TjTyrKKkyuIiT9IsZnGUxmk4TZNZnuc0y6N8mlJBef4D\",\"0Qiz4ptswDUaFIKEx62H3qLmFw33DtIrQd4cDfM+oCQP/itE2PcTg2aET2otn4Up+CEb+6x9eoKOeNu5UXHog+SSxsFCuUMEdz214MNwImL7lZ38M/D6fhzu5FGbezJ2wughWNlgTE3QaUnWEbKAK0arYFC90TVZS+yZ6osdV5BHrCaWplEeRzEWOM2ajCIMpywOWRE1VTGjBHG8nI+cuW6v9zQ922PphUa2PfeDs/iNnFn5Ps7is52lb+RMsvdxlp7trHgjZ6J9H2fF2c6it4rjSrzTRftOHj8fl9XxD+4X0Xf4ik21e104WVT9nhP3lOduKvj4Ec7bVMcWqnHfNvgpK+vzq3///61hs9n8CwAA//8=\"]"
"size": 276,
"text": "[\"H4sIAAAAAAAA/4TPQUvDQBAF4P8y5xwkNxd6CiIeKikNOShSptnXJGV3J+xOqqXsf5dGPKhIb8PHvMfMhSwrk7kQdEDE7LeYxI0LaUSwY+grcQ6djhLSlSfu8RQOsqSCreaYJJKhpnzxXdnebcr7ee/bo310p/1RdL1ZraiggdMzPrTmHmQO7BIWqyNOo8zphyflqLeK36mg3U7PEwJ7kKH6+7BcEGyPROb17dfOQ7vedgM8N+cJzd8HKwnha7y2/B+lnPMnAAAA//8=\"]"
},
"cookies": [],
"headers": [
{
"name": "date",
"value": "Mon, 28 Aug 2023 15:36:14 GMT"
"value": "Thu, 21 Sep 2023 18:24:12 GMT"
},
{
"name": "content-type",
Expand Down Expand Up @@ -127,7 +127,7 @@
},
{
"name": "x-ratelimit-rpmreset",
"value": "1693237033"
"value": "1695320712"
},
{
"name": "x-ratelimit-rpslimit",
Expand All @@ -139,7 +139,11 @@
},
{
"name": "x-ratelimit-rpsreset",
"value": "1693236974"
"value": "1695320653"
},
{
"name": "x-request-cost",
"value": "0.000000"
},
{
"name": "cf-cache-status",
Expand Down Expand Up @@ -167,29 +171,29 @@
},
{
"name": "cf-ray",
"value": "7fdda0ecc8f90f4b-EWR"
"value": "80a458003c5643f9-EWR"
},
{
"name": "alt-svc",
"value": "h3=\":443\"; ma=86400"
}
],
"headersSize": 873,
"headersSize": 899,
"httpVersion": "HTTP/1.1",
"redirectURL": "",
"status": 200,
"statusText": "OK"
},
"startedDateTime": "2023-08-28T15:36:13.264Z",
"time": 986,
"startedDateTime": "2023-09-21T18:24:12.581Z",
"time": 310,
"timings": {
"blocked": -1,
"connect": -1,
"dns": -1,
"receive": 0,
"send": 0,
"ssl": -1,
"wait": 986
"wait": 310
}
}
],
Expand Down
13 changes: 8 additions & 5 deletions packages/libs/sdk/src/api/graphql/modifyQueryForChain.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { DefinitionNode, FieldNode, Kind, DocumentNode } from 'graphql';
import { TypedDocumentNode } from '@urql/core';
import { ChainName } from '../types/chains';
import { klona } from 'klona';

type Mutable<T> = {
-readonly [k in keyof T]: T[k];
};

type MutableDocumentNode = Mutable<DocumentNode>;

// Takes the generated query document and modifies the chain name to the one passed in
export function modifyQueryForChain<TQuery, TQueryVariables>(
chainName: ChainName,
documentNode: MutableDocumentNode
originalDocumentNode: MutableDocumentNode
): TypedDocumentNode<TQuery, TQueryVariables> {
// We need to deep clone the document node in order to not mutate the query so it is consistent
// across multiple calls to the same query with different chains
const documentNode = klona(originalDocumentNode);

documentNode.definitions = documentNode.definitions.map(
(doc: DefinitionNode) => {
if (doc.kind === Kind.OPERATION_DEFINITION) {
Expand All @@ -25,9 +29,7 @@ export function modifyQueryForChain<TQuery, TQueryVariables>(
) {
const updatedChainSelection: FieldNode = {
...selection,
...{
name: { ...selection.name, value: chainName },
},
name: { ...selection.name, value: chainName },
};
return updatedChainSelection;
}
Expand All @@ -38,5 +40,6 @@ export function modifyQueryForChain<TQuery, TQueryVariables>(
return doc;
}
);

return documentNode;
}
18 changes: 7 additions & 11 deletions packages/libs/sdk/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -572,15 +572,6 @@
"@graphql-codegen/plugin-helpers" "^2.6.2"
tslib "~2.4.0"

"@graphql-codegen/introspection@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@graphql-codegen/introspection/-/introspection-3.0.1.tgz#403c9bb12abf998a3bd37a519eb0fd01b537d64d"
integrity sha512-D6vJQTEL/np4EmeUHm5spLK59cr+AMXEoLRoTI+dagFzlHYDTfXZH6F7uhKaakxcj0SAQhIWKvGMggotUdEtyg==
dependencies:
"@graphql-codegen/plugin-helpers" "^4.1.0"
"@graphql-codegen/visitor-plugin-common" "^3.0.1"
tslib "~2.5.0"

"@graphql-codegen/plugin-helpers@^2.6.2":
version "2.7.1"
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.1.tgz#de999bdf8a1485f6f3c4c5f21cfb038e99d67e3e"
Expand All @@ -593,7 +584,7 @@
lodash "~4.17.0"
tslib "~2.4.0"

"@graphql-codegen/plugin-helpers@^4.1.0", "@graphql-codegen/plugin-helpers@^4.2.0":
"@graphql-codegen/plugin-helpers@^4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-4.2.0.tgz#8324914d0f99162a223cfa01796cdd6be972d2ae"
integrity sha512-THFTCfg+46PXlXobYJ/OoCX6pzjI+9woQqCjdyKtgoI0tn3Xq2HUUCiidndxUpEYVrXb5pRiRXb7b/ZbMQqD0A==
Expand Down Expand Up @@ -675,7 +666,7 @@
parse-filepath "^1.0.2"
tslib "~2.4.0"

"@graphql-codegen/visitor-plugin-common@3.1.1", "@graphql-codegen/visitor-plugin-common@^3.0.1":
"@graphql-codegen/visitor-plugin-common@3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-3.1.1.tgz#50c2aa3c537a805ce68d2f115d0a9811b151428c"
integrity sha512-uAfp+zu/009R3HUAuTK2AamR1bxIltM6rrYYI6EXSmkM3rFtFsLTuJhjUDj98HcUCszJZrADppz8KKLGRUVlNg==
Expand Down Expand Up @@ -2798,6 +2789,11 @@ jsonify@~0.0.0:
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978"
integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==

klona@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==

lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6924,7 +6924,7 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==

klona@^2.0.4, klona@^2.0.5:
klona@^2.0.4, klona@^2.0.5, klona@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==
Expand Down

0 comments on commit 43809b5

Please sign in to comment.