Skip to content

Commit

Permalink
Merge pull request #9 from StauroXYZ/lighthouse-storage
Browse files Browse the repository at this point in the history
feat: Lighthouse storage + GW3 upload support
  • Loading branch information
talentlessguy authored Nov 20, 2023
2 parents 2d5c005 + 70b6490 commit bbb3dfb
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 38 deletions.
9 changes: 8 additions & 1 deletion site/docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ We support a wide range of different IPFS providers.
- URL: https://www.gw3.io
- API Docs: https://doc.gw3.io/api/gateway/pinning.html
- API token env var: `BLUMEN_GW3_TOKEN`, `BLUMEN_GW3_ACCESS_KEY`
- Supported methods: Upload, Pin [not working for now]
- Supported methods: Upload, Pin

## Lighthouse

- URL: https://lighthouse.storage
- API Docs: https://docs.lighthouse.storage
- API token env var: `BLUMEN_LIGHTHOUSE_TOKEN`
- Supported methods: Upload, Pin
1 change: 1 addition & 0 deletions src/actions/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const deployAction = async (
car: blob,
token,
accessKey: apiTokens.get('GW3_ACCESS_KEY'),
cid,
})
}
catch (e) {
Expand Down
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { uploadOnFilebase } from './providers/filebase.js'
import { statusOnGW3, uploadOnGW3 } from './providers/gw3.js'
import { uploadOnLighthouse } from './providers/lighthouse.js'
import { statusOnW3S, uploadOnW3S } from './providers/w3s.js'
import type { StatusFunction, UploadFunction } from './types.js'

Expand All @@ -21,4 +22,8 @@ string,
name: 'Filebase',
upload: uploadOnFilebase,
},
LIGHTHOUSE_TOKEN: {
name: 'Lighthouse',
upload: uploadOnLighthouse,
},
}
6 changes: 5 additions & 1 deletion src/polyfills/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import fetch, { Headers, Request, Response, FormData } from 'node-fetch'
import fetch, { Headers, Request, Response, FormData, Blob } from 'node-fetch'

if (!('fetch' in globalThis)) {
Object.assign(globalThis, { fetch, Headers, Request, Response, FormData })
}

if (!('Blob' in globalThis)) {
Object.assign(globalThis, { Blob })
}
4 changes: 2 additions & 2 deletions src/providers/filebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { specPin } from './spec.js'
const providerName = 'Filebase'
const baseURL = 'https://api.filebase.io/v1/ipfs/pins'

