Step-by-step examples
1. mixFetch

mixFetch

An easy way to secure parts or all of your web app is to replace calls to fetch (opens in a new tab) with mixFetch:

MixFetch works the same as vanilla fetch as it's a proxied wrapper around the original function. Sounds great, are there any catches? Well, there are a few (for now):

  1. Currently, the operators of Network Requesters that make the final request at the egress part of the Nym mixnet to the internet use a standard allow list (opens in a new tab) in combination with their own configuration. If you are trying to access something that is not on the allow list, please check the FAQ page.

  2. CA certificates in mixFetch are periodically updated, so if you get a certificate error, the root certificate you need might not be valid. If that's the case, send a PR (opens in a new tab) if you need changes to the Certificates.

  3. If you are using mixFetch in a web app with HTTPS you will need to use a gateway that has Secure Websockets to avoid getting a mixed content (opens in a new tab) error.

  4. For now, mixfetch doesn't work with SURBS, altough this may change in the future.

Read this article (opens in a new tab) to learn more about mixFetch.

ℹ️

We are currently working on a feature that adds a Secure Websocket (WSS) listener with HTTPS (automatically generated with LetsEncrypt) to Nym's gateways. While we are adding this feature, you can use a gateway that has Caddy providing HTTPS/WSS by adding this to the options when setting up mixFetch:

// For mainnet
import type { SetupMixFetchOps } from '@nymproject/mix-fetch';
 
const mixFetchOptions: SetupMixFetchOps = {
  preferredGateway: 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM', // with WSS
  preferredNetworkRequester:
    'GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW',
  mixFetchOverride: {
    requestTimeoutMs: 60_000,
  },
  forceTls: true, // force WSS
  extra: {}, 
};
Environment Setup

Begin by creating a directory and configuring your application environment:

npm create vite@latest

During the environment setup, choose React and subsequently opt for Typescript if you want your application to function smoothly following this tutorial. Next, navigate to your application directory and run the following commands:

cd < YOUR_APP >
npm i 
npm run dev
Installation

Install the required package:

npm install @nymproject/mix-fetch-full-fat
Imports

In the src folder, open the App.tsx file and delete all the code.

Import the client in your app:

import { mixFetch } from "@nymproject/mix-fetch-full-fat";
Example: using the mixFetch client:

Get and Post outputs will be observable from your console.

import "./App.css";
import { mixFetch, SetupMixFetchOps } from '@nymproject/mix-fetch-full-fat';
import React from 'react';
 
const mixFetchOptions: SetupMixFetchOps = {
  preferredGateway: 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM', // with WSS
  preferredNetworkRequester:
    'GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW',
  mixFetchOverride: {
    requestTimeoutMs: 60_000,
  },
  forceTls: true, // force WSS
  extra: {},
};
 
 
export function HttpGET() {
  const [html, setHtml] = React.useState('')
    async function get () {
       //Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
      const response = await mixFetch('https://nymtech.net/favicon.svg', { mode: 'unsafe-ignore-cors' }, mixFetchOptions)
      const text = await response.text()
      console.log('response was', text)
      setHtml(html)
    }
 
  return (
    <>
      <button onClick={() => { get() }}>Get</button>
    </>
  )
}
 
export function HttpPOST() {
    async function post () {
       //Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
      const apiResponse = await mixFetch('https://postman-echo.com/post', {
        method: 'POST',
        body: JSON.stringify({ foo: 'bar' }),
  headers: { 'Content-Type': 'application/json' }
      }, mixFetchOptions)
      console.log(apiResponse)
    }
  return (
    <>
      <button onClick={() => { post() }}>Post</button>
    </>
  )
}
 
export default function App() {
  return (
    <>
    <HttpGET/>
    <HttpPOST/>
    </>
  )
}