JavaScript API
How to build the JavaScript interface for your smart contract.
Getting Started
Once your smart contract is built, tested, and deployed, you'll build a JavaScript API to interact with your smart contract. Navigate to the source folder to build and edit your JavaScript API.
Additional resources
Haven't written your unit tests? See Unit Tests before moving forward. The JavaScript API is written using React and makes use of both React Query and React Hooks. It also uses Ethers to interact with the Ethereum Network.
Source Folder
The source folder contains the following files for the JavaScript API.
moduleLibrary.ts
- Library that contains the detailed functions that read & write to the blockchain.useHook.ts
- React hook that exposes your library to the react ecosystem.Provider.tsx
- Hyperverse modules use the React Context to expose state to child components.environment.ts
- Simple component that will identify which blockchain and network your module is being used under.index.ts
- Handles imports and exports for JavaScript API.
Update moduleLibrary.ts
The moduleLibrary.ts
contains the detailed functions that read & write to the blockchain.
// Update file name to match smart module (ex. erc721Library.ts)
import { HyperverseConfig } from "@decentology/hyperverse";
import { EvmLibraryBase, getProvider } from "@decentology/hyperverse-evm";
import { ethers } from "ethers";
import { CancellablePromise } from "real-cancellable-promise";
import { getEnvironment } from "./environment";
export type ModuleLibraryType = Awaited<ReturnType<typeof ModuleLibraryInternal>>;
export function ModuleLibrary(...args: Parameters<typeof ModuleLibraryInternal>): CancellablePromise<ModuleLibraryType> {
return new CancellablePromise(ModuleLibraryInternal(...args), () => { });
}
async function ModuleLibraryInternal(
hyperverse: HyperverseConfig,
providerOrSigner?: ethers.providers.Provider | ethers.Signer
) {
const { FactoryABI, factoryAddress, ContractABI } = getEnvironment(
hyperverse.blockchain?.name!,
hyperverse.network
);
if (!providerOrSigner) {
providerOrSigner = getProvider(hyperverse.network);
}
const base = await EvmLibraryBase(
'CustomModule',
hyperverse,
factoryAddress!,
FactoryABI,
ContractABI,
providerOrSigner
);
// Add additional functionality to read and write from smart contract
return {
...base
// Return all additional consts as specified above
}
}
info
View an example of the completed erc721Library.ts
file here
Update useHook.ts
useHook.ts
provides hooks that expose your library to the React ecosystem.
// Update file name to match smart module (ex. useERC721.ts)
import { useState, useEffect } from 'react';
import { createContainer, useContainer } from '@decentology/unstated-next';
import { useEvm } from '@decentology/hyperverse-evm';
// Update imports to match smart module
import { ModuleLibrary, ModuleLibraryType } from './moduleLibrary';
import { useHyperverse } from '@decentology/hyperverse';
// Update name to match smart module
function ModuleState(initialState: { tenantId: string } = { tenantId: '' }) {
const { tenantId } = initialState;
const { address, connectedProvider, readOnlyProvider } = useEvm();
const hyperverse = useHyperverse();
// Update name to match smart module
const [hyperverseModule, setHyperverseModule] = useState<ModuleLibraryType>();
useEffect(() => {
// Update library to match smart module
const lib = ModuleLibrary(hyperverse, connectedProvider || readOnlyProvider).then(setHyperverseModule)
return lib.cancel;
}, [connectedProvider])
return {
// Update name to match smart module
...hyperverseModule,
tenantId,
};
}
// Update occurrences of module to match smart module
export const Module = createContainer(ModuleState);
export function useModule() {
return useContainer(Module);
}
info
View an example of the completed useERC721.ts
file here
Update Provider.tsx
provider.tsx
contains the React Context to expose state to child components.
import { FC } from "react";
import { QueryClientProvider, QueryClient } from "react-query";
// Update occurrences of module to match smart module
import { HyperverseModuleInstance } from "@decentology/hyperverse";
import { Module } from "./useHook";
const client = new QueryClient();
const Provider: FC<HyperverseModuleInstance> = ({ children, tenantId }) => {
if (tenantId == null) {
throw new Error("Tenant ID is required");
}
return (
// Update occurrences of module to match smart module
<QueryClientProvider client={client}>
<Module.Provider initialState={{ tenantId: tenantId }}>
{children}
</Module.Provider>
</QueryClientProvider>
);
};
export { Provider };
info
View an example of the completed ERC721 Provider.tsx
here
Update environment.ts
environment.ts
is a simple component that will identify which blockchain and network your module is being used under. This allows EVM modules to easily work with any supported EVM module
import {
Blockchain,
isEvm,
BlockchainEvm,
EvmEnvironment,
NetworkConfig,
} from '@decentology/hyperverse';
// Update occurrences of module in imports and exports to match smart module
import Factory from '../artifacts/contracts/ModuleFactory.sol/ModuleFactory.json';
import Contract from '../artifacts/contracts/Module.sol/Module.json';
import Contracts from '../contracts.json';
export const ContractABI = Contract.abi;
export const FactoryABI = Factory.abi;
const environment = Contracts as EvmEnvironment;
function getEnvironment(blockchainName: Blockchain, network: NetworkConfig) {
if (blockchainName == null) {
throw new Error('Blockchain is not set');
}
if (!isEvm(blockchainName)) {
throw new Error('Blockchain is not EVM compatible');
}
const chain = environment[blockchainName as BlockchainEvm];
if (!chain) {
throw new Error('Blockchain is not supported');
}
const env = chain[network.type];
return {
...env,
ContractABI,
FactoryABI,
};
}
export { environment, getEnvironment };
info
View an example of the completed ERC721 environment.ts
file here
Update index.ts
index.ts
handles imports and exports for JavaScript API.
// Update occurrences of module to match smart module
export { useModule } from "./useHook";
import { Provider } from "./Provider";
export { Provider } from "./Provider";
// Update occurrences of module to match smart module
export const ModuleName = "CustomModule";
export { ModuleLibrary } from "./moduleLibrary";
export const CustomModule = {
Provider,
ModuleName,
};
info
View an example of the completed ERC721 index.ts
file here
Build UI Harness
You're now ready to start building your UI Harness!