export const uploadOnFilebase: UploadFunction = async ({ cid, name, token }) => {
if (!cid) throw new UploadNotSupportedError(providerName)
export const uploadOnFilebase: UploadFunction = async ({ cid, name, token, car }) => {
if (car) throw new UploadNotSupportedError(providerName)

return await specPin({ baseURL, providerName, cid, name, token })
}
43 changes: 23 additions & 20 deletions src/providers/gw3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export const uploadOnGW3: UploadFunction = async ({
accessKey,
}) => {
if (!accessKey) throw new MissingKeyError('GW3_ACCESS_KEY')
if (cid) {
const res = await fetch(
new URL(`/api/v0/pin/add?arg=${cid}&ts=${getTs()}`, baseURL),
if (car) {
const res1 = await fetch(
new URL(`https://gw3.io/api/v0/dag/import?size=${car!.size}&ts=${getTs()}`, baseURL),
{
method: 'POST',
headers: {
Expand All @@ -44,20 +44,29 @@ export const uploadOnGW3: UploadFunction = async ({
},
},
)

const json = await res.json()
if (!res.ok) {
const json = await res1.json()
if (!res1.ok || json.code !== 200) {
throw new DeployError(
providerName,
(json).msg,
json.msg,
)
}
const fd = new FormData()

fd.append('file', car as Blob)

const res2 = await fetch(json.data.url, {
method: 'POST',
body: fd,
})

if (!res2.ok) throw new DeployError(providerName, await res2.text())

return { cid }
}
else {
const res1 = await fetch(
new URL(`https://gw3.io/api/v0/dag/import?size=${car!.size}&ts=${getTs()}&path=/`, baseURL),
const res = await fetch(
new URL(`/api/v0/pin/add?arg=${cid}&ts=${getTs()}`, baseURL),
{
method: 'POST',
headers: {
Expand All @@ -68,22 +77,16 @@ export const uploadOnGW3: UploadFunction = async ({
},
},
)
const json = await res1.json()
if (!res1.ok || json.code !== 200) {

const json = await res.json()
if (!res.ok) {
throw new DeployError(
providerName,
json.msg,
(json).msg,
)
}

const res2 = await fetch(json.data.url, {
method: 'POST',
body: car as Blob,
})

if (!res2.ok) throw new DeployError(providerName, await res2.text())

return { cid: CID.parse(res2.headers.get('ipfs-hash')!).toV1().toString() }
return { cid }
}
}

Expand Down
50 changes: 50 additions & 0 deletions src/providers/lighthouse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { DeployError } from '../errors.js'
import { UploadFunction } from '../types.js'

const providerName = 'Lighthouse'

export const uploadOnLighthouse: UploadFunction = async ({ car, cid, name, token }) => {
if (car) {
const depotTokenRes = await fetch('https://data-depot.lighthouse.storage/api/auth/lighthouse_auth', {
headers: {
Authorization: `Bearer ${token}`,
},
})
const depotTokenJson = await depotTokenRes.json()

if (!depotTokenRes.ok) throw new DeployError(providerName, depotTokenJson)

const fd = new FormData()
fd.append('file', car as Blob)
const res = await fetch('https://data-depot.lighthouse.storage/api/upload/upload_files', {
method: 'POST',
body: fd,
headers: {
Authorization: `Bearer ${depotTokenJson.access_token}`,
},
})
const json = await res.text()

if (!res.ok) throw new DeployError(providerName, json)

return { cid }
}
else {
const res = await fetch(new URL('/api/lighthouse/pin', 'https://api.lighthouse.storage'), {
method: 'POST',
body: JSON.stringify({
cid, fileName: name,
}),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
})

const json = await res.json()

if (!res.ok) throw new DeployError(providerName, json.errors[0].message)

return { cid }
}
}
4 changes: 2 additions & 2 deletions src/providers/spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DeployError, UploadNotSupportedError } from '../errors.js'
import { UploadFunction } from '../types.js'

export const specPin: UploadFunction<{ baseURL: string, providerName: string }> = async ({ baseURL, providerName, cid, name, token }) => {
if (!cid) throw new UploadNotSupportedError(providerName)
export const specPin: UploadFunction<{ baseURL: string, providerName: string }> = async ({ baseURL, providerName, cid, name, token, car }) => {
if (car) throw new UploadNotSupportedError(providerName)

const res = await fetch(new URL('pins', baseURL), {
method: 'POST',
Expand Down
3 changes: 1 addition & 2 deletions src/providers/w3s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ const providerName = 'web3.storage'
export const uploadOnW3S: UploadFunction = async ({
token,
car,
cid,
name,
}) => {
if (cid) throw new PinningNotSupportedError(providerName)
if (!car) throw new PinningNotSupportedError(providerName)

const res = await fetch(new URL('/car', baseURL), {
method: 'POST',
Expand Down
17 changes: 8 additions & 9 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ReadableStream } from 'node:stream/web'
import { Blob } from 'node:buffer'
import type { ReadableStream } from 'node:stream/web'

export interface BlobLike {
/**
Expand All @@ -25,16 +24,16 @@ type AuthArgs = {
}

export type UploadArgs<T> = (
| {
car: Blob
cid?: never
{
cid: string
name: string
}
} &
({
car: Blob
}
| {
car?: never
cid: string
name: string
}
})
) &
AuthArgs & T

Expand Down
1 change: 0 additions & 1 deletion src/utils/ipfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { createDirectoryEncoderStream, CAREncoderStream } from '../ipfs-car/inde
import { Block } from '@ipld/unixfs'
import { writableToWeb } from '../polyfills/toWeb.js'
import { Writable } from 'node:stream'
import { Blob } from 'node:buffer'

const tmp = tmpdir()

Expand Down

0 comments on commit bbb3dfb

Please sign in to comment.