API Examples: Using Apollo Client

This guide will walk you through how to use the io.vault GraphQL API with the Apollo Client library in a modern TypeScript environment.

Setting up Apollo Client

First, install the necessary packages:

npm install @apollo/client graphql

Then, initialize the Apollo Client:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: 'https://api.iofinnet.com/graphql',
});

const authLink = setContext((_, { headers }) => {
  // Get the access token (implementation covered in next section)
  const token = getAccessToken();

  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache()
});

The authLink is responsible for adding the access token to the Authorization header of each request. We'll cover how to obtain this token in the next section.

With the Apollo Client set up, you're ready to start making queries and mutations!

Obtaining an Access Token

To authenticate with the io.vault API, you need to exchange your Client ID and Client Secret for an access token. Here's how you can implement this:

async function getAccessToken(): Promise<string> {
  const response = await fetch('https://api.iofinnet.com/auth/v1/accessToken', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      clientId: process.env.IO_VAULT_CLIENT_ID,
      clientSecret: process.env.IO_VAULT_CLIENT_SECRET,
    }),
  });

  const data = await response.json();
  return data.accessToken;
}

This function sends a POST request to the /auth/v1/accessToken endpoint with your Client ID and Client Secret in the request body. The server will respond with an access token, which you can then use to authenticate your GraphQL requests.

Be sure to store your Client ID and Client Secret securely, such as in environment variables (process.env.IO_VAULT_CLIENT_ID and process.env.IO_VAULT_CLIENT_SECRET in this example). Never hard-code these values or commit them to version control.

The getAccessToken function will be called by the authLink we set up earlier to attach the token to each request.

Making GraphQL Queries

With Apollo Client set up and an access token function in place, you can now make GraphQL queries. Here's an example of how to query for a list of vaults:

import { gql } from '@apollo/client';

const GET_VAULTS = gql`
  query GetVaults {
    vaults {
      id
      name
      description
      status
      threshold
    }
  }
`;

async function getVaults() {
  const { data } = await client.query({
    query: GET_VAULTS,
  });

  return data.vaults;
}

This code defines a GET_VAULTS query using the gql template literal tag. The query selects the id, name, description, status, and threshold fields for all vaults.

The getVaults function executes this query using the client.query method and returns the vaults from the response data.

You can customize the query to include different fields, arguments, variables, fragments, and directives based on your specific needs. Refer to the io.vault API reference for available queries and schema details.

Making GraphQL Mutations

Making mutations with Apollo Client is similar to making queries. Here's an example of how to create a new vault:

import { gql } from '@apollo/client';

const CREATE_VAULT = gql`
  mutation CreateVault($input: CreateVaultInput!) {
    createVault(input: $input) {
      id
      status
    }
  }
`;

async function createVault(name: string, description: string, threshold: number, signerIds: string[]) {
  const { data } = await client.mutate({
    mutation: CREATE_VAULT,
    variables: {
      input: {
        name,
        description,
        signingParty: {
          threshold,
          signers: signerIds.map(id => ({ deviceId: id })),
        },
      },
    },
  });

  return data.createVault;
}

This code defines a CREATE_VAULT mutation with an $input variable of type CreateVaultInput. The mutation selects the id and status fields of the newly created vault.

The createVault function executes this mutation using the client.mutate method, passing the necessary input data as variables. It returns the createVault field from the response data.

Like with queries, you can customize mutations based on the available schema and your specific requirements.

Example Usage

Here's a complete example that demonstrates how to use the getVaults and createVault functions:

async function main() {
  // Get a list of existing vaults
  const vaults = await getVaults();
  console.log('Existing Vaults:', vaults);

  // Create a new vault
  const newVault = await createVault(
    'My New Vault',
    'A vault created from the API',
    2,
    ['cl1qzm9ue0183yk6lhds8wp2e', 'cl1qzm9ue0183yk6lhds8wp2f'],
  );
  console.log('New Vault:', newVault);
}

main().catch((err) => console.error(err));

This code first calls getVaults to retrieve a list of existing vaults and logs them to the console.

It then calls createVault to create a new vault with the specified name, description, threshold, and signer IDs. The newly created vault is logged to the console.

Remember to replace the placeholder signer IDs with actual device IDs associated with your io.vault account.

That covers the basics of using the io.vault GraphQL API with Apollo Client in TypeScript! Consult the API reference for more details on available operations and customization options.