{"id":13523409,"url":"https://github.com/infu/icblast","last_synced_at":"2025-04-01T00:31:37.002Z","repository":{"id":60288486,"uuid":"464900945","full_name":"infu/icblast","owner":"infu","description":null,"archived":false,"fork":false,"pushed_at":"2024-09-19T10:07:17.000Z","size":3746,"stargazers_count":14,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-04T04:48:25.327Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/infu.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-03-01T13:18:56.000Z","updated_at":"2025-02-13T09:41:08.000Z","dependencies_parsed_at":"2023-11-15T17:27:51.233Z","dependency_job_id":"be99ec5f-d7cb-4a11-9d1b-3127cda94d90","html_url":"https://github.com/infu/icblast","commit_stats":{"total_commits":66,"total_committers":2,"mean_commits":33.0,"dds":"0.015151515151515138","last_synced_commit":"c23ed52f73544d48ad5aef3c8114e313b28cd103"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infu%2Ficblast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infu%2Ficblast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infu%2Ficblast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infu%2Ficblast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infu","download_url":"https://codeload.github.com/infu/icblast/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246563351,"owners_count":20797441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-01T06:00:59.819Z","updated_at":"2025-04-01T00:31:36.053Z","avatar_url":"https://github.com/infu.png","language":"JavaScript","funding_links":[],"categories":["Client Libraries (Agents)"],"sub_categories":["JavaScript/TypeScript"],"readme":"\u003cimg src=\"./icblast.svg\" width=\"300\"\u003e\n\n# ICBlast client library\n\nUsed in Blast Playground\nhttps://jglts-daaaa-aaaai-qnpma-cai.ic0.app/\n\n# Install\n\n`npm i @infu/icblast`\n\n# Purpose\n\nConvenience, Operations, maintenance, testing, exploring and learning.\n\nProvide easy access to the Internet Computer from NodeJS \u0026 Browser.\n\nBy default works with the production IC network.\n\n## Features\n\n🦄 Service discovery 🦄 InternetIdentity 🦄 Proxy Calls 🦄 AgentJS 🦄 Internet Computer 🦄 Opt handled without []\n\nForum post: https://forum.dfinity.org/t/icblast-opinionated-client-library-undefined-or/19578\n\n\u003cbr clear=all /\u003e\n\n## ✨ Reasons to use\n\n- You don't think optional values should be []\n- You want serializable responses for your state\n- You think Err should be thrown\n- You want traversable .idl.js\n- You think calls should accept your serialized values and auto convert them.\n- `JS` tooling instead of `ic-repl` or `bash` scripts using `dfx`:\n- As dApp maker, you already know javascript or you can’t make your frontend\n- You already have all your transformation functions in JS. (AccountIdentifier, Token, etc.)\n- You already got used to how AgentJs serializes objects. DFX and ic-repl use different syntax\n- You can fetch something from a canister, modify and send it back easily\n- You can use all the NPM libraries like ic-js, Principal, Lodash\n- When testing if your canisters will upgrade well locally, you switch between git commits. You deploy the older code and switch back to the newer one, then run upgrade scripts. Your interface specs coming from files will be wrong. This fetches them from replica, so they will be the correct old ones.\n- Easy for hacking one-time use scripts when there is an edge case\n- You can handle asynchronicity and concurrency easily\n- You value your time to be fetching the service interface specs manually, transforming them and messing with files, just to send a few calls with a script you may never run again.\n- Catch and handle exceptions\n\n# Usage\n\n## 🦄 Simple - Node\n\n```js\nimport icblast from \"@infu/icblast\";\n\nlet ic = icblast({ local: true }); // you can also add local_host: \"http://192.168.0.100:8000\"\n\nlet can = await ic(\"r7inp-6aaaa-aaaaa-aaabq-cai\"); // It will fetch the IDL spec, no need to specify it manually\n\nconsole.log(await can.config_get());\n```\n\n## Inside a browser\n\nFor production dapps it's probably a better idea to use AgentJs directly, but if you want to hack something quick or need dynamic interface generation, you can use icblast.\n\n```js\nimport icblast from \"@infu/icblast\";\n\nlet ic = icblast({ local: true });\n\nlet can = await ic(\"r7inp-6aaaa-aaaaa-aaabq-cai\"); // It will fetch the IDL spec, no need to specify it manually\n\nconsole.log(await can.config_get());\n```\n\n## Interface definition\n\n```js\nlet can = await ic(\"r7inp-6aaaa-aaaaa-aaabq-cai\"); // it will try to get candid from meta or _if_hack\nlet can = await ic(\"r7inp-6aaaa-aaaaa-aaabq-cai\", idlFactory); // it will use the object (comes from generated .idl.js)\nlet can = await ic(\n  \"r7inp-6aaaa-aaaaa-aaabq-cai\",\n  \"https://raw.githubusercontent.com/dfinity/ic-js/main/packages/sns/candid/sns_governance.did\"\n); // it will fetch it and transpile and use it\nlet can = await ic(\n  \"r7inp-6aaaa-aaaaa-aaabq-cai\",\n  \"https://raw.githubusercontent.com/dfinity/ic-js/main/packages/sns/candid/sns_governance.idl.js\"\n); // it will fetch and use it\nlet can = await ic(\"r7inp-6aaaa-aaaaa-aaabq-cai\", text_did); // it will transpile and use it\n```\n\n## Explainer\n\nIf you want traversable interface (Perhaps making a browser)\n\n```js\nimport { explainer } from \"@infu/icblast\";\nexplainer(idlFactory);\n```\n\n## toState\n\nYou want to store responses in your state\n\n```js\nimport { toState } from \"@infu/icblast\";\n\ntoState(myobj);\n```\n\n## 🌈 InternetIdentity\n\n```js\nlet identity = await internetIdentity();\n\nconsole.log(identity.getPrincipal().toText());\n```\n\nIt will open a window to InternetIdentity. It will not store the key anywhere. To be most secure, make sure your browser extensions with full permissions are set to manually activated \"on click\"\n\n## 🍭 fileIdentity, hashIdentity and concurrent async calls\n\n```js\nimport icblast, { fileIdentity } from \"@infu/icblast\";\n\n// stores your private keys in a json file in ~/.icblast/identity.json\n// you have 10 identites you can switch 0-9\nlet identityJohn = fileIdentity(0);\n// In browsers you can use hashIdentity('a secret that will get hashed')\n\n// TIP: Go to Motoko Playground at https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/\n// Choose \"Counter\" and deploy it\n// Take the canister id and put replace it in this code\n\nlet ic = icblast({identity : identityJohn});\n\nlet counterCanJohn = await ic(\"x2ojg-ciaaa-aaaab-qadba-cai\");\n\n// sends 10 requests with max concurrency 5 at a time\nlet results = await blast(10, 5, (idx) =\u003e {\n  await delay(1);\n  return counterCanJohn.get();\n});\n```\n\n## 🎠 Wallet calls (easy)\n\n```js\nlet identity = await fileIdentity(0);\nconsole.log(identity.getPrincipal().toText());\n\n// Note: This won't work unless the wallet is the controller of the canister you are checking\n// the status of. Also won't work if you don't have the current identity added as controller in\n// the wallet canister.\n\nlet ic = icblast({ identity }); // can switch identity or go local\n\nlet aaa = await ic(\"aaaaa-aa\", \"ic\");\nlet wallet = await ic(\"vlgg5-pyaaa-aaaai-qaqba-cai\", \"wallet\");\n\nlet res = await walletCall(\n  wallet,\n  aaa,\n  \"canister_status\",\n  0 // you can also send cycles. Used when creating canisters\n)({ canister_id: Principal.fromText(\"kbzti-laaaa-aaaai-qe2ma-cai\") });\n\n// or\n\nlet res = await walletProxy(wallet, aaa).canister_status({\n  canister_id: Principal.fromText(\"kbzti-laaaa-aaaai-qe2ma-cai\"),\n});\n\n// or\n\nlet res = await walletProxy(wallet, aaa, 100000).canister_status({\n  canister_id: Principal.fromText(\"kbzti-laaaa-aaaai-qe2ma-cai\"),\n});\n```\n\n## 🐉 Wallet calls (verbose) - useful when making your own proxy canisters\n\n```js\nlet ic = icblast({ identity }); // can switch identity or go local\n\n// we need to specify \"ic\" preset because this canister doesn't support downloading IDL spec\nlet aaa = await ic(\"aaaaa-aa\", \"ic\");\n\n// each method has also a version with $ suffix. It will not make a call but return the encoded arguments.\n// Useful for proxy calls\nlet encoded = aaa.canister_status$({\n  canister_id: Principal.fromText(\"kbzti-laaaa-aaaai-qe2ma-cai\"),\n});\n\n// we need to specify \"wallet\" preset for this canister as well\nlet wallet = await ic(\"vlgg5-pyaaa-aaaai-qaqba-cai\", \"wallet\");\n\n// now we make a wallet proxy call\nlet response = await wallet.wallet_call({\n  args: encoded,\n  cycles: 0,\n  method_name: \"canister_status\",\n  canister: Principal.fromText(\"aaaaa-aa\"),\n});\n\n// each method has also version with $ prefix. It will decode responses\nlet decoded = aaa.$canister_status(response.Ok.return);\n\nconsole.log(decoded);\n```\n\n## 🏳️‍🌈 File uploads\n\n```js\n// Deploy a canister and take the canister_id\n// from this playground: https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=1212716285\nlet canister_id = \"6zfvq-kiaaa-aaaab-qacra-cai\";\n\nlet ic = icblast();\nlet can = await ic(canister_id);\n\nawait can.put(await file(\"./testfile.bin\"));\n\nlet fetched_file = await can.get();\n\nconsole.log(fetched_file);\n```\n\nLICENSE MIT ☮️\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfu%2Ficblast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfu%2Ficblast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfu%2Ficblast/lists"}