Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import { useIotaClient, useIotaClientContext } from '@iota/dapp-kit';
import { type IdentityClientReadOnly } from '@iota/identity-wasm/web';
import { type NotarizationClientReadOnly } from '@iota/notarization/web';
import { type AuditTrailClientReadOnly } from '@iota/audit-trails/web';
import { type PropsWithChildren, useEffect, useMemo, useState } from 'react';
import { TrustFrameworkContext, type TrustFrameworkProviderContext } from '~/contexts';
import {
createAuditTrailClientReadOnly,
createIdentityClientReadOnly,
createNotarizationClientReadOnly,
} from '~/lib/utils/trust-framework/client';
Expand All @@ -20,6 +22,7 @@ export function TrustFrameworkProvider({ children }: PropsWithChildren) {
const [notarizationClient, setNotarizationClient] = useState<NotarizationClientReadOnly | null>(
null,
);
const [auditTrailClient, setAuditTrailClient] = useState<AuditTrailClientReadOnly | null>(null);

useEffect(() => {
if (!iotaClient) return;
Expand All @@ -35,14 +38,21 @@ export function TrustFrameworkProvider({ children }: PropsWithChildren) {
setNotarizationClient(_notarizationClient);
};
instantiateNotarizationClient();

const instantiateAuditTrailClient = async () => {
const _auditTrailClient = await createAuditTrailClientReadOnly(iotaClient, network);
setAuditTrailClient(_auditTrailClient);
};
instantiateAuditTrailClient();
}, [iotaClient, network]);

const ctx = useMemo(
(): TrustFrameworkProviderContext => ({
identityClient,
notarizationClient,
auditTrailClient,
}),
[identityClient, notarizationClient],
[identityClient, notarizationClient, auditTrailClient],
);

return <TrustFrameworkContext.Provider value={ctx}>{children}</TrustFrameworkContext.Provider>;
Expand Down
11 changes: 11 additions & 0 deletions apps/explorer/src/contexts/trustFrameworkContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@

import type { IdentityClientReadOnly } from '@iota/identity-wasm/web';
import type { NotarizationClientReadOnly } from '@iota/notarization/web';
import type { AuditTrailClientReadOnly } from '@iota/audit-trails/web';
import { createContext, useContext } from 'react';

export interface TrustFrameworkProviderContext {
identityClient: IdentityClientReadOnly | null;
notarizationClient: NotarizationClientReadOnly | null;
auditTrailClient: AuditTrailClientReadOnly | null;
}

export const TrustFrameworkContext = createContext<TrustFrameworkProviderContext>({
identityClient: null,
notarizationClient: null,
auditTrailClient: null,
});

export function useTrustFramework(): TrustFrameworkProviderContext {
Expand All @@ -35,10 +38,18 @@ export function useNotarizationClient(): NotarizationClientReadOnly | null {
return useTrustFramework().notarizationClient;
}

export function useAuditTrailClient(): AuditTrailClientReadOnly | null {
return useTrustFramework().auditTrailClient;
}

export function useIdentityPkgId(): string | null {
return useIdentityClient()?.packageId() || null;
}

export function useNotarizationPkgId(): string | null {
return useNotarizationClient()?.packageId() || null;
}

export function useAuditTrailPkgId(): string | null {
return useAuditTrailClient()?.packageId() || null;
}
9 changes: 8 additions & 1 deletion apps/explorer/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import './index.css';
import { Disclaimer, handleConsentAccepted } from '@iota/core';
import { LEGAL_LINKS } from './lib';
import { Link } from './components';
import { initIdentityWasmWeb, initNotarizationWasmWeb } from './lib/utils/trust-framework/client';
import {
initAuditTrailWasmWeb,
initIdentityWasmWeb,
initNotarizationWasmWeb,
} from './lib/utils/trust-framework/client';

// Load Amplitude as early as we can:
initAmplitude();
Expand All @@ -29,6 +33,9 @@ initIdentityWasmWeb();
// Load Notarization WASM module as early as we can:
initNotarizationWasmWeb();

// Load Audit Trail WASM module as early as we can:
initAuditTrailWasmWeb();

// Start loading features as early as we can:
appsBackendClient.refreshFeatures();

Expand Down
2 changes: 2 additions & 0 deletions apps/explorer/src/lib/constants/trustFramework.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@

export const IOTA_IDENTITY_PKG_ID = import.meta.env.VITE_IOTA_IDENTITY_PKG_ID;
export const IOTA_NOTARIZATION_PKG_ID = import.meta.env.VITE_IOTA_NOTARIZATION_PKG_ID;
export const IOTA_AUDIT_TRAIL_PKG_ID = import.meta.env.VITE_IOTA_AUDIT_TRAIL_PKG_ID;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VITE_IOTA_AUDIT_TRAIL_PKG_ID and VITE_IOTA_TF_COMPONENTS_PKG_ID shouldnt be in the .env.example¿

export const IOTA_TF_COMPONENTS_PKG_ID = import.meta.env.VITE_IOTA_TF_COMPONENTS_PKG_ID;
export const DID_PROTOCOL_SEGMENT_SYMBOL = ':';
export const DID_URL_SEGMENT_SYMBOL = '-';
44 changes: 44 additions & 0 deletions apps/explorer/src/lib/utils/trust-framework/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ import * as identity from '@iota/identity-wasm/web';
import identityWasmUrl from '@iota/identity-wasm/web/identity_wasm_bg.wasm?url';
import * as notarization from '@iota/notarization/web';
import notarizationWasmUrl from '@iota/notarization/web/notarization_wasm_bg.wasm?url';
import * as auditTrail from '@iota/audit-trails/web';
import auditTrailWasmUrl from '@iota/audit-trails/web/audit_trail_wasm_bg.wasm?url';
import { type IotaClient, Network } from '@iota/iota-sdk/client';
import {
DID_PROTOCOL_SEGMENT_SYMBOL,
DID_URL_SEGMENT_SYMBOL,
IOTA_IDENTITY_PKG_ID,
IOTA_NOTARIZATION_PKG_ID,
IOTA_AUDIT_TRAIL_PKG_ID,
IOTA_TF_COMPONENTS_PKG_ID,
} from '~/lib/constants/trustFramework.constants';

const regularNetworks = new Set([Network.Mainnet, Network.Testnet, Network.Devnet]);
let initIdentityPromise: Promise<void> | null = null;
let initNotarizationPromise: Promise<void> | null = null;
let initAuditTrailPromise: Promise<void> | null = null;

/**
* Idempotent initialization of WASM module of Identity.
Expand Down Expand Up @@ -49,6 +54,22 @@ export const initNotarizationWasmWeb = async (): Promise<void> => {
return initNotarizationPromise;
};

/**
* Idempotent initialization of WASM module of Audit Trail.
*
* Use it everytime you need to call any audit trail API.
*/
export const initAuditTrailWasmWeb = async (): Promise<void> => {
if (!initAuditTrailPromise) {
initAuditTrailPromise = auditTrail.init(auditTrailWasmUrl).catch((e) => {
console.error('failed to load audit trail wasm (web version)', e);
initAuditTrailPromise = null; // allow retry
throw e;
});
}
return initAuditTrailPromise;
};

export const createIdentityClientReadOnly = async (
iotaClient: IotaClient,
network: string,
Expand Down Expand Up @@ -95,6 +116,29 @@ export const createNotarizationClientReadOnly = async (
);
};

export const createAuditTrailClientReadOnly = async (
iotaClient: IotaClient,
network: string,
): Promise<auditTrail.AuditTrailClientReadOnly> => {
// If IOTA_AUDIT_TRAIL_PKG_ID is declared it has precedence
await initAuditTrailWasmWeb();
if (IOTA_AUDIT_TRAIL_PKG_ID != null && IOTA_TF_COMPONENTS_PKG_ID != null) {
return await auditTrail.AuditTrailClientReadOnly.createWithPackageOverrides(
iotaClient,
new auditTrail.PackageOverrides(IOTA_AUDIT_TRAIL_PKG_ID, IOTA_TF_COMPONENTS_PKG_ID),
);
}

// Well-known networks have well-known notarization package id
if (regularNetworks.has(network as Network)) {
return await auditTrail.AuditTrailClientReadOnly.create(iotaClient);
}

throw new Error(
'Failed to create a AuditTrailClientReadOnly; declare IOTA_AUDIT_TRAIL_PKG_ID and IOTA_TF_COMPONENTS_PKG_ID environment if running on a custom network.',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit 🙏

Suggested change
'Failed to create a AuditTrailClientReadOnly; declare IOTA_AUDIT_TRAIL_PKG_ID and IOTA_TF_COMPONENTS_PKG_ID environment if running on a custom network.',
'Failed to create a AuditTrailClientReadOnly; declare IOTA_AUDIT_TRAIL_PKG_ID and IOTA_TF_COMPONENTS_PKG_ID environment variables if running on a custom network.',

);
};

export async function tryDIDParse(didCandidate: string): Promise<identity.IotaDID | null> {
try {
await initIdentityWasmWeb();
Expand Down
Loading