Skip to content

Commit

Permalink
feat: implement minimal server
Browse files Browse the repository at this point in the history
  • Loading branch information
baumstern committed Jan 20, 2024
1 parent 3795e92 commit dc5e641
Show file tree
Hide file tree
Showing 7 changed files with 2,475 additions and 130 deletions.
9 changes: 9 additions & 0 deletions app/model/report.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class Report {
name: string;
description: string;

constructor(name: string, description: string) {
this.name = name;
this.description = description;
}
}
54 changes: 28 additions & 26 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import type { MetaFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

import { Report } from "../model/report";
import { ReportService } from "../server/bootstrap.server";

export interface IReportLoader {
reports: Report[];
}

export const loader = async (): Promise<IReportLoader> => {
const reportService = await ReportService.getInstance();
return { reports: reportService.getReports() };
};

export const meta: MetaFunction = () => {
return [
Expand All @@ -8,34 +21,23 @@ export const meta: MetaFunction = () => {
};

export default function Index() {
const { reports } = useLoaderData<typeof loader>();
return (
<div>
<h1 className="text-7xl">Welcome to Remix</h1>
<ul>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/blog"
rel="noreferrer"
>
15m Quickstart Blog Tutorial
</a>
</li>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/jokes"
rel="noreferrer"
>
Deep Dive Jokes App Tutorial
</a>
</li>
<li>
<a target="_blank" href="https://remix.run/docs" rel="noreferrer">
Remix Docs
</a>
</li>
</ul>
<h1 className="text-7xl">Impact Report</h1>
<div className="text-xl">
{reports.map((report) => {
return (
<div key={report.name}>
-----
<br />
name: {report.name}
<br />
description: {report.description}
</div>
);
})}
</div>
</div>
);
}
58 changes: 58 additions & 0 deletions app/server/bootstrap.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ClaimsByOwnerQuery, HypercertClient } from "@hypercerts-org/sdk";

import { Report } from "../model/report";
import { GraphService } from "./service/graph-service.server";
import { IpfsService } from "./service/ipfs-service.server";

export class ReportService {
private static instance: ReportService;
reports: Report[];

hypercertClient: HypercertClient;

constructor() {
this.reports = new Array<Report>();

this.hypercertClient = new HypercertClient({
chain: { id: 11155111 }, // Sepolia
});
}

static async getInstance(): Promise<ReportService> {
if (!ReportService.instance) {
ReportService.instance = new ReportService();
await ReportService.instance.init();
}

return ReportService.instance;
}

getReports() {
return this.reports;
}

private async init() {
const claims = await this.getHyperCertClaims();
for (const claim of claims) {
const metadata = await this.getHyperCertMetadata(claim.uri as string);

this.reports.push(new Report(metadata.name, metadata.description));
}
}

private async getHyperCertClaims() {
const graphService = await GraphService.getInstance();
const { claims } = (await graphService.claimsByOwner(
"0x42fbf4d890b4efa0fb0b56a9cc2c5eb0e07c1536",
)) as ClaimsByOwnerQuery;

return claims;
}

private async getHyperCertMetadata(claimUri: string) {
const ipfsService = await IpfsService.getInstance();
const metadata = await ipfsService.getMetadata(claimUri);

return metadata;
}
}
27 changes: 27 additions & 0 deletions app/server/service/graph-service.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { HypercertClient } from "@hypercerts-org/sdk";

import { ReportService } from "../bootstrap.server";

// graphql schema of hypercert v1.4.1: https://github.com/hypercerts-org/hypercerts/blob/89009f1fcd072aaedd06ede8ba264623277244e9/graph/schema.graphql
export class GraphService {
private static instance: GraphService;
private hypercertClient: HypercertClient;

constructor(hypercertClient: HypercertClient) {
this.hypercertClient = hypercertClient;
}

static async getInstance(): Promise<GraphService> {
if (!GraphService.instance) {
GraphService.instance = new GraphService(
(await ReportService.getInstance()).hypercertClient,
);
}
return GraphService.instance;
}

// see graphql query: https://github.com/hypercerts-org/hypercerts/blob/main/sdk/src/indexer/queries/claims.graphql#L1-L11
async claimsByOwner(owner: string) {
return await this.hypercertClient.indexer.claimsByOwner(owner);
}
}
27 changes: 27 additions & 0 deletions app/server/service/ipfs-service.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { HypercertClient } from "@hypercerts-org/sdk";

import { ReportService } from "../bootstrap.server";

export class IpfsService {
private static instance: IpfsService;
private hypercertClient: HypercertClient;

constructor(hypercertClient: HypercertClient) {
this.hypercertClient = hypercertClient;
}

static async getInstance(): Promise<IpfsService> {
if (!IpfsService.instance) {
IpfsService.instance = new IpfsService(
(await ReportService.getInstance()).hypercertClient,
);
}
return IpfsService.instance;
}

// get metadata of hypercert claim
// see Hypercert metadata format v1.4.1: https://github.com/hypercerts-org/hypercerts/blob/89009f1fcd072aaedd06ede8ba264623277244e9/sdk/src/types/metadata.d.ts#L11-L46
async getMetadata(claimUri: string) {
return await this.hypercertClient.storage.getMetadata(claimUri);
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"dependencies": {
"@fontsource-variable/plus-jakarta-sans": "^5.0.19",
"@hypercerts-org/sdk": "^1.4.1",
"@remix-run/node": "^2.5.0",
"@remix-run/react": "^2.5.0",
"@remix-run/serve": "^2.5.0",
Expand Down
Loading

0 comments on commit dc5e641

Please sign in to comment.