{"id":30703171,"url":"https://github.com/dfinity/response-verification","last_synced_at":"2025-09-02T16:56:47.081Z","repository":{"id":142913190,"uuid":"542543333","full_name":"dfinity/response-verification","owner":"dfinity","description":"Client side response verification for the Internet Computer","archived":false,"fork":false,"pushed_at":"2025-08-21T15:16:57.000Z","size":2203,"stargazers_count":20,"open_issues_count":2,"forks_count":11,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-08-24T08:14:48.336Z","etag":null,"topics":["certification","computer","internet","internet-computer","response","verification"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dfinity.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-28T10:56:28.000Z","updated_at":"2025-08-16T23:08:45.000Z","dependencies_parsed_at":"2023-10-12T23:31:22.704Z","dependency_job_id":"8ec500a0-2b82-4094-9adc-003a88820b36","html_url":"https://github.com/dfinity/response-verification","commit_stats":{"total_commits":445,"total_committers":17,"mean_commits":"26.176470588235293","dds":0.4674157303370786,"last_synced_commit":"35b21602b805ac27d247781a16fb674aaca4e603"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/dfinity/response-verification","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfinity%2Fresponse-verification","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfinity%2Fresponse-verification/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfinity%2Fresponse-verification/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfinity%2Fresponse-verification/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dfinity","download_url":"https://codeload.github.com/dfinity/response-verification/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfinity%2Fresponse-verification/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273317765,"owners_count":25084037,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"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":["certification","computer","internet","internet-computer","response","verification"],"created_at":"2025-09-02T16:56:45.449Z","updated_at":"2025-09-02T16:56:47.071Z","avatar_url":"https://github.com/dfinity.png","language":"Rust","readme":"# Response Verification\n\n## Introduction\n\nThe Internet Computer Protocol features two primary types of calls that can be used to interact with canisters: query calls and update calls.\n\n| Query Calls                                            | Update Calls                                        |\n| ------------------------------------------------------ | --------------------------------------------------- |\n| Readonly, cannot change canister state.                | Can change canister state.                          |\n| Response does not go through consensus.                | Response goes through consensus.                    |\n| Answered by a single replica on the canister's subnet. | Answered by every replica on the canister's subnet. |\n\nThe different properties of query and update calls present a trade off in terms of performance and security. Since query call responses do not go through consensus and are fulfilled by only a single replica, they are much faster than update calls. In contrast, the lack of consensus poses a security concern and these responses cannot be trusted since any individual replica can arbitrarily change the response.\n\nCanister certification provides a solution to this problem by pre-calculating responses and putting those pre-calculated responses through consensus. Consensus will produce a certificate for the pre-calculated responses that can be returned with the responses by any individual replica. Any clients requesting these responses can then verify this certificate to validate that consensus has agreed on this response prior to the request. This approach will give the performance characteristics of a query call, with the security profile of an update call, providing the best of both types of calls.\n\nCanister certification is enabled by the [Certified data](https://internetcomputer.org/docs/references/ic-interface-spec/#system-api-certified-data) feature of the Internet Computer. This feature allows canisters to specify a 32 byte blob that will be included in consensus. How this 32 byte blob is determined is entirely up to canister developers to decide for themselves. This repo provides solutions that rely on merkle trees and won't discuss any other methods, but there are many other possibilities for imaginative developers that would like to roll their own solution.\n\nIn the next consensus round following this 32 byte blob being set (via [`ic0.certified_data_set`](https://internetcomputer.org/docs/references/ic-interface-spec/#system-api-certified-data)), the Internet Computer will prepare a certificate for the canister. This certificate, and the process for verifying it, is described in detail in the [interface spec](https://internetcomputer.org/docs/references/ic-interface-spec/#certification).\n\nWhen responding to query calls, a canister can request the certificate (via [`ic0.certified_data_size`](https://internetcomputer.org/docs/references/ic-interface-spec/#system-api-certified-data) and [`ic0.certified_data_copy`](https://internetcomputer.org/docs/references/ic-interface-spec/#system-api-certified-data)) and then include this certificate in the response, to allow for clients to validate the response's authenticity.\n\n## Standard Certification\n\nThe standard, or default, method of certification is the simplest form of certification. The high-level procedure for certification is as follows:\n\n1. Pre-calculate any query call responses that need to be certified.\n2. Arrange query call response hashes into a merkle tree.\n3. Calculate the root hash of the merkle tree.\n4. Set the root hash as the canister's certified data.\n5. If an update call is received that changes state, return to step 1.\n6. If a query call is received, return the pre-calculated response along with the certified data certificate.\n\nThere are a number of questions that a developer needs to answer on a per-project basis when using this style of certification that should be agreed upon with clients beforehand and done consistently by both client and canister:\n\n- How are responses hashed?\n  - What properties are included/excluded? (e.g., `response_timestamp` is excluded but `id` is included).\n  - What format of each property is hashed? (e.g., leb, big/little endian encoding for numbers).\n  - In what order are properties hashed? (e.g., sort properties alphabetically).\n  - The [representation independent hash](https://internetcomputer.org/docs/references/ic-interface-spec/#hash-of-map) from the Internet Computer Protocol spec can be used, or serve as inspiration for developers.\n- How are response hashes arranged in the tree?\n  - Each exposed canister method should have a pre-determined path where its response hash will be presented in the merkle tree (e.g., the `get_count` method returns a response and the hash of this response is present at the `[\"count\"]` path of the merkle tree).\n  - This pre-determined path may use parameters of the request or calling principal to arrange more dynamic data in the tree (e.g., the `get_account` method returns a response and the hash of this response is present at the `[\"account\", caller.to_text()]` path of the merkle tree).\n\n### Process Flow\n\n```mermaid\nflowchart TB;\n  subgraph lifecycle_hooks[Lifecycle hooks]\n    init;\n    post_upgrade;\n  end\n  init--\u003ecertification;\n  post_upgrade--\u003ecertification;\n\n  subgraph update_calls\n    update_call;\n    update_state;\n    update_call--\u003eupdate_state;\n  end\n  update_state--\u003ecertification;\n\n  subgraph query_calls\n    direction TB;\n\n    query_call;\n    serve_response[Serve pre-calculated response];\n    query_call--\u003eserve_response;\n  end\n\n  subgraph certification[Certification]\n    direction TB;\n\n    certification_step_one[pre-calculate response];\n    certification_step_two[insert response hash into merkle tree];\n    certification_step_three[calculate root hash of merkle tree];\n    certification_step_four[set canister certified data];\n\n    certification_step_one--\u003ecertification_step_two--\u003ecertification_step_three--\u003ecertification_step_four;\n  end\n```\n\n### Resources\n\n- [`ic-certification` Cargo crate](https://crates.io/crates/ic-certification).\n- [`ic-certification` docs](https://docs.rs/ic-certification/latest/ic_certification).\n- [Example with a certified counter](./examples/certification/certified-counter/README.md).\n- [`ic-certification` source code](./packages/ic-certification/README.md).\n- [`ic-representation-independant-hash` Cargo crate](https://crates.io/crates/ic-representation-independent-hash).\n- [`ic-representation-independant-hash` docs](https://docs.rs/ic-representation-independent-hash/2.3.0/ic_representation_independent_hash).\n- [`ic-representation-independent-hash` source code](./packages/ic-representation-independent-hash/README.md).\n\n## Certificate verification\n\nCertifications of a response need to be verified by the caller. The process for this is as follows:\n\n1. Extract the canister's certificate from the response and verify it:\n   - If the certificate has a delegation:\n     1. Verify the delegation's signature using the Internet Comptuer Protocol's public key.\n     2. Assert that the delegation is valid for the canister's canister ID.\n     3. Extract the subnet's public key from the delegation.\n     4. Verify the certificate's signature using the subnet's public key.\n   - Otherwise:\n     1. Verify the certificate's signature using the Internet Computer Protocol's public key.\n2. Verify that the certificate's time is not too far in the past or future.\n3. Extract the canister's merkle tree from the response and calculate it's root hash.\n4. Ensure that the merkle tree's root hash matches the canister's certified data in the certificate.\n5. Calculate the hash of the canister's response.\n6. Ensure that the response hash is in the merkle tree at the expected path.\n\nSteps 1 through 4 (inclusive) is encapsulated by the `@dfinity/certificate-verification` (JavaScript) and the `ic-certificate-verification` (Rust) packages.\n\nFor testing code that verifies responses, the `@dfinity/certification-testing` (JavaScript) and `ic-certification-testing` (Rust, unpublished) packages can be used to create certifications.\n\n### Resources\n\n- [`@dfinity/certificate-verification` source code](./packages/certificate-verification-js/README.md).\n- [`@dfinity/certificate-verification` NPM package](https://www.npmjs.com/package/@dfinity/certificate-verification).\n- [`ic-certificate-verification` Cargo crate](https://crates.io/crates/ic-certificate-verification).\n- [`ic-certificate-verification` docs](https://docs.rs/ic-certificate-verification/2.3.0/ic_certificate_verification).\n- [`ic-certificate-verification` source code](./packages/ic-certificate-verification/README.md).\n- [`@dfinity/certification-testing` NPM package](https://www.npmjs.com/package/@dfinity/certification-testing).\n- [`@dfinity/certification-testing` source code](./packages/ic-certification-testing-wasm/README.md).\n- [`ic-certification-testing` source code (unpublished)](./packages/ic-certification-testing/README.md).\n\n## HTTP Certification\n\nCanisters may leverage the [HTTP Gateway Protocol](https://github.com/dfinity/http-gateway) to serve HTTP-compatible responses to HTTP-aware clients, such as a web browser. This is a much more involved process than [standard certification](#standard-certification). With [standard certification](#standard-certification) canister developers are free to make a lot of decisions on their own because they will likely also control the clients that will be performing certification. This is in contrast to HTTP certification where a generic client (the [HTTP Gateway](https://github.com/dfinity/http-gateway)) will verify all canisters implementing this protocol.\n\n### Process Flow\n\n```mermaid\nflowchart TB;\n  subgraph lifecycle_hooks[Lifecycle hooks]\n    init;\n    post_upgrade;\n  end\n  init--\u003ecertification;\n  post_upgrade--\u003ecertification;\n\n  subgraph query_calls[Query calls]\n    http_request;\n    should_upgrade{State change?};\n    serve_response[Serve pre-calculated response];\n    upgrade[Upgrade to update call];\n\n    http_request--\u003eshould_upgrade;\n    should_upgrade -- No--\u003eserve_response;\n    should_upgrade -- Yes--\u003eupgrade;\n  end\n  upgrade--\u003eupdate_calls;\n\n  subgraph update_calls[Update calls]\n    http_request_update;\n    update_state;\n\n    http_request_update--\u003eupdate_state;\n  end\n  update_state--\u003ecertification;\n\n  subgraph certification[Certification]\n    direction TB;\n\n    certification_step_one[pre-calculate response];\n    certification_step_two[pre-calculate CEL expression];\n    certification_step_three[pre-calculate certification];\n\n    certification_step_one[pre-calculate response];\n    certification_step_two[pre-calculate CEL expression];\n    certification_step_three[insert response hash into merkle tree];\n    certification_step_four[calculate root hash of merkle tree];\n    certification_step_five[set canister certified data];\n\n    certification_step_one--\u003ecertification_step_two--\u003ecertification_step_three--\u003ecertification_step_four--\u003ecertification_step_five;\n  end\n```\n\n### Resources\n\n- [`ic-http-certification` Cargo crate](https://crates.io/crates/ic-http-certification).\n- [`ic-http-certification` docs](https://docs.rs/ic-http-certification/latest/ic_http_certification).\n- [Example project serving a REST API](./examples/http-certification/json-api/README.md).\n- [Example project with a custom implementation serving static assets](./examples/http-certification/custom-assets/README.md).\n- [`ic-http-certification` source code](./packages/ic-http-certification/README.md).\n\n## Asset Certification\n\nAsset certification is a high level abstraction on [HTTP Certification](#http-certification) that allows canisters to serve static assets (e.g., HTML, CSS, JS, images, etc.) to clients. This is a common use case for web developers that want to host a website on the Internet Computer.\n\nThe `ic-asset-certification` crate provides a simple API for canisters to serve static assets. It is built on top of the `ic-http-certification` crate and provides a way to serve certified assets without needing to understand how HTTP certification works.\n\n### Resources\n\n- [`ic-asset-certification` Cargo crate](https://crates.io/crates/ic-asset-certification).\n- [`ic-asset-certification` docs](https://docs.rs/ic-asset-certification/latest/ic_asset_certification).\n- [Example project serving a static website](./examples/http-certification/assets/README.md).\n- [`ic-asset-certification` source code](./packages/ic-asset-certification/README.md).\n\n## Response Verification\n\nResponse verification on the [Internet Computer](https://dfinity.org) is the process of verifying that an HTTP-compatible canister response from a replica has gone through consensus with other replicas hosting the same canister. It is the client-side counterpart to [HTTP Certification](#http-certification) and [Asset Certification](#asset-certification).\n\nThe `ic-response-verification` and `@dfinity/response-verification` packages encapsulate this verification protocol. It is used by [ICX Proxy](https://github.com/dfinity/ic/tree/master/rs/boundary_node/icx_proxy) and the [local HTTP Proxy](https://github.com/dfinity/http-proxy) and may be used by other implementations of the [HTTP Gateway Protocol](https://internetcomputer.org/docs/references/ic-interface-spec/#http-gateway) in the future.\n\n### Resources\n\n- [`ic-response-verificaiton` source code](./packages/ic-response-verification/README.md)\n- [`@dfinity/response-verification` source code](./packages/ic-response-verification-wasm/README.md)\n- [Usage example in the `ic-http-gateway` library](https://github.com/dfinity/http-gateway/tree/main/packages/ic-http-gateway)\n\n## Miscellaneous Projects\n\n### Representation Independent Hash\n\nThis is a utility crate to implement [representation independent hashing](https://internetcomputer.org/docs/references/ic-interface-spec/#hash-of-map) of data.\n\n- [`ic-representation-independant-hash` Cargo crate](https://crates.io/crates/ic-representation-independent-hash).\n- [`ic-representation-independant-hash` docs](https://docs.rs/ic-representation-independent-hash/2.3.0/ic_representation_independent_hash).\n- [`ic-representation-independent-hash` source code](./packages/ic-representation-independent-hash/README.md).\n\n### CBOR\n\nThis is a utilty crate to implement decoding of CBOR-encoded data.\n\n- [`ic-cbor` Cargo crate](https://crates.io/crates/ic-cbor).\n- [`ic-cbor` docs](https://docs.rs/ic-cbor/2.3.0/ic_cbor).\n- [`ic-cbor` source code](./packages/ic-cbor/README.md).\n\n## Contributing\n\nCheck out the [contribution guidelines](./.github/CONTRIBUTING.md).\n\n### Command Reference\n\nMake sure to follow the [system setup](#system-setup) instructions first.\n\n| Command       | Description             |\n| ------------- | ----------------------- |\n| `cargo build` | Build all Cargo crates  |\n| `cargo test`  | Test all Cargo crates   |\n| `cargo fmt`   | Format all Cargo crates |\n| `pnpm build`  | Build all NPM packages  |\n| `pnpm test`   | Test all NPM packages   |\n| `pnpm format` | Format all NPM packages |\n\n#### Certification\n\n| Command                                          | Description            |\n| ------------------------------------------------ | ---------------------- |\n| `cargo build -p ic-certification`                | Build Cargo crate      |\n| `cargo test -p ic-certification`                 | Test Cargo crate       |\n| `cargo doc -p ic-certification --no-deps --open` | Build Cargo crate docs |\n\n#### Certificate Verification\n\n| Command                                               | Description       |\n| ----------------------------------------------------- | ----------------- |\n| `pnpm run -F @dfinity/certificate-verification build` | Build NPM package |\n| `pnpm run -F @dfinity/certificate-verification test`  | Test NPM package  |\n\n#### Certification Testing\n\n| Command                                                  | Description            |\n| -------------------------------------------------------- | ---------------------- |\n| `cargo build -p ic-certification-testing`                | Build Cargo crate      |\n| `cargo doc -p ic-certification-testing --no-deps --open` | Build Cargo crate docs |\n| `pnpm run -F @dfinity/certification-testing build`       | Build NPM package      |\n\n### HTTP Certification\n\n| Command                                               | Description            |\n| ----------------------------------------------------- | ---------------------- |\n| `cargo build -p ic-http-certification`                | Build Cargo crate      |\n| `cargo test -p ic-http-certification`                 | Test Cargo crate       |\n| `cargo doc -p ic-http-certification --no-deps --open` | Build Cargo crate docs |\n\n### Asset Certification\n\n| Command                                                | Description            |\n| ------------------------------------------------------ | ---------------------- |\n| `cargo build -p ic-asset-certification`                | Build Cargo crate      |\n| `cargo test -p ic-asset-certification`                 | Test Cargo crate       |\n| `cargo doc -p ic-asset-certification --no-deps --open` | Build Cargo crate docs |\n\n### Response Verification\n\n| Command                                                                 | Description            |\n| ----------------------------------------------------------------------- | ---------------------- |\n| `cargo build -p ic-response-verification`                               | Build Cargo crate      |\n| `cargo test -p ic-response-verification`                                | Test Cargo crate       |\n| `wasm-pack test --node packages/ic-response-verification --features=js` | Test Cargo crate WASM  |\n| `cargo doc -p ic-response-verification --no-deps --open`                | Build Cargo crate docs |\n| `pnpm run -F @dfinity/response-verification build`                      | Build NPM package      |\n| `pnpm run -F @dfinity/response-verification test`                       | Test NPM package       |\n| `./scripts/e2e.sh`                                                      | Run e2e tests          |\n\n#### Representation Independent Hash\n\n| Command                                                            | Description            |\n| ------------------------------------------------------------------ | ---------------------- |\n| `cargo build -p ic-representation-independent-hash`                | Build Cargo crate      |\n| `cargo test -p ic-representation-independent-hash`                 | Test Cargo crate       |\n| `cargo doc -p ic-representation-independent-hash --no-deps --open` | Build Cargo crate docs |\n\n#### CBOR\n\n| Command                                 | Description            |\n| --------------------------------------- | ---------------------- |\n| `cargo build -p ic-cbor`                | Build Cargo crate      |\n| `cargo test -p ic-cbor`                 | Test Cargo crate       |\n| `cargo doc -p ic-cbor --no-deps --open` | Build Cargo crate docs |\n\n### System Setup\n\n- [Install pre-commit](https://pre-commit.com/#installation)\n- [Install commitizen](https://commitizen-tools.github.io/commitizen/#installation)\n- [Install Rust](https://www.rust-lang.org/learn/get-started)\n- [Install wasm-pack](https://rustwasm.github.io/wasm-pack/installer)\n- [Install NVM](https://github.com/nvm-sh/nvm)\n- [Install dfx](https://internetcomputer.org/docs/building-apps/getting-started/install)\n\nInstall the correct version of NodeJS:\n\n```shell\nnvm install\n```\n\nActivate the correct version of NodeJS:\n\n```shell\nnvm use\n```\n\nInstall and activate the correct version of PNPM:\n\n```shell\ncorepack enable\n```\n\n### Working on WASM crates\n\nUntil Cargo supports [per package targets](https://github.com/rust-lang/cargo/issues/9406), the WASM crates are excluded from the `default_members` array of the Cargo workspace.\nCommands such as `cargo build` and `cargo check` will not include these crates, so they must be built separately with the corresponding `pnpm` command listed under [projects](#projects).\n\nSince `rust-analyzer` will also apply the same target to all crates, these crates will show errors in the IDE. To workaround this, create a `.cargo/config.toml` file:\n\n```toml\n[build]\ntarget = \"wasm32-unknown-unknown\"\n```\n\nWhile this file exists, some of the non-WASM crates will show errors instead. Delete the file to work on the non-WASM crates.\n\n### Making a Commit\n\n```shell\ncz commit\n```\n\nSee [Conventional commits](https://www.conventionalcommits.org/en/v1.0.0) for more information on the commit message formats.\n\n### Adding a new package\n\n- Follow the [Package naming conventions](#package-naming-conventions) when naming the package.\n- Add the package's package manager file to the `version_files` field in `.cz.yaml`.\n  - `package.json` for NPM packages\n  - Nothing for for Cargo crates, it is already covered by the root `Cargo.toml`\n- Set the initial version of the package in its package manager file to match the current version in the `version` field in `.cz.yaml`\n  - For `package.json`, set the version manually\n  - For `Cargo.toml`, use `version.workspace = true`\n- Add the package's package manager file(s) to the `add-paths` property in the `Create Pull Request` job of the `Create Release PR` workflow in `.github/workflows/create-release-pr.yml`\n  - `package.json` for NPM packages\n  - No files need to be added for Cargo crates\n- If the package is a Rust crate:\n  - Add the package to the `members` section in `Cargo.toml` and the `default-members` section\n    - If the package must be compiled to WASM then do not add it to the `default-members` section\n  - Add a `Release ic-\u003cpackage-name\u003e Cargo crate` job to the `Release` workflow in `.github/workflows/release.yml`\n  - Add `target/package/ic-\u003cpackage-name\u003e-${{ github.ref_name }}.crate` to the `artifacts` property in the `Create Github release` job of the `Release` workflow in `.github/workflows/release.yml`\n    - Make sure every entry except the last is comma delimited\n  - If the crate has dependenencies in this repository, make sure it is published _after_ the dependencies\n  - If the crate has a dependent in this repository, make sure it is published _before_ the dependents\n- If the package is an NPM package:\n  - Add the package to `pnpm-workspace.yaml`\n  - Add a `Pack @dfinity/\u003cpackage-name\u003e NPM package` job to the `Release` workflow in `.github/workflows/release.yml`\n  - Add a `Release @dfinity/\u003cpackage-name\u003e NPM package` job to the `Release` workflow in `.github/workflows/release.yml`\n  - Add `dfinity-\u003cpackage-name\u003e-${{ github.ref_name }}.tgz` to the `artifacts` property in the `Create Github release` job of the `Create Release PR` workflow in `.github/workflows/create-release-pr.yml`\n    - Make sure every entry except the last is comma delimited\n\n### Package naming conventions\n\nCargo crates are named `ic-\u003cpackage-name\u003e`, likewise for the folder name.\nIf the Cargo crate will be compiled to WASM then the folder name is `ic-\u003cpackage-name\u003e-wasm`.\n\nNPM packages are named `@dfinity/\u003cpackage-name\u003e`.\nIf the NPM package is a pure JS package then the folder name is `\u003cpackage-name\u003e-js`.\nIf the NPM package is built from a Rust crate then the folder name is `ic-\u003cpackage-name\u003e-wasm`.\n\n### Referencing a Cargo crate\n\nA Cargo crate can be referenced using a relative path in `Cargo.toml`:\n\n```toml\n[dependencies]\nic-response-verification-test-utils = { path = \"../ic-response-verification-test-utils\" }\n```\n\nIf the _referencing_ Cargo crate is published to crates.io then the current version must be included and the _referenced_ crate must also be published:\n\n```toml\n[dependencies]\nic-response-verification-test-utils = { path = \"../ic-response-verification-test-utils\", version = \"1.0.0\" }\n```\n\nIf a version is included in a dev dependency then the referenced dev dependency must also be published, but the version can be omitted for dev dependencies to avoid this.\n\n### Referencing an NPM package\n\nAn NPM package can be referenced using the package name and [PNPM workspace protocol](https://pnpm.io/workspaces#workspace-protocol-workspace) in `package.json`:\n\n```json\n{\n  \"dependencies\": {\n    \"@dfinity/certificate-verification\": \"workspace:*\"\n  }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfinity%2Fresponse-verification","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdfinity%2Fresponse-verification","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfinity%2Fresponse-verification/lists"}