Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some cleanup and additions #29

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
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
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ This repository contains a simple web interface and API for creating, viewing, a

Visit [inscribe.news](https://inscribe.news) to see it in action!

## API Endpoints
Visit the [inscribe.news documentation](https://docs.inscribe.news) to learn more about the standard!

The API fetches info, content, or news from an inscription ID, grabbing the data from the [Hiro Ordinals API](https://github.com/hirosystems/ordinals-api) with either [ordapi.xyz](https://ordapi.xyz) or [ordinals.com](https://ordinals.com) as a fallback, then saving it in KV for future requests.
## API

- `/api/info/INSCRIPTION_ID` - returns inscription data (all)
- `/api/content/INSCRIPTION_ID` - returns inscription content (all)
- `/api/news/INSCRIPTION_ID` - returns html from news inscription body (news only)
- `/api/data/INSCRIPTION_ID` - returns inscription data and content (news only)
- `/api/data/ord-news` - returns all known news inscriptions in KV
- `/api/data/ord-list` - returns all known inscriptions in KV
The API fetches info, content, or news from an inscription ID or inscription number, and will:

- first try to return the data from Cloudflare KV, if indexed
- fetch and store the data from the [Hiro Ordinals API](https://github.com/hirosystems/ordinals-api) for future reads

The available endpoints are [listed in the documentation](https://docs.inscribe.news/api).

## Development

This repository can be cloned and hosted with an active Cloudflare account, using [Cloudflare Pages](https://pages.cloudflare.com/).
This repository can be cloned and hosted with an active Cloudflare account using [Cloudflare Pages](https://pages.cloudflare.com/).

To develop the site locally, run:

Expand All @@ -30,13 +30,17 @@ npx wrangler pages dev dist/
To develop the site locally with KV enabled:

```
npx wrangler pages dev --kv ORD_LIST --kv ORD_NEWS --kv ORD_DATA --local ./public ./dist
npx wrangler pages dev --kv ORD_LIST_V2 --kv ORD_NEWS_V2 --local ./public ./dist
```

### Cloudflare Configuration

In order to setup the same environment, a few Cloudflare settings need to be enabled on the dashboard for this Pages project.

#### Link to GitHub

Clone this repository and set it up within the Cloudflare Dashboard using Cloudflare Pages.

#### Builds & Deployments

- Build command: npm run build
Expand All @@ -57,12 +61,10 @@ Preview:

Create KV namespaces:

- ord-list
- ord-news
- ord-data
- ord-list-preview
- ord-news-preview
- ord-data-preview
- ord-list-v2
- ord-news-v2
- ord-list-preview-v2
- ord-news-preview-v2

#### Functions

Expand All @@ -71,10 +73,8 @@ Usage model: Unbound
KV namespace bindings:

- Production:
- ORD_LIST = ord-list
- ORD_NEWS = ord-news
- ORD_DATA = ord-data
- ORD_LIST_V2 = ord-list-v2
- ORD_NEWS_V2 = ord-news-v2
- Preview:
- ORD_LIST = ord-list-preview
- ORD_NEWS = ord-news-preview
- ORD_DATA = ord-data-preview
- ORD_LIST_V2 = ord-list-preview-v2
- ORD_NEWS_V2 = ord-news-preview-v2
12 changes: 7 additions & 5 deletions functions/api/[[catchall]].ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ export async function onRequest({ request }): Promise<Response> {
const url = new URL(request.url);
const path = url.pathname;
return createResponse(
`Welcome to the Ordinal News Indexer and API! Supported routes below:\n\n
/api/info/INSCRIPTION_ID - returns inscription data (all)\n
/api/content/INSCRIPTION_ID - returns inscription content (all)\n
/api/news/INSCRIPTION_ID - returns html from news inscription body (news only)\n
/api/data/INSCRIPTION_ID - returns inscription data and content (news only)\n
`Welcome to the Ordinal News Indexer and API!\n\n
More information can be found in the docs: https://docs.inscribe.news/api\n\n
Supported routes below, where ID = inscription ID or number:\n\n
/api/info/ID - returns inscription data (all)\n
/api/content/ID - returns inscription content (all)\n
/api/news/ID - returns html from news inscription body (news only)\n
/api/data/ID - returns inscription data and content (news only)\n
/api/data/ord-news - returns all known news inscriptions in KV\n
/api/data/ord-list - returns all known inscriptions in KV\n\n
current path: ${path}`
Expand Down
12 changes: 1 addition & 11 deletions lib/api-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,10 @@ export async function getInscription(
};
}
} catch (err) {
// TODO: throw err?
console.log(`getInscription: unable to retrieve from V2 KV key\n${id}\n${String(err)}`);
}

// check for data in V1 key, store if found
try {
const kvData = await env.ORD_LIST.getWithMetadata(id, { type: 'arrayBuffer' });
if (kvData.metadata !== null && kvData.value !== null) {
metadata = kvData.metadata as InscriptionMeta;
content = new Response(kvData.value as ArrayBuffer);
}
} catch (err) {
console.log(`getInscription: unable to retrieve from V1 KV key\n${id}\n${String(err)}`);
}

// check that data was returned, fetch from Hiro API if not
// works with inscription ID or inscription number
if (metadata === undefined || Object.keys(metadata).length === 0 || content === undefined) {
Expand Down
2 changes: 0 additions & 2 deletions lib/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { KVNamespace } from '@cloudflare/workers-types';

// KV binding
export interface Env {
ORD_LIST: KVNamespace;
ORD_NEWS: KVNamespace;
ORD_LIST_V2: KVNamespace;
ORD_NEWS_V2: KVNamespace;
}
Expand Down
23 changes: 23 additions & 0 deletions src/components/bitcoin-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Icon } from '@chakra-ui/react';

// credit for the bitcoin icon
// https://commons.wikimedia.org/wiki/File:Bitcoin_logo.svg#/media/File:Bitcoin.svg
export default function BitcoinIcon({ color = 'currentColor' }) {
return (
<Icon
viewBox="0 0 64 64"
className="bitcoin-icon"
>
<g transform="translate(0.00630876,-0.00301984)">
<path
fill={color}
d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"
/>
<path
fill="#FFF"
d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"
/>
</g>
</Icon>
);
}
22 changes: 1 addition & 21 deletions src/routes/post-news.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
FormControl,
FormLabel,
Heading,
Icon,
Input,
Link as ChakraLink,
Modal,
Expand All @@ -29,26 +28,7 @@ import {
} from '@chakra-ui/react';
import { Link } from 'react-router-dom';
import copy from 'copy-to-clipboard';

// credit for the bitcoin icon
// https://commons.wikimedia.org/wiki/File:Bitcoin_logo.svg#/media/File:Bitcoin.svg
const BitcoinIcon = () => (
<Icon
viewBox="0 0 64 64"
className="bitcoin-icon"
>
<g transform="translate(0.00630876,-0.00301984)">
<path
fill="currentColor"
d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"
/>
<path
fill="#FFF"
d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"
/>
</g>
</Icon>
);
import BitcoinIcon from '../components/bitcoin-icon';

// credit for the form template goes to:
// https://chakra-templates.dev/templates/forms/authentication/simpleSignupCard
Expand Down
10 changes: 6 additions & 4 deletions src/routes/recent-news.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { Box, Divider, Heading, HStack, Text, VStack, Wrap, WrapItem } from '@chakra-ui/react';
import { Box, Divider, Heading, HStack, Text, VStack } from '@chakra-ui/react';
import { KVNamespaceListKey, KVNamespaceListResult } from '@cloudflare/workers-types';
import { InscriptionMeta, OrdinalNews } from '../../lib/api-types';
import { Link } from 'react-router-dom';
Expand All @@ -10,7 +10,6 @@ async function getRecentNews() {
const result = await fetch(new URL(`/api/data/ord-news`, apiUrl).toString());
if (result.ok) {
const infoData: KVNamespaceListResult<unknown, string> = await result.json();
console.log(`getRecentNews: found ${infoData.keys.length} news items from API`);
return infoData;
}
console.log(`getRecentNews: ${result.status} ${result.statusText}`);
Expand Down Expand Up @@ -52,8 +51,6 @@ function NewsItem(props: InscriptionMeta & OrdinalNews) {
<HStack flexWrap="wrap">
<Text>{new Date(timestamp).toLocaleString()}</Text>
<Text>•</Text>
<Text>News # 005</Text>
<Text>•</Text>
<Text>Inscription # {number.toLocaleString()}</Text>
<Text>•</Text>
<Text>{author ? author : 'anonymous'}</Text>
Expand All @@ -63,6 +60,11 @@ function NewsItem(props: InscriptionMeta & OrdinalNews) {
);
}

/*
<Text>•</Text>
<Text>News # 005</Text>
*/

export default function RecentNews() {
const [loading, setLoading] = useState(true);
const [newsList, setNewsList] = useState<string[] | undefined>(undefined);
Expand Down
8 changes: 7 additions & 1 deletion src/routes/view-news.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export default function ViewNews() {
setData(data);
// extract news values as InscriptionMeta
const { p, op, title, url, body, author, authorAddress, signature } = data;
// TODO: fix for SNS names coming up in view-news
if (p === 'ons' && title) {
setNews({
p,
Expand Down Expand Up @@ -159,6 +158,13 @@ export default function ViewNews() {
maxW="100%"
pt={3}
>
<Text>
{new Date(data.timestamp).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</Text>
{news.author && <Text pb={3}>Author: {news.author}</Text>}
{news.url && (
<Text pb={3}>
Expand Down