Skip to content

Commit

Permalink
arweave instead of ipfs for image uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
tempe-techie committed Sep 15, 2024
1 parent d0ee51f commit f368aa8
Show file tree
Hide file tree
Showing 29 changed files with 1,000 additions and 1,229 deletions.
13 changes: 11 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
ARWEAVE_ADDRESS=
ARWEAVE_KTY=
ARWEAVE_N=
ARWEAVE_E=
ARWEAVE_D=
ARWEAVE_P=
ARWEAVE_Q=
ARWEAVE_DP=
ARWEAVE_DQ=
ARWEAVE_QI=
FILE_UPLOAD_SERVICE=
IMAGEKIT_ENDPOINT=
IMAGEKIT_PUBLIC_KEY=
IMAGEKIT_PRIVATE_KEY=
LINK_PREVIEW_SERVICE=
RPC_CUSTOM=
TENOR_KEY=
THIRDWEB_CLIENT_ID=
TENOR_KEY=
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

The first NFT launchpad and marketplace on the Degen Chain.

Links:
- https://nftdegen.lol
- https://nftdegen.org (if you're of more serious nature 🤪)
Link: https://nftdegen.lol

## .env

Expand Down Expand Up @@ -51,21 +49,37 @@ If you want to have GIF search implemented, create your own Tenor API Key on Goo

Then enter the key in environment variables (`TENOR_KEY`).

## Image upload (ThirdWeb/IPFS)
## Image upload (Arweave)

