{"id":3115,"date":"2021-07-21T13:06:00","date_gmt":"2021-07-21T01:06:00","guid":{"rendered":"https:\/\/www.talkcrypto.org\/blog\/?p=3115"},"modified":"2023-11-27T21:16:13","modified_gmt":"2023-11-27T08:16:13","slug":"how-to-list-all-transactions-for-a-given-address-in-subquery","status":"publish","type":"post","link":"https:\/\/www.talkcrypto.org\/blog\/2021\/07\/21\/how-to-list-all-transactions-for-a-given-address-in-subquery\/","title":{"rendered":"How to list all transactions for a given address in SubQuery"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">What we will do here is to write a query to list all the transaction for a given Polkadot address as seen in the screenshot below. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"338\" src=\"https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-1024x338.png\" alt=\"\" class=\"wp-image-3116\" srcset=\"https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-1024x338.png 1024w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-300x99.png 300w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-768x253.png 768w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-1536x506.png 1536w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-07-at-10.34.28-am-2048x675.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pre-requisites <\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Have gone through the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.talkcrypto.org\/blog\/2021\/05\/04\/part-1-subql-hello-world-in-less-than-5-mins\/\" target=\"_blank\">SubQuery Hello World<\/a> exercise. This ensures your environment has all the required applications.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 1: Run subql init<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This will set up the scaffolding making everything a lot easier.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/Code\/subQuery\/projects$ subql init\nProject name &#91;subql-starter]: subql-list-transactions\nGit repository: \nRPC endpoint &#91;wss:\/\/polkadot.api.onfinality.io\/public-ws]: \nAuthors: sa\nDescription: \nVersion: &#91;1.0.0]: \nLicense: &#91;Apache-2.0]: \nInit the starter package... subql-list-transactions is ready\n~\/Code\/subQuery\/projects$ <\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step 2: Create a schema<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The first step is to create your schema file which &#8220;defines the shape of your data&#8221;. Here we will define 2 entities or objects, Account and Transfer.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Account @entity {\n  id: ID!\n  sentTransfers: &#91;Transfer] @derivedFrom(field: \"from\")\n  receivedTransfers: &#91;Transfer] @derivedFrom(field: \"to\")\n}\n\ntype Transfer @entity {\n  id: ID!\n  amount: BigInt\n  to: Account!\n  from: Account!\n}<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step 3: Update the manifest file<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In the manifest file, we want to create a handler called handleTransfer (to be written next). This is a standard substrate\/Eventhandler and we will filter on the balances module. The filter is optional but recommended as they significantly reduce the amount of data processed by your SubQuery project and will improve indexing performance. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>specVersion: 0.0.1\ndescription: \"\"\nrepository: \"\"\nschema: .\/schema.graphql\nnetwork:\n  endpoint: wss:\/\/polkadot.api.onfinality.io\/public-ws\ndataSources:\n  - name: main\n    kind: substrate\/Runtime\n    startBlock: 6716560\n    mapping:\n      handlers:\n        - handler: handleTransfer\n          kind: substrate\/EventHandler\n          filter:\n            module: balances\n            method: Transfer\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step 4: Writing the mappings<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is perhaps the most challenging part for those still learning SubQuery and Polkdadot. What the code below does is create a helper function called &#8220;ensureAccounts&#8221; and a handleTransfer EventHandler function to grab the transferred amount along with the to and from Id. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import {SubstrateExtrinsic,SubstrateEvent,SubstrateBlock} from \"@subql\/types\";\nimport {Transfer, Account} from \"..\/types\";\nimport {Balance} from \"@polkadot\/types\/interfaces\";\n\nasync function ensureAccounts(accountIds: string&#91;]): Promise&lt;void> {\n    for (const accountId of accountIds) {\n        const account = await Account.get(accountId);\n        if (!account) {\n            await new Account(accountId).save();\n        }\n    }\n}\n\nexport async function handleTransfer(event: SubstrateEvent): Promise&lt;void> {\n    const {\n        event: {\n            data: &#91;from, to, amount],\n        },\n    } = event;\n    await ensureAccounts(&#91;from.toString(), to.toString()]);\n    const transferInfo = new Transfer(\n        `${event.block.block.header.number.toNumber()}-${event.idx}`,\n    );\n    transferInfo.fromId = from.toString();\n    transferInfo.toId = to.toString();\n    transferInfo.amount = (amount as Balance).toBigInt();\n    await transferInfo.save();\n}\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step 5: Build and deploy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run the standard commands.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>yarn codegen\nyarn build\ndocker-compose pull &amp; docker-compose up<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 6: Query<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now comes the fun part, the query. Below is an example query that can be used. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>query {\n    accounts (first:15 orderBy:CREATED_AT_DESC filter:{id: {equalTo: \"12qvDzHzs3LFBnir7UAYR154t4ZWNLjMehniqLhTp2CBCeW4\"}} ) {\n        nodes {\n            id\n            createdAt\n            updatedAt\n          recievedTransfers {\n            edges {\n              node {\n                id\n                amount\n              }\n            }\n          }\n        }\n    }\n    transfers ( orderBy:CREATED_AT_DESC filter:{id: {equalTo: \"12qvDzHzs3LFBnir7UAYR154t4ZWNLjMehniqLhTp2CBCeW4\"}} ) {\n        nodes {\n            id\n          createdAt\n          updatedAt\n            amount\n            toId\n            fromId\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will return:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"data\": {\n    \"accounts\": {\n      \"nodes\": &#91;\n        {\n          \"id\": \"12qvDzHzs3LFBnir7UAYR154t4ZWNLjMehniqLhTp2CBCeW4\",\n          \"createdAt\": \"2021-09-07T00:01:15.719+00:00\",\n          \"updatedAt\": \"2021-09-07T00:01:15.719+00:00\",\n          \"recievedTransfers\": {\n            \"edges\": &#91;\n              {\n                \"node\": {\n                  \"id\": \"6716562-3\",\n                  \"amount\": \"20000000000\"\n                }\n              },\n              {\n                \"node\": {\n                  \"id\": \"6716591-1\",\n                  \"amount\": \"700000000000\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"transfers\": {\n      \"nodes\": &#91;]\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And this matches <a rel=\"noreferrer noopener\" href=\"https:\/\/polkadot.subscan.io\/account\/12qvDzHzs3LFBnir7UAYR154t4ZWNLjMehniqLhTp2CBCeW4?tab=transfer\" target=\"_blank\">subscan<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"478\" src=\"https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/image-1024x478.png\" alt=\"\" class=\"wp-image-3121\" srcset=\"https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/image-1024x478.png 1024w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/image-300x140.png 300w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/image-768x358.png 768w, https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2021\/09\/image.png 1213w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction What we will do here is to write a<\/p>\n","protected":false},"author":1,"featured_media":3405,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-3115","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain"],"featured_image_urls":{"full":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses.png",1538,910,false],"thumbnail":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-150x150.png",150,150,true],"medium":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-300x178.png",300,178,true],"medium_large":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-768x454.png",640,378,true],"large":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-1024x606.png",640,379,true],"1536x1536":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-1536x909.png",1536,909,true],"2048x2048":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses.png",1538,910,false],"chromenews-featured":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-1024x606.png",1024,606,true],"chromenews-large":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-825x575.png",825,575,true],"chromenews-medium":["https:\/\/www.talkcrypto.org\/blog\/wp-content\/uploads\/2023\/11\/addresses-590x410.png",590,410,true]},"author_info":{"info":["seandotau"]},"category_info":"<a href=\"https:\/\/www.talkcrypto.org\/blog\/category\/blockchain\/\" rel=\"category tag\">Blockchain<\/a>","tag_info":"Blockchain","comment_count":"0","_links":{"self":[{"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/posts\/3115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/comments?post=3115"}],"version-history":[{"count":1,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/posts\/3115\/revisions"}],"predecessor-version":[{"id":3122,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/posts\/3115\/revisions\/3122"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/media\/3405"}],"wp:attachment":[{"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/media?parent=3115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/categories?post=3115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.talkcrypto.org\/blog\/wp-json\/wp\/v2\/tags?post=3115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}