Skip to content
Comms.ID
Esc
↑↓navigate↵open⌘Jpreview
On this page

Find an Indigenous corporation by name, then read it by ICN

Find an Indigenous corporation by name, then read it by ICN

What you build: a server-side flow for a grants or procurement system. A clerk types part of a corporation’s name; your server lists the matches from the ORIC register with their ICNs; the clerk picks one; your server reads that corporation’s record by its ICN. An empty search is a real answer; an outage is not.

Before you start: a development app, then a production app

  1. npx comms-id init makes a development key in .env.local and prints its public key. In the Companion App, register it as a development app, enable ORIC for it, and put the app id in .env.local as COMMS_ID_CLIENT_ID. This key reaches only the TEST service (https://api-test.comms.id): the same API, errors and authentication as LIVE, with synthetic replies.
  2. When it works in TEST, npx comms-id key --worker <your worker> makes the production key straight into your server’s COMMS_ID_PRIVATE_JWK secret and prints the public key; register it as a production app with ORIC enabled. Going live changes only the environment and the key: nothing in the code below.

A .env.local never holds a production key, and a browser never holds any key.

The code

pnpm add @comms-id/oric

find-corporation.ts:

// Find an Indigenous corporation by name, then read one record by its ICN, on your server.
import { type OricClient, outcomeOf } from "@comms-id/oric";

export interface Corporation {
  readonly icn: string;
  readonly name: string;
  readonly status: string;
}

/** The corporations whose names contain `term`; an empty list is a real answer, an outage is not. */
export const findByName = async (term: string, oric: OricClient): Promise<readonly Corporation[]> => {
  const found = await oric.search({ term });
  if (found.status === "unavailable") {
    throw new Error("The ORIC register did not answer; try again later.");
  }
  if (found.status !== "found" || !("data" in found)) {
    return [];
  }
  return found.data.map((row) => ({ icn: row.icn, name: row.name, status: row.statusReason ?? "unknown" }));
};

/** One corporation's register record, or undefined when the ICN is not on the register. */
export const readByIcn = async (icn: string, oric: OricClient) => {
  try {
    const reply = await oric.lookup({ kind: "icn", value: icn });
    if (reply.status === "unavailable") {
      throw new Error("The ORIC register did not answer; try again later.");
    }
    const snapshot = reply.snapshot;
    return snapshot !== undefined && snapshot.status === "found" ? snapshot.data : undefined;
  } catch (error) {
    if (outcomeOf(error) === "source-unavailable") {
      throw new Error("The ORIC register did not answer; try again later.");
    }
    throw error;
  }
};

search answers from the published ORIC dataset; lookup by ICN answers status: "complete" with the register record (and, when the portal answered too, its details). unavailable is a status of its own, so the function throws rather than return an empty record.

TEST first

import { createOricClient } from "@comms-id/oric/server";
import { findByName, readByIcn } from "./find-corporation";

const oric = createOricClient({
  clientId: process.env.COMMS_ID_CLIENT_ID!,
  privateJwk: JSON.parse(process.env.COMMS_ID_PRIVATE_JWK!),
  environment: "test",
});

const matches = await findByName("Urapuntja", oric); // the published example term: one fictional match
const record = await readByIcn(matches[0]!.icn, oric); // its ICN (4172 in TEST)
await findByName("nomatch anything", oric); // []
await readByIcn("503", oric); // throws: the register did not answer

LIVE

Remove environment: "test" and use the production key. Reference: ORIC API. The attribution in each reply (Source: ... ORIC, via data.gov.au) must be shown wherever the data is.

Was this page helpful?