diff --git a/README.md b/README.md index c8ae6de..ea5bec7 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,36 @@ Inspired by the [cookbook github action deployment guide](https://cookbook.arweave.dev/guides/deployment/github-action.html), `permaweb-deploy` is a Node.js command-line tool designed to streamline the deployment of JavaScript bundles to the permaweb using Arweave. It simplifies the process by bundling JS code, deploying it as a transaction to Arweave, and updating ArNS (Arweave Name Service) with the transaction ID. ### Features + - **Bundle Deployment:** Automatically bundles your JS code and deploys it to Arweave. - **ArNS Update:** Updates ArNS with the new transaction ID each time new content is deployed. - **Automated Workflow:** Integrates with GitHub Actions for continuous deployment directly from your repository. +- **Cross-chain support:** Upload data to Arweave and update ArNS using Arweave, Eth, or POL/Matic wallets. ### Installation + Install the package using npm: + ```bash npm install permaweb-deploy ``` ### Prerequisites + Before using `permaweb-deploy`, you must: + 1. Encode your Arweave wallet key in base64 format and set it as a GitHub secret: ```bash base64 -i wallet.json | pbcopy ``` -3. Ensure that the secret name for the encoded wallet is `DEPLOY_KEY`. + +2. Ensure that the secret name for the encoded wallet is `DEPLOY_KEY`. + +**NOTE:** ETH and POL/Matic wallets should use their private key, **_WITHOUT_** base64 encoding for `DEPLOY_KEY` ### Usage + To deploy your application, ensure you have a build script and a deployment script in your `package.json`: ```json @@ -34,8 +44,40 @@ To deploy your application, ensure you have a build script and a deployment scri Replace `` with your actual ANT process. +#### Deploy Folder + +The default folder to upload is `./dist`, you can specify a different folder path using the `--deploy-folder` flag: + +```bash +permaweb-deploy --ant-process --deploy-folder "./next" +``` + +#### Ethereum and POL/Matic + +Permaweb-deploy defaults to uploading with an Arweave Wallet. You can specify an ETH or POL/Matic wallet by providing a `--sig-type` flag with the values "ethereum" or "polygon". + +```bash +permaweb-deploy --ant-process --sig-type 'polygon' +``` + +The `DEPLOY_KEY` environmental variable must be set to the private key of the ETH or POL/Matic wallet, without any additional encoding. + +**NOTE:** All uploads via Permaweb-deploy are paid for using Turbo Credits, you cannot pay for an upload using the native token for ETH or POL/Matic directly. Get Turbo Credits at [turbo-topup.com](https://turbo-topup.com/) + +#### Undernames + +Permaweb-deploy can update undername records for an ArNS name instead of the top level name. That is, you can deploy your project to `this-project_my-name` where `this-project` is an undername on the ArNS name `my-name`. + +This is done by specifying the undername using the `--undername` flag: + +```bash +permaweb-deploy --ant-process --undername "this-project" +``` + ### GitHub Actions Workflow + To automate the deployment, set up a GitHub Actions workflow as follows: + ```yaml name: publish @@ -65,6 +107,7 @@ DEPLOY_KEY=$(base64 -i wallet.json) npx permaweb-deploy --ant-process fs.createReadStream(filePath), - fileSizeFactory: () => fileSize, - signal: AbortSignal.timeout(10_000), // cancel the upload after 10 seconds - dataItemOpts: { - tags: [ - { name: 'Content-Type', value: contentType }, - { name: 'App-Name', value: 'Permaweb-Deploy' }, - ], - }, - }); - - console.log(`Uploaded ${relativePath} with id:`, uploadResult.id); - // adds uploaded file txId to the new manifest json - newManifest.paths[relativePath] = { id: uploadResult.id }; - - if (file === '404.html') { - // sets manifest fallback to 404.html if found - newManifest.fallback.id = uploadResult.id; - } - } catch (err) { - console.error(`Error uploading file ${relativePath}:`, err); - } - } - } catch (err) { - console.error('ERROR:', err); - } - } - } - - async function uploadManifest(manifest) { - try { - const manifestString = JSON.stringify(manifest); - const uploadResult = await turbo.uploadFile({ - fileStreamFactory: () => Readable.from(Buffer.from(manifestString)), - fileSizeFactory: () => Buffer.byteLength(manifestString), - signal: AbortSignal.timeout(10_000), - dataItemOpts: { - tags: [ - { - name: 'Content-Type', - value: 'application/x.arweave-manifest+json', - }, - { - name: 'App-Name', - value: 'Permaweb-Deploy', - }, - ], - }, - }); - return uploadResult.id; - } catch (error) { - console.error('Error uploading manifest:', error); - return null; - } - } - - // starts processing files in the selected directory - await processFiles(deployFolder); - - if (!newManifest.fallback.id) { - // if no 404.html file is found, manifest fallback is set to the txId of index.html - newManifest.fallback.id = newManifest.paths['index.html'].id; - } - - const manifestId = await uploadManifest(newManifest); - if (manifestId) { - console.log(`Manifest uploaded with Id: ${manifestId}`); - return manifestId; - } -}