To support image uploads on IPFS please create an API key on ThirdWeb: https://thirdweb.com/dashboard/settings/api-keys
To support image uploads, create an Arweave Wallet (e.g. here: https://arweave.app/) and send some AR to it.

Make sure to whitelist only your website domain/URL. And also restrict (toggle off) the API key usage for other services apart from Storage Upload service (even Storage Download is not needed).
Then go to the wallet settings and download Backup Keyfile.

Then add the Client ID of your API key to your environment variables:
In this file you'll find 10 different variables, enter these into your .env file:

```bash
THIRDWEB_CLIENT_ID=
ARWEAVE_KTY=
ARWEAVE_N=
ARWEAVE_E=
ARWEAVE_D=
ARWEAVE_P=
ARWEAVE_Q=
ARWEAVE_DP=
ARWEAVE_DQ=
ARWEAVE_QI=
```

## Image upload fallback
And add the arweave address too:

It is recommended to use ImageKit as the fallback option, in case Thirdweb has technical issues.
```bash
ARWEAVE_ADDRESS=
```

Also make sure these variables are set on your hosting provider (Netlify, Vercel, etc).

## ImageKit upload

It is recommended to use ImageKit as the fallback option, in case Arweave has technical issues.

For this to work, create an account at [ImageKit.io](https://imagekit.io/) and add these environment variables to your project:

Expand All @@ -75,6 +89,8 @@ IMAGEKIT_PUBLIC_KEY=
IMAGEKIT_PRIVATE_KEY=
```

You can also use ImageKit as your main image upload, if you set the `fileUploadStorageType` variable in nuxt config to "imagekit".

## Customize

- Project-specific settings in `nuxt.config.ts`
Expand Down
61 changes: 61 additions & 0 deletions api/arweaveUploader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Arweave from 'arweave';
import { Buffer } from 'buffer';

export default async function handler(req, res) {
// Check if the request method is POST
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method Not Allowed' });
}

try {
const { fileData, fileName, fileType } = req.body;

// Initialize Arweave
const arweave = Arweave.init({
host: 'arweave.net',
port: 443,
protocol: 'https'
});

// Construct the key file object from environment variables
const keyFile = {
kty: process.env.ARWEAVE_KTY,
n: process.env.ARWEAVE_N,
e: process.env.ARWEAVE_E,
d: process.env.ARWEAVE_D,
p: process.env.ARWEAVE_P,
q: process.env.ARWEAVE_Q,
dp: process.env.ARWEAVE_DP,
dq: process.env.ARWEAVE_DQ,
qi: process.env.ARWEAVE_QI
};

// Convert base64 file data to buffer
const fileBuffer = Buffer.from(fileData, 'base64');

// Create a transaction
const transaction = await arweave.createTransaction({ data: fileBuffer }, keyFile);

// Add tags to the transaction
transaction.addTag('Content-Type', fileType);
transaction.addTag('File-Name', fileName);

// Sign the transaction
await arweave.transactions.sign(transaction, keyFile);

// Submit the transaction
const response = await arweave.transactions.post(transaction);

if (response.status === 200) {
return res.status(200).json({
message: 'File uploaded successfully',
transactionId: transaction.id
});
} else {
throw new Error('Failed to upload file to Arweave');
}
} catch (error) {
console.error('Error:', error);
return res.status(500).json({ message: 'Internal server error' });
}
}
14 changes: 7 additions & 7 deletions api/imageUploaderFallback.js → api/imageKitUploader.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const ImageKit = require("imagekit");
const ImageKit = require('imagekit')

export default async function handler(request, response) {
try {
const imagekit = new ImageKit({
urlEndpoint: process.env.IMAGEKIT_ENDPOINT,
publicKey: process.env.IMAGEKIT_PUBLIC_KEY,
privateKey: process.env.IMAGEKIT_PRIVATE_KEY
privateKey: process.env.IMAGEKIT_PRIVATE_KEY,
})

return response.status(200).json({
data: imagekit.getAuthenticationParameters()
});
data: imagekit.getAuthenticationParameters(),
})
} catch (error) {
console.error(error);
next(error);
console.error(error)
next(error)
}
}
}
25 changes: 0 additions & 25 deletions api/pinIpfsCid.js

This file was deleted.

35 changes: 0 additions & 35 deletions api/pinIpfsCid2.js

This file was deleted.

2 changes: 2 additions & 0 deletions components/Image.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export default {
if (parsedImage && parsedImage.includes("ipfs://")) {
parsedImage = parsedImage.replace("ipfs://", this.$config.ipfsGateway);
} else if (parsedImage && parsedImage.includes("ar://")) {
parsedImage = parsedImage.replace("ar://", this.$config.arweaveGateway);
}
return parsedImage;
Expand Down
2 changes: 1 addition & 1 deletion components/chat/ChatFeed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
@processFileUrl="insertImage"
title="Upload image"
infoText="Upload an image."
storageType="imagekit"
:storageType="$config.fileUploadStorageType"
:componentId="$.uid"
:maxFileSize="$config.fileUploadSizeLimit"
/>
Expand Down
2 changes: 1 addition & 1 deletion components/nft/collection/AddImageToCollectionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<FileUploadInput
btnCls="btn btn-primary"
:maxFileSize="$config.fileUploadSizeLimit"
storageType="imagekit"
:storageType="$config.fileUploadStorageType"
@processUploadedFileUrl="insertImageLink"
/>

Expand Down
2 changes: 1 addition & 1 deletion components/nft/collection/ChangeCollectionPreviewModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<FileUploadInput
btnCls="btn btn-primary"
storageType="imagekit"
:storageType="$config.fileUploadStorageType"
:maxFileSize="$config.fileUploadSizeLimit"
@processUploadedFileUrl="insertImageLink"
/>
Expand Down
3 changes: 1 addition & 2 deletions components/nft/collection/ChangeMediaModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
<div class="modal-body">
<p>Change media metadata for your NFT.</p>
<p>You will need to upload these files somewhere first, we recommend
<a target="_blank" href="https://thirdweb.com/dashboard/settings/storage">Thirdweb</a>, or
<a target="_blank" href="https://filebase.com/">Filebase</a>.
<a target="_blank" href="https://ardrive.io/">ArDrive</a>.
</p>

<div class="mt-4">
Expand Down
6 changes: 4 additions & 2 deletions components/nft/collection/SendNftModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export default {
return;
}
const tokenURI = await nftContract.tokenURI(this.tokenId);
let tokenURI = await nftContract.tokenURI(this.tokenId);
if (tokenURI.startsWith("ipfs://")) {
tokenURI = tokenURI.replace("ipfs://", this.$config.ipfsGateway);
Expand All @@ -176,7 +176,9 @@ export default {
if (json["image"].startsWith("ipfs://")) {
json["image"] = json["image"].replace("ipfs://", this.$config.ipfsGateway);
}
} else if (json["image"].startsWith("ar://")) {
json["image"] = json["image"].replace("ar://", this.$config.arweaveGateway);
}
this.nftImage = json["image"];
this.nftDataLoaded = true;
Expand Down
2 changes: 1 addition & 1 deletion components/profile/PunkProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
@processFileUrl="insertImage"
title="Change profile image"
infoText="Upload a new profile picture."
storageType="imagekit"
:storageType="$config.fileUploadStorageType"
:componentId="$.uid"
:maxFileSize="$config.fileUploadSizeLimit"
/>
Expand Down
Loading

0 comments on commit f368aa8

Please sign in to comment.