Getting Started

Using @othent/kms

The Othent JS SDK exports a TypeScript class Othent that exposes a collection of functions that enable interaction with wallet under Othent's custody. These functions are designed to make it seamless for developers to integrate Othent into their applications, and closely follow ArConnect's API to provide a familiar interface.

Installation & Setup

To use the library in your project, you first need to install it using npm / pnpm / yarn:

npm i @othent/kms
pnpm i @othent/kms
yarn add @othent/kms

Make sure peer dependencies (arweave, axios and warp-arbundles) are also installed.

TypeScript types are included in the @othent/kms package. You can find an exhaustive list in TypeScript Types.

Next, simply instantiate Othent with any options you need:

import { Othent, AppInfo } from "@othent/kms";

const appInfo: AppInfo = {
  name: "My Awesome App",
  version: "1.0.0",
  env: "production",
};

const othent = new Othent({ appInfo, ... });

Additionally, if you set the persistLocalStorage option to persist and/or sync user details across tabs, you need to call startTabSynching and make sure the cleanup function it returns is called once you no longer need the Othent instance you've created.

Here's an example inside a React component:

import { Othent } from "@othent/kms";

const MyComponent = () => {
  const othent = useMemo(() => {
    return new Othent(options);
  }, [options]);

  useEffect(() => {
      const cleanupFn = othent.startTabSynching();

      return () => {
        cleanupFn();
      };
  }, [othent])
}

Whitelisting your domain

Development

You must use http://localhost:3000, http://localhost:5173 or http://localhost:8081.

Deploying to a preview environment on Vercel will also work, all https://*.vercel.app domains are whitelisted.

Production (web2 domain)

To use Othent in production on your own web2 domain, you'll have to reach out to the Othent team on Discord to get your domain whitelisted.

Production (gateway + ArNS subdomain)

To use Othent in production through a gateway with your ArNS subdomain, you must use one of these whitelisted gateways:

  • https://arweave.ar

  • https://arweave.net / https://arweave.dev

  • https://ar-io.net / https://ar-io.dev

  • https://g8way.io

  • https://ar.io

Production (ar:// URI)

Whitelisting a ar:// URI is technically possible too, but due to the way AR.IO Wayfinder works, Othent won't work properly.

While you can use your ar:// URI as auth0RedirectURI and auth0ReturnToURI, that won't currently work as expected because request made from your dApp will never originate from your ar:// domain, but from the gateway's domain AR.IO Wayfinder randomly picked.

Moreover, your dApp won't work for users using AR.IO Wayfinder if they are routed through a different non-whitelisted gateway.

Track the progress on this GitHub issue.

React

If you are using Othent with React, you might want to consider using React's Context to use a single Othent instance for your whole app, or decoupling it even more by using a state management library like MobX, TanStack Query or Redux.

Alternatively, you might prefer to use ArweaveKit. See Indirect Usage (through ArweaveKit) below.

Next.js

On top of the information on the React section above, when using Next.js you don't need / cannot instantiate Othent on he server, as that will throw an error coming from @auth0+auth0-spa-js:

unhandledRejection: ReferenceError: document is not defined
  at getAll (.../node_modules/@auth0/auth0-spa-js/dist/lib/auth0-spa-js.cjs.js:1324:22)

Make sure you add a check to only instantiate Othent on the client:

import { Othent, AppInfo } from '@othent/kms';

const appInfo: AppInfo = {
  name: "My Awesome App",
  version: "1.0.0",
  env: "production",
};

export const othent = typeof window === "undefined" ? null : new Othent({ appInfo, ... });

React Native

Othent directly uses the Web/Node.js Crypto API to create hashes, verify signatures and, indirectly, through arweave-js. If your environment doesn't has this API natively, you'll have to polyfill it.

Next, update your platform-specific configuration files to work with Auth0:

  • See "Integrate Auth0 in Your Application" to update your build.gradle and AppDelegate.mm files. Othent's Auth0 domain is auth.othent.io.

  • See "Configure Callback and Logout URLs" to define your callback and logout URLs. They should look something like this, for Android and iOS, respectively:

    {PACKAGE_NAME}.auth0://{YOUR_DOMAIN}/android/{PACKAGE_NAME}/callback
    {BUNDLE_IDENTIFIER}.auth0://{YOUR_DOMAIN}/ios/{BUNDLE_IDENTIFIER}/callback

Then, you need to set (at least) the following options when instantiating Othent:

  • auth0LogInMethod = "redirect"

  • auth0RedirectURI (callback URL): Based on the values defined above.

  • auth0ReturnToURI (log out URL): Based on the values defined above.

  • auth0Cache: You have to pass a custom ICache implementation. This object will be responsible of persisting the refresh tokens, so, on iOS, we recommend implementing it using Keychain Services.

Lastly, make sure when Auth0 redirects the user back to your app (auth0RedirectURI), you call completeConnectionAfterRedirect, passing the URI with the code and state params provided by Auth0, which handles the redirect callback.

See Auth0's handleRedirectCallback.

Indirect Usage (through arweave-js)

Similarly to using ArConnect or other browser-based wallets, to use Othent in your application, you don't need to integrate or learn how the Othent JS SDK API works. Using arweave-js, you can easily sign transactions through Othent.

To use Othent library like this:

  1. Import it into your project.

  2. Instantiate it passing in the inject = true option. This will set window.arweaveWallet to this Othent instance.

  3. Now you can use arweave-js, which will use Othent in the background.

import { Othent, AppInfo } from "@othent/kms";

const appInfo: AppInfo = {
  name: "My Awesome App",
  version: "1.0.0",
  env: "production",
};

new Othent({ appInfo, inject: true, ... });

// Create an Arweave transaction:
const tx = await arweave.createTransaction({ /* Transaction options */ });

// Sign the transaction:
await arweave.transactions.sign(tx);

// Do something else with the transaction (e.g. post it to the network).

When signing a transaction through arweave-js, you'll need to omit the second argument of the sign() function, or set it to "use_wallet". This will let the package know you want to use the injected wallet, which has been exposed at window.arweaveWallet, to sign the transaction in the background.

Once the transaction is signed, you can safely post it to the network.

Indirect Usage (through Arweave Wallet Kit)

Arweave Wallet Kit provides a set of React Hooks and Components for better interaction with Arweave wallets.

Note, however, that there might be some limitations, like some methods like signDataItem, signMessage or verifyMessage not being (currently) available.

TODO: We are still working on this. We'll update the documentation soon.

Direct Usage (through Othent instance)

Alternatively, you can also use Othent's JS SDK directly, which provides some extra functionalities. These features are not integrated in the arweave-js package, but can be useful to further customize your app.

To use Othent library like this:

  1. Import it into your project.

  2. Instantiate it (no need for inject = true in this case).

  3. Now you can access Othent's properties & methods directly from the Othent instance. Each property & method is described in detail in the following pages.

See here for a basic example:

import { Othent, AppInfo } from "@othent/kms";

const appInfo: AppInfo = {
  name: "My Awesome App",
  version: "1.0.0",
  env: "production",
};

const othent = new Othent({ appInfo, throwErrors: false, ... });

othent.addEventLister("error", (err) => {
  console.error(err);
});

await othent.connect();

const mySecret = await othent.encrypt("My secret");

const transaction = await arweave.createTransaction({
  data: mySecret,
});

const result = await othent.dispatch(transaction);
const transactionURL = `https://viewblock.io/arweave/tx/${result.id}`;

console.log(transactionURL);

Last updated