Skip to content

Commit

Permalink
Merge pull request #32 from StauroDEV/spektr
Browse files Browse the repository at this point in the history
Spektr
  • Loading branch information
talentlessguy authored Apr 29, 2024
2 parents 7882a10 + e2589f4 commit fe4de44
Show file tree
Hide file tree
Showing 13 changed files with 1,056 additions and 251 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Status][gh-actions-img]][github-actions] ![npm](https://img.shields.io/npm/dt/bl
</div>


**Blumen** is a CLI to deploy apps on the decentralized web using IPFS and Ethereum.
**Blumen** is a CLI to deploy apps on the decentralized web using IPFS and Ethereum. Built with [Spektr](https://github.com/StauroDEV/spektr).

> Blumen is in an alpha stage and has been neither audited nor tested yet. Use with caution!
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@
"@web3-storage/access": "^18.2.0",
"@web3-storage/w3up-client": "^12.4.1",
"ascii-bar": "^1.0.3",
"cac": "^6.7.14",
"cborg": "^4.1.3",
"colorette": "^2.0.20",
"globby": "^14.0.1",
"ipfs-car": "^1.2.0",
"multiformats": "^13.1.0",
"spektr": "^0.0.5",
"table": "^6.8.1",
"viem": "^2.8.13"
},
Expand All @@ -61,7 +61,7 @@
"@typescript-eslint/parser": "^7.7.1",
"eslint": "^9.1.1",
"globals": "^15.1.0",
"semantic-release": "^23.0.5",
"semantic-release": "^23.0.8",
"typescript": "^5.4.2"
},
"release": {
Expand Down
1,004 changes: 839 additions & 165 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions scripts/version.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import { readFile, writeFile } from 'node:fs/promises'

const pkg = await readFile('./package.json', 'utf8')
const {stdout} = await promisify(exec)(`git describe --tags --abbrev=0`)

const {version} = JSON.parse(pkg)
const patchVersion = stdout.slice(stdout.lastIndexOf('.'))

await writeFile('./src/utils/version.ts', `export const BLUMEN_VERSION = '${version}'`)
const newVersion = stdout.replace('v','').replace(patchVersion, `.${parseInt(patchVersion[1]) + 1}`)

await writeFile('./src/utils/version.ts', `export const BLUMEN_VERSION = '${newVersion}'\n`)
2 changes: 1 addition & 1 deletion site/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<h1>Blumen</h1>
</div>

**Blumen** is a CLI app to deploy apps on the decentralized web using IPFS and Ethereum.
**Blumen** is a CLI to deploy apps on the decentralized web using IPFS and Ethereum. Built with [Spektr](https://github.com/StauroDEV/spektr).

<video src="/blumen.mp4" height="1254" width="960" controls />

Expand Down
37 changes: 16 additions & 21 deletions src/actions/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,32 @@ import { MissingDirectoryError, NoProvidersError } from '../errors.js'
import { walk, fileSize, packCAR, parseTokensFromEnv, tokensToProviderNames, findEnvVarProviderName } from '../index.js'
import { exists } from '../utils/fs.js'
import mod from 'ascii-bar'
import { ensAction } from './ens.js'
import { ChainName } from '../types.js'
import { Address } from 'viem'
import { EnsActionArgs, ensAction } from './ens.js'
import { deployMessage, logger } from '../utils/logger.js'
import * as colors from 'colorette'
import { dnsLinkAction } from './dnslink.js'

// @ts-expect-error authors of AsciiBar didnt publish the package properly
const AsciiBar = mod.default

type DeployActionArgs = {
export type DeployActionArgs = Partial<{
strict: boolean
chain?: ChainName
ens?: string
resolverAddress?: Address
safe?: Address
name?: string
dist?: string
providers?: string
verbose?: boolean
dnslink?: string
}
ens: string
name: string
dist: string
providers: string
verbose: boolean
dnslink: string
}> & EnsActionArgs

export const deployAction = async (
dir: string,
{
{ dir, options = {} }: { dir?: string, options?: DeployActionArgs },
) => {
const {
strict, ens, chain = 'mainnet', safe, name: customName,
dist, verbose = false, providers: providersList, resolverAddress,
dnslink,
}: DeployActionArgs,
) => {
dnslink, rpcUrl,
} = options
if (!dir) {
if (await exists('dist')) dir = 'dist'
else dir = '.'
Expand Down Expand Up @@ -125,10 +120,10 @@ export const deployAction = async (

if (typeof ens === 'string') {
console.log('\n')
await ensAction(cid, ens, { chain, safe, resolverAddress })
await ensAction({ cid, domain: ens, options: { chain, safe, resolverAddress, rpcUrl } })
}

if (dnslink) {
await dnsLinkAction(cid, dnslink, { verbose })
await dnsLinkAction({ cid, name, options: { verbose } })
}
}
3 changes: 2 additions & 1 deletion src/actions/dnslink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { updateDnsLink } from '../utils/dnslink.js'
import { logger } from '../utils/logger.js'

export const dnsLinkAction = async (
cid: string, name: string, { verbose }: { verbose: boolean }, /* { init = false }: { init?: boolean } */
{ cid, name, options = {} }: { cid: string, name: string, options?: { verbose?: boolean } },
) => {
const { verbose = false } = options
const apiKey = process.env.BLUMEN_CF_KEY
const zoneId = process.env.BLUMEN_CF_ZONE_ID

Expand Down
33 changes: 26 additions & 7 deletions src/actions/ens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
Hex,
encodeFunctionData,
} from 'viem'
import { MissingKeyError } from '../errors.js'
import { InvalidCIDError, MissingCLIArgsError, MissingKeyError } from '../errors.js'
import { PUBLIC_RESOLVER_ADDRESS, prepareUpdateEnsArgs, abi } from '../utils/ens.js'
import { ChainName } from '../types.js'
import type { ChainName } from '../types.js'
import { privateKeyToAccount } from 'viem/accounts'
import { goerli, mainnet } from 'viem/chains'
import { walletSafeActions, publicSafeActions } from '@stauro/piggybank/actions'
Expand All @@ -21,14 +21,33 @@ import { chainIdToSafeApiUrl } from '../utils/safe.js'
import * as colors from 'colorette'
import { logger } from '../utils/logger.js'
import { isTTY } from '../constants.js'
import { CID } from 'multiformats'

export type EnsActionArgs = Partial<{
chain: ChainName
safe: Address | EIP3770Address
rpcUrl: string
resolverAddress: Address
}>

export const ensAction = async (
cid: string,
domain: string,
{
chain: chainName, safe: safeAddress, rpcUrl, resolverAddress,
}: { chain: ChainName } & Partial<{ safe: Address | EIP3770Address, rpcUrl: string, resolverAddress: Address }>,
{ cid, domain, options = {} }: {
cid: string
domain: string
options: EnsActionArgs
},
) => {
const {
chain: chainName = 'mainnet', safe: safeAddress, rpcUrl, resolverAddress,
} = options

try {
CID.parse(cid)
}
catch {
throw new InvalidCIDError(cid)
}
if (!domain) throw new MissingCLIArgsError([domain])
const chain = chainName === 'mainnet' ? mainnet : goerli

const transport = http(rpcUrl ?? chain.id === 1 ? 'https://rpc.ankr.com/eth' : 'https://rpc.ankr.com/eth_goerli')
Expand Down
13 changes: 9 additions & 4 deletions src/actions/ping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ let retryCount = 0
const gwOfflineMessage = `😞 Max retries exceeded. Gateway is ${colors.bold(colors.red('Offline'))}.`

export const pingAction = async (
cid: string, endpoint: string, { maxRetries: retries = Infinity, retryInterval = 5000, timeout = 10000 }:
Partial<{ maxRetries: number, retryInterval: number, timeout: number }>,
{ cid, endpoint, options }: {
cid: string
endpoint: string
options: Partial<{ maxRetries: number, retryInterval: number, timeout: number }>
},
): Promise<void> => {
const { maxRetries: retries = Infinity, retryInterval = 5000, timeout = 10000 } = options

retryCount++
const url = `https://${cid}.ipfs.${endpoint}`
console.log(`${colors.bold(`[${retryCount}]`)}: Requesting content at ${url}`)
Expand All @@ -17,7 +22,7 @@ export const pingAction = async (
if (retries > 1) {
console.log(`🔄 Retrying in ${retryInterval / 1000} seconds...`)
await new Promise(resolve => setTimeout(resolve, retryInterval))
return pingAction(cid, endpoint, { maxRetries: retries - 1, retryInterval })
return pingAction({ cid, endpoint, options: { maxRetries: retries - 1, retryInterval } })
}
else {
return console.error(gwOfflineMessage)
Expand All @@ -35,7 +40,7 @@ export const pingAction = async (
if (error instanceof DOMException) {
if (retries > 1) {
console.log(`⌛ Timed out. Retrying...`)
return pingAction(cid, endpoint, { maxRetries: retries - 1, retryInterval })
return pingAction({ cid, endpoint, options: { maxRetries: retries - 1, retryInterval } })
}
else {
return console.error(gwOfflineMessage)
Expand Down
7 changes: 5 additions & 2 deletions src/actions/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import { parseTokensFromEnv, findEnvVarProviderName } from '../index.js'
import { pinStatus } from '../utils/pin.js'

export const statusAction = async (
cid: string,
{ providers: providersOptionList, verbose }: { providers: string, verbose?: boolean },
{ cid, options = {} }: {
cid: string
options?: Partial<{ providers: string, verbose: boolean }>
},
) => {
const { providers: providersOptionList, verbose } = options
// Validate CID
try {
CID.parse(cid)
Expand Down
Loading

0 comments on commit fe4de44

Please sign in to comment.