Files
explorer/web/store/proofs.ts
2024-08-16 07:37:42 -04:00

113 lines
2.2 KiB
TypeScript

import { ThunkDispatch } from 'redux-thunk';
import { AppRootState } from './index';
import type { Proof } from 'tlsn-js-v5/build/types';
import { useSelector } from 'react-redux';
import deepEqual from 'fast-deep-equal';
import { EXPLORER_URL } from '../utils/constants';
import { Attestation } from '../utils/types/types';
import { verify } from '../utils';
enum ActionType {
SetIPFSProof = 'proofs/setIPFSProof',
}
export type Action<payload = any> = {
type: ActionType;
payload: payload;
error?: boolean;
meta?: any;
};
type ProofData = {
raw: Attestation;
proof?: {
time: number;
sent: string;
recv: string;
notaryUrl: string;
};
};
type State = {
ipfs: {
[cid: string]: ProofData;
};
};
const initState: State = {
ipfs: {},
};
export const fetchProofFromIPFS =
(cid: string, notaryKey = '') =>
async (
dispatch: ThunkDispatch<AppRootState, ActionType, Action>,
getState: () => AppRootState,
) => {
const old = getState().proofs.ipfs[cid];
let data;
if (!old?.raw) {
const response = await fetch(EXPLORER_URL + `/gateway/ipfs/${cid}`);
if (!response.ok) {
throw new Error('Failed to fetch file from IPFS');
}
data = await response.json();
} else {
data = old.raw;
}
const proof = await verify(data, notaryKey);
dispatch(setIPFSProof({ cid, proof, raw: data }));
};
export const setIPFSProof = (
payload: ProofData & {
cid: string;
},
) => ({
type: ActionType.SetIPFSProof,
payload: payload,
});
export default function proofs(
state = initState,
action: Action<{
cid: string;
raw: Proof;
proof: {
time: number;
sent: string;
recv: string;
notaryUrl: string;
};
}>,
): State {
switch (action.type) {
case ActionType.SetIPFSProof:
return {
...state,
ipfs: {
...state.ipfs,
[action.payload.cid]: {
proof: action.payload.proof,
raw: action.payload.raw,
},
},
};
default:
return state;
}
}
export const useIPFSProof = (cid?: string): ProofData | null => {
return useSelector((state: AppRootState) => {
if (!cid) return null;
return state.proofs.ipfs[cid] || null;
}, deepEqual);
};