{"id":50982495,"url":"https://github.com/sudhir-b/deserialise","last_synced_at":"2026-06-19T15:44:30.916Z","repository":{"id":42698450,"uuid":"510495479","full_name":"sudhir-b/deserialise","owner":"sudhir-b","description":"Anchor-based Solana account deserialiser","archived":false,"fork":false,"pushed_at":"2022-07-15T15:52:36.000Z","size":57,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-05-02T01:54:33.946Z","etag":null,"topics":["anchor","aws","rust","solana","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudhir-b.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-04T20:31:28.000Z","updated_at":"2022-07-18T08:09:11.000Z","dependencies_parsed_at":"2022-09-18T18:16:24.992Z","dependency_job_id":null,"html_url":"https://github.com/sudhir-b/deserialise","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/sudhir-b/deserialise","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudhir-b%2Fdeserialise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudhir-b%2Fdeserialise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudhir-b%2Fdeserialise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudhir-b%2Fdeserialise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudhir-b","download_url":"https://codeload.github.com/sudhir-b/deserialise/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudhir-b%2Fdeserialise/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34538475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anchor","aws","rust","solana","typescript"],"created_at":"2026-06-19T15:44:30.297Z","updated_at":"2026-06-19T15:44:30.911Z","avatar_url":"https://github.com/sudhir-b.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deserialise\n\nDeserialise is an implementation of dynamic Solana account deserialisation using\n[on-chain IDL files as specified by the Anchor framework](https://book.anchor-lang.com/anchor_references/cli.html#idl), designed to be accessed behind an AWS Lambda Function URL (with or without\na custom domain) with plain HTTP GET requests.\n\n`HTTP GET` requests to a function URL take the following query parameters:\n\n- `programId`\n  - **required**\n  - base 58 encoded public key\n- `accountId`\n  - **required**\n  - base 58 encoded public key\n- `accountType`\n  - **required**\n  - string\n- `cluster`\n  - optional\n  - if specified, must be one of: `mainnet-beta`, `testnet`, `devnet`\n  - defaults to `mainnet-beta` if unspecified\n\n### Example request:\n\n```\nhttps://\u003cLAMBDA_FUNCTION_URL\u003e?programId=nosJhNRqr2bc9g1nfGDcXXTXvYUmxD4cVwy2pMWhrYM\u0026accountType=jobs\u0026accountId=BNHE7twpb1SQVutNkZ9knQfLTjaAMpGMwnwKGBmsPyZw\n```\n\nThis query fetches the on-chain IDL for the program `nosJhNRqr2bc9g1nfGDcXXTXvYUmxD4cVwy2pMWhrYM`,\nwhich is the [Nosana Jobs program](https://github.com/nosana-ci/nosana-jobs) (just a handy\nexample - no affiliation), and attempts to deserialise and return the account data at\n`BNHE7twpb1SQVutNkZ9knQfLTjaAMpGMwnwKGBmsPyZw` by using the account definition for\nthe account `jobs` in the IDL file.\n\n## Motivation\n\nThe main motivation for this was the lack of some service, accessible via plain\nHTTP GET requests, that could be used to deserialise on-chain NFT metadata so that\na the URI for the deserialised account could be used in the `URI` field of a\nMetaplex Token Metadata account for an NFT.\n\n## Design\n\nThe account deserialisation here uses two Lambda functions - one written in TypeScript,\nand another written in Rust.\n\nThe entrypoint for the end-to-end account deserialisation is the TypeScript Lambda function,\nwhich calls into the Rust function to fetch and deserialise on-chain IDL files.\nThe Rust Lambda function can be used on its own to retrieve IDL files written to on-chain accounts.\n\n## Installation\n\n### Prerequisites\n\n- [cargo-lambda](https://github.com/cargo-lambda/cargo-lambda)\n- [Serverless framework](https://www.serverless.com/framework/docs/getting-started)\n- [Yarn](https://yarnpkg.com/getting-started/install)\n- an AWS account with an IAM role set up for the Rust Lambda function - something like\n  the following should be sufficient:\n\n    \u003cdetails\u003e\n    \u003csummary\u003eExample IAM Role\u003c/summary\u003e\n\n  ```\n  {\n      \"Version\": \"2012-10-17\",\n      \"Statement\": [\n          {\n              \"Action\": [\n                  \"logs:CreateLogStream\",\n                  \"logs:CreateLogGroup\"\n              ],\n              \"Resource\": [\n                  \"arn:aws:logs:eu-west-1:135929403262:log-group:/aws/lambda/deserialise-dev*:*\"\n              ],\n              \"Effect\": \"Allow\"\n          },\n          {\n              \"Action\": [\n                  \"logs:PutLogEvents\"\n              ],\n              \"Resource\": [\n                  \"arn:aws:logs:eu-west-1:135929403262:log-group:/aws/lambda/deserialise-dev*:*:*\"\n              ],\n              \"Effect\": \"Allow\"\n          }\n      ]\n  }\n  ```\n\n    \u003c/details\u003e\n\n### Rust Lambda function\n\nIn `./rust`, to build the Rust Lambda function, run\n\n`cargo lambda build --release --arm64`\n\nTo deploy, run:\n\n`cargo lambda deploy --iam-role \u003cLAMBDA_IAM_ROLE\u003e --enable-function-url deserialise --profile \u003cAWS_PROFILE\u003e`\n\nYou may omit `--profile` if you have a default AWS profile set up.\n\nIn order for the TypeScript Lambda function to be deployed, you will have to\ncreate a new SSM parameter called `idl_function_url` with the value set to the\nLambda function URL you receive from deploying the Rust lambda function.\n\n### TypeScript Lambda function\n\nIn `./ts`, first run `yarn install`.\n\nThen, run `sls deploy --aws-profile \u003cAWS_PROFILE\u003e`\n\nYou may omit `--aws-profile` if you have a default AWS profile set up.\n\n## Limitations \u0026 future work\n\n### **Issues with the design**\n\nI tried (admittedly not for too long) to write this all as a single TypeScript function,\nbut I was having trouble correctly inflating the compressed IDL file with zlib. I could\nwell have missed something obvious though, which I'd be glad to find out!\n\nI also tried to write this all as a single Rust function, but I ran into a problem\ntrying to dynamically use the fetched IDL file to deserialise other program accounts.\nIf I've missed something obvious, please let me know.\n\nThis project uses a Lambda 'anti-pattern' of having one Lambda synchronously invoke\nanother, which was my workaround for not being to write it all in a single function.\n\nI've used the spelling 'deserialise' with an 's' instead of a 'z' because I'm\nBritish, but I don't actually have a strong opinion on this, so please don't\npick a fight with me about it!\n\nI'm also relatively new to both TypeScript \u0026 Rust so it's likely there's\nun-idiomatic code in this project - let me know what can be done better!\n### **TODO list**\nIn no particular order:\n\n- Improve error handling\n- Maybe don't use the Rust lambda via its Function URL?\n- Provide an option to 'metaplex-ise' the deserialised account data\n- Allow custom cluster URLs\n- Be able to deploy both Lambda functions with the same tool/command (try AWS CDK?)\n- Add instructions for putting Lambda Function URLs behind custom domain names\n- Allow abbreviated cluster names in query params\n- It would be nice if the type of account could be worked out from the account\n  data - more specifically, it feels like the account discriminator should be \n  enough to know, so we might be able to avoid asking for `accountType`\n- Improve performance? (currently ~2s from cold start)\n\n## Credit\n\nThe Rust Lambda function borrows very heavily from the code in the function\n`fetch_idl` in the [Anchor CLI source code](https://github.com/coral-xyz/anchor/blob/master/cli/src/lib.rs).\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudhir-b%2Fdeserialise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudhir-b%2Fdeserialise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudhir-b%2Fdeserialise/lists"}