Use this file to discover all available pages before exploring further.
This guide assumes you’re creating a wallet using a web browser extension, but the same principles apply
to integrate our APIs for Mobile or Desktop wallets.Let us know if you’d like to see a guide for a specific
use-case that’s not covered here.
The goal of integrating ChainPatrol’s API into your wallet is to prevent users from interacting
with a malicious website that is intended to steal their funds or credentials.To achieve this goal, you will need to do the following:
🔍 Detect when a user has visited a new website
🥷 Check if the website is malicious with the ChainPatrol API
⚠️ Display a warning to the user if the website is malicious
(Recommended) Option 1: Use the browser.onBeforeNavigate API
This approach requires adding the webNavigation permission to your manifest.json file:
{ "permissions": ["webNavigation"]}
If your extension does not already have this permission, this will trigger a new
permissions request when the user installs/updates your extension to “Read your browsing history”.Alternatively, you can make this permission optional and request it at runtime to avoid
disabling your extension for users who don’t want to grant this permission. Read more
about optional permissions here.
Then you can listen for the onBeforeNavigate event in your Background script:
import browser from "webextension-polyfill";browser.webNavigation.onBeforeNavigate.addListener(async function (details) { // Filter out subframes and any navigation events that don't have a URL if (details.frameId !== 0 || !details.url) { return; } // ...});
This approach requires adding the tabs permission to your manifest.json:
{ "permissions": ["tabs"]}
If your extension does not already have this permission, this will trigger a new
permissions request when the user installs/updates your extension to “Read your browsing history”.Alternatively, you can make this permission optional and request it at runtime to avoid
disabling your extension for users who don’t want to grant this permission. Read more
about optional permissions here.
Then you can listen for the onUpdated event in your Background script:
import browser from "webextension-polyfill";browser.tabs.onUpdated.addListener(async function (tabId, changeInfo, tab) { // Filter out any tab change events that aren't complete, aren't for the // active tab, or tabs that don't have a URL if (changeInfo.status !== "complete" || !tab.active || !tab.url) { return; } // ...});
If your extension does not already have this permission, this will trigger a new
permissions request when the user installs your extension to “Read and change all your
data on all websites”.This is a very broad permission, and the warning message may scare some users away if
you don’t already have this permission. For this reason, we recommend using one of the
other options above if possible. But if you need to use this option, you can make this
permission optional and inject the content script at runtime. Read more about this approach
here.
If you’re already using a content script in your extension, you can get the current
URL from the window.location object without needing to add any additional permissions.
const url = window.location.href;
You can read this value at any time, but we recommend reading it either when the page
first loads, or when the user attempts to initiate a transaction in your wallet app.You’ll need to send this URL to your background script so that it can check if the
website is malicious. This can be done using message passing:
// content.jsconst url = window.location.href;// send the URL to the background scriptbrowser.runtime.sendMessage({ type: "CHAINPATROL_CHECK_URL", url });
// background.js// listen for the message from the content scriptbrowser.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === "CHAINPATROL_CHECK_URL") { // do something with request.url }});
If the website is malicious, you should display a warning to the user.Our recommended approach is to redirect the user to a warning page which will let the
user know that they are about to visit a malicious website, and give them the option to
safely exit, continue, or report a false positive if they believe the website is not malicious.There are two options for creating the warning page:
When you have determined that the site is malicious, you can redirect the tab to the ChainPatrol warning page. You need to pass the originUrl query parameter to the warning page so that it can display the URL to the user.
browser.webNavigation.onBeforeNavigate.addListener(async function (details) { const isBlocked = await checkUrl(details.url); if (isBlocked) { // redirect browser.tabs.update(details.tabId, { url: `https://app.chainpatrol.io/warning?originUrl=${details.url}`, }); }});
To allow the user to ignore the warning and continue to the potentially malicious site, listen for the CHAINPATROL_CONTINUE_AT_OWN_RISK message in your background script
and add the domain to a list of domains to ignore.
// In your extension's background scriptbrowser.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === "CHAINPATROL_CONTINUE_AT_OWN_RISK") { addToIgnoreList(request.domain); }});
Then you can update your code to first check if the URL is in the ignore list before checking if it’s blocked:
browser.webNavigation.onBeforeNavigate.addListener(async function (details) { // exit early if the URL is in the ignore list if (checkIgnoreList(details.url)) { return; } const isBlocked = await checkUrl(details.url); if (isBlocked) { // redirect browser.tabs.update(details.tabId, { url: `https://app.chainpatrol.io/warning?originUrl=${details.url}`, }); }});
It’s up to you how you want to store this data, but we recommended using the
browser’s storage APIs, such as:
chrome.storage
for Chrome extensions.
If you want to customize the look and feel of the warning page, reach out to us
and we can work with you to create a custom branded warning page with your logo and colors.
We can display the warning by reading the originUrl query parameter:
const urlParams = new URLSearchParams(window.location.search);const originUrl = urlParams.get("originUrl");
and displaying it on the page.
<h1>Warning</h1><p> You are about to visit a website that has been flagged as malicious by ChainPatrol.</p><p><strong>Origin URL:</strong> {{ originUrl }}</p>
If the user wishes to continue, we can allow them to do so by adding a button to the warning page that will redirect them
back to the original website
<a href="{{ originUrl }}">Continue at your own risk</a>
To prevent the user from seeing the warning again, we can add the domain to a
list of domains to ignore. It’s up to you how you want to store this data, but
we recommended using the browser’s storage APIs or equivalent on other
platforms.
If the user believes the website is not malicious, we can allow them to report a false positive
by adding a button to the warning page that will redirect them to the ChainPatrol dispute page.
<a href="https://app.chainpatrol.io/dispute?content={{ originUrl }}"> Report a false positive</a>
If you need help deciding which option is best for you, please feel free to reach out to us.